[PATCH] D38513: [LLD] [RFC] [COFF] Add support for GNU binutils import libraries

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 11 23:27:31 PDT 2017


mstorsjo added a comment.

In https://reviews.llvm.org/D38513#895246, @smeenai wrote:

> Could you elaborate on "the first object file in the static import library to be included is the function itself"? Is the function in question the linker-provided import thunk, or something else?


It's the import library provided import thunk.

To elaborate:
Given an import library for a dll testlib.dll, it contains a number of object files, d000000.o, d000001.o etc.

The first one, d000000.o, contains (among others) the symbols `__IMPORT_DESCRIPTOR_testlib` and `__head_testlib_dll`, which among others contains references to local zero bytes sections `.idata$4` and `.idata$5`, intended to get a pointer to the start of the IAT for this DLL, and a reference to `_testlib_dll_iname`.

A later one, d000010.o in my test case, contains the symbols `func` and `__imp_func`, and contains 4 bytes of data for `.idata$4` and `.idata$5` (filling in one entry in the IAT), and a reference to `__head_testlib_dll`.

Finally, the last one in the library, d000011.o in my test, contains `_testlib_dll_iname` and 4 null byte terminators for `.idata$4` and `.idata$5`.

Now while linking the module that might reference this import library, initially no object files from the import library are included. When encountering an undefined reference to `func` or `__imp_func`, it will pull in `d000010.o` which defines those. This object has an undefined reference to `__head_testlib_dll` which pulls in `d000000.o`, which in turn has got an undefined reference to `_testlib_dll_iname` which pulls in `d000011.o`.

This means that the object files, ordered by the order they are referenced (as I think lld does it right now?) is `d000010.o`, `d000000.o` and `d000011.o`. This means that the `.idata$5` section group will be: [func entry 4 bytes] [0 bytes section chunk, referenced from the import descriptor] [4 null bytes terminator]. This means that the import descriptor actually points at the terminator. And if any other functions from the same import library were to be linked later, they would end up after the terminator. Or worse, if imports are done from multiple import libraries, they end up intermixed.

By enforcing the object files to be ordered alphabetically (or e.g. by their respective order in the import library archive), I make sure that the `.idata$5` section group starts with [0 bytes section chunk referenced from the import descriptor], then [func entry 4 bytes] for every function referenced in the library, finishing with [4 null bytes terminator].

But this hack then turned out to break other things when linking msvcrt.lib (which contains a number of actual object files as well, in addition to the normal import library entries), exactly what it broke is yet undiagnosed.


https://reviews.llvm.org/D38513





More information about the llvm-commits mailing list