[PATCH] ld/PE: Handle MS style import libraries for files named *.exe too

Martin Storsjö martin@martin.st
Mon Nov 11 12:27:13 GMT 2024


On Mon, 11 Nov 2024, Jan Beulich wrote:

>> Another alternative would be to invert the condition - skipping this for
>> any member which is named *.o, which should cover practically all the GNU
>> import libraries (and also skipping it if it doesn't contain .idata
>> sections). But that's only marginally better than the current solution,
>> looking for *.dll and/or *.exe.
>
> Checking for *.o wouldn't be any better. No file name checks whatsoever
> will be.

I agree that file name based checks are not ideal - but given the actual 
potential static libraries that exist, it would be a less problematic file 
name based check.

For regular static libraries, they commonly contain files named *.o. The 
same goes for the import libraries generated by GNU tools. To be 
marginally more generic, we could also extend it to cover *.obj which 
would be static libraries produced by MSVC toolchains.

However the MSVC style import libraries contain members named *.dll, 
*.exe, *.drv, etc.

Therefore, I think that enumerating the file name extensions of regular 
object files, *.o and *.obj, is easier than enumerating the potential file 
name extensions in the MSVC style import libraries.

And as long as we still have a check for "object file contains .idata 
sections", the only critical case to cover is the other cases that do 
fulfill this condition, i.e. import libraries produced by GNU tools, which 
contain members named *.o.

> However, for Windows-style libraries actual section contents (and 
> relocations) are "manufactured" by pe_ILF_build_a_bfd(). Can't that flag 
> the resulting bfd-s in some way, to at least mostly eliminate the need 
> for heuristics?

No, that wouldn't suffice - because the ILF form MS import libraries also 
contain a handful of regular COFF object files (for the header/trailer).

To visualize it more clearly:

Import library created by GNU tools, allegedly also used by really old MS 
tools, contains the following members:

mylib_dll_h.o      - header, regular COFF object
mylib_dll_s00000.o - import for one symbol, regular COFF object
mylib_dll_s00001.o - import for another symbol, regular COFF object
mylib_dll_t.o      - trailer, regular COFF object

Import library created by modern MSVC tools:

mylib.dll - header, regular COFF object
mylib.dll - import for one symbol, ILF style file
mylib.dll - import for another symbol, ILF style file
mylib.dll - trailer 1, regular COFF object
mylib.dll - trailer 2, regular COFF object

For the ILF style files, you're right that we're synthesizing things with 
pe_ILF_build_a_bfd, and we could identify it that way. However that's not 
the main question.

The main question is about the header/trailer objects, which are regular 
COFF objects. On that level, they're indistinguishable from the regular 
COFF object files in the old/GNU style import libraries, as long as we 
only look at the contents of the individual archive member file.

The only differentiating feature, as far as I know, is the file name; 
either the suffix itself, or the fact that we have multiple archive 
members with the same file name.

> Then again that wouldn't cover the non-ILF form that MS also used ages 
> ago (which I expect you mean when talking about GNU format import 
> libraries), where this (admittedly odd) re-ordering would also appear to 
> be necessary.

TBH, I've read about MS using this form as well, but the oldest MSVC I've 
tried was 6.0 from 1998, and that one already used the new/modern format. 
It's possible to get access to older versions to inspect them, but I 
haven't yet set that up.

> I wonder how LINK.EXE actually manages to get the objects / section
> constituents correctly ordered. The numbering of the sub-portions of the
> section (.idata$2 etc) alone doesn't look to be sufficient (when pretty
> clearly that must have been the original goal).

Yeah I'm not entirely sure how they do it either (and I haven't tried 
reverse engineering it); for the old style files they clearly seem to be 
sorting things based on archive member name just like GNU ld does, but I'm 
not sure what heuristics they use for the ILF style files, for sorting the 
headers/trailers correctly.

// Martin



More information about the Binutils mailing list