[PATCH 0/3] PE delay import fixes

Jeremy Drake sourceware-bugzilla@jdrake.com
Tue Apr 22 17:45:33 GMT 2025


Ping after 1 week.  My mail client doesn't like to keep In-Reply-To on
subject changes, so here are links to the 3 patches:

https://inbox.sourceware.org/binutils/9e48774c-4b02-b763-aaf7-37133399e1fe@jdrake.com/T/#u
https://inbox.sourceware.org/binutils/ea41e347-1fe8-2ca4-9d74-3bbe9ebf7017@jdrake.com/T/#u
https://inbox.sourceware.org/binutils/346348f7-5f9e-de25-6ada-a8c9e59df702@jdrake.com/T/#u

On Mon, 14 Apr 2025, Jeremy Drake wrote:

> This patch series fixes delay import functionality, which was broken in
> 2.44 when the .idata section was made read-only.  The first patch, by LIU
> Hao, moved all of the delay import data that was previously in .idata into
> .didat.  My followup patch moves the read-only portions of this data into
> .rdata in the linker script, leaving only .didat$5 in the new .didat
> section.  This,  conveniently, is compatible with the
> IMAGE_GUARD_PROTECT_DELAYLOAD_IAT|IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION
> flags in the load config .GuardFlags member.  The third patch fills in the
> delay import directory in the PE headers.
>
> There was some debate as to whether it would be better to squash these
> patches.  I feel it's easier to squash patches later than to un-squash
> them, so I figured to send them separate and if requested I can squash
> them for a v2.
>
> To test the delayload guard flags:
> == main.c ==
> #include <assert.h>
> #include <stdio.h>
> #include <winsock2.h>
> #include <windows.h>
>
> __attribute__((__used__))
> const IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {
>   .Size = sizeof(_load_config_used),
>   .GuardFlags = 0x3000, /*IMAGE_GUARD_PROTECT_DELAYLOAD_IAT|IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION*/
> };
>
> int global_var = 42;
>
> int main(void) {
>   unsigned short ret;
>   setvbuf(stdout, NULL, _IONBF, 0);
>   printf("MAIN: starting\n");
>   printf("MAIN: incremented global var = %d\n", ++global_var);
>   printf("MAIN: about to call htons\n");
>   ret = htons(0x1234);
>   printf("MAIN: htons returned %hx\n", ret);
>   printf("MAIN: incremented global var = %d\n", ++global_var);
>   printf("MAIN: OK\n");
>   return 0;
> }
>
> == WS2_32.def (x86_64) ==
> LIBRARY WS2_32.DLL
> EXPORTS
> htons
>
> == build ==
> dlltool --input-def "ws2_32.def" --output-delaylib ws2_32.lib
> gcc -o main.exe main.c ws2_32.lib -ldloadhelper
> ./main.exe
>
> (-ldloadhelper is part of mingw-w64, and hooks up the delay load helper
> with the kernel32 ResolveDelayLoadedAPI function)
> (for i386 you'd need htons@4, and maybe the --kill-at flag for dlltool?)
>
> The first patch actually fixes PR 14339 and PR 32675.
>
> Jeremy Drake (2):
>   move read-only delayimp data into .rdata
>   bfd: populate delay import directory in PE header.
>
> LIU Hao (1):
>   bfd,ld,dlltool: Emit delay-load import data into its own section
>
>  bfd/coffgen.c         |  1 +
>  bfd/pe-aarch64.c      |  2 +
>  bfd/pe-arm.c          |  2 +
>  bfd/pe-i386.c         |  2 +
>  bfd/pe-x86_64.c       |  2 +
>  bfd/peXXigen.c        | 53 ++++++++++++++++++++++-
>  bfd/pei-aarch64.c     |  2 +
>  bfd/pei-arm.c         |  2 +
>  bfd/pei-i386.c        |  2 +
>  bfd/pei-loongarch64.c |  2 +
>  bfd/pei-riscv64.c     |  2 +
>  bfd/pei-x86_64.c      |  2 +
>  bfd/syms.c            |  1 +
>  binutils/dlltool.c    | 98 ++++++++++++++++++++++++++++++++++++-------
>  ld/scripttempl/pe.sc  | 29 ++++++++++++-
>  ld/scripttempl/pep.sc | 31 +++++++++++++-
>  16 files changed, 214 insertions(+), 19 deletions(-)
>
>


More information about the Binutils mailing list