This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch: mingw/cygwin] Don't strip '@' dangles from stdcall/fastcall dllimport references
- From: Danny Smith <dannysmith at clear dot net dot nz>
- To: GCC-patches <gcc-patches at gcc dot gnu dot org>
- Cc: Dave Korn <dave dot korn at artimi dot com>, rth at redhat dot com
- Date: Fri, 13 Jul 2007 21:12:02 +1200
- Subject: [Patch: mingw/cygwin] Don't strip '@' dangles from stdcall/fastcall dllimport references
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" } } */