[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