aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl/pe.em
diff options
context:
space:
mode:
Diffstat (limited to 'ld/emultempl/pe.em')
-rw-r--r--ld/emultempl/pe.em83
1 files changed, 54 insertions, 29 deletions
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 869ffd3..9a2b576 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -18,7 +18,7 @@ esac
rm -f e${EMULATION_NAME}.c
(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
fragment <<EOF
-/* Copyright (C) 1995-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2025 Free Software Foundation, Inc.
This file is part of the GNU Binutils.
@@ -160,6 +160,7 @@ static char * thumb_entry_symbol = NULL;
static lang_assignment_statement_type *image_base_statement = 0;
static unsigned short pe_dll_characteristics = DEFAULT_DLL_CHARACTERISTICS;
static bool insert_timestamp = true;
+static bool orphan_init_done;
static const char *emit_build_id;
#ifdef PDB_H
static int pdb;
@@ -647,7 +648,7 @@ set_pe_subsystem (void)
if (v[i].name == NULL)
{
- einfo (_("%F%P: invalid subsystem type %s\n"), optarg);
+ fatal (_("%P: invalid subsystem type %s\n"), optarg);
return;
}
@@ -668,7 +669,7 @@ set_pe_value (char *name)
set_pe_name (name, strtoul (optarg, &end, 0));
if (end == optarg)
- einfo (_("%F%P: invalid hex number for PE parameter '%s'\n"), optarg);
+ fatal (_("%P: invalid hex number for PE parameter '%s'\n"), optarg);
optarg = end;
}
@@ -685,7 +686,7 @@ set_pe_stack_heap (char *resname, char *comname)
set_pe_value (comname);
}
else if (*optarg)
- einfo (_("%F%P: strange hex info for PE parameter '%s'\n"), optarg);
+ fatal (_("%P: strange hex info for PE parameter '%s'\n"), optarg);
}
#define DEFAULT_BUILD_ID_STYLE "md5"
@@ -701,7 +702,7 @@ gld${EMULATION_NAME}_handle_option (int optc)
case OPTION_BASE_FILE:
link_info.base_file = fopen (optarg, FOPEN_WB);
if (link_info.base_file == NULL)
- einfo (_("%F%P: cannot open base file %s\n"), optarg);
+ fatal (_("%P: cannot open base file %s\n"), optarg);
break;
/* PE options. */
@@ -1230,7 +1231,7 @@ make_runtime_ref (void)
= bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
rr, true, false, true);
if (!h)
- einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n"));
+ fatal (_("%P: bfd_link_hash_lookup failed: %E\n"));
else
{
if (h->type == bfd_link_hash_new)
@@ -1528,7 +1529,7 @@ gld${EMULATION_NAME}_after_open (void)
if (bfd_get_flavour (link_info.output_bfd) != bfd_target_coff_flavour
|| coff_data (link_info.output_bfd) == NULL
|| !obj_pe (link_info.output_bfd))
- einfo (_("%F%P: cannot perform PE operations on non PE output file '%pB'\n"),
+ fatal (_("%P: cannot perform PE operations on non PE output file '%pB'\n"),
link_info.output_bfd);
pe_data (link_info.output_bfd)->pe_opthdr = pe;
@@ -1601,7 +1602,7 @@ gld${EMULATION_NAME}_after_open (void)
These will only be created if the output format is an arm format,
hence we do not support linking and changing output formats at the
same time. Use a link followed by objcopy to change output formats. */
- einfo (_("%F%P: error: cannot change output format "
+ fatal (_("%P: error: cannot change output format "
"whilst linking %s binaries\n"), "ARM");
return;
}
@@ -1661,7 +1662,7 @@ gld${EMULATION_NAME}_after_open (void)
if (!bfd_generic_link_read_symbols (is->the_bfd))
{
- einfo (_("%F%P: %pB: could not read symbols: %E\n"),
+ fatal (_("%P: %pB: could not read symbols: %E\n"),
is->the_bfd);
return;
}
@@ -1747,13 +1748,28 @@ gld${EMULATION_NAME}_after_open (void)
/* Microsoft import libraries may contain archive members for
one or more DLLs, together with static object files.
- Inspect all members that are named *.dll - check whether
- they contain .idata sections. Do the renaming of all
- archive members that seem to be Microsoft style import
- objects. */
+ The head and sentinels are regular COFF object files,
+ while the thunks are special ILF files that get synthesized
+ by bfd into COFF object files.
+
+ As Microsoft import libraries can be for a module with
+ almost any file name (*.dll, *.exe, etc), we can't easily
+ know which archive members to inspect.
+
+ Inspect all members, except ones named *.o or *.obj (which
+ is the case both for regular static libraries or for GNU
+ style import libraries). Archive members with file names other
+ than *.o or *.obj, that do contain .idata sections, are
+ considered to be Microsoft style import objects, and are
+ renamed accordingly.
+
+ If this heuristic is wrong and we apply this on archive members
+ that already have unique names, it shouldn't make any difference
+ as we only append a suffix on the names. */
pnt = strrchr (bfd_get_filename (is->the_bfd), '.');
- if (pnt != NULL && (fileext_cmp (pnt + 1, "dll") == 0))
+ if (pnt != NULL && (fileext_cmp (pnt + 1, "o") != 0 &&
+ fileext_cmp (pnt + 1, "obj") != 0))
{
int idata2 = 0, reloc_count = 0, idata = 0;
asection *sec;
@@ -1768,8 +1784,8 @@ gld${EMULATION_NAME}_after_open (void)
reloc_count += sec->reloc_count;
}
- /* An archive member named .dll, but not having any .idata
- sections - apparently not a Microsoft import object
+ /* An archive member not named .o or .obj, but not having any
+ .idata sections - apparently not a Microsoft import object
after all: Skip renaming it. */
if (!idata)
continue;
@@ -1833,7 +1849,7 @@ gld${EMULATION_NAME}_after_open (void)
if (!bfd_generic_link_read_symbols (is->the_bfd))
{
- einfo (_("%F%P: %pB: could not read symbols: %E\n"),
+ fatal (_("%P: %pB: could not read symbols: %E\n"),
is->the_bfd);
return;
}
@@ -1944,7 +1960,7 @@ gld${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIBU
h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true);
if (h == (struct bfd_link_hash_entry *) NULL)
- einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n"));
+ fatal (_("%P: bfd_link_hash_lookup failed: %E\n"));
if (h->type == bfd_link_hash_new)
{
h->type = bfd_link_hash_undefined;
@@ -2017,6 +2033,10 @@ gld${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUTE
static void
gld${EMULATION_NAME}_finish (void)
{
+ /* Support the object-only output. */
+ if (config.emit_gnu_object_only)
+ orphan_init_done = false;
+
#if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_wince_pe)
struct bfd_link_hash_entry * h;
@@ -2176,7 +2196,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
if (os == NULL)
{
- static struct orphan_save hold[] =
+ static struct orphan_save orig_hold[] =
{
{ ".text",
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
@@ -2194,6 +2214,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
SEC_ALLOC,
0, 0, 0, 0 }
};
+ static struct orphan_save hold[ARRAY_SIZE (orig_hold)];
enum orphan_save_index
{
orphan_text = 0,
@@ -2202,7 +2223,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
orphan_data,
orphan_bss
};
- static int orphan_init_done = 0;
struct orphan_save *place;
lang_output_section_statement_type *after;
etree_type *address;
@@ -2211,15 +2231,20 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
if (!orphan_init_done)
{
- struct orphan_save *ho;
- for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
- if (ho->name != NULL)
- {
- ho->os = lang_output_section_find (ho->name);
- if (ho->os != NULL && ho->os->flags == 0)
- ho->os->flags = ho->flags;
- }
- orphan_init_done = 1;
+ struct orphan_save *ho, *horig;
+ for (ho = hold, horig = orig_hold;
+ ho < hold + ARRAY_SIZE (hold);
+ ++ho, ++horig)
+ {
+ *ho = *horig;
+ if (ho->name != NULL)
+ {
+ ho->os = lang_output_section_find (ho->name);
+ if (ho->os != NULL && ho->os->flags == 0)
+ ho->os->flags = ho->flags;
+ }
+ }
+ orphan_init_done = true;
}
flags = s->flags;