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.