bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Another bug in GNU ld for Win32.


From: Eric Youngdale
Subject: RE: Another bug in GNU ld for Win32.
Date: Mon, 15 Dec 2003 15:34:58 -0500


        This patch also works.  I guess my concern is that I don't know under what circumstances a leading @ or '?' will appear in a name.  For what it is worth, I made a slightly different test using a C++ program that called the global new operator.  As it turns out, that symbol is mangled to:

        address@hidden@Z

what is interesting is that the symbol type for that comes as IMPORT_NAME, and hence the section of code in question isn't even executed.

        The Microsoft documentation for IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE simply states "Import name == public symbol name skipping leading ?, @, or optionally _".  Does this mean at most one character, or does it mean at most one of each?  If we had a specific example, I suppose it would be easier to say one way or another.  I cannot help but wonder if this is just a legasy of a different name mangling scheme used by a much older compiler.

-Eric


-----Original Message-----
From: Nick Clifton [mailto:address@hidden]
Sent: Monday, December 15, 2003 2:10 PM
To: Eric Youngdale
Cc: 'address@hidden'
Subject: Re: Another bug in GNU ld for Win32.


Hi Eric,

>        This is a problem that comes up when you use a Microsoft
>    generated import library, using MSVC >= 6.  The problem is that
>    the imports listed in the .idata table have the wrong names -
>    functions that have multiple leading underscores have them all
>    stripped, and these exports don't exist in the referenced dll.
>    Functions that have only a single leading underscore were fine.
>
>        I don't know offhand about symbols that start with '?' or
>    '@'.  I would want to see examples before I could say what is
>    correct, I suppose.

I think that the intention of the code was to strip any single
occurrence of a leading underscore and/or @-sign or question mark.

I agree that the way that this is coded is incorrect, however I would
like to propose a slightly different patch.  Please could you try out
the change below and let me know if it fixes the problem that you
encountered ?

Cheers
        Nick
       
Index: bfd/peicode.h
===================================================================
RCS file: /cvs/src/src/bfd/peicode.h,v
retrieving revision 1.39
diff -c -3 -p -r1.39 peicode.h
*** bfd/peicode.h       31 Oct 2003 05:32:46 -0000      1.39
--- bfd/peicode.h       15 Dec 2003 19:15:44 -0000
*************** pe_ILF_build_a_bfd (bfd *           abfd
*** 902,911 ****
        symbol = symbol_name;
 
        if (import_name_type != IMPORT_NAME)
!       /* Skip any prefix in symbol_name.  */
!       while (*symbol == '@' || * symbol == '?' || * symbol == '_')
!         ++ symbol;
 
        if (import_name_type == IMPORT_NAME_UNDECORATE)
        {
          /* Truncate at the first '@'  */
--- 902,941 ----
        symbol = symbol_name;
 
        if (import_name_type != IMPORT_NAME)
!       {
!         bfd_boolean skipped_leading_underscore = FALSE;
!         bfd_boolean skipped_leading_at = FALSE;
!         bfd_boolean skipped_leading_question_mark = FALSE;
!         bfd_boolean check_again;
!        
!         /* Skip any prefix in symbol_name.  */
!         -- symbol;
!         do
!           {
!             check_again = FALSE;
!             ++ symbol;
 
+             switch (*symbol)
+               {
+               case '@':
+                 if (! skipped_leading_at)
+                   check_again = skipped_leading_at = TRUE;
+                 break;
+               case '?':
+                 if (! skipped_leading_question_mark)
+                   check_again = skipped_leading_question_mark = TRUE;
+                 break;
+               case '_':
+                 if (! skipped_leading_underscore)
+                   check_again = skipped_leading_underscore = TRUE;
+                 break;
+               default:
+                 break;
+               }
+           }
+         while (check_again);
+       }
+      
        if (import_name_type == IMPORT_NAME_UNDECORATE)
        {
          /* Truncate at the first '@'  */


reply via email to

[Prev in Thread] Current Thread [Next in Thread]