[PATCH] ld/PE: Handle MS style import libraries for files named *.exe too
Martin Storsjö
martin@martin.st
Fri Nov 8 12:09:22 GMT 2024
On Fri, 8 Nov 2024, Jan Beulich wrote:
> On 07.11.2024 13:21, Martin Storsjö wrote:
>> On Thu, 7 Nov 2024, Jan Beulich wrote:
>>
>>> On 06.11.2024 10:31, Martin Storsjö wrote:
>>>> When handling MS style import libraries (also called short import
>>>> libraries, or ILF), we need to detect the kind of library.
>>>>
>>>> So far, this has been done by looking at the member file names
>>>> in the import library - in an MS style import library, all the
>>>> member files for a specific library have the same member file
>>>> name - the name of the runtime module to link against. Usually
>>>> this is a DLL - thus we do a case insensitive comparison and
>>>> check if the suffix is .dll.
>>>>
>>>> However, an .exe can also export symbols which can be linked
>>>> against in the same way. In particular, if linking against
>>>> WDK (Windows Driver Kit) import libraries, e.g. wdmsec.lib, the
>>>> import libraries can provide imports for ntoskrnl.exe.
>>>>
>>>> Thus extend the preexisting check from checking for the .dll
>>>> suffix to also checking for .exe. While this isn't entirely
>>>> complete and scalable (in theory, such libraries could have
>>>> any suffix), this should cover a larger majority of them.
>>>
>>> How difficult would it be to remove this dependency on file name
>>> extensions? I really don't like going from 1 to 2, when - as you
>>> validly say - any can be used. Just think of drivers, using .drv.
>>
>> I haven't fully thought it through, but I think it's unfortunately less
>> easy than it seems on first glance.
>>
>> For the long import libraries that GNU tools generate, the import
>> libraries consist of a bunch of files named <common_base><suffix>.o - all
>> of these are regular object files.
>>
>> For the MS import libraries, all member file names are named the same,
>> e.g. "kernel32.dll". Most of them (for each imported symbol) aren't object
>> files, but the special short import file format, and it should be simple
>> to detect this just by looking at the contents of the files. But for the
>> header and trailer object files, those are plain regular object files,
>> just like in the long import libraries.
>>
>> So for the individual symbols, we can easily detect this, but for
>> headers/trailers, we don't see anything different than just regular object
>> files.
>
> Is that really the case? Would an ordinary object file ever have (non-
> empty, i.e. not just marker) .idata$<N> sections?
Normal (user code) object files normally wouldn't have such sections - but
some special cases (custom user code doing things similar to import
libraries) might, e.g. it wouldn't surprise me if Wine had something like
that somewhere.
> IOW can't the file name check simply be dropped, relying on
>
> /* An archive member named .dll, but not having any .idata
> sections - apparently not a Microsoft import object
> after all: Skip renaming it. */
> if (!idata)
> continue;
>
> in the middle of the loop instead (with the comment adjusted)?
No, I don't think that would work entirely as wanted.
Then it would try to do renaming of every archive member, skip it for
normal code object files (which don't have .idata sections), but it would
do renaming of all the archive members in GNU style import libraries too,
as those all contain .idata sections.
It's possible that it would be benign and end up working anyway - but
ideally we shouldn't be doing this fixup for anything else than the MS
import libraries.
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.
> Talking of comments - if your change was the one to go in, it'll also need
> to update those comments talking of .dll.
Right, sure.
// Martin
More information about the Binutils
mailing list