[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.
- [Bug binutils/31728] New: dlltool generates incorrect hints in import libraries,
pali at kernel dot org <=