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
+

Reply via email to