libiberty: sync with gcc

Message ID 9cf2b6d89d9f2e805e9079c7c58123dfe679bd2d.1731909732.git.sam@gentoo.org
State New
Headers
Series libiberty: sync with gcc |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Sam James Nov. 18, 2024, 6:02 a.m. UTC
  This imports the following commits from GCC as of r15-5375-gbeec291225be9b:
	94bea5dd6c9a libiberity: ANSIfy test-demangle.c
	aa84020b2edb libiberty: Fix comment typos
	c1b2100e736c libiberty: Restore build with CP_DEMANGLE_DEBUG defined
	bb8dd0980b39 libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614]
---
OK? This primarily fixes a C23 issue in test-demangle.c.

 libiberty/ChangeLog                 |  37 +++++
 libiberty/cp-demangle.c             |   4 +-
 libiberty/cplus-dem.c               |   2 +-
 libiberty/simple-object-elf.c       | 210 +++++++++++++++++++---------
 libiberty/testsuite/test-demangle.c |  15 +-
 5 files changed, 187 insertions(+), 81 deletions(-)


base-commit: a2f774427e078f3da2c06bdea25f77a61979a695
  

Comments

Tom Tromey Nov. 22, 2024, 3:30 p.m. UTC | #1
>>>>> "Sam" == Sam James <sam@gentoo.org> writes:

Sam> This imports the following commits from GCC as of r15-5375-gbeec291225be9b:
Sam> 	94bea5dd6c9a libiberity: ANSIfy test-demangle.c
Sam> 	aa84020b2edb libiberty: Fix comment typos
Sam> 	c1b2100e736c libiberty: Restore build with CP_DEMANGLE_DEBUG defined
Sam> 	bb8dd0980b39 libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614]
Sam> ---
Sam> OK? This primarily fixes a C23 issue in test-demangle.c.

Thank you.  Please check this in.
Approved-By: Tom Tromey <tom@tromey.com>

Tom
  
Sam James Nov. 22, 2024, 3:46 p.m. UTC | #2
Tom Tromey <tom@tromey.com> writes:

>>>>>> "Sam" == Sam James <sam@gentoo.org> writes:
>
> Sam> This imports the following commits from GCC as of r15-5375-gbeec291225be9b:
> Sam> 	94bea5dd6c9a libiberity: ANSIfy test-demangle.c
> Sam> 	aa84020b2edb libiberty: Fix comment typos
> Sam> 	c1b2100e736c libiberty: Restore build with CP_DEMANGLE_DEBUG defined
> Sam> 	bb8dd0980b39 libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614]
> Sam> ---
> Sam> OK? This primarily fixes a C23 issue in test-demangle.c.
>
> Thank you.  Please check this in.
> Approved-By: Tom Tromey <tom@tromey.com>

Thanks. I'm going to add this commit on top to catch another change
which went in later:

diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 4a461602ac0..83e9120c444 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,7 @@
+2024-11-19  Evgeny Karpov  <evgeny.karpov@microsoft.com>
+
+       * simple-object-coff.c: Add aarch64.
+
 2024-11-16  Andrew Pinski  <quic_apinski@quicinc.com>

        * testsuite/test-demangle.c (get_line): Change K&R style
diff --git a/libiberty/simple-object-coff.c b/libiberty/simple-object-coff.c
index e748205972f..fd3c310db51 100644
--- a/libiberty/simple-object-coff.c
+++ b/libiberty/simple-object-coff.c
@@ -219,7 +219,9 @@ static const struct coff_magic_struct coff_magic[] =
   /* i386.  */
   { 0x14c, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL },
   /* x86_64.  */
-  { 0x8664, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL }
+  { 0x8664, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL },
+  /* AArch64.  */
+  { 0xaa64, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL }
 };

 /* See if we have a COFF file.  */
 
>
> Tom

thanks,
sam
  
Tom Tromey Nov. 22, 2024, 11:43 p.m. UTC | #3
>>>>> "Sam" == Sam James <sam@gentoo.org> writes:

>> Thank you.  Please check this in.
>> Approved-By: Tom Tromey <tom@tromey.com>

Sam> Thanks. I'm going to add this commit on top to catch another change
Sam> which went in later:

That's totally fine, thank you.  I think these kind of merges are
basically pre-approved and the main thing is to discuss if there's
something difficult or contentious in there.  If we could automate this
I probably would.

Tom
  

Patch

diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 949fec62fe4..4a461602ac0 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,40 @@ 
+2024-11-16  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	* testsuite/test-demangle.c (get_line): Change K&R style
+	definition into ANSI C90 definitions.
+	(fail): Likewise.
+	(main): Likewise.
+
+2024-10-31  Mark Wielaard  <mark@klomp.org>
+
+	* cplus-dem.c: Change preceeded to preceded.
+
+2024-10-10  Simon Martin  <simon@nasilyan.com>
+
+	* cp-demangle.c (d_dump): Fix compilation when CP_DEMANGLE_DEBUG
+	is defined.
+
+2024-09-07  Jakub Jelinek  <jakub@redhat.com>
+
+	PR lto/116614
+	* simple-object-elf.c (SHN_COMMON): Align comment with neighbouring
+	comments.
+	(SHN_HIRESERVE): Use uppercase hex digits instead of lowercase for
+	consistency.
+	(simple_object_elf_find_sections): Formatting fixes.
+	(simple_object_elf_fetch_attributes): Likewise.
+	(simple_object_elf_attributes_merge): Likewise.
+	(simple_object_elf_start_write): Likewise.
+	(simple_object_elf_write_ehdr): Likewise.
+	(simple_object_elf_write_shdr): Likewise.
+	(simple_object_elf_write_to_file): Likewise.
+	(simple_object_elf_copy_lto_debug_section): Likewise.  Don't fail for
+	new_i - 1 >= SHN_LORESERVE, instead arrange in that case to copy
+	over .symtab_shndx sections, though emit those last and compute their
+	section content when processing associated .symtab sections.  Handle
+	simple_object_internal_read failure even in the .symtab_shndx reading
+	case.
+
 2024-08-05  Andrew Burgess  <aburgess@redhat.com>
 
 	* argv.c (only_whitespace): Delete.
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index fc2cf64e6e0..5b1bd5dff22 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -655,9 +655,9 @@  d_dump (struct demangle_component *dc, int indent)
       return;
     case DEMANGLE_COMPONENT_EXTENDED_BUILTIN_TYPE:
       {
-	char suffix[2] = { dc->u.s_extended_builtin.type->suffix, 0 };
+	char suffix[2] = { dc->u.s_extended_builtin.suffix, 0 };
 	printf ("builtin type %s%d%s\n", dc->u.s_extended_builtin.type->name,
-		dc->u.s_extended_builtin.type->arg, suffix);
+		dc->u.s_extended_builtin.arg, suffix);
       }
       return;
     case DEMANGLE_COMPONENT_OPERATOR:
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index ee9e84f5d6b..e67ae930049 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -215,7 +215,7 @@  ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
     goto unknown;
 
   /* Most of the demangling will trivially remove chars.  Operator names
-     may add one char but because they are always preceeded by '__' which is
+     may add one char but because they are always preceded by '__' which is
      replaced by '.', they eventually never expand the size.
      A few special names such as '___elabs' add a few chars (at most 7), but
      they occur only once.  */
diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c
index c09c216656c..5e95297b2fc 100644
--- a/libiberty/simple-object-elf.c
+++ b/libiberty/simple-object-elf.c
@@ -128,9 +128,9 @@  typedef struct {
 
 #define SHN_UNDEF	0		/* Undefined section */
 #define SHN_LORESERVE	0xFF00		/* Begin range of reserved indices */
-#define SHN_COMMON	0xFFF2	/* Associated symbol is in common */
+#define SHN_COMMON	0xFFF2		/* Associated symbol is in common */
 #define SHN_XINDEX	0xFFFF		/* Section index is held elsewhere */
-#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
+#define SHN_HIRESERVE	0xFFFF		/* End of reserved indices */
 
 
 /* 32-bit ELF program header.  */
@@ -569,8 +569,8 @@  simple_object_elf_find_sections (simple_object_read *sobj,
 				 void *data,
 				 int *err)
 {
-  struct simple_object_elf_read *eor =
-    (struct simple_object_elf_read *) sobj->data;
+  struct simple_object_elf_read *eor
+    = (struct simple_object_elf_read *) sobj->data;
   const struct elf_type_functions *type_functions = eor->type_functions;
   unsigned char ei_class = eor->ei_class;
   size_t shdr_size;
@@ -662,8 +662,8 @@  simple_object_elf_fetch_attributes (simple_object_read *sobj,
 				    const char **errmsg ATTRIBUTE_UNUSED,
 				    int *err ATTRIBUTE_UNUSED)
 {
-  struct simple_object_elf_read *eor =
-    (struct simple_object_elf_read *) sobj->data;
+  struct simple_object_elf_read *eor
+    = (struct simple_object_elf_read *) sobj->data;
   struct simple_object_elf_attributes *ret;
 
   ret = XNEW (struct simple_object_elf_attributes);
@@ -689,10 +689,10 @@  simple_object_elf_release_read (void *data)
 static const char *
 simple_object_elf_attributes_merge (void *todata, void *fromdata, int *err)
 {
-  struct simple_object_elf_attributes *to =
-    (struct simple_object_elf_attributes *) todata;
-  struct simple_object_elf_attributes *from =
-    (struct simple_object_elf_attributes *) fromdata;
+  struct simple_object_elf_attributes *to
+    = (struct simple_object_elf_attributes *) todata;
+  struct simple_object_elf_attributes *from
+    = (struct simple_object_elf_attributes *) fromdata;
 
   if (to->ei_data != from->ei_data || to->ei_class != from->ei_class)
     {
@@ -751,8 +751,8 @@  simple_object_elf_start_write (void *attributes_data,
 			       const char **errmsg ATTRIBUTE_UNUSED,
 			       int *err ATTRIBUTE_UNUSED)
 {
-  struct simple_object_elf_attributes *attrs =
-    (struct simple_object_elf_attributes *) attributes_data;
+  struct simple_object_elf_attributes *attrs
+    = (struct simple_object_elf_attributes *) attributes_data;
   struct simple_object_elf_write *ret;
 
   /* We're just going to record the attributes, but we need to make a
@@ -769,8 +769,8 @@  static int
 simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor,
 			      const char **errmsg, int *err)
 {
-  struct simple_object_elf_attributes *attrs =
-    (struct simple_object_elf_attributes *) sobj->data;
+  struct simple_object_elf_attributes *attrs
+    = (struct simple_object_elf_attributes *) sobj->data;
   const struct elf_type_functions* fns;
   unsigned char cl;
   size_t ehdr_size;
@@ -852,8 +852,8 @@  simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor,
 			      size_t sh_entsize,
 			      const char **errmsg, int *err)
 {
-  struct simple_object_elf_attributes *attrs =
-    (struct simple_object_elf_attributes *) sobj->data;
+  struct simple_object_elf_attributes *attrs
+    = (struct simple_object_elf_attributes *) sobj->data;
   const struct elf_type_functions* fns;
   unsigned char cl;
   size_t shdr_size;
@@ -894,8 +894,8 @@  static const char *
 simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor,
 				 int *err)
 {
-  struct simple_object_elf_write *eow =
-    (struct simple_object_elf_write *) sobj->data;
+  struct simple_object_elf_write *eow
+    = (struct simple_object_elf_write *) sobj->data;
   struct simple_object_elf_attributes *attrs = &eow->attrs;
   unsigned char cl;
   size_t ehdr_size;
@@ -1088,11 +1088,11 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 					   char *(*pfn) (const char *),
 					   int *err)
 {
-  struct simple_object_elf_read *eor =
-    (struct simple_object_elf_read *) sobj->data;
+  struct simple_object_elf_read *eor
+    = (struct simple_object_elf_read *) sobj->data;
   const struct elf_type_functions *type_functions = eor->type_functions;
-  struct simple_object_elf_write *eow =
-    (struct simple_object_elf_write *) dobj->data;
+  struct simple_object_elf_write *eow
+    = (struct simple_object_elf_write *) dobj->data;
   unsigned char ei_class = eor->ei_class;
   size_t shdr_size;
   unsigned int shnum;
@@ -1106,10 +1106,13 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
   int changed;
   int *pfnret;
   const char **pfnname;
-  unsigned new_i;
+  unsigned new_i, new_count;
   unsigned *sh_map;
   unsigned first_shndx = 0;
   unsigned int *symtab_indices_shndx;
+  int pass_symtab_indices_shndx;
+  unsigned int first_symtab_indices_shndx;
+  unsigned char **symtab_indices_shndx_buf;
 
   shdr_size = (ei_class == ELFCLASS32
 	       ? sizeof (Elf32_External_Shdr)
@@ -1179,8 +1182,7 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
       ret = (*pfn) (name);
       pfnret[i - 1] = ret == NULL ? -1 : 0;
       pfnname[i - 1] = ret == NULL ? name : ret;
-      if (first_shndx == 0
-	  && pfnret[i - 1] == 0)
+      if (first_shndx == 0 && pfnret[i - 1] == 0)
 	first_shndx = i;
 
       /* Remember the indexes of existing SHT_SYMTAB_SHNDX sections.  */
@@ -1191,11 +1193,12 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 	  unsigned int sh_link;
 	  sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 				     shdr, sh_link, Elf_Word);
-	  symtab_indices_shndx[sh_link - 1] = i - 1;
-	  /* Always discard the extended index sections, after
-	     copying it will not be needed.  This way we don't need to
-	     update it and deal with the ordering constraints of
-	     processing the existing symtab and changing the index.  */
+	  symtab_indices_shndx[sh_link - 1] = i;
+	  /* Discard the extended index sections, after copying it will not
+	     be needed, unless we need more than SHN_LORESERVE - 1 sections
+	     in the output.  This way we don't need to update it and deal with
+	     the ordering constraints of processing the existing symtab and
+	     changing the index.  */
 	  pfnret[i - 1] = -1;
 	}
     }
@@ -1291,16 +1294,25 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
       else
 	sh_map[i] = new_i++;
     }
+  first_symtab_indices_shndx = new_i;
+  symtab_indices_shndx_buf = NULL;
   if (new_i - 1 >= SHN_LORESERVE)
-    {
-      *err = ENOTSUP;
-      return "Too many copied sections";
-    }
-  eow->shdrs = XNEWVEC (unsigned char, shdr_size * (new_i - 1));
+    for (i = 1; i < shnum; ++i)
+      if (pfnret[i - 1] == 0 && symtab_indices_shndx[i - 1] != 0)
+	{
+	  pfnret[symtab_indices_shndx[i - 1] - 1] = 0;
+	  sh_map[symtab_indices_shndx[i - 1]] = new_i++;
+	}
+  new_count = new_i;
+  if (new_count != first_symtab_indices_shndx)
+    symtab_indices_shndx_buf
+      = XNEWVEC (unsigned char *, new_count - first_symtab_indices_shndx);
+  eow->shdrs = XNEWVEC (unsigned char, shdr_size * (new_count - 1));
 
   /* Then perform the actual copying.  */
   new_i = 0;
-  for (i = 1; i < shnum; ++i)
+  pass_symtab_indices_shndx = 0;
+  for (i = 1; i <= shnum; ++i)
     {
       unsigned char *shdr;
       unsigned int sh_name, sh_type;
@@ -1311,11 +1323,30 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
       off_t flags;
       unsigned char *buf;
 
+      if (i == shnum)
+	{
+	  if (new_count - 1 < SHN_LORESERVE || pass_symtab_indices_shndx)
+	    break;
+	  i = 0;
+	  pass_symtab_indices_shndx = 1;
+	  continue;
+	}
+
       if (pfnret[i - 1])
 	continue;
 
-      new_i++;
       shdr = shdrs + (i - 1) * shdr_size;
+      sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+				 shdr, sh_type, Elf_Word);
+      if (sh_type == SHT_SYMTAB_SHNDX)
+	{
+	  if (!pass_symtab_indices_shndx)
+	    continue;
+	}
+      else if (pass_symtab_indices_shndx)
+	continue;
+
+      new_i++;
       sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 				 shdr, sh_name, Elf_Word);
       if (sh_name >= name_size)
@@ -1324,6 +1355,7 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 	  XDELETEVEC (names);
 	  XDELETEVEC (shdrs);
 	  XDELETEVEC (symtab_indices_shndx);
+	  XDELETEVEC (symtab_indices_shndx_buf);
 	  return "ELF section name out of range";
 	}
 
@@ -1332,16 +1364,14 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 				shdr, sh_offset, Elf_Addr);
       length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 				shdr, sh_size, Elf_Addr);
-      sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
-				 shdr, sh_type, Elf_Word);
 
-      dest = simple_object_write_create_section (dobj, pfnname[i - 1],
-						 0, &errmsg, err);
+      dest = simple_object_write_create_section (dobj, name, 0, &errmsg, err);
       if (dest == NULL)
 	{
 	  XDELETEVEC (names);
 	  XDELETEVEC (shdrs);
 	  XDELETEVEC (symtab_indices_shndx);
+	  XDELETEVEC (symtab_indices_shndx_buf);
 	  return errmsg;
 	}
 
@@ -1363,6 +1393,7 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 	  XDELETEVEC (names);
 	  XDELETEVEC (shdrs);
 	  XDELETEVEC (symtab_indices_shndx);
+	  XDELETEVEC (symtab_indices_shndx_buf);
 	  return errmsg;
 	}
 
@@ -1378,7 +1409,8 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 	  /* Read the section index table if present.  */
 	  if (symtab_indices_shndx[i - 1] != 0)
 	    {
-	      unsigned char *sidxhdr = shdrs + symtab_indices_shndx[i - 1] * shdr_size;
+	      unsigned char *sidxhdr
+		= shdrs + (symtab_indices_shndx[i - 1] - 1) * shdr_size;
 	      off_t sidxoff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 					       sidxhdr, sh_offset, Elf_Addr);
 	      size_t sidxsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
@@ -1388,11 +1420,20 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 				   sidxhdr, sh_type, Elf_Word);
 	      if (shndx_type != SHT_SYMTAB_SHNDX)
 		return "Wrong section type of a SYMTAB SECTION INDICES section";
-	      shndx_table = (unsigned *)XNEWVEC (char, sidxsz);
-	      simple_object_internal_read (sobj->descriptor,
-					   sobj->offset + sidxoff,
-					   (unsigned char *)shndx_table,
-					   sidxsz, &errmsg, err);
+	      shndx_table = (unsigned *) XNEWVEC (char, sidxsz);
+	      if (!simple_object_internal_read (sobj->descriptor,
+						sobj->offset + sidxoff,
+						(unsigned char *) shndx_table,
+						sidxsz, &errmsg, err))
+		{
+		  XDELETEVEC (buf);
+		  XDELETEVEC (names);
+		  XDELETEVEC (shdrs);
+		  XDELETEVEC (symtab_indices_shndx);
+		  XDELETEVEC (shndx_table);
+		  XDELETEVEC (symtab_indices_shndx_buf);
+		  return errmsg;
+		}
 	    }
 
 	  /* Find a WEAK HIDDEN symbol which name we will use for removed
@@ -1407,17 +1448,20 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 	      unsigned char *st_other;
 	      if (ei_class == ELFCLASS32)
 		{
-		  st_info = &((Elf32_External_Sym *)ent)->st_info;
-		  st_other = &((Elf32_External_Sym *)ent)->st_other;
+		  st_info = &((Elf32_External_Sym *) ent)->st_info;
+		  st_other = &((Elf32_External_Sym *) ent)->st_other;
 		}
 	      else
 		{
-		  st_info = &((Elf64_External_Sym *)ent)->st_info;
-		  st_other = &((Elf64_External_Sym *)ent)->st_other;
+		  st_info = &((Elf64_External_Sym *) ent)->st_info;
+		  st_other = &((Elf64_External_Sym *) ent)->st_other;
 		}
 	      if (st_shndx == SHN_XINDEX)
-		st_shndx = type_functions->fetch_Elf_Word
-		    ((unsigned char *)(shndx_table + (ent - buf) / entsize));
+		{
+		  unsigned char *ndx_ptr
+		    = (unsigned char *) (shndx_table + (ent - buf) / entsize);
+		  st_shndx = type_functions->fetch_Elf_Word (ndx_ptr);
+		}
 
 	      if (st_shndx != SHN_COMMON
 		  && !(st_shndx != SHN_UNDEF
@@ -1442,19 +1486,26 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 	      unsigned char *st_info;
 	      unsigned char *st_other;
 	      int discard = 0;
+	      unsigned char *ndx_ptr = NULL;
 	      if (ei_class == ELFCLASS32)
 		{
-		  st_info = &((Elf32_External_Sym *)ent)->st_info;
-		  st_other = &((Elf32_External_Sym *)ent)->st_other;
+		  st_info = &((Elf32_External_Sym *) ent)->st_info;
+		  st_other = &((Elf32_External_Sym *) ent)->st_other;
 		}
 	      else
 		{
-		  st_info = &((Elf64_External_Sym *)ent)->st_info;
-		  st_other = &((Elf64_External_Sym *)ent)->st_other;
+		  st_info = &((Elf64_External_Sym *) ent)->st_info;
+		  st_other = &((Elf64_External_Sym *) ent)->st_other;
 		}
+	      if (shndx_table)
+		ndx_ptr
+		  = (unsigned char *) (shndx_table + (ent - buf) / entsize);
+
 	      if (st_shndx == SHN_XINDEX)
-		st_shndx = type_functions->fetch_Elf_Word
-		    ((unsigned char *)(shndx_table + (ent - buf) / entsize));
+		{
+		  st_shndx = type_functions->fetch_Elf_Word (ndx_ptr);
+		  type_functions->set_Elf_Word (ndx_ptr, SHN_UNDEF);
+		}
 	      /* Eliminate all COMMONs - this includes __gnu_lto_slim
 		 which otherwise cause endless LTO plugin invocation.
 		 FIXME: remove the condition once we remove emission
@@ -1488,9 +1539,14 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 			 defined in the first prevailing section.  */
 		      ELF_SET_FIELD (type_functions, ei_class, Sym,
 				     ent, st_name, Elf_Word, 0);
+		      st_shndx = sh_map[first_shndx];
+		      if (st_shndx >= SHN_LORESERVE)
+			{
+			  type_functions->set_Elf_Word (ndx_ptr, st_shndx);
+			  st_shndx = SHN_XINDEX;
+			}
 		      ELF_SET_FIELD (type_functions, ei_class, Sym,
-				     ent, st_shndx, Elf_Half,
-				     sh_map[first_shndx]);
+				     ent, st_shndx, Elf_Half, st_shndx);
 		    }
 		  else
 		    {
@@ -1514,11 +1570,24 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 		}
 	      else if (raw_st_shndx < SHN_LORESERVE
 		       || raw_st_shndx == SHN_XINDEX)
-		/* Remap the section reference.  */
-		ELF_SET_FIELD (type_functions, ei_class, Sym,
-			       ent, st_shndx, Elf_Half, sh_map[st_shndx]);
+		{
+		  /* Remap the section reference.  */
+		  st_shndx = sh_map[st_shndx];
+		  if (st_shndx >= SHN_LORESERVE)
+		    {
+		      type_functions->set_Elf_Word (ndx_ptr, st_shndx);
+		      st_shndx = SHN_XINDEX;
+		    }
+		  ELF_SET_FIELD (type_functions, ei_class, Sym,
+				 ent, st_shndx, Elf_Half, st_shndx);
+		}
 	    }
-	  XDELETEVEC (shndx_table);
+	  if (symtab_indices_shndx_buf)
+	    symtab_indices_shndx_buf[sh_map[symtab_indices_shndx[i - 1]]
+				     - first_symtab_indices_shndx]
+	      = (unsigned char *) shndx_table;
+	  else
+	    XDELETEVEC (shndx_table);
 	}
       else if (sh_type == SHT_GROUP)
 	{
@@ -1538,15 +1607,21 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 	  /* Adjust the length.  */
 	  length = dst - buf;
 	}
+      else if (sh_type == SHT_SYMTAB_SHNDX)
+	{
+	  XDELETEVEC (buf);
+	  buf = symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx];
+	  symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx] = NULL;
+	}
 
-      errmsg = simple_object_write_add_data (dobj, dest,
-					     buf, length, 1, err);
+      errmsg = simple_object_write_add_data (dobj, dest, buf, length, 1, err);
       XDELETEVEC (buf);
       if (errmsg)
 	{
 	  XDELETEVEC (names);
 	  XDELETEVEC (shdrs);
 	  XDELETEVEC (symtab_indices_shndx);
+	  XDELETEVEC (symtab_indices_shndx_buf);
 	  return errmsg;
 	}
 
@@ -1586,6 +1661,7 @@  simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
   XDELETEVEC (pfnname);
   XDELETEVEC (symtab_indices_shndx);
   XDELETEVEC (sh_map);
+  XDELETEVEC (symtab_indices_shndx_buf);
 
   return NULL;
 }
diff --git a/libiberty/testsuite/test-demangle.c b/libiberty/testsuite/test-demangle.c
index abe9015c316..f79cd89277a 100644
--- a/libiberty/testsuite/test-demangle.c
+++ b/libiberty/testsuite/test-demangle.c
@@ -49,8 +49,7 @@  static unsigned int lineno;
 #define LINELEN 80
 
 static void
-get_line(buf)
-     struct line *buf;
+get_line(struct line *buf)
 {
   char *data = buf->data;
   size_t alloc = buf->alloced;
@@ -134,12 +133,8 @@  protect_end (const char * s)
 }
 
 static void
-fail (lineno, opts, in, out, exp)
-     int lineno;
-     const char *opts;
-     const char *in;
-     const char *out;
-     const char *exp;
+fail (int lineno, const char *opts, const char *in,
+      const char *out, const char *exp)
 {
   printf ("\
 FAIL at line %d, options %s:\n\
@@ -170,9 +165,7 @@  exp: %s\n",
 */
 
 int
-main(argc, argv)
-     int argc;
-     char **argv;
+main(int argc, char **argv)
 {
   enum demangling_styles style = auto_demangling;
   int no_params;