|
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 '@' */
[Prev in Thread] | Current Thread | [Next in Thread] |