[Patch: mingw/cygwin] Don't strip '@' dangles from stdcall/fastcall dllimport references

Danny Smith dannysmith@clear.net.nz
Fri Jul 13 09:28:00 GMT 2007


Hello

The following testcase fails on mingw32 and cygwin (and has done since
the 2007-03-29 rewrite of dllimport by Richard Henderson)


/* Ensure that MS Windows stdcall and fastcall decorations are applied
  to assembler name of dllimports. */

/* { dg-do compile { target i?86-pc-cygwin i?86-pc-mingw* } } */

void __attribute__((dllimport, fastcall)) bar (int);
void __attribute__((dllimport, stdcall))  foo (int);
void bas (void);
 
void bas()
{
  bar(1);
  foo(1);
}
 
/* { dg-final { scan-assembler "__imp_@bar@4" } } */
/* { dg-final { scan-assembler "__imp__foo@4" } } */

The '@n' decorations are lost on dllimports


The reason is that i386/i386.c:get_dllimport_decl() uses
targetm.strip_name_encoding to strip off extra encoding from the
assembler name. However, the cygwin/mingw version of strip_name_encoding
imcorrectly stips off the fastcall and stdcall decorations. These
dangles are actually part of the external identifier string
(analogous to the mangling of C++ symbols) and should not be stripped.

Using the default_strip_name_encoding works just fine on mingw and
cygwin. In varasm.c:assemble_name(), the identifier that we really want
to mark as referenced is the one that points to the decorated name. When
when we do want to strip off the '@' dangles (when generating section
names
in winnt.c:i386_pe_unique_section), we use
i386_pe_strip_name_encoding_full instead of targetm.strip_name_encoding

There is a related thinko in i386.c:get_dllimport_decl(). With fastcall
names we do not want to skip over the '@' prefix but keep it as part of
the external reference.

I am surprised that nobody else has noticed this. The following patch
has been in my tree since mid-April, but I had forgotten why it was
there. ): It fixes the problem, with no new testsuite regressions. In
addition it allows bootstrap of gcc with -D__W32API_USE_DLLIMPORT__ in
CFLAGS. This is an optimization which causes win32api functions to be
imported using dllimport semantics. Almost all win32api use stdcall
attribute.


2007-07-13  Danny Smith  <dannysmith@users.sourceforge.net>

	* config/i386/cygming.h (TARGET_STRIP_NAME_ENCODING): Don't
	override default.
	* config/i386/i386.c (get_dllimport_decl): Don't strip
	FASTCALL_PREFIX.

testsuite
	* gcc.dg/dll-7.c: New file.


Index: config/i386/cygming.h
===================================================================
*** config/i386/cygming.h	(revision 126544)
--- config/i386/cygming.h	(working copy)
*************** do {
\
*** 184,191 ****
     Note that we can be called twice on the same decl.  */
  
  #define SUBTARGET_ENCODE_SECTION_INFO  i386_pe_encode_section_info
- #undef  TARGET_STRIP_NAME_ENCODING
- #define TARGET_STRIP_NAME_ENCODING  i386_pe_strip_name_encoding_full
  
  /* Output a common block.  */
  #undef ASM_OUTPUT_ALIGNED_DECL_COMMON
--- 184,189 ----
Index: config/i386/i386.c
===================================================================
*** config/i386/i386.c	(revision 126542)
--- config/i386/i386.c	(working copy)
*************** get_dllimport_decl (tree decl)
*** 7588,7601 ****
  
    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    name = targetm.strip_name_encoding (name);
!   if (name[0] == FASTCALL_PREFIX)
!     {
!       name++;
!       prefix = "*__imp_";
!     }
!   else
!     prefix = "*__imp__";
! 
    namelen = strlen (name);
    prefixlen = strlen (prefix);
    imp_name = (char *) alloca (namelen + prefixlen + 1);
--- 7588,7594 ----
  
    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    name = targetm.strip_name_encoding (name);
!   prefix = name[0] == FASTCALL_PREFIX  ?  "*__imp_" : "*__imp__";
    namelen = strlen (name);
    prefixlen = strlen (prefix);
    imp_name = (char *) alloca (namelen + prefixlen + 1);
*** /dev/null	Fri Jul 13 20:08:41 2007
--- testsuite/gcc.dg/dll-7.c	Fri Jul 13 20:05:25 2007
***************
*** 0 ****
--- 1,17 ----
+ /* Ensure that MS Windows stdcall and fastcall decorations are
+    applied to assembler name of dllimports.  */
+ 
+ /* { dg-do compile { target i?86-pc-cygwin i?86-pc-mingw* } } */
+ 
+ void __attribute__((dllimport, fastcall)) bar (int);
+ void __attribute__((dllimport, stdcall))  foo (int);
+ void bas (void);
+  
+ void bas()
+ {
+   bar(1);
+   foo(1);
+ }
+ 
+ /* { dg-final { scan-assembler "__imp_@bar@4" } } */
+ /* { dg-final { scan-assembler "__imp__foo@4" } } */



More information about the Gcc-patches mailing list