diff options
Diffstat (limited to 'ld/emultempl/pe.em')
-rw-r--r-- | ld/emultempl/pe.em | 83 |
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; |