bug-binutils
[Top][All Lists]
Advanced

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

[Bug binutils/31728] New: dlltool generates incorrect hints in import li


From: pali at kernel dot org
Subject: [Bug binutils/31728] New: dlltool generates incorrect hints in import libraries
Date: Fri, 10 May 2024 19:30:40 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=31728

            Bug ID: 31728
           Summary: dlltool generates incorrect hints in import libraries
           Product: binutils
           Version: 2.43 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: pali at kernel dot org
  Target Milestone: ---

When dlltool is requested to generate import library from the def file, it
generates incorrect hints of the symbols.

I scanned the git repository I and found that breakage happened by commit
35fd2ddeb1d90f1750401cfb6d01fe055656b88d (Generate correct hint value for
IDATA6). Before that commit it was correct.

After reverting this commit on top of the master branch, dlltool started
generated correct hints again for symbols into import library.


Test case for reproducing this problem:

First create very simple DLL library with 3 exported functions:

cat library.c
void func2(void) {}
void func1(void) {}
void func0(void) {}
int __attribute__((stdcall)) _DllMainCRTStartup(void *handle, unsigned int
reason, void *reserved)
{
  return 1;
}

$ cat library.def
LIBRARY "library.dll"
EXPORTS
func0 @2
func1 @3
func2 @1

$ i686-w64-mingw32-gcc -c library.c -Os
$ ld -m i386pe -b pe-i386 -s -shared -o library.dll library.o library.def


Now examine exported symbols from the created dll library. As GNU binutils does
not provide a tool to show hint indexes of exported symbols from DLL library
(or at least I do not know which/how), show it via MSVC DUMPBIN.EXE tool:

$ dumpbin.exe /exports library.dll
...
            ordinal hint   name

                  2    0   func0  (00001000)
                  3    1   func1  (00001001)
                  1    2   func2  (00001002)

As can be seen the GNU LD puts exported symbols into the DLL library in order
as they are specified in the DEF file. In this order they are also in the
Export name table, which provides the hint number.


Now create an import library from def file and link it with test executable.

$ cat test.c
__attribute__((dllimport)) void func0(void);
__attribute__((dllimport)) void func1(void);
__attribute__((dllimport)) void func2(void);
int mainCRTStartup(void)
{
  func1();
  func0();
  func2();
  return 0;
}

$ dlltool -d library.def -l library.a --as i686-w64-mingw32-as
$ i686-w64-mingw32-ranlib library.a
$ i686-w64-mingw32-gcc -c test.c -Os
$ ld -m i386pe -b pe-i386 -s -o test.exe test.o library.a


And inspect it via GNU objdump and readpe utility:

$ objdump -p test.exe
...
The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00003000       00003028 00000000 00000000 0000306c 00003038

        DLL Name: library.dll
        vma:  Hint/Ord Member-Name Bound-To
        3048        2  func0
        3050        3  func1
        3058        1  func2

$ readpe -i test.exe
Imported functions
    Library
        Name:                            library.dll
        Functions
            Function
                Hint:                            2
                Name:                            func0
            Function
                Hint:                            3
                Name:                            func1
            Function
                Hint:                            1
                Name:                            func2



As can be seen, hints of the symbols in test.exe do not match hints of the
exported symbols from the library.dll. Which indicates that the import library
contains incorrect hints (generated by dlltool).

Now I reverted commit 35fd2ddeb1d90f1750401cfb6d01fe055656b88d, re-run dlltool,
ranlib and ld. And inspection of the created test.exe shows:

$ objdump -p test.exe
...
The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00003000       00003028 00000000 00000000 0000306c 00003038

        DLL Name: library.dll
        vma:  Hint/Ord Member-Name Bound-To
        3048        0  func0
        3050        1  func1
        3058        2  func2

$ readpe -i test.exe
Imported functions
    Library
        Name:                            library.dll
        Functions
            Function
                Hint:                            0
                Name:                            func0
            Function
                Hint:                            1
                Name:                            func1
            Function
                Hint:                            2
                Name:                            func2


As can be seen now after reverting that commit
35fd2ddeb1d90f1750401cfb6d01fe055656b88d, hits in the test.exe matches the
hints in the library.dll as was shown by dumpbin.exe.

I'm not sure what that commit should do, but this experiment show that it is
wrong.

Hints and ordinal numbers are two different things, they cannot be exchanged.
When def file does not contain any explicit ordinal number, then ordinal number
== hint+1. But when def file contains ordinal number, there is no correlation
between hints and ordinal numbers (as can be seen in the test example).


Some more details and explanation:

Every exported symbol from DLL library contains its ordinal number and
optionally also its name and its hint index. Hint index is an index of the name
in the Export name table.

When executable (or other DLL library) depends on symbol from another DLL
library, it can reference it either by ordinal number or by symbol name. If the
second option (by symbol name) is used then part of it is also optional hint
index.

PE loader loads dependent library and look into that library Export name table
at position of hint index. If the name in that table matches with the name of
the symbol on which executable depends then it is used. If does not match
(meaning that hint index was incorrect or zero - not provided), then PE loader
scans the Export name table until it finds entry with the requested symbol
name.

So it means that also executable with incorrect hints can be properly loaded,
works fine and the issue does not have to be spotted.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

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