在 2025-3-7 06:51, Jeremy Drake via Mingw-w64-public 写道:
On Thu, 6 Mar 2025, Jeremy Drake via Mingw-w64-public wrote:On Thu, 6 Mar 2025, Jacek Caban wrote:Relying on __delayLoadHelper2 behavior specific to mingw-w64 comes with drawbacks. As I mentioned earlier, an application can forward the call to ResolveDelayLoadedAPI, which will bypass this change and fail to work, while it previously worked with earlier binutils.I tested this, and -ldloadhelper (which forwards to the OS API) does work with current binutils.Actaully, the test case I was starting with was delay loading from a non-existant module, and using the failure hook to load it. In the case of the ResolveDelayLoadedAPI function, it does not seem to save the function returned from the failure hook back to the delay IAT. Doing a more "normal" delay load of a function/module that *does* exist does result in a segfault with current binutils and ResolveDelayLoadedAPI.
Please try this patch for binutils. -- Best regards, LIU Hao
From 5a998ac8ddc7196dcad912664f18d2a0eb9b5c48 Mon Sep 17 00:00:00 2001 From: LIU Hao <lh_mo...@126.com> Date: Fri, 7 Mar 2025 23:23:21 +0800 Subject: [PATCH] bfd,ld,dlltool: Emit delay-load import data into its own section A delay-import symbol (of a function) is resolved when a call to it is made. The delay loader may overwrite the `__imp_` pointer to the actual function after it has been resolved, which requires the pointer itself be in a writeable section. Previously it was placed in the ordinary Import Address Table (IAT), which is emitted into the `.idata` section, which had been changed to read-only in db00f6c3aceabbf03acdb69e74b59b2d2b043cd7, which caused segmentation faults when functions from delay-import library were called. This commit makes DLLTOOL emit delay-import IAT into `.didata`, as specified by Microsoft. Most of the code is copied from `.idata`, except that this section is writeable. Using this DEF: ``` ; ws2_32.def LIBRARY "WS2_32.DLL" EXPORTS WSAGetLastError ``` and this C program: ``` // delay.c #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> #include <stdio.h> ///////////////////////////////////////////////////////// // User code ///////////////////////////////////////////////////////// DWORD WINAPI WSAGetLastError(void); extern PVOID __imp_WSAGetLastError; int main(void) { fprintf(stderr, "before delay load, __imp_WSAGetLastError = %p\n", __imp_WSAGetLastError); SetLastError(123); fprintf(stderr, "WSAGetLastError() = %d\n", WSAGetLastError()); fprintf(stderr, "after delay load, __imp_WSAGetLastError = %p\n", __imp_WSAGetLastError); __imp_WSAGetLastError = (PVOID) 1234567; fprintf(stderr, "after plain write, __imp_WSAGetLastError = %p\n", __imp_WSAGetLastError); } ///////////////////////////////////////////////////////// // Overridden `__delayLoadHelper2` facility ///////////////////////////////////////////////////////// extern char __ImageBase[]; PVOID WINAPI ResolveDelayLoadedAPI(PVOID ParentModuleBase, LPCVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, FARPROC* ThunkAddress, ULONG Flags); FARPROC WINAPI DelayLoadFailureHook(LPCSTR name, LPCSTR function); FARPROC WINAPI __delayLoadHelper2(LPCVOID pidd, FARPROC* ppfnIATEntry) { return ResolveDelayLoadedAPI(&__ImageBase, pidd, NULL, (PVOID) DelayLoadFailureHook, ppfnIATEntry, 0); } ``` This program used to crash: ``` $ dlltool -nn -d ws2_32.def -y delay_ws2_32.a $ gcc -g delay.c delay_ws2_32.a -o delay.exe $ ./delay.exe before delay load, __imp_WSAGetLastError = 00007FF6937215C6 Segmentation fault ``` After this commit, it loads and calls `WSAGetLastError()` properly, and `__imp_WSAGetLastError` is writeable: ``` $ dlltool -nn -d ws2_32.def -y delay_ws2_32.a $ gcc -g delay.c delay_ws2_32.a -o delay.exe $ ./delay.exe before delay load, __imp_WSAGetLastError = 00007FF76E2215C6 WSAGetLastError() = 123 after delay load, __imp_WSAGetLastError = 00007FFF191FA720 after plain write, __imp_WSAGetLastError = 000000000012D687 ``` Reference: https://learn.microsoft.com/en-us/windows/win32/secbp/pe-metadata#import-handling Signed-off-by: LIU Hao <lh_mo...@126.com> --- 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 | 1 + 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 | 76 +++++++++++++++++++++++++++++++++++++++---- ld/scripttempl/pe.sc | 26 ++++++++++++++- ld/scripttempl/pep.sc | 27 ++++++++++++++- 16 files changed, 144 insertions(+), 8 deletions(-) diff --git a/bfd/coffgen.c b/bfd/coffgen.c index f87e54f9722..cc2beb3f240 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -3125,6 +3125,7 @@ coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) else if (startswith (o->name, ".idata") || startswith (o->name, ".pdata") || startswith (o->name, ".xdata") + || startswith (o->name, ".didat") || startswith (o->name, ".rsrc")) o->gc_mark = 1; diff --git a/bfd/pe-aarch64.c b/bfd/pe-aarch64.c index 64975d19f67..2204a51c509 100644 --- a/bfd/pe-aarch64.c +++ b/bfd/pe-aarch64.c @@ -48,6 +48,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pe-arm.c b/bfd/pe-arm.c index fe4e18e7e06..5efa559a353 100644 --- a/bfd/pe-arm.c +++ b/bfd/pe-arm.c @@ -43,6 +43,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pe-i386.c b/bfd/pe-i386.c index 07f674342cf..3742fd8feb4 100644 --- a/bfd/pe-i386.c +++ b/bfd/pe-i386.c @@ -36,6 +36,8 @@ #define COFF_SECTION_ALIGNMENT_ENTRIES \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pe-x86_64.c b/bfd/pe-x86_64.c index d56d75dabd0..9151aac5792 100644 --- a/bfd/pe-x86_64.c +++ b/bfd/pe-x86_64.c @@ -57,6 +57,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 29012688adf..cdcca9eff19 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -999,6 +999,7 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out) { ".arch", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_8BYTES }, { ".bss", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE }, { ".data", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE }, + { ".didat", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE }, { ".edata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA }, { ".idata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA }, { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA }, diff --git a/bfd/pei-aarch64.c b/bfd/pei-aarch64.c index 3d7f5b376a6..00f38e0f9bb 100644 --- a/bfd/pei-aarch64.c +++ b/bfd/pei-aarch64.c @@ -49,6 +49,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pei-arm.c b/bfd/pei-arm.c index 2abc14de025..07cebb510ef 100644 --- a/bfd/pei-arm.c +++ b/bfd/pei-arm.c @@ -45,6 +45,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pei-i386.c b/bfd/pei-i386.c index 676a824877b..a26f1702b3b 100644 --- a/bfd/pei-i386.c +++ b/bfd/pei-i386.c @@ -35,6 +35,8 @@ #define COFF_SECTION_ALIGNMENT_ENTRIES \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pei-loongarch64.c b/bfd/pei-loongarch64.c index 4b3a30d4ddc..f22498cab21 100644 --- a/bfd/pei-loongarch64.c +++ b/bfd/pei-loongarch64.c @@ -49,6 +49,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pei-riscv64.c b/bfd/pei-riscv64.c index e87aa429350..c4ae7bfb89a 100644 --- a/bfd/pei-riscv64.c +++ b/bfd/pei-riscv64.c @@ -49,6 +49,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c index 3f8f255af33..a5c2fd85f06 100644 --- a/bfd/pei-x86_64.c +++ b/bfd/pei-x86_64.c @@ -51,6 +51,8 @@ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ +{ COFF_SECTION_NAME_PARTIAL_MATCH (".didat"), \ + COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \ { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \ diff --git a/bfd/syms.c b/bfd/syms.c index 95017ba4f11..df2229b3fa3 100644 --- a/bfd/syms.c +++ b/bfd/syms.c @@ -594,6 +594,7 @@ struct section_to_type adding entries. Since it is so short, a linear search is used. */ static const struct section_to_type stt[] = { + {".didat", 'i'}, /* MSVC's .didat (delay import) section */ {".drectve", 'i'}, /* MSVC's .drective section */ {".edata", 'e'}, /* MSVC's .edata (export) section */ {".idata", 'i'}, /* MSVC's .idata (import) section */ diff --git a/binutils/dlltool.c b/binutils/dlltool.c index ef21423b06d..0e0138305f4 100644 --- a/binutils/dlltool.c +++ b/binutils/dlltool.c @@ -2250,7 +2250,7 @@ typedef struct #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA) #define BSS_SEC_FLAGS SEC_ALLOC -static sinfo secdata[NSECS] = +static sinfo secdata_plain[NSECS] = { INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2), @@ -2261,6 +2261,17 @@ static sinfo secdata[NSECS] = INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1) }; +static sinfo secdata_delay[NSECS] = +{ + INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), + INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2), + INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2), + INIT_SEC_DATA (IDATA7, ".didat$7", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA5, ".didat$5", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA4, ".didat$4", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA6, ".didat$6", SEC_HAS_CONTENTS, 1) +}; + /* This is what we're trying to make. We generate the imp symbols with both single and double underscores, for compatibility. @@ -2323,6 +2334,7 @@ make_imp_label (bfd *abfd, const char *prefix, const char *name) static bfd * make_one_lib_file (export_type *exp, int i, int delay) { + sinfo *const secdata = delay ? secdata_delay : secdata_plain; char *outname = TMP_STUB; size_t name_len = strlen (outname); sprintf (outname + name_len - 7, "%05d.o", i); @@ -2814,7 +2826,7 @@ make_delay_head (void) if (!no_idata5) { - fprintf (f, "\t.section\t.idata$5\n"); + fprintf (f, "\t.section\t.didat$5\n"); /* NULL terminating list. */ if (create_for_pep) fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); @@ -2825,15 +2837,15 @@ make_delay_head (void) if (!no_idata4) { - fprintf (f, "\t.section\t.idata$4\n"); + fprintf (f, "\t.section\t.didat$4\n"); fprintf (f, "\t%s\t0\n", ASM_LONG); if (create_for_pep) fprintf (f, "\t%s\t0\n", ASM_LONG); - fprintf (f, "\t.section\t.idata$4\n"); + fprintf (f, "\t.section\t.didat$4\n"); fprintf (f, "__INT_%s:\n", imp_name_lab); } - fprintf (f, "\t.section\t.idata$2\n"); + fprintf (f, "\t.section\t.didat$2\n"); fclose (f); @@ -2900,6 +2912,57 @@ make_tail (void) return abfd; } +static bfd * +make_delay_tail (void) +{ + FILE *f = fopen (TMP_TAIL_S, FOPEN_WT); + bfd *abfd; + + if (f == NULL) + { + fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S); + return NULL; + } + + temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S; + + if (!no_idata4) + { + fprintf (f, "\t.section\t.didat$4\n"); + if (create_for_pep) + fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); + else + fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ + } + + if (!no_idata5) + { + fprintf (f, "\t.section\t.didat$5\n"); + if (create_for_pep) + fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); + else + fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ + } + + fprintf (f, "\t.section\t.didat$7\n"); + fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab); + fprintf (f, "__%s_iname:\t%s\t\"%s\"\n", + imp_name_lab, ASM_TEXT, dll_name); + + fclose (f); + + assemble_file (TMP_TAIL_S, TMP_TAIL_O); + + abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET); + if (abfd == NULL) + /* xgettext:c-format */ + fatal (_("failed to open temporary tail file: %s: %s"), + TMP_TAIL_O, bfd_get_errmsg ()); + + temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O; + return abfd; +} + static void gen_lib_file (int delay) { @@ -2935,12 +2998,13 @@ gen_lib_file (int delay) if (delay) { ar_head = make_delay_head (); + ar_tail = make_delay_tail(); } else { ar_head = make_head (); + ar_tail = make_tail(); } - ar_tail = make_tail(); if (ar_head == NULL || ar_tail == NULL) return; diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc index 96a47515444..8bc20674c7f 100644 --- a/ld/scripttempl/pe.sc +++ b/ld/scripttempl/pe.sc @@ -14,7 +14,7 @@ fi # substitution, so we do this instead. # Sorting of the .foo$* sections is required by the definition of # grouped sections in PE. -# Sorting of the file names in R_IDATA is required by the +# Sorting of the file names in R_IDATA and R_DIDAT is required by the # current implementation of dlltool (this could probably be changed to # use grouped sections instead). if test "${RELOCATING}"; then @@ -39,6 +39,16 @@ if test "${RELOCATING}"; then R_IDATA67=' KEEP (SORT(*)(.idata$6)) KEEP (SORT(*)(.idata$7))' + R_DIDAT234=' + KEEP (SORT(*)(.didat$2)) + KEEP (SORT(*)(.didat$3)) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + KEEP (SORT(*)(.didat$4))' + R_DIDAT5='KEEP (SORT(*)(.didat$5))' + R_DIDAT67=' + KEEP (SORT(*)(.didat$6)) + KEEP (SORT(*)(.didat$7))' R_CRT_XC='KEEP (*(SORT(.CRT$XC*))) /* C initialization */' R_CRT_XI='KEEP (*(SORT(.CRT$XI*))) /* C++ initialization */' R_CRT_XL='KEEP (*(SORT(.CRT$XL*))) /* TLS callbacks */' @@ -61,6 +71,9 @@ else R_IDATA234= R_IDATA5= R_IDATA67= + R_DIDAT234= + R_DIDAT5= + R_DIDAT67= R_CRT_XC= R_CRT_XI= R_CRT_XL= @@ -244,6 +257,17 @@ SECTIONS ${R_IDATA67} } + .didat ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + ${R_DIDAT234} + ${RELOCATING+__DELAY_IAT_start__ = .;} + ${R_DIDAT5} + ${RELOCATING+__DELAY_IAT_end__ = .;} + ${R_DIDAT67} + } + /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be at the end of section. This is important because _tls_start MUST be at the beginning of the section to enable SECREL32 relocations with TLS diff --git a/ld/scripttempl/pep.sc b/ld/scripttempl/pep.sc index e2c6c2cedd2..a7304b29cd6 100644 --- a/ld/scripttempl/pep.sc +++ b/ld/scripttempl/pep.sc @@ -14,7 +14,7 @@ fi # substitution, so we do this instead. # Sorting of the .foo$* sections is required by the definition of # grouped sections in PE. -# Sorting of the file names in R_IDATA is required by the +# Sorting of the file names in R_IDATA and R_DIDAT is required by the # current implementation of dlltool (this could probably be changed to # use grouped sections instead). if test "${RELOCATING}"; then @@ -40,6 +40,17 @@ if test "${RELOCATING}"; then R_IDATA67=' KEEP (SORT(*)(.idata$6)) KEEP (SORT(*)(.idata$7))' + R_DIDAT234=' + KEEP (SORT(*)(.didat$2)) + KEEP (SORT(*)(.didat$3)) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + . = ALIGN(8); + KEEP (SORT(*)(.didat$4))' + R_DIDAT5='SORT(*)(.didat$5)' + R_DIDAT67=' + KEEP (SORT(*)(.didat$6)) + KEEP (SORT(*)(.didat$7))' R_CRT_XC='KEEP (*(SORT(.CRT$XC*))) /* C initialization */' R_CRT_XI='KEEP (*(SORT(.CRT$XI*))) /* C++ initialization */' R_CRT_XL='KEEP (*(SORT(.CRT$XL*))) /* TLS callbacks */' @@ -62,6 +73,9 @@ else R_IDATA234= R_IDATA5= R_IDATA67= + R_DIDAT234= + R_DIDAT5= + R_DIDAT67= R_CRT_XC= R_CRT_XI= R_CRT_XL= @@ -251,6 +265,17 @@ SECTIONS ${R_IDATA67} } + .didat ${RELOCATING+BLOCK(__section_alignment__)} : + { + /* This cannot currently be handled with grouped sections. + See pep.em:sort_sections. */ + ${R_DIDAT234} + ${RELOCATING+__DELAY_IAT_start__ = .;} + ${R_DIDAT5} + ${RELOCATING+__DELAY_IAT_end__ = .;} + ${R_DIDAT67} + } + /* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be at the end of the .tls section. This is important because _tls_start MUST be at the beginning of the section to enable SECREL32 relocations with TLS -- 2.48.1
OpenPGP_signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public