On Fri, 7 Mar 2025, Jeremy Drake via Mingw-w64-public wrote:
> On Fri, 7 Mar 2025, Jeremy Drake via Mingw-w64-public wrote:
>
> > On Fri, 7 Mar 2025, Jeremy Drake via Mingw-w64-public wrote:
> >
> > > That bug was avoided, due to the fact that the code that tries to
> > > garbage-collect unused stubs only looks at .idata sections, and delayloads
> > > are now in .didat sections.
> > >
> > > However, this patch is probably overkill. This puts the whole of the
> > > delay load stuff into .didat, while only the IAT needs to be there
> > > (writable). I will try just moving .idata$5 into .didat$5 and see what
> > > happens.
> >
> > I tried the attached patch, and it works, but brings back the bug I
> > referenced for 32-bit.
> >
> > > Also, I noticed in objdump that the Delay import directory entry in the
> > > optional header is 0. This may have been the case before, I'm not seeing
> > > any code to fill it in.
> >
> > This needs some symbols or sections for the delay import directory table.
> > Right now, it is put into .text$2, which seems like a hack for the fact
> > that putting it into .idata$2 would have messed up the normal import
> > directory.
> >
> > I am confused by what LLD is doing though. It is putting the functions and
> > modules into .data, and the read-only stuff into .didat. The way I read
> > the docs suggested to use .didat to hold the function pointers so that the
> > guard flags could allow the OS to change protection as needed without
> > affecting other data.
>
>
> OK, apparently I forgot to attach the patch last time. Oh well, here's a
> new one!
The list is eating my attachment. Trying again with .txt extension
>
> This patch unfortunately does a few different things at this point:
> * moves delay load directory table into .didat$2 section, and puts this
> into .idata(!)
> * fills in the delay import descriptor table data directory entry
> * fills in the load config table data directory entry if _load_config_used
> is present (it isn't unless it's actually referenced by an object)
> * moves delay load IAT into .dadat$5 section, which goes into new .didat
> section
> * fixes https://sourceware.org/bugzilla/show_bug.cgi?id=14339 by excluding
> delay import stubs from being excluded
>
> I've only tested this in MINGW32, but it works even when hex editing the
> load config guard flags to make Windows protect the delay load IAT (this
> still wants the default flags for the section to be read/write, and
> Windows will take away write access at load time). This is more than can
> be said for LLD at this point, because it puts the IAT itself in the .data
> section it blows up early if Windows takes away write access from pages in
> it. Martin, do you know anything about this?
>
>
> I'm not at all convinced that your initial idea to put all of the delay
> load stuff into the new .didat section isn't the way to go. It seemed to
> me like only the IAT needed to go in the section where its protection
> changed. The module handle is still in .data, do you think it was
> intended to put that in .didat also so it also gets write protected? The
> docs do say:
> Delayload import table in its own .didat section (with nothing else in it)
> that can be freely reprotected.
>
> #define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000
>
> Which is what this patch currently does.
>
>
> Feel free to pick this up and continue working on it.
> _______________________________________________
> Mingw-w64-public mailing list
> Mingw-w64-public@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
diff -ur binutils-2.44.ORIG/bfd/coffgen.c binutils-2.44/bfd/coffgen.c
--- binutils-2.44.ORIG/bfd/coffgen.c 2025-03-07 11:08:40.756680100 -0800
+++ binutils-2.44/bfd/coffgen.c 2025-03-07 11:08:50.489285700 -0800
@@ -3120,6 +3120,7 @@
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 -ur binutils-2.44.ORIG/bfd/pe-aarch64.c binutils-2.44/bfd/pe-aarch64.c
--- binutils-2.44.ORIG/bfd/pe-aarch64.c 2025-03-07 11:08:40.362193200 -0800
+++ binutils-2.44/bfd/pe-aarch64.c 2025-03-07 11:08:50.508464400 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pe-arm.c binutils-2.44/bfd/pe-arm.c
--- binutils-2.44.ORIG/bfd/pe-arm.c 2025-03-07 11:08:40.377852200 -0800
+++ binutils-2.44/bfd/pe-arm.c 2025-03-07 11:08:50.520989900 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pe-i386.c binutils-2.44/bfd/pe-i386.c
--- binutils-2.44.ORIG/bfd/pe-i386.c 2025-03-07 11:08:40.377852200 -0800
+++ binutils-2.44/bfd/pe-i386.c 2025-03-07 11:08:50.536642100 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pei-aarch64.c binutils-2.44/bfd/pei-aarch64.c
--- binutils-2.44.ORIG/bfd/pei-aarch64.c 2025-03-07 11:08:40.393906100
-0800
+++ binutils-2.44/bfd/pei-aarch64.c 2025-03-07 11:08:50.599389900 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pei-arm.c binutils-2.44/bfd/pei-arm.c
--- binutils-2.44.ORIG/bfd/pei-arm.c 2025-03-07 11:08:40.409549500 -0800
+++ binutils-2.44/bfd/pei-arm.c 2025-03-07 11:08:50.615458600 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pei-i386.c binutils-2.44/bfd/pei-i386.c
--- binutils-2.44.ORIG/bfd/pei-i386.c 2025-03-07 11:08:40.724374700 -0800
+++ binutils-2.44/bfd/pei-i386.c 2025-03-07 11:08:50.631119800 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pei-loongarch64.c
binutils-2.44/bfd/pei-loongarch64.c
--- binutils-2.44.ORIG/bfd/pei-loongarch64.c 2025-03-07 11:08:40.409549500
-0800
+++ binutils-2.44/bfd/pei-loongarch64.c 2025-03-07 11:08:50.646727400 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pei-riscv64.c binutils-2.44/bfd/pei-riscv64.c
--- binutils-2.44.ORIG/bfd/pei-riscv64.c 2025-03-07 11:08:40.409549500
-0800
+++ binutils-2.44/bfd/pei-riscv64.c 2025-03-07 11:08:50.646727400 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pei-x86_64.c binutils-2.44/bfd/pei-x86_64.c
--- binutils-2.44.ORIG/bfd/pei-x86_64.c 2025-03-07 11:08:40.409549500 -0800
+++ binutils-2.44/bfd/pei-x86_64.c 2025-03-07 11:08:50.662359400 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/pe-x86_64.c binutils-2.44/bfd/pe-x86_64.c
--- binutils-2.44.ORIG/bfd/pe-x86_64.c 2025-03-07 11:08:40.377852200 -0800
+++ binutils-2.44/bfd/pe-x86_64.c 2025-03-07 11:08:50.568095000 -0800
@@ -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 -ur binutils-2.44.ORIG/bfd/peXXigen.c binutils-2.44/bfd/peXXigen.c
--- binutils-2.44.ORIG/bfd/peXXigen.c 2025-03-07 11:08:40.393906100 -0800
+++ binutils-2.44/bfd/peXXigen.c 2025-03-07 16:13:04.699583800 -0800
@@ -593,7 +593,7 @@
struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
bfd_vma sa, fa, ib;
- IMAGE_DATA_DIRECTORY idata2, idata5, tls;
+ IMAGE_DATA_DIRECTORY idata2, idata5, didat2, tls;
sa = extra->SectionAlignment;
fa = extra->FileAlignment;
@@ -601,6 +601,7 @@
idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
+ didat2 = pe->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR];
tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
if (aouthdr_in->tsize)
@@ -650,6 +651,7 @@
a final link is going to be performed, it can overwrite them. */
extra->DataDirectory[PE_IMPORT_TABLE] = idata2;
extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
+ extra->DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR] = didat2;
extra->DataDirectory[PE_TLS_TABLE] = tls;
if (extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress == 0)
@@ -999,6 +1001,7 @@
{ ".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 },
@@ -4540,6 +4543,84 @@
}
}
+ /* The delay import directory. This is .didat$2 */
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ "__DELAY_DIRECTORY_start__", false, false, true);
+ if (h1 != NULL)
+ {
+ if ((h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ {
+ bfd_vma delay_va;
+
+ delay_va =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ "__DELAY_DIRECTORY_end__", false, false,
true);
+ if (h1 != NULL
+ && (h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ {
+ pe_data
(abfd)->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR].Size =
+ ((h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset)
+ - delay_va);
+ if (pe_data
(abfd)->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR].Size != 0)
+ pe_data
(abfd)->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR].VirtualAddress =
+ delay_va - pe_data (abfd)->pe_opthdr.ImageBase;
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in
DataDictionary[PE_DELAY_IMPORT_DESCRIPTOR(13)]"
+ " because .didat$2 is missing"), abfd);
+ result = false;
+ }
+ }
+ }
+
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ (bfd_get_symbol_leading_char (abfd) != 0
+ ? "__load_config_used" : "_load_config_used"),
+ false, false, true);
+ if (h1 != NULL)
+ {
+ char sz[4];
+ if ((h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data
(abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset
+ - pe_data (abfd)->pe_opthdr.ImageBase);
+ else
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDictionary[10] because
__load_config_used is missing"),
+ abfd);
+ result = false;
+ }
+ if (!bfd_get_section_contents (abfd,
h1->root.u.def.section->output_section,
+ sz, h1->root.u.def.section->output_offset, 4))
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDictionary[10] because we can't read
the size"),
+ abfd);
+ result = false;
+ }
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].Size =
H_GET_32 (abfd, sz);
+ }
+
h1 = coff_link_hash_lookup (coff_hash_table (info),
(bfd_get_symbol_leading_char (abfd) != 0
? "__tls_used" : "_tls_used"),
diff -ur binutils-2.44.ORIG/bfd/syms.c binutils-2.44/bfd/syms.c
--- binutils-2.44.ORIG/bfd/syms.c 2025-03-07 11:08:40.692211500 -0800
+++ binutils-2.44/bfd/syms.c 2025-03-07 11:08:50.693791800 -0800
@@ -594,6 +594,7 @@
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 -ur binutils-2.44.ORIG/binutils/dlltool.c binutils-2.44/binutils/dlltool.c
--- binutils-2.44.ORIG/binutils/dlltool.c 2025-03-07 11:07:53.114156900
-0800
+++ binutils-2.44/binutils/dlltool.c 2025-03-07 12:16:09.844181400 -0800
@@ -2268,7 +2268,7 @@
#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),
@@ -2279,6 +2279,17 @@
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, ".idata$7", SEC_HAS_CONTENTS, 2),
+ INIT_SEC_DATA (IDATA5, ".didat$5", SEC_HAS_CONTENTS, 2),
+ INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2),
+ INIT_SEC_DATA (IDATA6, ".idata$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.
@@ -2341,6 +2352,7 @@
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);
@@ -2807,7 +2819,7 @@
/* Output the delay import descriptor */
fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C);
- fprintf (f, ".section\t.text$2\n");
+ fprintf (f, ".section\t.didat$2\n");
fprintf (f, "%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab);
fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab);
fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C);
@@ -2835,7 +2847,7 @@
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);
@@ -2854,8 +2866,6 @@
fprintf (f, "__INT_%s:\n", imp_name_lab);
}
- fprintf (f, "\t.section\t.idata$2\n");
-
fclose (f);
assemble_file (TMP_HEAD_S, TMP_HEAD_O);
@@ -2921,6 +2931,57 @@
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.idata$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.idata$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)
{
@@ -2956,12 +3017,13 @@
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 -ur binutils-2.44.ORIG/ld/emultempl/pe.em binutils-2.44/ld/emultempl/pe.em
--- binutils-2.44.ORIG/ld/emultempl/pe.em 2025-03-07 11:08:37.530839700
-0800
+++ binutils-2.44/ld/emultempl/pe.em 2025-03-07 17:42:42.902585800 -0800
@@ -1827,7 +1827,7 @@
{
if (is->the_bfd->my_archive)
{
- int is_imp = 0;
+ int is_imp = 0, is_delayimp = 0;
asection *sec, *stub_sec = NULL;
/* See if this is an import library thunk. */
@@ -1835,13 +1835,17 @@
{
if (strncmp (sec->name, ".idata\$", 7) == 0)
is_imp = 1;
+ else if (strncmp (sec->name, ".didat\$", 7) == 0)
+ is_delayimp = 1;
/* The section containing the jmp stub has code
and has a reloc. */
if ((sec->flags & SEC_CODE) && sec->reloc_count)
stub_sec = sec;
}
- if (is_imp && stub_sec)
+ /* delay imports need the stub section: it is referenced by the
+ default __imp_ pointer: PR 14339 */
+ if (is_imp && !is_delayimp && stub_sec)
{
asymbol **symbols;
long nsyms, src_count;
diff -ur binutils-2.44.ORIG/ld/scripttempl/pe.sc
binutils-2.44/ld/scripttempl/pe.sc
--- binutils-2.44.ORIG/ld/scripttempl/pe.sc 2025-03-07 11:08:37.641333200
-0800
+++ binutils-2.44/ld/scripttempl/pe.sc 2025-03-07 12:41:46.385459200 -0800
@@ -14,7 +14,7 @@
# 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,8 @@
R_IDATA67='
KEEP (SORT(*)(.idata$6))
KEEP (SORT(*)(.idata$7))'
+ R_DIDAT2='KEEP (SORT(*)(.didat$2))'
+ R_DIDAT5='KEEP (SORT(*)(.didat$5))'
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 +63,7 @@
R_IDATA234=
R_IDATA5=
R_IDATA67=
+ R_DIDAT5=
R_CRT_XC=
R_CRT_XI=
R_CRT_XL=
@@ -242,6 +245,18 @@
${R_IDATA5}
${RELOCATING+__IAT_end__ = .;}
${R_IDATA67}
+ ${RELOCATING+__DELAY_DIRECTORY_start__ = .;}
+ ${R_DIDAT2}
+ ${RELOCATING+__DELAY_DIRECTORY_end__ = .;}
+ }
+
+ .didat ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* This cannot currently be handled with grouped sections.
+ See pe.em:sort_sections. */
+ ${RELOCATING+__DELAY_IAT_start__ = .;}
+ ${R_DIDAT5}
+ ${RELOCATING+__DELAY_IAT_end__ = .;}
}
/* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be
diff -ur binutils-2.44.ORIG/ld/scripttempl/pep.sc
binutils-2.44/ld/scripttempl/pep.sc
--- binutils-2.44.ORIG/ld/scripttempl/pep.sc 2025-03-07 11:08:37.641333200
-0800
+++ binutils-2.44/ld/scripttempl/pep.sc 2025-03-07 12:45:46.771734700 -0800
@@ -14,7 +14,7 @@
# 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,8 @@
R_IDATA67='
KEEP (SORT(*)(.idata$6))
KEEP (SORT(*)(.idata$7))'
+ R_DIDAT2='KEEP (SORT(*)(.didat$2))'
+ R_DIDAT5='SORT(*)(.didat$5)'
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 +64,7 @@
R_IDATA234=
R_IDATA5=
R_IDATA67=
+ R_DIDAT5=
R_CRT_XC=
R_CRT_XI=
R_CRT_XL=
@@ -249,6 +252,18 @@
${R_IDATA5}
${RELOCATING+__IAT_end__ = .;}
${R_IDATA67}
+ ${RELOCATING+__DELAY_DIRECTORY_start__ = .;}
+ ${R_DIDAT2}
+ ${RELOCATING+__DELAY_DIRECTORY_end__ = .;}
+ }
+
+ .didat ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* This cannot currently be handled with grouped sections.
+ See pep.em:sort_sections. */
+ ${RELOCATING+__DELAY_IAT_start__ = .;}
+ ${R_DIDAT5}
+ ${RELOCATING+__DELAY_IAT_end__ = .;}
}
/* Windows TLS expects .tls\$AAA to be at the start and .tls\$ZZZ to be
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public