commit: e0a1bcadfb3cf92271b5d67ffa283a8309a6dd92 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Thu Oct 30 06:17:51 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Thu Oct 30 06:17:51 2025 +0000 URL: https://gitweb.gentoo.org/proj/toolchain/binutils-patches.git/commit/?id=e0a1bcad
9999: drop obsolete patch An alternative was merged upstream from Alan. Signed-off-by: Sam James <sam <AT> gentoo.org> ...-internal-symbol-table-in-relocatable-BFD.patch | 849 --------------------- 1 file changed, 849 deletions(-) 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 deleted file mode 100644 index 4ef3fbd..0000000 --- a/9999/0005-elf-Cache-internal-symbol-table-in-relocatable-BFD.patch +++ /dev/null @@ -1,849 +0,0 @@ -From cc559d319379dc169fa2e4bce2c584b2684e1c90 Mon Sep 17 00:00:00 2001 -Message-ID: <cc559d319379dc169fa2e4bce2c584b2684e1c90.1760774616.git....@gentoo.org> -From: "H.J. Lu" <[email protected]> -Date: Thu, 9 Oct 2025 13:16:19 +0800 -Subject: [PATCH] elf: Cache full internal symbol table for relocatable input - -Add bfd_elf_get_elf_syms_cached to cache internal symbol table for -relocatable input and use the internal symbol table cache for both local -and global symbols to avoid swapping in the same symbol table repeatedly -for --gc-sections. This improves linker --gc-sections speed by ~2x for -PR ld/33530. - -Pass non-NULL pointers for internal/external symbol tables and symbol -section indices to bfd_elf_get_elf_syms_cache only if caller uses them -since since it can be very expensive to copy from internal cache to them. -It should be avoided. - -Data to link the 3.1GB clang executable in LLVM 21 debug build on -Linux/x86-64 with 32GB RAM is: - - before after improvement -user 48.29 46.45 3.8% -system 7.82 5.47 30% -total 56.1 51.92 7% -maximum set(GB) 10.5 10.7 -0.2% -page faults 2535779 2509896 0.1% - -and data to link the 308M cc1plus executable in GCC 16 stage 1 build is: - - before after improvement -user 3.56 3.39 4.8% -system 0.66 0.53 20% -total 4.22 3.94 6.6% -maximum set(MB) 946 970 -2.5% -page faults 236737 243509 -0.3% - -bfd/ - - PR ld/33530 - * elf-bfd.h (elf_obj_tdata): Add symtab. - (bfd_elf_get_elf_syms_cached): New function. - (bfd_elf_free_symtab): Likewise. - * 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): Renamed to ... - (bfd_elf_get_elf_syms_cached): This. Cache internal symbol - table. - (bfd_elf_get_elf_syms): Call bfd_elf_get_elf_syms_cached. - (group_signature): Call bfd_elf_get_elf_syms_cached instead of - bfd_elf_get_elf_syms and pass NULL for external symbol table - and symbol section indices. - (bfd_sym_from_r_symndx): Likewise. - (_bfd_elf_free_cached_info): Free internal symbol table cache. - * elfcode.h (elf_slurp_symbol_table): Call - bfd_elf_get_elf_syms_cached instead of bfd_elf_get_elf_syms. - Don't free internal symbol buffer. - * elflink.c (bfd_elf_link_record_local_dynamic_symbol): Call - bfd_elf_get_elf_syms_cached instead of bfd_elf_get_elf_syms - and pass NULL for external symbol table and symbol section - indices. - (elf_link_is_defined_archive_symbol): Call - bfd_elf_get_elf_syms_cached instead of bfd_elf_get_elf_syms. - Free internal symbol table cache. - (elf_link_add_object_symbols): Call bfd_elf_get_elf_syms_cached - instead of bfd_elf_get_elf_syms. Free internal symbol table - cache if it has been changed or there is an error. - (bfd_elf_match_symbols_in_sections): Call - bfd_elf_get_elf_syms_cached instead of bfd_elf_get_elf_syms. - Don't free the internal symbol table. - (elf_final_link_info): Remove external_syms, locsym_shndx and - internal_syms. - (elf_link_check_versioned_symbol): Call - bfd_elf_get_elf_syms_cached instead of bfd_elf_get_elf_syms. - (elf_link_input_bfd): Likewise. Pass NULL as pointers to - internal/external symbol tables and symbol section indices to - bfd_elf_get_elf_syms_cached. - (elf_final_link_free): Updated. - (bfd_elf_final_link): Don't clear flinfo fields after cleared - with memset. Don't set flinfo.external_syms, - flinfo.internal_syms nor flinfo.locsym_shndx. - * elfxx-x86.c (_bfd_x86_elf_link_relax_section): Call - bfd_elf_get_elf_syms_cached instead of bfd_elf_get_elf_syms. - Cache internal symbol table in symtab_hdr->contents if it has - been changed. - -libctf/ - - PR ld/33530 - * ctf-open-bfd.c (ctf_bfdopen_ctfsect): Call - bfd_elf_get_elf_syms_cached instead of bfd_elf_get_elf_syms. - Free internal symbol table cache. - -Signed-off-by: H.J. Lu <[email protected]> ---- - bfd/elf-bfd.h | 17 ++++ - bfd/elf-eh-frame.c | 17 +--- - bfd/elf.c | 189 +++++++++++++++++++++++++++++++++--------- - bfd/elfcode.h | 10 +-- - bfd/elflink.c | 95 +++++++-------------- - bfd/elfxx-x86.c | 22 +++-- - libctf/ctf-open-bfd.c | 6 +- - 7 files changed, 219 insertions(+), 137 deletions(-) - -diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h -index 5d19529d972..28179647e9d 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 it -+ is used by backends to 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; -@@ -2299,6 +2304,9 @@ extern char *bfd_elf_string_from_elf_section - 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 *); -+extern Elf_Internal_Sym *bfd_elf_get_elf_syms_cached -+ (bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *, -+ Elf_External_Sym_Shndx *); - 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 *); -@@ -3333,6 +3341,15 @@ bfd_section_is_ctf (const asection *sec) - return startswith (name, ".ctf") && (name[4] == 0 || name[4] == '.'); - } - -+/* Free ELF symbol table cache. */ -+ -+static inline void -+bfd_elf_free_symtab (bfd *abfd) -+{ -+ free (elf_tdata (abfd)->symtab); -+ elf_tdata (abfd)->symtab = NULL; -+} -+ - #ifdef __cplusplus - } - #endif -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.c b/bfd/elf.c -index bde7414ee21..134c3664f85 100644 ---- a/bfd/elf.c -+++ b/bfd/elf.c -@@ -427,22 +427,27 @@ bfd_elf_string_from_elf_section (bfd *abfd, - return ((char *) hdr->contents) + strindex; - } - --/* 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 -- 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. */ -+/* Read and convert symbols to internal format. PARTIAL_SYMCOUNT -+ specifies the number of symbols to read, starting from symbol -+ PARTIAL_SYMOFFSET. If any of INTSYM_BUF, PARTIAL_EXTSYM_BUF or -+ PARTIAL_EXTSHNDX_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 or NULL if there were no symbols or some kind of -+ problem. -+ -+ NB: Pass non-NULL for INTSYM_BUF, PARTIAL_EXTSYM_BUF or -+ PARTIAL_EXTSHNDX_BUF only if they will be used since it can be -+ very expensive to copy from internal cache to them. */ - - Elf_Internal_Sym * --bfd_elf_get_elf_syms (bfd *ibfd, -- Elf_Internal_Shdr *symtab_hdr, -- size_t symcount, -- size_t symoffset, -- Elf_Internal_Sym *intsym_buf, -- void *extsym_buf, -- Elf_External_Sym_Shndx *extshndx_buf) -+bfd_elf_get_elf_syms_cached (bfd *ibfd, -+ Elf_Internal_Shdr *symtab_hdr, -+ size_t partial_symcount, -+ size_t partial_symoffset, -+ Elf_Internal_Sym *intsym_buf, -+ void *partial_extsym_buf, -+ Elf_External_Sym_Shndx *partial_extshndx_buf) - { - Elf_Internal_Shdr *shndx_hdr; - void *alloc_ext; -@@ -455,7 +460,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; -+ Elf_External_Sym_Shndx *extshndx_buf = NULL; -+ void *extsym_buf = NULL; -+ bool cache_symtab = false; - - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) - abort (); -@@ -474,6 +484,25 @@ bfd_elf_get_elf_syms (bfd *ibfd, - return elf_tdata (ibfd)->dt_symtab + symoffset; - } - -+ if (elf_tdata (ibfd)->symtab != NULL) -+ { -+ /* Since extsym_buf and extshndx_buf aren't cached, free the -+ symbol table cache and re-read the symbol table. */ -+ if (partial_extsym_buf != NULL || partial_extshndx_buf != NULL) -+ bfd_elf_free_symtab (ibfd); -+ else -+ { -+ 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 +535,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 +592,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 +633,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,18 +647,83 @@ 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; - } - } - -+ /* Copy external symbol table before external symbol table buffer -+ is released by _bfd_munmap_temporary. */ -+ if (intsym_buf != NULL) -+ { -+ if (partial_extsym_buf != NULL) -+ memcpy (partial_extsym_buf, -+ extsym_buf + partial_symoffset * extsym_size, -+ partial_symcount * extsym_size); -+ if (extshndx_buf != NULL && partial_extshndx_buf != NULL) -+ memcpy (partial_extshndx_buf, -+ (extshndx_buf -+ + partial_symoffset * sizeof (Elf_External_Sym_Shndx)), -+ partial_symcount * sizeof (Elf_External_Sym_Shndx)); -+ } -+ - out1: - _bfd_munmap_temporary (alloc_extshndx, alloc_extshndx_size); - out2: - _bfd_munmap_temporary (alloc_ext, alloc_ext_size); - -+ if (intsym_buf == NULL || !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; -+} -+ -+/* Read and convert symbols to internal format. PARTIAL_SYMCOUNT -+ specifies the number of symbols to read, starting from symbol -+ PARTIAL_SYMOFFSET. If any of INTSYM_BUF, PARTIAL_EXTSYM_BUF -+ or PARTIAL_EXTSHNDX_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. */ -+ -+Elf_Internal_Sym * -+bfd_elf_get_elf_syms (bfd *ibfd, -+ Elf_Internal_Shdr *symtab_hdr, -+ size_t partial_symcount, -+ size_t partial_symoffset, -+ Elf_Internal_Sym *intsym_buf, -+ void *partial_extsym_buf, -+ Elf_External_Sym_Shndx *partial_extshndx_buf) -+{ -+ Elf_Internal_Sym *isym -+ = bfd_elf_get_elf_syms_cached (ibfd, symtab_hdr, partial_symcount, -+ partial_symoffset, intsym_buf, -+ partial_extsym_buf, -+ partial_extshndx_buf); -+ if (isym == NULL -+ || intsym_buf != NULL -+ || partial_symcount == 0 -+ || elf_use_dt_symtab_p (ibfd)) -+ return isym; -+ -+ size_t amt = partial_symcount * sizeof (*intsym_buf); -+ intsym_buf = bfd_malloc (amt); -+ if (intsym_buf != NULL) -+ memcpy (intsym_buf, isym, amt); -+ bfd_elf_free_symtab (ibfd); - return intsym_buf; - } - -@@ -659,8 +769,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 -@@ -674,8 +782,8 @@ 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) -+ if (bfd_elf_get_elf_syms_cached (abfd, hdr, 1, ghdr->sh_info, -+ &isym, NULL, NULL) == NULL) - return NULL; - - return bfd_elf_sym_name_raw (abfd, hdr, &isym); -@@ -3029,12 +3137,11 @@ 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) -+ if (bfd_elf_get_elf_syms_cached (abfd, symtab_hdr, 1, r_symndx, -+ &cache->sym[ent], NULL, NULL) -+ == NULL) - return NULL; - - if (cache->abfd != abfd) -@@ -10241,6 +10348,8 @@ _bfd_elf_free_cached_info (bfd *abfd) - } - free (tdata->symtab_hdr.contents); - tdata->symtab_hdr.contents = NULL; -+ free (tdata->symtab); -+ tdata->symtab = NULL; - } - - return _bfd_generic_bfd_free_cached_info (abfd); -diff --git a/bfd/elfcode.h b/bfd/elfcode.h -index 5224a1abee6..ae5e814cdcc 100644 ---- a/bfd/elfcode.h -+++ b/bfd/elfcode.h -@@ -1302,8 +1302,8 @@ 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); -+ isymbuf = bfd_elf_get_elf_syms_cached (abfd, hdr, symcount, 0, -+ 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..1259bd20f94 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; -@@ -868,8 +866,10 @@ bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, - return 0; - - /* 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)) -+ if (!bfd_elf_get_elf_syms_cached (input_bfd, -+ &elf_tdata (input_bfd)->symtab_hdr, -+ 1, input_indx, &entry->isym, NULL, -+ NULL)) - { - bfd_release (input_bfd, entry); - return 0; -@@ -3744,8 +3744,8 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) - return false; - - /* Read in the symbol table. */ -- isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, -- NULL, NULL, NULL); -+ isymbuf = bfd_elf_get_elf_syms_cached (abfd, hdr, extsymcount, -+ extsymoff, NULL, NULL, NULL); - if (isymbuf == NULL) - return false; - -@@ -3767,7 +3767,7 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) - } - } - -- free (isymbuf); -+ bfd_elf_free_symtab (abfd); - - return result; - } -@@ -4829,8 +4829,9 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) - sym_hash = elf_sym_hashes (abfd); - if (extsymcount != 0) - { -- isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, -- NULL, NULL, NULL); -+ isymbuf = bfd_elf_get_elf_syms_cached (abfd, hdr, extsymcount, -+ extsymoff, NULL, NULL, -+ NULL); - if (isymbuf == NULL) - goto error_return; - -@@ -4977,6 +4978,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) - (_("%pB: plugin needed to handle lto object"), abfd); - } - -+ bool symtab_changed = false; -+ - for (isym = isymbuf, isymend = PTR_ADD (isymbuf, extsymcount); - isym < isymend; - isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL)) -@@ -5013,6 +5016,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) - { - /* Treat common symbol as undefined for --no-define-common. */ - isym->st_shndx = SHN_UNDEF; -+ symtab_changed = true; - common = false; - } - discarded = false; -@@ -5086,6 +5090,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) - sec = bfd_und_section_ptr; - discarded = true; - isym->st_shndx = SHN_UNDEF; -+ symtab_changed = true; - } - else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) - value -= sec->vma; -@@ -5814,8 +5819,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) - - free (extversym); - extversym = NULL; -- free (isymbuf); -- isymbuf = NULL; -+ -+ /* Free internal symbol table cache if it has been changed. */ -+ if (symtab_changed) -+ bfd_elf_free_symtab (abfd); - - if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) - { -@@ -6167,7 +6174,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) - free (nondeflt_vers); - free (extversym); - error_free_sym: -- free (isymbuf); -+ bfd_elf_free_symtab (abfd); - error_return: - return false; - } -@@ -8808,8 +8815,8 @@ 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); -+ isymbuf1 = bfd_elf_get_elf_syms_cached (bfd1, hdr1, symcount1, -+ 0, NULL, NULL, NULL); - if (isymbuf1 == NULL) - goto done; - -@@ -8822,8 +8829,8 @@ 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); -+ isymbuf2 = bfd_elf_get_elf_syms_cached (bfd2, hdr2, symcount2, -+ 0, NULL, NULL, NULL); - if (isymbuf2 == NULL) - goto done; - -@@ -9013,8 +9020,6 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, - done: - free (symtable1); - free (symtable2); -- free (isymbuf1); -- free (isymbuf2); - - return result; - } -@@ -9056,14 +9061,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; -@@ -10665,8 +10662,9 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info, - if (extsymcount == 0) - continue; - -- isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, -- NULL, NULL, NULL); -+ isymbuf = bfd_elf_get_elf_syms_cached (input, hdr, extsymcount, -+ extsymoff, NULL, NULL, -+ NULL); - if (isymbuf == NULL) - return false; - -@@ -11459,10 +11457,9 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, 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, -- flinfo->internal_syms, -- flinfo->external_syms, -- flinfo->locsym_shndx); -+ isymbuf = bfd_elf_get_elf_syms_cached (input_bfd, symtab_hdr, -+ locsymcount, 0, NULL, NULL, -+ NULL); - if (isymbuf == NULL) - return false; - } -@@ -12632,9 +12629,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 +12657,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; -@@ -12697,12 +12690,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - if (flinfo.symstrtab == NULL) - return false; - -- if (! dynamic) -- { -- flinfo.hash_sec = NULL; -- flinfo.symver_sec = NULL; -- } -- else -+ if (dynamic) - { - flinfo.hash_sec = bfd_get_linker_section (dynobj, ".hash"); - /* Note that dynsym_sec can be NULL (on VMS). */ -@@ -12792,7 +12780,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 +12841,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 +13101,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 +13112,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. */ -diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c -index 140e86888a6..a44b0bb9124 100644 ---- a/bfd/elfxx-x86.c -+++ b/bfd/elfxx-x86.c -@@ -1157,9 +1157,10 @@ _bfd_x86_elf_link_relax_section (bfd *abfd ATTRIBUTE_UNUSED, - isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; - if (isymbuf == NULL) - { -- isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, -- symtab_hdr->sh_info, -- 0, NULL, NULL, NULL); -+ isymbuf -+ = bfd_elf_get_elf_syms_cached (abfd, symtab_hdr, -+ symtab_hdr->sh_info, -+ 0, NULL, NULL, NULL); - if (isymbuf == NULL) - goto error_return; - } -@@ -1345,13 +1346,18 @@ _bfd_x86_elf_link_relax_section (bfd *abfd ATTRIBUTE_UNUSED, - return_status = true; - - error_return: -- if ((unsigned char *) isymbuf != symtab_hdr->contents) -+ if (keep_symbuf && (unsigned char *) isymbuf != symtab_hdr->contents) - { -- /* Cache the symbol buffer if it must be kept. */ -- if (keep_symbuf) -- symtab_hdr->contents = (unsigned char *) isymbuf; -+ /* Cache the symbol buffer if it has been changed. */ -+ size_t amt = symtab_hdr->sh_info * sizeof (*isymbuf); -+ void *buffer = bfd_malloc (amt); -+ if (buffer == NULL) -+ return_status = false; - else -- free (isymbuf); -+ { -+ memcpy (buffer, isymbuf, amt); -+ symtab_hdr->contents = buffer; -+ } - } - if (elf_section_data (input_section)->relocs != internal_relocs) - free (internal_relocs); -diff --git a/libctf/ctf-open-bfd.c b/libctf/ctf-open-bfd.c -index 7241de70709..0cabab8dc1f 100644 ---- a/libctf/ctf-open-bfd.c -+++ b/libctf/ctf-open-bfd.c -@@ -145,9 +145,9 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, - goto err; - } - -- isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0, -- NULL, symtab, NULL); -- free (isymbuf); -+ isymbuf = bfd_elf_get_elf_syms_cached (abfd, symhdr, symcount, 0, -+ NULL, symtab, NULL); -+ bfd_elf_free_symtab (abfd); - if (isymbuf == NULL) - { - bfderrstr = N_("cannot read symbol table"); - -base-commit: 865101d377d06b428c7f6843d70001dd00857b2a --- -2.51.0 -
