From: Alan Modra Date: Fri, 1 May 2026 12:48:52 +0000 (+0930) Subject: PR 34062 type confusion in elf64_ia64_hash_copy_indirect X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1a5ae95bc1fde4aeb159e4e963118b17e1e730b5;p=thirdparty%2Fbinutils-gdb.git PR 34062 type confusion in elf64_ia64_hash_copy_indirect The output bfd determines the linker hash table type and symbol entry type, so the output bfd functions should be used when manipulating hash table symbols. * elflink.c (_bfd_elf_add_default_symbol): Get elf backend data from output bfd, not input. (elf_link_add_object_symbols): Likewise for e_b_hide_symbol and e_b_copy_symbol. (_bfd_elf_merge_symbol): Likewise. (_bfd_elf_fix_symbol_flags): Likewise. --- diff --git a/bfd/elflink.c b/bfd/elflink.c index 80938f043d4..6540184ed23 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1162,7 +1162,7 @@ _bfd_elf_merge_symbol (bfd *abfd, bfd *oldbfd; bool newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; bool newweak, oldweak, newfunc, oldfunc; - elf_backend_data *bed; + elf_backend_data *bed, *obed; const char *new_version; bool default_sym = *matched; struct elf_link_hash_table *htab; @@ -1183,6 +1183,7 @@ _bfd_elf_merge_symbol (bfd *abfd, *sym_hash = h; bed = get_elf_backend_data (abfd); + obed = get_elf_backend_data (info->output_bfd); htab = elf_hash_table (info); @@ -1434,7 +1435,7 @@ _bfd_elf_merge_symbol (bfd *abfd, && olddyn) { h = hi; - (*bed->elf_backend_hide_symbol) (info, h, true); + obed->elf_backend_hide_symbol (info, h, true); h->forced_local = 0; h->ref_dynamic = 0; h->def_dynamic = 0; @@ -1550,14 +1551,14 @@ _bfd_elf_merge_symbol (bfd *abfd, { hi->root.type = h->root.type; h->root.type = bfd_link_hash_indirect; - (*bed->elf_backend_copy_indirect_symbol) (info, hi, h); + obed->elf_backend_copy_indirect_symbol (info, hi, h); h->root.u.i.link = (struct bfd_link_hash_entry *) hi; if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED) { /* If the new symbol is hidden or internal, completely undo any dynamic link state. */ - (*bed->elf_backend_hide_symbol) (info, h, true); + obed->elf_backend_hide_symbol (info, h, true); h->forced_local = 0; h->ref_dynamic = 0; } @@ -1597,7 +1598,7 @@ _bfd_elf_merge_symbol (bfd *abfd, { /* If the new symbol is hidden or internal, completely undo any dynamic link state. */ - (*bed->elf_backend_hide_symbol) (info, h, true); + obed->elf_backend_hide_symbol (info, h, true); h->forced_local = 0; h->ref_dynamic = 0; } @@ -1700,9 +1701,9 @@ _bfd_elf_merge_symbol (bfd *abfd, /* We now know everything about the old and new symbols. We ask the backend to check if we can merge them. */ - if (bed->merge_symbol != NULL) + if (obed->merge_symbol != NULL) { - if (!bed->merge_symbol (h, sym, psec, newdef, olddef, oldbfd, oldsec)) + if (!obed->merge_symbol (h, sym, psec, newdef, olddef, oldbfd, oldsec)) return false; sec = *psec; } @@ -1819,7 +1820,7 @@ _bfd_elf_merge_symbol (bfd *abfd, { case STV_INTERNAL: case STV_HIDDEN: - (*bed->elf_backend_hide_symbol) (info, h, true); + obed->elf_backend_hide_symbol (info, h, true); break; } } @@ -1930,7 +1931,7 @@ _bfd_elf_merge_symbol (bfd *abfd, flip->root.u.undef.abfd = h->root.u.undef.abfd; h->root.type = bfd_link_hash_indirect; h->root.u.i.link = (struct bfd_link_hash_entry *) flip; - (*bed->elf_backend_copy_indirect_symbol) (info, flip, h); + obed->elf_backend_copy_indirect_symbol (info, flip, h); if (h->def_dynamic) { h->def_dynamic = 0; @@ -2006,7 +2007,7 @@ _bfd_elf_add_default_symbol (bfd *abfd, return true; } - bed = get_elf_backend_data (abfd); + bed = get_elf_backend_data (info->output_bfd); collect = bed->collect; dynamic = (abfd->flags & DYNAMIC) != 0; @@ -3167,7 +3168,7 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, } /* Backend specific symbol fixup. */ - bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); + bed = get_elf_backend_data (eif->info->output_bfd); if (bed->elf_backend_fixup_symbol && !(*bed->elf_backend_fixup_symbol) (eif->info, h)) return false; @@ -4425,7 +4426,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) Elf_Internal_Sym *isymbuf = NULL; Elf_Internal_Sym *isym; Elf_Internal_Sym *isymend; - elf_backend_data *bed; + elf_backend_data *bed, *obed; bool add_needed; struct elf_link_hash_table *htab; void *alloc_mark = NULL; @@ -4443,6 +4444,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) htab = elf_hash_table (info); bed = get_elf_backend_data (abfd); + obed = get_elf_backend_data (info->output_bfd); if (elf_use_dt_symtab_p (abfd)) { @@ -5703,7 +5705,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) { case STV_INTERNAL: case STV_HIDDEN: - (*bed->elf_backend_hide_symbol) (info, h, true); + obed->elf_backend_hide_symbol (info, h, true); dynsym = false; break; } @@ -5941,10 +5943,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) && hi->root.u.def.value == h->root.u.def.value && hi->root.u.def.section == h->root.u.def.section) { - (*bed->elf_backend_hide_symbol) (info, hi, true); + obed->elf_backend_hide_symbol (info, hi, true); hi->root.type = bfd_link_hash_indirect; hi->root.u.i.link = (struct bfd_link_hash_entry *) h; - (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); + obed->elf_backend_copy_indirect_symbol (info, h, hi); sym_hash = elf_sym_hashes (abfd); if (sym_hash) for (symidx = 0; symidx < extsymcount; ++symidx)