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

Martin Storsjö martin@martin.st
Thu Nov 7 12:21:40 GMT 2024


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.

So if we only need the detection for the per-symbol special files, it'd be 
simple to do, but I think the handling of them also requires remapping 
their file names as well.

So the condition would need to be something like "if there's another 
member file within the same archive, with the exact same file name and 
which is a short import file, treat this regular object file as a short 
import library". And that's kinda messy to apply if we're just doing a 
single pass over the archive members.

So all in all, less simple than I'd want to, so I haven't dug further into 
it, not quite yet at least.

>> --- a/ld/emultempl/pe.em
>> +++ b/ld/emultempl/pe.em
>> @@ -1753,7 +1753,8 @@ gld${EMULATION_NAME}_after_open (void)
>>  	       objects.  */
>>  	    pnt = strrchr (bfd_get_filename (is->the_bfd), '.');
>>
>> -	    if (pnt != NULL && (fileext_cmp (pnt + 1, "dll") == 0))
>> +	    if (pnt != NULL && (fileext_cmp (pnt + 1, "dll") == 0 ||
>> +                                fileext_cmp (pnt + 1, "exe") == 0))
>
> Please get indentation right here and ...
>
>> --- a/ld/emultempl/pep.em
>> +++ b/ld/emultempl/pep.em
>> @@ -1736,7 +1736,8 @@ gld${EMULATION_NAME}_after_open (void)
>>  	       objects.  */
>>  	    pnt = strrchr (bfd_get_filename (is->the_bfd), '.');
>>
>> -	    if (pnt != NULL && (fileext_cmp (pnt + 1, "dll") == 0))
>> +	    if (pnt != NULL && (fileext_cmp (pnt + 1, "dll") == 0 ||
>> +                                fileext_cmp (pnt + 1, "exe") == 0))
>
> ... here (in case the approach is to be kept): As many hard tabs as
> possible followed by as many blanks as necessary.

Indeed, I noticed this after posting this patch, so I have it fixed up 
locally. I can send a new patch with that fixed.

// Martin


More information about the Binutils mailing list