[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Another bug in GNU ld for Win32.
From: |
Nick Clifton |
Subject: |
Re: Another bug in GNU ld for Win32. |
Date: |
Mon, 15 Dec 2003 19:10:25 +0000 |
User-agent: |
Gnus/5.1001 (Gnus v5.10.1) Emacs/21.2 (gnu/linux) |
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 '@' */