@@ -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;
@@ -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"), \
@@ -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"), \
@@ -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"), \
@@ -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"), \
@@ -1001,6 +1001,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 },
@@ -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"), \
@@ -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"), \
@@ -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"), \
@@ -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"), \
@@ -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"), \
@@ -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"), \
@@ -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 */
@@ -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;
@@ -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
@@ -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