[PATCH 0/3] PE delay import fixes

Jeremy Drake sourceware-bugzilla@jdrake.com
Tue Apr 15 05:04:38 GMT 2025


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(-)

-- 
2.49.0.windows.1



More information about the Binutils mailing list