diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/aout-target.h | 4 | ||||
-rw-r--r-- | bfd/aoutx.h | 9 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 12 | ||||
-rw-r--r-- | bfd/coff-alpha.c | 2 | ||||
-rw-r--r-- | bfd/coff-arm.c | 12 | ||||
-rw-r--r-- | bfd/coff-mips.c | 2 | ||||
-rw-r--r-- | bfd/coff-rs6000.c | 2 | ||||
-rw-r--r-- | bfd/coff-sh.c | 2 | ||||
-rw-r--r-- | bfd/coff64-rs6000.c | 2 | ||||
-rw-r--r-- | bfd/coffcode.h | 21 | ||||
-rw-r--r-- | bfd/coffgen.c | 18 | ||||
-rw-r--r-- | bfd/cofflink.c | 49 | ||||
-rw-r--r-- | bfd/elf32-nds32.c | 18 | ||||
-rw-r--r-- | bfd/elflink.c | 49 | ||||
-rw-r--r-- | bfd/elfxx-x86.c | 20 | ||||
-rw-r--r-- | bfd/format.c | 25 | ||||
-rw-r--r-- | bfd/i386aout.c | 1 | ||||
-rw-r--r-- | bfd/libaout.h | 7 | ||||
-rw-r--r-- | bfd/libbfd-in.h | 6 | ||||
-rw-r--r-- | bfd/libbfd.h | 6 | ||||
-rw-r--r-- | bfd/libcoff.h | 9 | ||||
-rw-r--r-- | bfd/linker.c | 20 | ||||
-rw-r--r-- | bfd/pdp11.c | 9 | ||||
-rw-r--r-- | bfd/peXXigen.c | 111 | ||||
-rw-r--r-- | bfd/version.h | 2 | ||||
-rw-r--r-- | bfd/xcofflink.c | 97 |
26 files changed, 351 insertions, 164 deletions
diff --git a/bfd/aout-target.h b/bfd/aout-target.h index f513e1b..1b71104 100644 --- a/bfd/aout-target.h +++ b/bfd/aout-target.h @@ -286,9 +286,6 @@ MY (set_sizes) (bfd *abfd) #ifndef MY_add_dynamic_symbols #define MY_add_dynamic_symbols 0 #endif -#ifndef MY_add_one_symbol -#define MY_add_one_symbol 0 -#endif #ifndef MY_link_dynamic_object #define MY_link_dynamic_object 0 #endif @@ -312,7 +309,6 @@ static const struct aout_backend_data MY (backend_data) = MY_set_sizes, MY_exec_header_not_counted, MY_add_dynamic_symbols, - MY_add_one_symbol, MY_link_dynamic_object, MY_write_dynamic_symbol, MY_check_dynamic_reloc, diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 63c654f..81e0804 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -2973,9 +2973,6 @@ NAME (aout, link_hash_table_create) (bfd *abfd) static bool aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) { - bool (*add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **); struct external_nlist *syms; bfd_size_type sym_count; char *strings; @@ -3013,10 +3010,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) return false; obj_aout_sym_hashes (abfd) = sym_hash; - add_one_symbol = aout_backend_info (abfd)->add_one_symbol; - if (add_one_symbol == NULL) - add_one_symbol = _bfd_generic_link_add_one_symbol; - p = syms; pend = p + sym_count; for (; p < pend; p++, sym_hash++) @@ -3167,7 +3160,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) break; } - if (! ((*add_one_symbol) + if (! (_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, string, copy, false, (struct bfd_link_hash_entry **) sym_hash))) return false; diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 7a8318e..ec60f23 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2913,6 +2913,18 @@ const char *bfd_format_string (bfd_format format); && bfd_is_abs_section ((H)->u.def.section) \ && !(H)->rel_from_abs) +bool _bfd_generic_link_add_one_symbol + (struct bfd_link_info *info, + bfd *abfd, + const char *name, + flagword flags, + asection *section, + bfd_vma value, + const char *string, + bool copy, + bool collect, + struct bfd_link_hash_entry **hashp); + bool bfd_link_align_section (asection *, unsigned int); bool bfd_link_split_section (bfd *abfd, asection *sec); diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index 2798efd..e2f1a4d 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -2359,7 +2359,7 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data = alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL + NULL, NULL, NULL, }, /* Supported architecture. */ bfd_arch_alpha, diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c index ab5f7b0..ee57451 100644 --- a/bfd/coff-arm.c +++ b/bfd/coff-arm.c @@ -1876,8 +1876,8 @@ record_arm_to_thumb_glue (struct bfd_link_info * info, it. */ bh = NULL; val = globals->arm_glue_size + 1; - bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, - BSF_GLOBAL, s, val, NULL, true, false, &bh); + _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, + BSF_GLOBAL, s, val, NULL, true, false, &bh); free (tmp_name); @@ -1929,8 +1929,8 @@ record_thumb_to_arm_glue (struct bfd_link_info * info, bh = NULL; val = globals->thumb_glue_size + 1; - bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, - BSF_GLOBAL, s, val, NULL, true, false, &bh); + _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, + BSF_GLOBAL, s, val, NULL, true, false, &bh); /* If we mark it 'thumb', the disassembler will do a better job. */ myh = (struct coff_link_hash_entry *) bh; @@ -1952,8 +1952,8 @@ record_thumb_to_arm_glue (struct bfd_link_info * info, bh = NULL; val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4); - bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, - BSF_LOCAL, s, val, NULL, true, false, &bh); + _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name, + BSF_LOCAL, s, val, NULL, true, false, &bh); free (tmp_name); diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c index e2c632c..8c4d4f7 100644 --- a/bfd/coff-mips.c +++ b/bfd/coff-mips.c @@ -1316,7 +1316,7 @@ static const struct ecoff_backend_data mips_ecoff_backend_data = _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL + NULL, NULL, }, /* Supported architecture. */ bfd_arch_mips, diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 7a20dba..ae9a0f6 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -4584,7 +4584,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data = xcoff_ppc_relocate_section, coff_rtype_to_howto, NULL, /* _bfd_coff_adjust_symndx */ - _bfd_generic_link_add_one_symbol, coff_link_output_has_begun, coff_final_link_postscript, NULL /* print_pdata. */ @@ -4774,7 +4773,6 @@ static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data = xcoff_ppc_relocate_section, coff_rtype_to_howto, NULL, /* _bfd_coff_adjust_symndx */ - _bfd_generic_link_add_one_symbol, coff_link_output_has_begun, coff_final_link_postscript, NULL /* print_pdata. */ diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c index 275c4f5..c3e0e42 100644 --- a/bfd/coff-sh.c +++ b/bfd/coff-sh.c @@ -3108,7 +3108,7 @@ static const bfd_coff_backend_data bfd_coff_small_swap_table = coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, coff_classify_symbol, coff_compute_section_file_positions, coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, - coff_adjust_symndx, coff_link_add_one_symbol, + coff_adjust_symndx, coff_link_output_has_begun, coff_final_link_postscript, bfd_pe_print_pdata }; diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 5a4bcbf..ec7ed08 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -2495,7 +2495,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data = xcoff64_ppc_relocate_section, coff_rtype_to_howto, NULL, /* _bfd_coff_adjust_symndx */ - _bfd_generic_link_add_one_symbol, coff_link_output_has_begun, coff_final_link_postscript, NULL /* print_pdata. */ @@ -2768,7 +2767,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data = xcoff64_ppc_relocate_section, coff_rtype_to_howto, NULL, /* _bfd_coff_adjust_symndx */ - _bfd_generic_link_add_one_symbol, coff_link_output_has_begun, coff_final_link_postscript, NULL /* print_pdata. */ diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 325a8ab..bd0374f 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1516,11 +1516,6 @@ CODE_FRAGMENT . (bfd *, struct bfd_link_info *, bfd *, asection *, . struct internal_reloc *, bool *); . -. bool (*_bfd_coff_link_add_one_symbol) -. (struct bfd_link_info *, bfd *, const char *, flagword, -. asection *, bfd_vma, const char *, bool, bool, -. struct bfd_link_hash_entry **); -. . bool (*_bfd_coff_link_output_has_begun) . (bfd *, struct coff_final_link_info *); . @@ -1659,10 +1654,6 @@ INTERNAL .#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ . ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ . (obfd, info, ibfd, sec, rel, adjustedp)) -.#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\ -. value, string, cp, coll, hashp)\ -. ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ -. (info, abfd, name, flags, section, value, string, cp, coll, hashp)) . .#define bfd_coff_link_output_has_begun(a,p) \ . ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p)) @@ -5513,10 +5504,6 @@ dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED, #define coff_adjust_symndx NULL #endif -#ifndef coff_link_add_one_symbol -#define coff_link_add_one_symbol _bfd_generic_link_add_one_symbol -#endif - #ifndef coff_link_output_has_begun static bool @@ -5615,7 +5602,7 @@ static const bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED = coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, coff_classify_symbol, coff_compute_section_file_positions, coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, - coff_adjust_symndx, coff_link_add_one_symbol, + coff_adjust_symndx, coff_link_output_has_begun, coff_final_link_postscript, bfd_pe_print_pdata }; @@ -5656,7 +5643,7 @@ static const bfd_coff_backend_data ticoff0_swap_table = coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, coff_classify_symbol, coff_compute_section_file_positions, coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, - coff_adjust_symndx, coff_link_add_one_symbol, + coff_adjust_symndx, coff_link_output_has_begun, coff_final_link_postscript, bfd_pe_print_pdata }; @@ -5698,7 +5685,7 @@ static const bfd_coff_backend_data ticoff1_swap_table = coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, coff_classify_symbol, coff_compute_section_file_positions, coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, - coff_adjust_symndx, coff_link_add_one_symbol, + coff_adjust_symndx, coff_link_output_has_begun, coff_final_link_postscript, bfd_pe_print_pdata /* huh */ }; @@ -5941,7 +5928,7 @@ static const bfd_coff_backend_data bigobj_swap_table = coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate, coff_classify_symbol, coff_compute_section_file_positions, coff_start_final_link, coff_relocate_section, coff_rtype_to_howto, - coff_adjust_symndx, coff_link_add_one_symbol, + coff_adjust_symndx, coff_link_output_has_begun, coff_final_link_postscript, bfd_pe_print_pdata /* huh */ }; diff --git a/bfd/coffgen.c b/bfd/coffgen.c index f87e54f..ab4d790 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -42,6 +42,7 @@ #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" +#include "elf-bfd.h" #include "hashtab.h" /* Extract a long section name at STRINDEX and copy it to the bfd objstack. @@ -1270,9 +1271,24 @@ coff_write_alien_symbol (bfd *abfd, if (c != (coff_symbol_type *) NULL) native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; } + + const elf_symbol_type *elfsym = elf_symbol_from (symbol); + if (elfsym + && (symbol->flags & BSF_FUNCTION) + && elfsym->internal_elf_sym.st_size) + { + /* coff_data (abfd)->local_n_btshft is what ought to be used here, + just that it's set only when reading in COFF objects. */ + native->u.syment.n_type = DT_FCN << 4; + native->u.syment.n_numaux = 1; + native[1].u.auxent.x_sym.x_misc.x_fsize + = elfsym->internal_elf_sym.st_size; + /* FIXME .u.auxent.x_sym.x_fcnary.x_fcn.x_endndx would better also + be set, which would require updating the field once the next + function is seen. */ + } } - native->u.syment.n_type = 0; if (symbol->flags & BSF_FILE) native->u.syment.n_sclass = C_FILE; else if (symbol->flags & BSF_LOCAL) diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 876aed7..38278e2 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -27,6 +27,7 @@ #include "libbfd.h" #include "coff/internal.h" #include "libcoff.h" +#include "elf-bfd.h" #include "safe-ctype.h" static bool coff_link_add_object_symbols (bfd *, struct bfd_link_info *); @@ -445,7 +446,7 @@ coff_link_add_symbols (bfd *abfd, if (addit) { - if (! (bfd_coff_link_add_one_symbol + if (! (_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, (const char *) NULL, copy, false, (struct bfd_link_hash_entry **) sym_hash))) @@ -931,14 +932,52 @@ _bfd_coff_final_link (bfd *abfd, bfd_vma written = 0; bool rewrite = false; - if (! (sym->flags & BSF_LOCAL) - || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC - | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC - | BSF_SYNTHETIC)) + if ((sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC + | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC + | BSF_SYNTHETIC)) || ((sym->flags & BSF_DEBUGGING) && ! (sym->flags & BSF_FILE))) continue; + if (! (sym->flags & BSF_LOCAL)) + { + /* For ELF symbols try to represent their function-ness and + size, if available. */ + if (! (sym->flags & BSF_FUNCTION)) + continue; + + const elf_symbol_type *elfsym = elf_symbol_from (sym); + if (!elfsym) + continue; + + struct coff_link_hash_entry *hent + = (struct coff_link_hash_entry *) bfd_hash_lookup + (&info->hash->table, bfd_asymbol_name (sym), + false, false); + if (!hent) + continue; + + /* coff_data (abfd)->local_n_btshft is what ought to be used + here, just that it's set only when reading in COFF + objects. */ + hent->type = DT_FCN << 4; + if (!elfsym->internal_elf_sym.st_size) + continue; + + hent->aux = bfd_zalloc (abfd, sizeof (*hent->aux)); + if (!hent->aux) + continue; + + hent->numaux = 1; + hent->aux->x_sym.x_misc.x_fsize + = elfsym->internal_elf_sym.st_size; + /* FIXME ->x_sym.x_fcnary.x_fcn.x_endndx would better + also be set, yet that would likely need to happen + elsewhere anyway. */ + + continue; + } + /* See if we are discarding symbols with this name. */ if ((flaginfo.info->strip == strip_some && (bfd_hash_lookup (flaginfo.info->keep_hash, diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c index 1aff60a..3627b30 100644 --- a/bfd/elf32-nds32.c +++ b/bfd/elf32-nds32.c @@ -2697,7 +2697,8 @@ nds32_elf_do_9_pcrel_reloc (bfd * abfd, bfd_reloc_status_type status; /* Sanity check the address (offset in section). */ - if (offset > bfd_get_section_limit (abfd, input_section)) + bfd_vma octet = offset * bfd_octets_per_byte (abfd, input_section); + if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octet)) return bfd_reloc_outofrange; relocation = symbol_value + addend; @@ -2751,7 +2752,7 @@ struct nds32_hi20 static struct nds32_hi20 *nds32_hi20_list; static bfd_reloc_status_type -nds32_elf_hi20_reloc (bfd *abfd ATTRIBUTE_UNUSED, +nds32_elf_hi20_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data, @@ -2774,7 +2775,10 @@ nds32_elf_hi20_reloc (bfd *abfd ATTRIBUTE_UNUSED, } /* Sanity check the address (offset in section). */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + bfd_vma octet = (reloc_entry->address + * bfd_octets_per_byte (abfd, input_section)); + if (!bfd_reloc_offset_in_range (reloc_entry->howto, + abfd, input_section, octet)) return bfd_reloc_outofrange; ret = bfd_reloc_ok; @@ -2938,7 +2942,10 @@ nds32_elf_generic_reloc (bfd *input_bfd, arelent *reloc_entry, a section relative addend which is wrong. */ /* Sanity check the address (offset in section). */ - if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section)) + bfd_vma octet = (reloc_entry->address + * bfd_octets_per_byte (input_bfd, input_section)); + if (!bfd_reloc_offset_in_range (reloc_entry->howto, input_bfd, input_section, + octet)) return bfd_reloc_outofrange; ret = bfd_reloc_ok; @@ -4698,7 +4705,8 @@ nds32_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd, bfd_vma relocation; /* Sanity check the address. */ - if (address > bfd_get_section_limit (input_bfd, input_section)) + bfd_vma octet = address * bfd_octets_per_byte (input_bfd, input_section); + if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, octet)) return bfd_reloc_outofrange; /* This function assumes that we are dealing with a basic relocation diff --git a/bfd/elflink.c b/bfd/elflink.c index 1399352..919f2a7 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4965,6 +4965,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) asection *sec, *new_sec; flagword flags; const char *name; + const char *defvername; bool must_copy_name = false; struct elf_link_hash_entry *h; struct elf_link_hash_entry *hi; @@ -5141,6 +5142,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) old_alignment = 0; old_bfd = NULL; new_sec = sec; + defvername = NULL; if (is_elf_hash_table (&htab->root)) { @@ -5259,7 +5261,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) default version of the symbol. */ if ((iver.vs_vers & VERSYM_HIDDEN) == 0 && isym->st_shndx != SHN_UNDEF) - *p++ = ELF_VER_CHR; + *p++ = ELF_VER_CHR, defvername = name; memcpy (p, verstr, verlen + 1); name = newname; @@ -5709,9 +5711,15 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) } else if (dynamic && h->root.u.def.section->owner == abfd) - /* Add this symbol to first hash if this shared - object has the first definition. */ - elf_link_add_to_first_hash (abfd, info, name, must_copy_name); + { + /* Add this symbol to first hash if this shared + object has the first definition. */ + elf_link_add_to_first_hash (abfd, info, name, must_copy_name); + /* And if it was the default symbol version definition, + also add the short name. */ + if (defvername) + elf_link_add_to_first_hash (abfd, info, defvername, false); + } } } } @@ -6273,12 +6281,30 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) if (h->type == bfd_link_hash_undefined) { - /* If the archive element has already been loaded then one - of the symbols defined by that element might have been - made undefined due to being in a discarded section. */ - if (is_elf_hash_table (info->hash) - && ((struct elf_link_hash_entry *) h)->indx == -3) - continue; + if (is_elf_hash_table (info->hash)) + { + /* If the archive element has already been loaded then one + of the symbols defined by that element might have been + made undefined due to being in a discarded section. */ + if (((struct elf_link_hash_entry *) h)->indx == -3) + continue; + + /* In the pre-LTO-plugin pass we must not mistakenly + include this archive member if an earlier shared + library defined this symbol. */ + struct elf_link_hash_table *htab = elf_hash_table (info); + if (htab->first_hash) + { + struct elf_link_first_hash_entry *e + = ((struct elf_link_first_hash_entry *) + bfd_hash_lookup (htab->first_hash, symdef->name, + false, false)); + if (e + && (e->abfd->flags & DYNAMIC) != 0 + && e->abfd != abfd) + continue; + } + } } else if (h->type == bfd_link_hash_common) { @@ -14384,7 +14410,8 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info) if (o->flags & SEC_GROUP) { asection *first = elf_next_in_group (o); - o->gc_mark = first->gc_mark; + if (first != NULL) + o->gc_mark = first->gc_mark; } if (o->gc_mark) diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 6ea41f2..bc9bb70 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -609,8 +609,7 @@ _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab, return &ret->elf; } -/* Create an entry in a x86 ELF linker hash table. NB: THIS MUST BE IN - SYNC WITH _bfd_elf_link_hash_newfunc. */ +/* Create an entry in an x86 ELF linker hash table. */ struct bfd_hash_entry * _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry, @@ -629,27 +628,14 @@ _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry, } /* Call the allocation method of the superclass. */ - entry = _bfd_link_hash_newfunc (entry, table, string); + entry = _bfd_elf_link_hash_newfunc (entry, table, string); if (entry != NULL) { struct elf_x86_link_hash_entry *eh = (struct elf_x86_link_hash_entry *) entry; - struct elf_link_hash_table *htab - = (struct elf_link_hash_table *) table; - memset (&eh->elf.size, 0, - (sizeof (struct elf_x86_link_hash_entry) - - offsetof (struct elf_link_hash_entry, size))); + memset (&eh->elf + 1, 0, sizeof (*eh) - sizeof (eh->elf)); /* Set local fields. */ - eh->elf.indx = -1; - eh->elf.dynindx = -1; - eh->elf.got = htab->init_got_refcount; - eh->elf.plt = htab->init_plt_refcount; - /* Assume that we have been called by a non-ELF symbol reader. - This flag is then reset by the code which reads an ELF input - file. This ensures that a symbol created by a non-ELF symbol - reader will have the flag set correctly. */ - eh->elf.non_elf = 1; eh->plt_second.offset = (bfd_vma) -1; eh->plt_got.offset = (bfd_vma) -1; eh->tlsdesc_got = (bfd_vma) -1; diff --git a/bfd/format.c b/bfd/format.c index 7769ad0..3db0792 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -331,6 +331,25 @@ print_and_clear_messages (struct per_xvec_messages *list, free (iter); iter = next; } + + /* Don't retain a pointer to free'd memory. */ + list->next = NULL; +} + +/* Discard all messages associated with TARG in LIST. Unlike + print_and_clear_messages, PER_XVEC_NO_TARGET is not valid for TARG. */ + +static void +clear_messages (struct per_xvec_messages *list, + const bfd_target *targ) +{ + struct per_xvec_messages *iter; + + for (iter = list; iter != NULL; iter = iter->next) + { + if (iter->targ == targ) + clear_warnmsg (&iter->messages); + } } /* This a copy of lto_section defined in GCC (lto-streamer.h). */ @@ -545,6 +564,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) /* Change BFD's target temporarily. */ abfd->xvec = *target; + /* It is possible that targets appear multiple times in + bfd_target_vector. If this is the case, then we want to avoid + accumulating duplicate messages for a target in MESSAGES, so + discard any previous messages associated with this target. */ + clear_messages (&messages, abfd->xvec); + if (bfd_seek (abfd, 0, SEEK_SET) != 0) goto err_ret; diff --git a/bfd/i386aout.c b/bfd/i386aout.c index fb09597..082ebfb 100644 --- a/bfd/i386aout.c +++ b/bfd/i386aout.c @@ -79,7 +79,6 @@ static const struct aout_backend_data MY (backend_data) = MY (set_sizes), 1, /* Exec header not counted. */ 0, /* Add_dynamic_symbols. */ - 0, /* Add_one_symbol. */ 0, /* Link_dynamic_object. */ 0, /* Write_dynamic_symbol. */ 0, /* Check_dynamic_reloc. */ diff --git a/bfd/libaout.h b/bfd/libaout.h index ca4faec..7628d6a 100644 --- a/bfd/libaout.h +++ b/bfd/libaout.h @@ -177,13 +177,6 @@ struct aout_backend_data (bfd *, struct bfd_link_info *, struct external_nlist **, bfd_size_type *, char **); - /* Callback from the add symbols phase of the linker code to handle - adding a single symbol to the global linker hash table. */ - bool (*add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, - asection *, bfd_vma, const char *, bool, bool, - struct bfd_link_hash_entry **); - /* Called to handle linking a dynamic object. */ bool (*link_dynamic_object) (struct bfd_link_info *, bfd *); diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index b2f70fb..ae6d303 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -645,12 +645,6 @@ extern bool _bfd_generic_link_add_archive_symbols /* Forward declaration to avoid prototype errors. */ typedef struct bfd_link_hash_entry _bfd_link_hash_entry; -/* Generic routine to add a single symbol. */ -extern bool _bfd_generic_link_add_one_symbol - (struct bfd_link_info *, bfd *, const char *name, flagword, - asection *, bfd_vma, const char *, bool copy, - bool constructor, struct bfd_link_hash_entry **) ATTRIBUTE_HIDDEN; - /* Generic routine to mark section as supplying symbols only. */ extern void _bfd_generic_link_just_syms (asection *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 4f6f5ea..d367fea 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -651,12 +651,6 @@ extern bool _bfd_generic_link_add_archive_symbols /* Forward declaration to avoid prototype errors. */ typedef struct bfd_link_hash_entry _bfd_link_hash_entry; -/* Generic routine to add a single symbol. */ -extern bool _bfd_generic_link_add_one_symbol - (struct bfd_link_info *, bfd *, const char *name, flagword, - asection *, bfd_vma, const char *, bool copy, - bool constructor, struct bfd_link_hash_entry **) ATTRIBUTE_HIDDEN; - /* Generic routine to mark section as supplying symbols only. */ extern void _bfd_generic_link_just_syms (asection *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; diff --git a/bfd/libcoff.h b/bfd/libcoff.h index d0cfd09..05ebe35 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -864,11 +864,6 @@ typedef struct (bfd *, struct bfd_link_info *, bfd *, asection *, struct internal_reloc *, bool *); - bool (*_bfd_coff_link_add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, - asection *, bfd_vma, const char *, bool, bool, - struct bfd_link_hash_entry **); - bool (*_bfd_coff_link_output_has_begun) (bfd *, struct coff_final_link_info *); @@ -1005,10 +1000,6 @@ typedef struct #define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ (obfd, info, ibfd, sec, rel, adjustedp)) -#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\ - value, string, cp, coll, hashp)\ - ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ - (info, abfd, name, flags, section, value, string, cp, coll, hashp)) #define bfd_coff_link_output_has_begun(a,p) \ ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p)) diff --git a/bfd/linker.c b/bfd/linker.c index 2a4b8f0..a9a23e5 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -1378,7 +1378,25 @@ hash_entry_bfd (struct bfd_link_hash_entry *h) /*NOTREACHED*/ } -/* Add a symbol to the global hash table. +/* +FUNCTION + _bfd_generic_link_add_one_symbol + +SYNOPSIS + bool _bfd_generic_link_add_one_symbol + (struct bfd_link_info *info, + bfd *abfd, + const char *name, + flagword flags, + asection *section, + bfd_vma value, + const char *string, + bool copy, + bool collect, + struct bfd_link_hash_entry **hashp); + +DESCRIPTION + Add a symbol to the global hash table. ABFD is the BFD the symbol comes from. NAME is the name of the symbol. FLAGS is the BSF_* bits associated with the symbol. diff --git a/bfd/pdp11.c b/bfd/pdp11.c index bdd9fc2..2d12033 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -2839,9 +2839,6 @@ aout_link_check_archive_element (bfd *abfd, static bool aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) { - bool (*add_one_symbol) - (struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **); struct external_nlist *syms; bfd_size_type sym_count; char *strings; @@ -2875,10 +2872,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) return false; obj_aout_sym_hashes (abfd) = sym_hash; - add_one_symbol = aout_backend_info (abfd)->add_one_symbol; - if (add_one_symbol == NULL) - add_one_symbol = _bfd_generic_link_add_one_symbol; - p = syms; pend = p + sym_count; for (; p < pend; p++, sym_hash++) @@ -2951,7 +2944,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info) break; } - if (! ((*add_one_symbol) + if (! (_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, string, copy, false, (struct bfd_link_hash_entry **) sym_hash))) return false; diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 2901268..9938108 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -593,7 +593,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) 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, tls, loadcfg; sa = extra->SectionAlignment; fa = extra->FileAlignment; @@ -602,6 +602,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE]; idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE]; tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE]; + loadcfg = pe->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE]; if (aouthdr_in->tsize) { @@ -651,6 +652,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) extra->DataDirectory[PE_IMPORT_TABLE] = idata2; extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5; extra->DataDirectory[PE_TLS_TABLE] = tls; + extra->DataDirectory[PE_LOAD_CONFIG_TABLE] = loadcfg; if (extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress == 0) /* Until other .idata fixes are made (pending patch), the entry for @@ -4403,6 +4405,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) struct coff_link_hash_entry *h1; struct bfd_link_info *info = pfinfo->info; bool result = true; + char name[20]; /* There are a few fields that need to be filled in now while we have symbol table access. @@ -4430,8 +4433,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) else { _bfd_error_handler - (_("%pB: unable to fill in DataDictionary[1] because .idata$2 is missing"), - abfd); + (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"), + abfd, PE_IMPORT_TABLE, ".idata$2"); result = false; } @@ -4450,8 +4453,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) else { _bfd_error_handler - (_("%pB: unable to fill in DataDictionary[1] because .idata$4 is missing"), - abfd); + (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"), + abfd, PE_IMPORT_TABLE, ".idata$4"); result = false; } @@ -4471,8 +4474,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) else { _bfd_error_handler - (_("%pB: unable to fill in DataDictionary[12] because .idata$5 is missing"), - abfd); + (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"), + abfd, PE_IMPORT_ADDRESS_TABLE, ".idata$5"); result = false; } @@ -4491,8 +4494,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) else { _bfd_error_handler - (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"), - abfd); + (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"), + abfd, PE_IMPORT_ADDRESS_TABLE, ".idata$6"); result = false; } } @@ -4533,17 +4536,16 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) else { _bfd_error_handler - (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]" - " because .idata$6 is missing"), abfd); + (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"), + abfd, PE_IMPORT_ADDRESS_TABLE, "__IAT_end__"); result = false; } } } - h1 = coff_link_hash_lookup (coff_hash_table (info), - (bfd_get_symbol_leading_char (abfd) != 0 - ? "__tls_used" : "_tls_used"), - false, false, true); + name[0] = bfd_get_symbol_leading_char (abfd); + strcpy (name + !!name[0], "_tls_used"); + h1 = coff_link_hash_lookup (coff_hash_table (info), name, false, false, true); if (h1 != NULL) { if ((h1->root.type == bfd_link_hash_defined @@ -4558,8 +4560,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) else { _bfd_error_handler - (_("%pB: unable to fill in DataDictionary[9] because __tls_used is missing"), - abfd); + (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"), + abfd, PE_TLS_TABLE, name); result = false; } /* According to PECOFF sepcifications by Microsoft version 8.2 @@ -4573,6 +4575,81 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) #endif } + name[0] = bfd_get_symbol_leading_char (abfd); + strcpy (name + !!name[0], "_load_config_used"); + h1 = coff_link_hash_lookup (coff_hash_table (info), name, false, false, true); + if (h1 != NULL) + { + char data[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); + + if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].VirtualAddress + & (bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd) + - 1)) + { + _bfd_error_handler + (_("%pB: unable to fill in DataDirectory[%d]: %s not properly aligned"), + abfd, PE_LOAD_CONFIG_TABLE, name); + result = false; + } + + /* The size is stored as the first 4 bytes at _load_config_used. */ + if (bfd_get_section_contents (abfd, + h1->root.u.def.section->output_section, data, + h1->root.u.def.section->output_offset + h1->root.u.def.value, + 4)) + { + uint32_t size = bfd_get_32 (abfd, data); + /* The Microsoft PE format documentation says for compatibility + with Windows XP and earlier, the size must be 64 for x86 + images. */ + pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].Size + = (bfd_get_arch (abfd) == bfd_arch_i386 + && ((bfd_get_mach (abfd) & ~bfd_mach_i386_intel_syntax) + == bfd_mach_i386_i386) + && ((pe_data (abfd)->pe_opthdr.Subsystem + == IMAGE_SUBSYSTEM_WINDOWS_GUI) + || (pe_data (abfd)->pe_opthdr.Subsystem + == IMAGE_SUBSYSTEM_WINDOWS_CUI)) + && (pe_data (abfd)->pe_opthdr.MajorSubsystemVersion * 256 + + pe_data (abfd)->pe_opthdr.MinorSubsystemVersion + <= 0x0501)) + ? 64 : size; + + if (size > h1->root.u.def.section->size - h1->root.u.def.value) + { + _bfd_error_handler + (_("%pB: unable to fill in DataDirectory[%d]: size too large for the containing section"), + abfd, PE_LOAD_CONFIG_TABLE); + result = false; + } + } + else + { + _bfd_error_handler + (_("%pB: unable to fill in DataDirectory[%d]: size can't be read from %s"), + abfd, PE_LOAD_CONFIG_TABLE, name); + result = false; + } + } + else + { + _bfd_error_handler + (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"), + abfd, PE_LOAD_CONFIG_TABLE, name); + result = false; + } + } + /* If there is a .pdata section and we have linked pdata finally, we need to sort the entries ascending. */ #if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)) diff --git a/bfd/version.h b/bfd/version.h index 8cb9007..532112c 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20250403 +#define BFD_VERSION_DATE 20250415 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 446fa5a..b50b17f 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -243,6 +243,55 @@ xcoff_get_section_contents (bfd *abfd, asection *sec) return contents; } +/* Read .loader and swap in the header. Sanity check to prevent + buffer overflows. Don't bother to check for overlap as that sort + of insanity shouldn't lead to incorrect program behaviour. */ + +static bfd_byte * +xcoff_get_ldhdr (bfd *abfd, asection *lsec, struct internal_ldhdr *ldhdr) +{ + bfd_byte *contents = xcoff_get_section_contents (abfd, lsec); + if (contents) + { + bfd_xcoff_swap_ldhdr_in (abfd, contents, ldhdr); + if (ldhdr->l_nsyms != 0) + { + bfd_vma symoff = bfd_xcoff_loader_symbol_offset (abfd, ldhdr); + if (symoff > lsec->size) + goto fail; + bfd_size_type onesym = bfd_xcoff_ldsymsz (abfd); + bfd_size_type syms; + if (_bfd_mul_overflow (ldhdr->l_nsyms, onesym, &syms) + || syms > lsec->size - symoff) + goto fail; + } + if (ldhdr->l_stlen != 0 + && (ldhdr->l_stoff > lsec->size + || ldhdr->l_stlen > lsec->size - ldhdr->l_stoff)) + goto fail; + if (ldhdr->l_nreloc != 0) + { + bfd_vma reloff = bfd_xcoff_loader_reloc_offset (abfd, ldhdr); + if (reloff > lsec->size) + goto fail; + bfd_size_type onerel = bfd_xcoff_ldrelsz (abfd); + bfd_size_type rels; + if (_bfd_mul_overflow (ldhdr->l_nreloc, onerel, &rels) + || rels > lsec->size - reloff) + goto fail; + } + if (ldhdr->l_nimpid != 0 + && (ldhdr->l_impoff > lsec->size + || ldhdr->l_istlen > lsec->size - ldhdr->l_impoff)) + goto fail; + } + return contents; + + fail: + bfd_set_error (bfd_error_file_truncated); + return NULL; +} + /* Get the size required to hold the dynamic symbols. */ long @@ -265,12 +314,10 @@ _bfd_xcoff_get_dynamic_symtab_upper_bound (bfd *abfd) return -1; } - contents = xcoff_get_section_contents (abfd, lsec); + contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr); if (!contents) return -1; - bfd_xcoff_swap_ldhdr_in (abfd, (void *) contents, &ldhdr); - return (ldhdr.l_nsyms + 1) * sizeof (asymbol *); } @@ -299,12 +346,10 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms) return -1; } - contents = xcoff_get_section_contents (abfd, lsec); + contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr); if (!contents) return -1; - bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); - strings = (char *) contents + ldhdr.l_stoff; symbuf = bfd_zalloc (abfd, ldhdr.l_nsyms * sizeof (* symbuf)); @@ -322,9 +367,7 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms) symbuf->symbol.the_bfd = abfd; - if (ldsym._l._l_l._l_zeroes == 0) - symbuf->symbol.name = strings + ldsym._l._l_l._l_offset; - else + if (ldsym._l._l_l._l_zeroes != 0) { char *c; @@ -335,6 +378,10 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms) c[SYMNMLEN] = '\0'; symbuf->symbol.name = c; } + else if (ldsym._l._l_l._l_offset < ldhdr.l_stlen) + symbuf->symbol.name = strings + ldsym._l._l_l._l_offset; + else + symbuf->symbol.name = _("<corrupt>"); if (ldsym.l_smclas == XMC_XO) symbuf->symbol.section = bfd_abs_section_ptr; @@ -384,12 +431,10 @@ _bfd_xcoff_get_dynamic_reloc_upper_bound (bfd *abfd) return -1; } - contents = xcoff_get_section_contents (abfd, lsec); + contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr); if (!contents) return -1; - bfd_xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr); - return (ldhdr.l_nreloc + 1) * sizeof (arelent *); } @@ -419,12 +464,10 @@ _bfd_xcoff_canonicalize_dynamic_reloc (bfd *abfd, return -1; } - contents = xcoff_get_section_contents (abfd, lsec); + contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr); if (!contents) return -1; - bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); - relbuf = bfd_alloc (abfd, ldhdr.l_nreloc * sizeof (arelent)); if (relbuf == NULL) return -1; @@ -905,7 +948,7 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info) return false; } - contents = xcoff_get_section_contents (abfd, lsec); + contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr); if (!contents) return false; @@ -913,8 +956,6 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info) included in the link. */ bfd_section_list_clear (abfd); - bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); - strings = (char *) contents + ldhdr.l_stoff; elsym = contents + bfd_xcoff_loader_symbol_offset(abfd, &ldhdr); @@ -934,14 +975,16 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info) if ((ldsym.l_smtype & L_EXPORT) == 0) continue; - if (ldsym._l._l_l._l_zeroes == 0) - name = strings + ldsym._l._l_l._l_offset; - else + if (ldsym._l._l_l._l_zeroes != 0) { memcpy (nambuf, ldsym._l._l_name, SYMNMLEN); nambuf[SYMNMLEN] = '\0'; name = nambuf; } + else if (ldsym._l._l_l._l_offset < ldhdr.l_stlen) + name = strings + ldsym._l._l_l._l_offset; + else + continue; /* Normally we could not call xcoff_link_hash_lookup in an add symbols routine, since we might not be using an XCOFF hash @@ -2368,12 +2411,10 @@ xcoff_link_check_dynamic_ar_symbols (bfd *abfd, /* There are no symbols, so don't try to include it. */ return true; - contents = xcoff_get_section_contents (abfd, lsec); + contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr); if (!contents) return false; - bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); - strings = (char *) contents + ldhdr.l_stoff; elsym = contents + bfd_xcoff_loader_symbol_offset (abfd, &ldhdr); @@ -2392,14 +2433,16 @@ xcoff_link_check_dynamic_ar_symbols (bfd *abfd, if ((ldsym.l_smtype & L_EXPORT) == 0) continue; - if (ldsym._l._l_l._l_zeroes == 0) - name = strings + ldsym._l._l_l._l_offset; - else + if (ldsym._l._l_l._l_zeroes != 0) { memcpy (nambuf, ldsym._l._l_name, SYMNMLEN); nambuf[SYMNMLEN] = '\0'; name = nambuf; } + else if (ldsym._l._l_l._l_offset < ldhdr.l_stlen) + name = strings + ldsym._l._l_l._l_offset; + else + continue; h = bfd_link_hash_lookup (info->hash, name, false, false, true); |