commit: a3c33571d7f0c64df3b509556b9a11388451070c Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Fri Oct 10 04:57:00 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Fri Oct 10 04:57:00 2025 +0000 URL: https://gitweb.gentoo.org/proj/toolchain/binutils-patches.git/commit/?id=a3c33571
9999: add H.J.'s patch for caching Bug: https://sourceware.org/PR33530 Signed-off-by: Sam James <sam <AT> gentoo.org> ...-internal-symbol-table-in-relocatable-BFD.patch | 1775 ++++++++++++++++++++ 1 file changed, 1775 insertions(+) diff --git a/9999/0005-elf-Cache-internal-symbol-table-in-relocatable-BFD.patch b/9999/0005-elf-Cache-internal-symbol-table-in-relocatable-BFD.patch new file mode 100644 index 0000000..dbf42d5 --- /dev/null +++ b/9999/0005-elf-Cache-internal-symbol-table-in-relocatable-BFD.patch @@ -0,0 +1,1775 @@ +From a724f5c582f8df93eee54d43cf7766bc47d30f44 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" <[email protected]> +Date: Thu, 9 Oct 2025 13:16:19 +0800 +Subject: [PATCH] elf: Cache internal symbol table in relocatable BFD + +Don't cache internal symbol table in symtab_hdr->contents. + +bfd/ + + PR ld/33530 + * elf-bfd.h (elf_obj_tdata): Add symtab. + * elf-eh-frame.c (adjust_eh_frame_local_symbols): Changed to + return void. + (_bfd_elf_discard_section_eh_frame): Updated. Don't cache + internal symbol table in symtab_hdr. + * elf.c (bfd_elf_get_elf_syms): Cache internal symbol table in + BFD. + (_bfd_elf_free_cached_info): Free internal symbol table in BFD. + * elfcode.h (elf_slurp_symbol_table): Don't free internal symbol + buffer. + * elflink.c (elf_link_is_defined_archive_symbol): Likewise. + (elf_link_add_object_symbols): Free cached internal symbol buffer. + (elf_link_input_bfd): Don't use symtab_hdr->contents for internal + symbol table. + (init_reloc_cookie): Remove the keep_memory argument. Don't + cache internal symbol table in symtab_hdr. + (fini_reloc_cookie): Removed. + (init_reloc_cookie_for_section): Don't call fini_reloc_cookie on + error. + (_bfd_elf_gc_mark): Replace fini_reloc_cookie_for_section with + fini_reloc_cookie_rels. + (bfd_elf_gc_sections): Likewise. + (bfd_elf_discard_info): Likewise. Don't call fini_reloc_cookie. + (bfd_elf_parse_eh_frame_entries): Updated. + * elfxx-x86.c (_bfd_x86_elf_link_relax_section): Don't use + use symtab_hdr->contents for internal symbol table. + +libctf/ + + PR ld/33530 + * ctf-open-bfd.c (ctf_bfdopen_ctfsect): Free internal symbol + table in BFD. + +Signed-off-by: H.J. Lu <[email protected]> +--- + bfd/elf-bfd.h | 11 ++- + bfd/elf-eh-frame.c | 17 ++--- + bfd/elf-m10200.c | 4 +- + bfd/elf-m10300.c | 10 +-- + bfd/elf.c | 127 ++++++++++++++++++++++++---------- + bfd/elf32-arc.c | 2 +- + bfd/elf32-arm.c | 7 +- + bfd/elf32-avr.c | 12 ++-- + bfd/elf32-bfin.c | 2 +- + bfd/elf32-cr16.c | 6 +- + bfd/elf32-crx.c | 4 +- + bfd/elf32-csky.c | 2 +- + bfd/elf32-epiphany.c | 2 +- + bfd/elf32-ft32.c | 6 +- + bfd/elf32-h8300.c | 4 +- + bfd/elf32-hppa.c | 2 +- + bfd/elf32-ip2k.c | 2 +- + bfd/elf32-m32c.c | 8 ++- + bfd/elf32-m68hc11.c | 2 +- + bfd/elf32-m68hc1x.c | 2 +- + bfd/elf32-m68k.c | 2 +- + bfd/elf32-metag.c | 2 +- + bfd/elf32-microblaze.c | 2 +- + bfd/elf32-msp430.c | 4 +- + bfd/elf32-nds32.c | 4 +- + bfd/elf32-ppc.c | 4 +- + bfd/elf32-pru.c | 4 +- + bfd/elf32-rl78.c | 4 +- + bfd/elf32-rx.c | 4 +- + bfd/elf32-sh.c | 4 +- + bfd/elf32-spu.c | 4 +- + bfd/elf32-v850.c | 2 +- + bfd/elf32-xstormy16.c | 2 +- + bfd/elf32-xtensa.c | 2 +- + bfd/elf64-alpha.c | 2 +- + bfd/elf64-hppa.c | 2 +- + bfd/elf64-ia64-vms.c | 4 +- + bfd/elf64-mmix.c | 2 +- + bfd/elf64-ppc.c | 12 ++-- + bfd/elfcode.h | 8 +-- + bfd/elflink.c | 152 ++++++++++++----------------------------- + bfd/elfnn-aarch64.c | 4 +- + bfd/elfnn-ia64.c | 2 +- + bfd/elfnn-kvx.c | 2 +- + bfd/elfnn-loongarch.c | 2 +- + bfd/elfnn-riscv.c | 2 +- + bfd/elfxx-mips.c | 2 +- + bfd/elfxx-x86.c | 24 +++---- + libctf/ctf-open-bfd.c | 5 +- + 49 files changed, 237 insertions(+), 264 deletions(-) + +diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h +index 5d19529d972..b7061e55b59 100644 +--- a/bfd/elf-bfd.h ++++ b/bfd/elf-bfd.h +@@ -2165,6 +2165,11 @@ struct elf_obj_tdata + /* Symbol buffer. */ + void *symbuf; + ++ /* A pointer to the full internal symbol table of input relocatable ++ SHT_SYMTAB if not NULL. Don't use symtab_hdr->contents since not ++ all backends use it to only cache local symbols. */ ++ Elf_Internal_Sym *symtab; ++ + /* List of GNU properties. Will be updated by setup_gnu_properties + after all input GNU properties are merged for output. */ + elf_property_list *properties; +@@ -2207,6 +2212,9 @@ struct elf_obj_tdata + symbols. */ + unsigned int bad_symtab : 1; + ++ /* Set if the symbol table cache should be kept. */ ++ unsigned int keep_symtab : 1; ++ + /* Set if DT_FLAGS_1 has DF_1_PIE set. */ + unsigned int is_pie : 1; + +@@ -2297,8 +2305,7 @@ extern unsigned int _bfd_elf_section_from_bfd_section + extern char *bfd_elf_string_from_elf_section + (bfd *, unsigned, unsigned); + extern Elf_Internal_Sym *bfd_elf_get_elf_syms +- (bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *, +- Elf_External_Sym_Shndx *); ++ (bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *); + extern char * bfd_elf_get_str_section (bfd *, unsigned int); + extern const char *bfd_elf_sym_name + (bfd *, Elf_Internal_Shdr *, Elf_Internal_Sym *, asection *); +diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c +index 4eda3c991bb..bd2c85291fb 100644 +--- a/bfd/elf-eh-frame.c ++++ b/bfd/elf-eh-frame.c +@@ -1448,12 +1448,10 @@ _bfd_elf_adjust_eh_frame_global_symbol (struct elf_link_hash_entry *h, + /* The same for all local symbols defined in .eh_frame. Returns true + if any symbol was changed. */ + +-static int ++static void + adjust_eh_frame_local_symbols (const asection *sec, + struct elf_reloc_cookie *cookie) + { +- int adjusted = 0; +- + if (cookie->locsymcount > 1) + { + unsigned int shndx = elf_section_data (sec)->this_idx; +@@ -1467,13 +1465,9 @@ adjust_eh_frame_local_symbols (const asection *sec, + bfd_signed_vma delta = offset_adjust (sym->st_value, sec); + + if (delta != 0) +- { +- adjusted = 1; +- sym->st_value += delta; +- } ++ sym->st_value += delta; + } + } +- return adjusted; + } + + /* This function is called for each input file before the .eh_frame +@@ -1611,11 +1605,8 @@ _bfd_elf_discard_section_eh_frame + if (sec->size != sec->rawsize) + changed = 1; + +- if (changed && adjust_eh_frame_local_symbols (sec, cookie)) +- { +- Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; +- symtab_hdr->contents = (unsigned char *) cookie->locsyms; +- } ++ if (changed) ++ adjust_eh_frame_local_symbols (sec, cookie); + return changed; + } + +diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c +index ca9a92e1221..4da86774ee2 100644 +--- a/bfd/elf-m10200.c ++++ b/bfd/elf-m10200.c +@@ -627,7 +627,7 @@ mn10200_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -1321,7 +1321,7 @@ mn10200_elf_get_relocated_section_contents (bfd *output_bfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c +index b381bb9037c..373290cbe4a 100644 +--- a/bfd/elf-m10300.c ++++ b/bfd/elf-m10300.c +@@ -1328,7 +1328,7 @@ mn10300_elf_check_relocs (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf) + { + isym = isymbuf + r_symndx; +@@ -2676,7 +2676,7 @@ mn10300_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -3019,7 +3019,7 @@ mn10300_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -3347,7 +3347,7 @@ mn10300_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -4463,7 +4463,7 @@ mn10300_elf_get_relocated_section_contents (bfd *output_bfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf.c b/bfd/elf.c +index bde7414ee21..edce3d3b95f 100644 +--- a/bfd/elf.c ++++ b/bfd/elf.c +@@ -428,21 +428,20 @@ bfd_elf_string_from_elf_section (bfd *abfd, + } + + /* Read and convert symbols to internal format. +- SYMCOUNT specifies the number of symbols to read, starting from +- symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF ++ PARTIAL_SYMCOUNT specifies the number of symbols to read, starting ++ from symbol PARTIAL_SYMOFFSET. If INTSYM_BUF or PARTIAL_EXTSYM_BUF + are non-NULL, they are used to store the internal symbols, external +- symbols, and symbol section index extensions, respectively. +- Returns a pointer to the internal symbol buffer (malloced if necessary) +- or NULL if there were no symbols or some kind of problem. */ ++ symbols, and symbol section index extensions, respectively. Returns ++ a pointer to the internal symbol buffer (malloced if necessary) or ++ NULL if there were no symbols or some kind of problem. */ + + Elf_Internal_Sym * + bfd_elf_get_elf_syms (bfd *ibfd, + Elf_Internal_Shdr *symtab_hdr, +- size_t symcount, +- size_t symoffset, ++ size_t partial_symcount, ++ size_t partial_symoffset, + Elf_Internal_Sym *intsym_buf, +- void *extsym_buf, +- Elf_External_Sym_Shndx *extshndx_buf) ++ void *partial_extsym_buf) + { + Elf_Internal_Shdr *shndx_hdr; + void *alloc_ext; +@@ -455,7 +454,12 @@ bfd_elf_get_elf_syms (bfd *ibfd, + const struct elf_backend_data *bed; + size_t extsym_size; + size_t amt; +- file_ptr pos; ++ file_ptr pos = 0; ++ size_t symcount = partial_symcount; ++ size_t symoffset = partial_symoffset; ++ void *extsym_buf = NULL; ++ Elf_External_Sym_Shndx *extshndx_buf = NULL; ++ bool cache_symtab = false; + + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) + abort (); +@@ -474,6 +478,22 @@ bfd_elf_get_elf_syms (bfd *ibfd, + return elf_tdata (ibfd)->dt_symtab + symoffset; + } + ++ if (elf_tdata (ibfd)->symtab != NULL) ++ { ++ /* NB: Should extsym_buf be cached? */ ++ if (partial_extsym_buf != NULL) ++ abort (); ++ ++ if (intsym_buf != NULL) ++ { ++ memcpy (intsym_buf, elf_tdata (ibfd)->symtab + symoffset, ++ symcount * sizeof (*intsym_buf)); ++ return intsym_buf; ++ } ++ else ++ return elf_tdata (ibfd)->symtab + symoffset; ++ } ++ + /* Normal syms might have section extension entries. */ + shndx_hdr = NULL; + if (elf_symtab_shndx_list (ibfd) != NULL) +@@ -506,19 +526,31 @@ bfd_elf_get_elf_syms (bfd *ibfd, + } + } + ++ if (elf_elfheader (ibfd)->e_type == ET_REL ++ && symtab_hdr->sh_entsize != 0) ++ { ++ symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize; ++ symoffset = 0; ++ cache_symtab = true; ++ } ++ + /* Read the symbols. */ + alloc_ext = NULL; + alloc_extshndx = NULL; + alloc_intsym = NULL; + bed = get_elf_backend_data (ibfd); + extsym_size = bed->s->sizeof_sym; +- if (_bfd_mul_overflow (symcount, extsym_size, &amt)) ++ size_t extsym_buf_size; ++ if (_bfd_mul_overflow (symcount, extsym_size, &extsym_buf_size)) + { + bfd_set_error (bfd_error_file_too_big); + return NULL; + } +- pos = symtab_hdr->sh_offset + symoffset * extsym_size; +- size_t alloc_ext_size = amt; ++ if (cache_symtab) ++ pos = symtab_hdr->sh_offset; ++ else ++ pos = symtab_hdr->sh_offset + symoffset * extsym_size; ++ size_t alloc_ext_size = extsym_buf_size; + if (bfd_seek (ibfd, pos, SEEK_SET) != 0 + || !_bfd_mmap_read_temporary (&extsym_buf, &alloc_ext_size, + &alloc_ext, ibfd, false)) +@@ -551,22 +583,24 @@ bfd_elf_get_elf_syms (bfd *ibfd, + } + } + +- if (intsym_buf == NULL) ++ if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt)) + { +- if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt)) +- { +- bfd_set_error (bfd_error_file_too_big); +- goto out1; +- } +- alloc_intsym = (Elf_Internal_Sym *) bfd_malloc (amt); +- intsym_buf = alloc_intsym; +- if (intsym_buf == NULL) +- goto out1; ++ bfd_set_error (bfd_error_file_too_big); ++ goto out1; ++ } ++ alloc_intsym = (Elf_Internal_Sym *) bfd_malloc (amt); ++ if (alloc_intsym == NULL) ++ { ++ intsym_buf = NULL; ++ goto out1; + } + ++ if (intsym_buf == NULL) ++ intsym_buf = alloc_intsym; ++ + /* Convert the symbols to internal form. */ +- isymend = intsym_buf + symcount; +- for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf, ++ isymend = alloc_intsym + symcount; ++ for (esym = (const bfd_byte *) extsym_buf, isym = alloc_intsym, + shndx = extshndx_buf; + isym < isymend; + esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL) +@@ -590,7 +624,9 @@ bfd_elf_get_elf_syms (bfd *ibfd, + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB symbol number %lu uses unsupported binding of %u"), +- ibfd, (unsigned long) (isym - intsym_buf), bind); ++ ibfd, ++ (unsigned long) (isym - alloc_intsym), ++ bind); + free (alloc_intsym); + intsym_buf = NULL; + goto out1; +@@ -602,19 +638,42 @@ bfd_elf_get_elf_syms (bfd *ibfd, + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB symbol number %lu uses unsupported type of %u"), +- ibfd, (unsigned long) (isym - intsym_buf), t); ++ ibfd, ++ (unsigned long) (isym - alloc_intsym), ++ t); + free (alloc_intsym); + intsym_buf = NULL; + goto out1; + } + } + ++ if (intsym_buf != NULL && partial_extsym_buf != NULL) ++ { ++ if (partial_symcount != symcount) ++ abort (); ++ memcpy (partial_extsym_buf, extsym_buf, extsym_buf_size); ++ } ++ + out1: + _bfd_munmap_temporary (alloc_extshndx, alloc_extshndx_size); + out2: + _bfd_munmap_temporary (alloc_ext, alloc_ext_size); + +- return intsym_buf; ++ if (intsym_buf == NULL) ++ return intsym_buf; ++ ++ if (!cache_symtab) ++ return intsym_buf; ++ ++ elf_tdata (ibfd)->symtab = alloc_intsym; ++ if (intsym_buf != alloc_intsym) ++ { ++ memcpy (intsym_buf, alloc_intsym + partial_symoffset, ++ partial_symcount * sizeof (*intsym_buf)); ++ return intsym_buf; ++ } ++ else ++ return alloc_intsym + partial_symoffset; + } + + /* Look up a symbol name. */ +@@ -659,8 +718,6 @@ static const char * + group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr) + { + Elf_Internal_Shdr *hdr; +- unsigned char esym[sizeof (Elf64_External_Sym)]; +- Elf_External_Sym_Shndx eshndx; + Elf_Internal_Sym isym; + + /* First we need to ensure the symbol table is available. Make sure +@@ -675,7 +732,7 @@ group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr) + /* Go read the symbol. */ + hdr = &elf_tdata (abfd)->symtab_hdr; + if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info, +- &isym, esym, &eshndx) == NULL) ++ &isym, NULL) == NULL) + return NULL; + + return bfd_elf_sym_name_raw (abfd, hdr, &isym); +@@ -3029,12 +3086,10 @@ bfd_sym_from_r_symndx (struct sym_cache *cache, + if (cache->abfd != abfd || cache->indx[ent] != r_symndx) + { + Elf_Internal_Shdr *symtab_hdr; +- unsigned char esym[sizeof (Elf64_External_Sym)]; +- Elf_External_Sym_Shndx eshndx; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx, +- &cache->sym[ent], esym, &eshndx) == NULL) ++ &cache->sym[ent], NULL) == NULL) + return NULL; + + if (cache->abfd != abfd) +@@ -10239,8 +10294,8 @@ _bfd_elf_free_cached_info (bfd *abfd) + free (sec_info->cies); + } + } +- free (tdata->symtab_hdr.contents); +- tdata->symtab_hdr.contents = NULL; ++ free (elf_tdata (abfd)->symtab); ++ elf_tdata (abfd)->symtab = NULL; + } + + return _bfd_generic_bfd_free_cached_info (abfd); +diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c +index ebfe4dcc26a..ed1dd56a59f 100644 +--- a/bfd/elf32-arc.c ++++ b/bfd/elf32-arc.c +@@ -3037,7 +3037,7 @@ arc_elf_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c +index ae3dc246be0..627c03eb507 100644 +--- a/bfd/elf32-arm.c ++++ b/bfd/elf32-arm.c +@@ -5928,7 +5928,7 @@ cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab, + local_syms = (Elf_Internal_Sym *) symtab_hdr->contents; + if (local_syms == NULL) + local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, +- symtab_hdr->sh_info, 0, NULL, NULL, ++ symtab_hdr->sh_info, 0, NULL, + NULL); + if (symtab_hdr->sh_info && local_syms == NULL) + return false; +@@ -6611,7 +6611,7 @@ elf32_arm_size_stubs (bfd *output_bfd, + local_syms + = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (local_syms == NULL) + goto error_ret_free_internal; + } +@@ -7966,8 +7966,7 @@ bfd_elf32_arm_init_maps (bfd *abfd) + /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field + should contain the number of local symbols, which should come before any + global symbols. Mapping symbols are always local. */ +- isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, +- NULL); ++ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL); + + /* No internal symbols read? Skip this BFD. */ + if (isymbuf == NULL) +diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c +index 6653e4d72f6..28e41914bd0 100644 +--- a/bfd/elf32-avr.c ++++ b/bfd/elf32-avr.c +@@ -2064,7 +2064,7 @@ elf32_avr_relax_delete_bytes (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +@@ -2197,7 +2197,7 @@ retrieve_local_syms (bfd *input_bfd) + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; + if (isymbuf == NULL && locsymcount != 0) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + + /* Save the symbols for this input file so they won't be read again. */ + if (isymbuf && isymbuf != (Elf_Internal_Sym *) symtab_hdr->contents) +@@ -2569,7 +2569,7 @@ elf32_avr_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -3008,7 +3008,7 @@ elf32_avr_relax_section (bfd *abfd, + (abfd, + symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + break; + } +@@ -3241,7 +3241,7 @@ elf32_avr_get_relocated_section_contents (bfd *output_bfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -3590,7 +3590,7 @@ get_local_syms (bfd *input_bfd, struct bfd_link_info *info) + { + local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + /* Cache them for elf_link_input_bfd. */ + symtab_hdr->contents = (unsigned char *) local_syms; + } +diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c +index 7ed1285f4c2..8b74a9f3039 100644 +--- a/bfd/elf32-bfin.c ++++ b/bfd/elf32-bfin.c +@@ -5351,7 +5351,7 @@ bfd_bfin_elf32_create_embedded_relocs (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c +index 31d1ba41c17..3fc4b4adfa1 100644 +--- a/bfd/elf32-cr16.c ++++ b/bfd/elf32-cr16.c +@@ -1511,7 +1511,7 @@ elf32_cr16_get_relocated_section_contents (bfd *output_bfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -1765,7 +1765,7 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -2739,7 +2739,7 @@ bfd_cr16_elf32_create_embedded_relocs (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c +index d2bc1f7ba72..03c20aab6cb 100644 +--- a/bfd/elf32-crx.c ++++ b/bfd/elf32-crx.c +@@ -772,7 +772,7 @@ elf32_crx_get_relocated_section_contents (bfd *output_bfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -1021,7 +1021,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-csky.c b/bfd/elf32-csky.c +index 40781a0e1bb..cc93602f5b0 100644 +--- a/bfd/elf32-csky.c ++++ b/bfd/elf32-csky.c +@@ -3543,7 +3543,7 @@ elf32_csky_size_stubs (bfd *output_bfd, + bfd_elf_get_elf_syms (input_bfd, + symtab_hdr, + symtab_hdr->sh_info, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (local_syms == NULL) + goto error_ret_free_internal; + } +diff --git a/bfd/elf32-epiphany.c b/bfd/elf32-epiphany.c +index ea60ce4dc72..bace4943dea 100644 +--- a/bfd/elf32-epiphany.c ++++ b/bfd/elf32-epiphany.c +@@ -259,7 +259,7 @@ epiphany_elf_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-ft32.c b/bfd/elf32-ft32.c +index 6ca175533da..ee9294def64 100644 +--- a/bfd/elf32-ft32.c ++++ b/bfd/elf32-ft32.c +@@ -837,7 +837,7 @@ elf32_ft32_relax_delete_bytes (struct bfd_link_info *link_info, bfd * abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +@@ -995,7 +995,7 @@ elf32_ft32_relax_is_branch_target (struct bfd_link_info *link_info, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +@@ -1119,7 +1119,7 @@ ft32_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + symtab_hdr->contents = (unsigned char *) isymbuf; +diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c +index e183577fca4..4bd20f9c433 100644 +--- a/bfd/elf32-h8300.c ++++ b/bfd/elf32-h8300.c +@@ -778,7 +778,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -1654,7 +1654,7 @@ elf32_h8_get_relocated_section_contents (bfd *output_bfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c +index 2f463e12829..085b10b8ea9 100644 +--- a/bfd/elf32-hppa.c ++++ b/bfd/elf32-hppa.c +@@ -2506,7 +2506,7 @@ get_local_syms (bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *info) + { + local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + /* Cache them for elf_link_input_bfd. */ + symtab_hdr->contents = (unsigned char *) local_syms; + } +diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c +index 5c28a06f318..71de071e1ec 100644 +--- a/bfd/elf32-ip2k.c ++++ b/bfd/elf32-ip2k.c +@@ -1130,7 +1130,7 @@ ip2k_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c +index 8f6881bcb0b..bf24f487c44 100644 +--- a/bfd/elf32-m32c.c ++++ b/bfd/elf32-m32c.c +@@ -980,7 +980,7 @@ dump_symtab (bfd * abfd, void *internal_syms, void *external_syms) + if (free_internal) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- internal_syms, external_syms, NULL); ++ internal_syms, external_syms); + else + isymbuf = internal_syms; + isymend = isymbuf + locsymcount; +@@ -1191,7 +1191,7 @@ m32c_elf_relax_plt_section (asection *splt, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +@@ -1488,7 +1488,9 @@ m32c_elf_relax_section (bfd *abfd, + } + else + { +- intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL); ++ intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, ++ symtab_hdr->sh_info, 0, NULL, ++ NULL); + symtab_hdr->contents = (bfd_byte *) intsyms; + } + +diff --git a/bfd/elf32-m68hc11.c b/bfd/elf32-m68hc11.c +index f70716d66a2..b4e0a3220ac 100644 +--- a/bfd/elf32-m68hc11.c ++++ b/bfd/elf32-m68hc11.c +@@ -823,7 +823,7 @@ m68hc11_elf_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c +index 7e8e0383717..9c1bac23549 100644 +--- a/bfd/elf32-m68hc1x.c ++++ b/bfd/elf32-m68hc1x.c +@@ -375,7 +375,7 @@ elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd, + { + local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + /* Cache them for elf_link_input_bfd. */ + symtab_hdr->contents = (unsigned char *) local_syms; + } +diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c +index 44ef102ea60..728da0754ab 100644 +--- a/bfd/elf32-m68k.c ++++ b/bfd/elf32-m68k.c +@@ -4439,7 +4439,7 @@ bfd_m68k_elf32_create_embedded_relocs (bfd *abfd, struct bfd_link_info *info, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c +index 916f3e15c72..f754af6e3be 100644 +--- a/bfd/elf32-metag.c ++++ b/bfd/elf32-metag.c +@@ -3604,7 +3604,7 @@ get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd, + { + local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + /* Cache them for elf_link_input_bfd. */ + symtab_hdr->contents = (unsigned char *) local_syms; + } +diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c +index db7ed465779..3a526391676 100644 +--- a/bfd/elf32-microblaze.c ++++ b/bfd/elf32-microblaze.c +@@ -1801,7 +1801,7 @@ microblaze_elf_relax_section (bfd *abfd, + symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym); + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + BFD_ASSERT (isymbuf != NULL); + + internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory); +diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c +index 3b356bfe4e2..5250f13a8b9 100644 +--- a/bfd/elf32-msp430.c ++++ b/bfd/elf32-msp430.c +@@ -2071,7 +2071,7 @@ msp430_elf_relax_section (bfd * abfd, asection * sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -2295,7 +2295,7 @@ msp430_elf_relax_section (bfd * abfd, asection * sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c +index e22b58c4ea8..b15626349a8 100644 +--- a/bfd/elf32-nds32.c ++++ b/bfd/elf32-nds32.c +@@ -9225,7 +9225,7 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec, + if (isym == NULL) + { + isym = bfd_elf_get_elf_syms (abfd, symtab_hdr, +- symtab_hdr->sh_info, 0, NULL, NULL, NULL); ++ symtab_hdr->sh_info, 0, NULL, NULL); + symtab_hdr->contents = (bfd_byte *) isym; + } + +@@ -9533,7 +9533,7 @@ nds32_get_local_syms (bfd *abfd, asection *sec ATTRIBUTE_UNUSED, + { + *isymbuf_p = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (*isymbuf_p == NULL) + return false; + } +diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c +index a3adcf8430e..e77e77fd687 100644 +--- a/bfd/elf32-ppc.c ++++ b/bfd/elf32-ppc.c +@@ -4114,7 +4114,7 @@ get_sym_h (struct elf_link_hash_entry **hp, + if (locsyms == NULL) + locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, + symtab_hdr->sh_info, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (locsyms == NULL) + return false; + *locsymsp = locsyms; +@@ -5570,7 +5570,7 @@ ppc_elf_late_size_sections (bfd *output_bfd, + if (local_syms == NULL && locsymcount != 0) + { + local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (local_syms == NULL) + return false; + } +diff --git a/bfd/elf32-pru.c b/bfd/elf32-pru.c +index 45a86be3ccf..e0d9eb507e2 100644 +--- a/bfd/elf32-pru.c ++++ b/bfd/elf32-pru.c +@@ -1215,7 +1215,7 @@ pru_elf_relax_delete_bytes (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +@@ -1393,7 +1393,7 @@ pru_elf32_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-rl78.c b/bfd/elf32-rl78.c +index e2ea6b1d15f..3608008c977 100644 +--- a/bfd/elf32-rl78.c ++++ b/bfd/elf32-rl78.c +@@ -1573,7 +1573,7 @@ rl78_elf_relax_plt_section (bfd *dynobj, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +@@ -2137,7 +2137,7 @@ rl78_elf_relax_section (bfd *abfd, + intsyms = (Elf_Internal_Sym *) symtab_hdr->contents; + else + { +- intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL); ++ intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL); + symtab_hdr->contents = (bfd_byte *) intsyms; + } + +diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c +index d8a2236a233..e18eab7bbda 100644 +--- a/bfd/elf32-rx.c ++++ b/bfd/elf32-rx.c +@@ -2070,7 +2070,7 @@ elf32_rx_relax_section (bfd *abfd, + intsyms = (Elf_Internal_Sym *) symtab_hdr->contents; + else + { +- intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL); ++ intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL); + symtab_hdr->contents = (bfd_byte *) intsyms; + } + +@@ -3362,7 +3362,7 @@ rx_dump_symtab (bfd * abfd, void * internal_syms, void * external_syms) + if (!internal_syms) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- internal_syms, external_syms, NULL); ++ internal_syms, external_syms); + else + isymbuf = internal_syms; + isymend = isymbuf + locsymcount; +diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c +index e078e41b675..022799f389b 100644 +--- a/bfd/elf32-sh.c ++++ b/bfd/elf32-sh.c +@@ -577,7 +577,7 @@ sh_elf_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +@@ -5118,7 +5118,7 @@ sh_elf_get_relocated_section_contents (bfd *output_bfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c +index de051e48185..eb1ce1c9a12 100644 +--- a/bfd/elf32-spu.c ++++ b/bfd/elf32-spu.c +@@ -538,7 +538,7 @@ get_sym_h (struct elf_link_hash_entry **hp, + if (locsyms == NULL) + locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, + symtab_hdr->sh_info, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (locsyms == NULL) + return false; + *locsymsp = locsyms; +@@ -3018,7 +3018,7 @@ discover_functions (struct bfd_link_info *info) + free (symtab_hdr->contents); + symtab_hdr->contents = NULL; + syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + symtab_hdr->contents = (void *) syms; + if (syms == NULL) + return false; +diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c +index 27744814691..4d96cf9fbce 100644 +--- a/bfd/elf32-v850.c ++++ b/bfd/elf32-v850.c +@@ -3548,7 +3548,7 @@ v850_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c +index 5cee2f389eb..ae043319206 100644 +--- a/bfd/elf32-xstormy16.c ++++ b/bfd/elf32-xstormy16.c +@@ -627,7 +627,7 @@ xstormy16_elf_relax_section (bfd *dynobj, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c +index b21676df36a..c554740f357 100644 +--- a/bfd/elf32-xtensa.c ++++ b/bfd/elf32-xtensa.c +@@ -6831,7 +6831,7 @@ retrieve_local_syms (bfd *input_bfd) + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; + if (isymbuf == NULL && locsymcount != 0) + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + + /* Save the symbols for this input file so they won't be read again. */ + if (isymbuf && isymbuf != (Elf_Internal_Sym *) symtab_hdr->contents) +diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c +index b13c99e4958..2b9eede314d 100644 +--- a/bfd/elf64-alpha.c ++++ b/bfd/elf64-alpha.c +@@ -3814,7 +3814,7 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c +index 05bb7f125b7..8cd2d918d8b 100644 +--- a/bfd/elf64-hppa.c ++++ b/bfd/elf64-hppa.c +@@ -560,7 +560,7 @@ elf64_hppa_check_relocs (bfd *abfd, + if (local_syms == NULL) + local_syms = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (local_syms == NULL) + return false; + } +diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c +index 822b263ae2c..f6d00fc1826 100644 +--- a/bfd/elf64-ia64-vms.c ++++ b/bfd/elf64-ia64-vms.c +@@ -467,7 +467,7 @@ elf64_ia64_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == 0) + goto error_return; + } +@@ -4896,7 +4896,7 @@ elf64_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) + if (extsymcount != 0) + { + isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + +diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c +index bb8350718a2..642b2cdb9bb 100644 +--- a/bfd/elf64-mmix.c ++++ b/bfd/elf64-mmix.c +@@ -2640,7 +2640,7 @@ mmix_elf_relax_section (bfd *abfd, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == 0) + goto error_return; + } +diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c +index fdda9e0bbb3..ee15d6f0639 100644 +--- a/bfd/elf64-ppc.c ++++ b/bfd/elf64-ppc.c +@@ -5666,7 +5666,7 @@ opd_entry_value (asection *opd_sec, + size_t symcnt = symtab_hdr->sh_info; + sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr, + symcnt, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (sym == NULL) + break; + symtab_hdr->contents = (bfd_byte *) sym; +@@ -5677,7 +5677,7 @@ opd_entry_value (asection *opd_sec, + { + sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr, + 1, symndx, +- NULL, NULL, NULL); ++ NULL, NULL); + if (sym == NULL) + break; + } +@@ -6987,7 +6987,7 @@ get_sym_h (struct elf_link_hash_entry **hp, + if (locsyms == NULL) + locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, + symtab_hdr->sh_info, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (locsyms == NULL) + return false; + *locsymsp = locsyms; +@@ -10325,7 +10325,7 @@ ppc64_elf_late_size_sections (bfd *output_bfd, + if (local_syms == NULL && locsymcount != 0) + { + local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (local_syms == NULL) + return false; + } +@@ -12921,7 +12921,7 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info) + if (local_syms == NULL && locsymcount != 0) + { + local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (local_syms == NULL) + return false; + } +@@ -13591,7 +13591,7 @@ got_and_plt_relr_for_local_syms (struct bfd_link_info *info) + if (local_syms == NULL && locsymcount != 0) + { + local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount, +- 0, NULL, NULL, NULL); ++ 0, NULL, NULL); + if (local_syms == NULL) + return false; + } +diff --git a/bfd/elfcode.h b/bfd/elfcode.h +index 5224a1abee6..8777a08a77a 100644 +--- a/bfd/elfcode.h ++++ b/bfd/elfcode.h +@@ -1303,7 +1303,7 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bool dynamic) + size_t i; + + isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return -1; + +@@ -1523,16 +1523,10 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bool dynamic) + } + + free (xverbuf); +- if (hdr->contents != (unsigned char *) isymbuf +- && !elf_use_dt_symtab_p (abfd)) +- free (isymbuf); + return symcount; + + error_return: + free (xverbuf); +- if (hdr->contents != (unsigned char *) isymbuf +- && !elf_use_dt_symtab_p (abfd)) +- free (isymbuf); + return -1; + } + +diff --git a/bfd/elflink.c b/bfd/elflink.c +index 3f3ea2cce51..da4da5c453a 100644 +--- a/bfd/elflink.c ++++ b/bfd/elflink.c +@@ -851,8 +851,6 @@ bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, + struct elf_strtab_hash *dynstr; + size_t dynstr_index; + char *name; +- Elf_External_Sym_Shndx eshndx; +- char esym[sizeof (Elf64_External_Sym)]; + + if (! is_elf_hash_table (info->hash)) + return 0; +@@ -869,7 +867,7 @@ bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, + + /* Go find the symbol, so that we can find it's name. */ + if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr, +- 1, input_indx, &entry->isym, esym, &eshndx)) ++ 1, input_indx, &entry->isym, NULL)) + { + bfd_release (input_bfd, entry); + return 0; +@@ -3745,7 +3743,7 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) + + /* Read in the symbol table. */ + isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + +@@ -3767,7 +3765,11 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) + } + } + +- free (isymbuf); ++ if (!elf_tdata (abfd)->keep_symtab) ++ { ++ free (elf_tdata (abfd)->symtab); ++ elf_tdata (abfd)->symtab = NULL; ++ } + + return result; + } +@@ -4830,7 +4832,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) + if (extsymcount != 0) + { + isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + +@@ -5814,8 +5816,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) + + free (extversym); + extversym = NULL; +- free (isymbuf); +- isymbuf = NULL; ++ ++ /* NB: Since st_shndx of symbol from discarded section is changed to ++ SHN_UNDEF, free the cached symbol table. */ ++ free (elf_tdata (abfd)->symtab); ++ elf_tdata (abfd)->symtab = NULL; + + if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) + { +@@ -6167,7 +6172,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) + free (nondeflt_vers); + free (extversym); + error_free_sym: +- free (isymbuf); ++ free (elf_tdata (abfd)->symtab); ++ elf_tdata (abfd)->symtab = NULL; + error_return: + return false; + } +@@ -8809,7 +8815,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, + if (ssymbuf1 == NULL) + { + isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf1 == NULL) + goto done; + +@@ -8823,7 +8829,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, + if (ssymbuf1 == NULL || ssymbuf2 == NULL) + { + isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, symcount2, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf2 == NULL) + goto done; + +@@ -9013,8 +9019,6 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, + done: + free (symtable1); + free (symtable2); +- free (isymbuf1); +- free (isymbuf2); + + return result; + } +@@ -9056,14 +9060,6 @@ struct elf_final_link_info + void *external_relocs; + /* Buffer large enough to hold internal relocs of any section. */ + Elf_Internal_Rela *internal_relocs; +- /* Buffer large enough to hold external local symbols of any input +- BFD. */ +- bfd_byte *external_syms; +- /* And a buffer for symbol section indices. */ +- Elf_External_Sym_Shndx *locsym_shndx; +- /* Buffer large enough to hold internal local symbols of any input +- BFD. */ +- Elf_Internal_Sym *internal_syms; + /* Array large enough to hold a symbol index for each local symbol + of any input BFD. */ + long *indices; +@@ -10666,7 +10662,7 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info, + continue; + + isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + +@@ -11410,7 +11406,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) + Elf_Internal_Shdr *symtab_hdr; + size_t locsymcount; + size_t extsymoff; +- Elf_Internal_Sym *isymbuf; ++ Elf_Internal_Sym *isymbuf = NULL; + Elf_Internal_Sym *isym; + Elf_Internal_Sym *isymend; + long *pindex; +@@ -11456,13 +11452,10 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) + ? -1 : ~elf_gnu_osabi_retain)); + + /* Read the local symbols. */ +- isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; +- if (isymbuf == NULL && locsymcount != 0) ++ if (locsymcount != 0) + { + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, +- flinfo->internal_syms, +- flinfo->external_syms, +- flinfo->locsym_shndx); ++ NULL, NULL); + if (isymbuf == NULL) + return false; + } +@@ -12632,9 +12625,6 @@ elf_final_link_free (bfd *obfd, struct elf_final_link_info *flinfo) + free (flinfo->contents); + free (flinfo->external_relocs); + free (flinfo->internal_relocs); +- free (flinfo->external_syms); +- free (flinfo->locsym_shndx); +- free (flinfo->internal_syms); + free (flinfo->indices); + free (flinfo->sections); + if (flinfo->symshndxbuf != (Elf_External_Sym_Shndx *) -1) +@@ -12663,7 +12653,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + bfd_size_type max_external_reloc_size; + bfd_size_type max_internal_reloc_count; + bfd_size_type max_sym_count; +- bfd_size_type max_sym_shndx_count; + Elf_Internal_Sym elfsym; + unsigned int i; + Elf_Internal_Shdr *symtab_hdr; +@@ -12792,7 +12781,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + } + max_internal_reloc_count = 0; + max_sym_count = 0; +- max_sym_shndx_count = 0; + merged = false; + for (o = abfd->sections; o != NULL; o = o->next) + { +@@ -12854,10 +12842,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + if (sym_count > max_sym_count) + max_sym_count = sym_count; + +- if (sym_count > max_sym_shndx_count +- && elf_symtab_shndx_list (sec->owner) != NULL) +- max_sym_shndx_count = sym_count; +- + esdi = elf_section_data (sec); + + if (esdi->this_hdr.sh_type == SHT_REL +@@ -13118,16 +13102,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + + if (max_sym_count != 0) + { +- amt = max_sym_count * bed->s->sizeof_sym; +- flinfo.external_syms = (bfd_byte *) bfd_malloc (amt); +- if (flinfo.external_syms == NULL) +- goto error_return; +- +- amt = max_sym_count * sizeof (Elf_Internal_Sym); +- flinfo.internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt); +- if (flinfo.internal_syms == NULL) +- goto error_return; +- + amt = max_sym_count * sizeof (long); + flinfo.indices = (long int *) bfd_malloc (amt); + if (flinfo.indices == NULL) +@@ -13139,14 +13113,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + goto error_return; + } + +- if (max_sym_shndx_count != 0) +- { +- amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); +- flinfo.locsym_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt); +- if (flinfo.locsym_shndx == NULL) +- goto error_return; +- } +- + if (htab->tls_sec) + { + bfd_vma base, end = 0; /* Both bytes. */ +@@ -13890,8 +13856,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + + static bool + init_reloc_cookie (struct elf_reloc_cookie *cookie, +- struct bfd_link_info *info, bfd *abfd, +- bool keep_memory) ++ struct bfd_link_info *info, bfd *abfd) + { + Elf_Internal_Shdr *symtab_hdr; + const struct elf_backend_data *bed; +@@ -13918,39 +13883,20 @@ init_reloc_cookie (struct elf_reloc_cookie *cookie, + else + cookie->r_sym_shift = 32; + +- cookie->locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; +- if (cookie->locsyms == NULL && cookie->locsymcount != 0) ++ if (cookie->locsymcount != 0) + { + cookie->locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, + cookie->locsymcount, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (cookie->locsyms == NULL) + { + info->callbacks->einfo (_("%P%X: can not read symbols: %E\n")); + return false; + } +- if (keep_memory || _bfd_elf_link_keep_memory (info)) +- { +- symtab_hdr->contents = (bfd_byte *) cookie->locsyms; +- info->cache_size += (cookie->locsymcount +- * sizeof (Elf_Internal_Sym)); +- } + } + return true; + } + +-/* Free the memory allocated by init_reloc_cookie, if appropriate. */ +- +-static void +-fini_reloc_cookie (struct elf_reloc_cookie *cookie, bfd *abfd) +-{ +- Elf_Internal_Shdr *symtab_hdr; +- +- symtab_hdr = &elf_tdata (abfd)->symtab_hdr; +- if (symtab_hdr->contents != (unsigned char *) cookie->locsyms) +- free (cookie->locsyms); +-} +- + /* Initialize the relocation information in COOKIE for input section SEC + of input bfd ABFD. */ + +@@ -13996,28 +13942,9 @@ init_reloc_cookie_for_section (struct elf_reloc_cookie *cookie, + struct bfd_link_info *info, + asection *sec, bool keep_memory) + { +- if (!init_reloc_cookie (cookie, info, sec->owner, keep_memory)) +- goto error1; +- if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec, +- keep_memory)) +- goto error2; +- return true; +- +- error2: +- fini_reloc_cookie (cookie, sec->owner); +- error1: +- return false; +-} +- +-/* Free the memory allocated by init_reloc_cookie_for_section, +- if appropriate. */ +- +-static void +-fini_reloc_cookie_for_section (struct elf_reloc_cookie *cookie, +- asection *sec) +-{ +- fini_reloc_cookie_rels (cookie, sec); +- fini_reloc_cookie (cookie, sec->owner); ++ return (init_reloc_cookie (cookie, info, sec->owner) ++ && init_reloc_cookie_rels (cookie, info, sec->owner, sec, ++ keep_memory)); + } + + /* Garbage collect unused sections. */ +@@ -14209,7 +14136,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info, + ret = false; + break; + } +- fini_reloc_cookie_for_section (&cookie, sec); ++ fini_reloc_cookie_rels (&cookie, sec); + } + } + +@@ -14231,7 +14158,7 @@ _bfd_elf_gc_mark (struct bfd_link_info *info, + if (!_bfd_elf_gc_mark_fdes (info, sec, eh_frame, + gc_mark_hook, &cookie)) + ret = false; +- fini_reloc_cookie_for_section (&cookie, eh_frame); ++ fini_reloc_cookie_rels (&cookie, eh_frame); + } + } + +@@ -14665,7 +14592,7 @@ bfd_elf_parse_eh_frame_entries (bfd *abfd ATTRIBUTE_UNUSED, + if (sec == NULL || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) + continue; + +- if (!init_reloc_cookie (&cookie, info, ibfd, false)) ++ if (!init_reloc_cookie (&cookie, info, ibfd)) + return false; + + for (sec = ibfd->sections; sec; sec = sec->next) +@@ -14724,7 +14651,7 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) + if (elf_section_data (sec)->sec_info + && (sec->flags & SEC_LINKER_CREATED) == 0) + elf_eh_frame_section (sub) = sec; +- fini_reloc_cookie_for_section (&cookie, sec); ++ fini_reloc_cookie_rels (&cookie, sec); + sec = bfd_get_next_section_by_name (NULL, sec); + } + } +@@ -14784,6 +14711,13 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) + if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) + return false; + } ++ ++ if (!elf_tdata (sub)->keep_symtab ++ && !_bfd_elf_link_keep_memory (info)) ++ { ++ free (elf_tdata (sub)->symtab); ++ elf_tdata (sub)->symtab = NULL; ++ } + } + + /* Allow the backend to mark additional target specific sections. */ +@@ -15239,7 +15173,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) + &cookie)) + changed = 1; + +- fini_reloc_cookie_for_section (&cookie, i); ++ fini_reloc_cookie_rels (&cookie, i); + } + } + +@@ -15274,7 +15208,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) + changed = 1; + } + +- fini_reloc_cookie_for_section (&cookie, i); ++ fini_reloc_cookie_rels (&cookie, i); + } + + eh_alignment = ((1 << o->alignment_power) +@@ -15339,7 +15273,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) + changed = 1; + } + } +- fini_reloc_cookie_for_section (&cookie, i); ++ fini_reloc_cookie_rels (&cookie, i); + } + /* Update the reference to the output .sframe section. Used to + determine later if PT_GNU_SFRAME segment is to be generated. */ +@@ -15362,13 +15296,11 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) + + if (bed->elf_backend_discard_info != NULL) + { +- if (!init_reloc_cookie (&cookie, info, abfd, false)) ++ if (!init_reloc_cookie (&cookie, info, abfd)) + return -1; + + if ((*bed->elf_backend_discard_info) (abfd, &cookie, info)) + changed = 1; +- +- fini_reloc_cookie (&cookie, abfd); + } + } + +diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c +index 3c3c2899674..553ba27b604 100644 +--- a/bfd/elfnn-aarch64.c ++++ b/bfd/elfnn-aarch64.c +@@ -4471,7 +4471,7 @@ _bfd_aarch64_add_call_stub_entries (bool *stub_changed, bfd *output_bfd, + local_syms + = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (local_syms == NULL) + goto error_ret_free_internal; + } +@@ -4934,7 +4934,7 @@ bfd_elfNN_aarch64_init_maps (bfd *abfd) + /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field + should contain the number of local symbols, which should come before any + global symbols. Mapping symbols are always local. */ +- isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, NULL); ++ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL); + + /* No internal symbols read? Skip this BFD. */ + if (isymbuf == NULL) +diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c +index 528b1dcdcc3..48fce2380cd 100644 +--- a/bfd/elfnn-ia64.c ++++ b/bfd/elfnn-ia64.c +@@ -468,7 +468,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == 0) + goto error_return; + } +diff --git a/bfd/elfnn-kvx.c b/bfd/elfnn-kvx.c +index 3b44db57421..8e75b400570 100644 +--- a/bfd/elfnn-kvx.c ++++ b/bfd/elfnn-kvx.c +@@ -1404,7 +1404,7 @@ elfNN_kvx_size_stubs (bfd *output_bfd, + local_syms + = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (local_syms == NULL) + goto error_ret_free_internal; + } +diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c +index 53cdb783859..10a4f99add7 100644 +--- a/bfd/elfnn-loongarch.c ++++ b/bfd/elfnn-loongarch.c +@@ -5792,7 +5792,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, + && !(symtab_hdr->contents = + (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, +- 0, NULL, NULL, NULL))) ++ 0, NULL, NULL))) + return true; + + /* Estimate the maximum alignment for all output sections once time +diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c +index 09cf7076733..d1ab410a94f 100644 +--- a/bfd/elfnn-riscv.c ++++ b/bfd/elfnn-riscv.c +@@ -5492,7 +5492,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec, + && !(symtab_hdr->contents = + (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, +- 0, NULL, NULL, NULL))) ++ 0, NULL, NULL))) + goto fail; + + /* Get the value of the symbol referred to by the reloc. */ +diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c +index 00ef0663728..44c58362dda 100644 +--- a/bfd/elfxx-mips.c ++++ b/bfd/elfxx-mips.c +@@ -14136,7 +14136,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec, + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, +- NULL, NULL, NULL); ++ NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } +diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c +index 140e86888a6..53083e0b54c 100644 +--- a/bfd/elfxx-x86.c ++++ b/bfd/elfxx-x86.c +@@ -1154,15 +1154,11 @@ _bfd_x86_elf_link_relax_section (bfd *abfd ATTRIBUTE_UNUSED, + /* Read this BFD's local symbols. */ + if (isymbuf == NULL) + { +- isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; ++ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, ++ symtab_hdr->sh_info, ++ 0, NULL, NULL); + if (isymbuf == NULL) +- { +- isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, +- symtab_hdr->sh_info, +- 0, NULL, NULL, NULL); +- if (isymbuf == NULL) +- goto error_return; +- } ++ goto error_return; + } + + isym = isymbuf + r_symndx; +@@ -1345,14 +1341,10 @@ _bfd_x86_elf_link_relax_section (bfd *abfd ATTRIBUTE_UNUSED, + return_status = true; + + error_return: +- if ((unsigned char *) isymbuf != symtab_hdr->contents) +- { +- /* Cache the symbol buffer if it must be kept. */ +- if (keep_symbuf) +- symtab_hdr->contents = (unsigned char *) isymbuf; +- else +- free (isymbuf); +- } ++ /* If the symbol table has been updated, it must be kept since it will ++ be used later. */ ++ if (keep_symbuf) ++ elf_tdata (abfd)->keep_symtab = 1; + if (elf_section_data (input_section)->relocs != internal_relocs) + free (internal_relocs); + return return_status; +diff --git a/libctf/ctf-open-bfd.c b/libctf/ctf-open-bfd.c +index 7241de70709..205347c4e22 100644 +--- a/libctf/ctf-open-bfd.c ++++ b/libctf/ctf-open-bfd.c +@@ -146,8 +146,9 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, + } + + isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0, +- NULL, symtab, NULL); +- free (isymbuf); ++ NULL, symtab); ++ free (elf_tdata (abfd)->symtab); ++ elf_tdata (abfd)->symtab = NULL; + if (isymbuf == NULL) + { + bfderrstr = N_("cannot read symbol table"); +-- +2.51.0 +
