This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR81968


This joint work rewrites LTO debug section copying to not leave
discarded sections around as SHT_NULL but to really discard them
and deal with the fallout (remapping all remaining section references).
This is to avoid diagnostics from the Solaris linker which doesn't
like those.

LTO bootstrapped on x86_64-unknown-linux-gnu, I also tested the
"incredibly large # of sections" testcase to verify SHN_XINDEX
handling.  A regular bootstrap & test run is currently in progress.

Rainer, can you check this patch on Solaris?  Maybe we can finally
close that PR ...

Ok for trunk?

Thanks,
Richard.

2017-01-10  Richard Biener  <rguenther@suse.de>
	Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR lto/81968
	libiberty/
	* simple-object-common.h (struct simple_object_functions):
	Change copy_lto_debug_sections callback signature.
	* simple-object-elf.c (SHN_HIRESERVE, SHT_SYMTAB_SHNDX,
	SHF_INFO_LINK): Add defines.
	(simple_object_elf_copy_lto_debug_sections): Instead of
	leaving not to be copied sections empty unnamed SHT_NULL
	remove them from the target section headers and adjust section
	reference everywhere.  Handle SHN_XINDEX in the symbol table
	processing properly.
	* simple-object.c (handle_lto_debug_sections): Change
	interface to return a modified string and handle renaming
	of relocation sections.

Index: libiberty/simple-object-common.h
===================================================================
--- libiberty/simple-object-common.h	(revision 256378)
+++ libiberty/simple-object-common.h	(working copy)
@@ -145,7 +145,7 @@ struct simple_object_functions
   /* Copy LTO debug sections.  */
   const char *(*copy_lto_debug_sections) (simple_object_read *sobj,
 					  simple_object_write *dobj,
-					  int (*pfn) (const char **),
+					  char *(*pfn) (const char *),
 					  int *err);
 };
 
Index: libiberty/simple-object-elf.c
===================================================================
--- libiberty/simple-object-elf.c	(revision 256378)
+++ libiberty/simple-object-elf.c	(working copy)
@@ -126,6 +126,7 @@ typedef struct {
 #define SHN_LORESERVE	0xFF00		/* Begin range of reserved indices */
 #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 */
 
 
 /* 32-bit ELF program header.  */
@@ -193,9 +194,11 @@ typedef struct {
 #define SHT_RELA	4		/* Relocation entries with addends */
 #define SHT_REL		9		/* Relocation entries, no addends */
 #define SHT_GROUP	17		/* Section contains a section group */
+#define SHT_SYMTAB_SHNDX 18		/* Extended section indeces */
 
 /* Values for sh_flags field.  */
 
+#define SHF_INFO_LINK	0x00000040	/* `sh_info' contains SHT index */
 #define SHF_EXECINSTR	0x00000004	/* Executable section.  */
 #define SHF_EXCLUDE	0x80000000	/* Link editor is to exclude this
 					   section from executable and
@@ -1070,7 +1073,7 @@ simple_object_elf_release_write (void *d
 static const char *
 simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
 					   simple_object_write *dobj,
-					   int (*pfn) (const char **),
+					   char *(*pfn) (const char *),
 					   int *err)
 {
   struct simple_object_elf_read *eor =
@@ -1091,7 +1094,10 @@ simple_object_elf_copy_lto_debug_section
   int changed;
   int *pfnret;
   const char **pfnname;
+  unsigned new_i;
+  unsigned *sh_map;
   unsigned first_shndx = 0;
+  unsigned int *symtab_indices_shndx;
 
   shdr_size = (ei_class == ELFCLASS32
 	       ? sizeof (Elf32_External_Shdr)
@@ -1130,18 +1136,20 @@ simple_object_elf_copy_lto_debug_section
       return errmsg;
     }
 
-  eow->shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1));
   pfnret = XNEWVEC (int, shnum);
   pfnname = XNEWVEC (const char *, shnum);
 
+  /* Map of symtab to index section.  */
+  symtab_indices_shndx = XCNEWVEC (unsigned int, shnum - 1);
+
   /* First perform the callbacks to know which sections to preserve and
      what name to use for those.  */
   for (i = 1; i < shnum; ++i)
     {
       unsigned char *shdr;
-      unsigned int sh_name;
+      unsigned int sh_name, sh_type;
       const char *name;
-      int ret;
+      char *ret;
 
       shdr = shdrs + (i - 1) * shdr_size;
       sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
@@ -1156,12 +1164,28 @@ simple_object_elf_copy_lto_debug_section
 
       name = (const char *) names + sh_name;
 
-      ret = (*pfn) (&name);
-      pfnret[i - 1] = ret == 1 ? 0 : -1;
-      pfnname[i - 1] = name;
+      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)
 	first_shndx = i;
+
+      /* Remember the indexes of existing SHT_SYMTAB_SHNDX sections.  */
+      sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+				 shdr, sh_type, Elf_Word);
+      if (sh_type == SHT_SYMTAB_SHNDX)
+	{
+	  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;
+	  /* 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.  */
+	  pfnret[i - 1] = -1;
+	}
     }
 
   /* Mark sections as preserved that are required by to be preserved
@@ -1244,7 +1268,26 @@ simple_object_elf_copy_lto_debug_section
     }
   while (changed);
 
+  /* Compute a mapping of old -> new section numbers.  */
+  sh_map = XNEWVEC (unsigned, shnum);
+  sh_map[0] = 0;
+  new_i = 1;
+  for (i = 1; i < shnum; ++i)
+    {
+      if (pfnret[i - 1] == -1)
+	sh_map[i] = 0;
+      else
+	sh_map[i] = new_i++;
+    }
+  if (new_i - 1 >= SHN_LORESERVE)
+    {
+      *err = ENOTSUP;
+      return "Too many copied sections";
+    }
+  eow->shdrs = XNEWVEC (unsigned char, shdr_size * (new_i - 1));
+
   /* Then perform the actual copying.  */
+  new_i = 0;
   for (i = 1; i < shnum; ++i)
     {
       unsigned char *shdr;
@@ -1252,11 +1295,14 @@ simple_object_elf_copy_lto_debug_section
       const char *name;
       off_t offset;
       off_t length;
-      int ret;
       simple_object_write_section *dest;
       off_t flags;
       unsigned char *buf;
 
+      if (pfnret[i - 1])
+	continue;
+
+      new_i++;
       shdr = shdrs + (i - 1) * shdr_size;
       sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 				 shdr, sh_name, Elf_Word);
@@ -1265,10 +1311,11 @@ simple_object_elf_copy_lto_debug_section
 	  *err = 0;
 	  XDELETEVEC (names);
 	  XDELETEVEC (shdrs);
+	  XDELETEVEC (symtab_indices_shndx);
 	  return "ELF section name out of range";
 	}
 
-      name = (const char *) names + sh_name;
+      name = pfnname[i - 1];
       offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 				shdr, sh_offset, Elf_Addr);
       length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
@@ -1276,178 +1323,216 @@ simple_object_elf_copy_lto_debug_section
       sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 				 shdr, sh_type, Elf_Word);
 
-      ret = pfnret[i - 1];
-      name = ret == 0 ? pfnname[i - 1] : "";
-
-      dest = simple_object_write_create_section (dobj, name, 0, &errmsg, err);
+      dest = simple_object_write_create_section (dobj, pfnname[i - 1],
+						 0, &errmsg, err);
       if (dest == NULL)
 	{
 	  XDELETEVEC (names);
 	  XDELETEVEC (shdrs);
+	  XDELETEVEC (symtab_indices_shndx);
 	  return errmsg;
 	}
 
       /* Record the SHDR of the source.  */
-      memcpy (eow->shdrs + (i - 1) * shdr_size, shdr, shdr_size);
-      shdr = eow->shdrs + (i - 1) * shdr_size;
+      memcpy (eow->shdrs + (new_i - 1) * shdr_size, shdr, shdr_size);
+      shdr = eow->shdrs + (new_i - 1) * shdr_size;
 
       /* Copy the data.
 	 ???  This is quite wasteful and ideally would be delayed until
 	 write_to_file ().  Thus it questions the interfacing
 	 which eventually should contain destination creation plus
 	 writing.  */
-      /* Keep empty sections for sections we should discard.  This avoids
-         the need to rewrite section indices in symtab and relocation
+      buf = XNEWVEC (unsigned char, length);
+      if (!simple_object_internal_read (sobj->descriptor,
+					sobj->offset + offset, buf,
+					(size_t) length, &errmsg, err))
+	{
+	  XDELETEVEC (buf);
+	  XDELETEVEC (names);
+	  XDELETEVEC (shdrs);
+	  XDELETEVEC (symtab_indices_shndx);
+	  return errmsg;
+	}
+
+      /* If we are processing .symtab purge __gnu_lto_v1 and
+	 __gnu_lto_slim symbols from it and any symbols in discarded
 	 sections.  */
-      if (ret == 0)
+      if (sh_type == SHT_SYMTAB)
 	{
-	  buf = XNEWVEC (unsigned char, length);
-	  if (!simple_object_internal_read (sobj->descriptor,
-					    sobj->offset + offset, buf,
-					    (size_t) length, &errmsg, err))
+	  unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+					      shdr, sh_entsize, Elf_Addr);
+	  unsigned strtab = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+					     shdr, sh_link, Elf_Word);
+	  unsigned char *strshdr = shdrs + (strtab - 1) * shdr_size;
+	  off_t stroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+					  strshdr, sh_offset, Elf_Addr);
+	  size_t strsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+					  strshdr, sh_size, Elf_Addr);
+	  char *strings = XNEWVEC (char, strsz);
+	  char *gnu_lto = strings;
+	  unsigned char *ent;
+	  unsigned *shndx_table = NULL;
+	  simple_object_internal_read (sobj->descriptor,
+				       sobj->offset + stroff,
+				       (unsigned char *)strings,
+				       strsz, &errmsg, err);
+	  /* Find gnu_lto_ in strings.  */
+	  while ((gnu_lto = (char *) memchr (gnu_lto, 'g',
+					     strings + strsz - gnu_lto)))
+	    if (strncmp (gnu_lto, "gnu_lto_v1",
+			 strings + strsz - gnu_lto) == 0)
+	      break;
+	    else
+	      gnu_lto++;
+	  /* Read the section index table if present.  */
+	  if (symtab_indices_shndx[i - 1] != 0)
 	    {
-	      XDELETEVEC (buf);
-	      XDELETEVEC (names);
-	      XDELETEVEC (shdrs);
-	      return errmsg;
+	      unsigned char *sidxhdr = shdrs + (strtab - 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,
+					       sidxhdr, sh_size, Elf_Addr);
+	      shndx_table = (unsigned *)XNEWVEC (char, sidxsz);
+	      simple_object_internal_read (sobj->descriptor,
+					   sobj->offset + sidxoff,
+					   (unsigned char *)shndx_table,
+					   sidxsz, &errmsg, err);
 	    }
-
-	  /* If we are processing .symtab purge __gnu_lto_v1 and
-	     __gnu_lto_slim symbols from it.  */
-	  if (sh_type == SHT_SYMTAB)
+	  for (ent = buf; ent < buf + length; ent += entsize)
 	    {
-	      unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
-						  shdr, sh_entsize, Elf_Addr);
-	      unsigned strtab = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
-						 shdr, sh_link, Elf_Word);
-	      unsigned char *strshdr = shdrs + (strtab - 1) * shdr_size;
-	      off_t stroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
-					      strshdr, sh_offset, Elf_Addr);
-	      size_t strsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
-					      strshdr, sh_size, Elf_Addr);
-	      char *strings = XNEWVEC (char, strsz);
-	      unsigned char *ent;
-	      simple_object_internal_read (sobj->descriptor,
-					   sobj->offset + stroff,
-					   (unsigned char *)strings,
-					   strsz, &errmsg, err);
-	      /* Find gnu_lto_ in strings.  */
-	      char *gnu_lto = strings;
-	      while ((gnu_lto = memchr (gnu_lto, 'g',
-					strings + strsz - gnu_lto)))
-		if (strncmp (gnu_lto, "gnu_lto_v1",
-			     strings + strsz - gnu_lto) == 0)
-		  break;
-		else
-		  gnu_lto++;
-	      for (ent = buf; ent < buf + length; ent += entsize)
+	      unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class,
+						   Sym, ent,
+						   st_shndx, Elf_Half);
+	      unsigned raw_st_shndx = st_shndx;
+	      unsigned char *st_info;
+	      unsigned char *st_other;
+	      int discard = 0;
+	      if (ei_class == ELFCLASS32)
 		{
-		  unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class,
-						       Sym, ent,
-						       st_shndx, Elf_Half);
-		  unsigned char *st_info;
-		  unsigned char *st_other;
-		  int discard = 0;
-		  if (ei_class == ELFCLASS32)
+		  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;
+		}
+	      if (st_shndx == SHN_XINDEX)
+		st_shndx = type_functions->fetch_Elf_Word
+		    ((unsigned char *)(shndx_table + (ent - buf) / entsize));
+	      /* Eliminate all COMMONs - this includes __gnu_lto_v1
+		 and __gnu_lto_slim which otherwise cause endless
+		 LTO plugin invocation.  */
+	      if (st_shndx == SHN_COMMON)
+		discard = 1;
+	      /* We also need to remove symbols refering to sections
+		 we'll eventually remove as with fat LTO objects
+		 we otherwise get duplicate symbols at final link
+		 (with GNU ld, gold is fine and ignores symbols in
+		 sections marked as EXCLUDE).  ld/20513  */
+	      else if (st_shndx != SHN_UNDEF
+		       && st_shndx < shnum
+		       && pfnret[st_shndx - 1] == -1)
+		discard = 1;
+
+	      if (discard)
+		{
+		  /* Make discarded symbols undefined and unnamed
+		     in case it is local.  */
+		  int bind = ELF_ST_BIND (*st_info);
+		  int other = STV_DEFAULT;
+		  if (bind == STB_LOCAL)
 		    {
-		      st_info = &((Elf32_External_Sym *)ent)->st_info;
-		      st_other = &((Elf32_External_Sym *)ent)->st_other;
+		      /* Make discarded local symbols unnamed and
+			 defined in the first prevailing section.  */
+		      ELF_SET_FIELD (type_functions, ei_class, Sym,
+				     ent, st_name, Elf_Word, 0);
+		      ELF_SET_FIELD (type_functions, ei_class, Sym,
+				     ent, st_shndx, Elf_Half,
+				     sh_map[first_shndx]);
 		    }
 		  else
 		    {
-		      st_info = &((Elf64_External_Sym *)ent)->st_info;
-		      st_other = &((Elf64_External_Sym *)ent)->st_other;
-		    }
-		  /* Eliminate all COMMONs - this includes __gnu_lto_v1
-		     and __gnu_lto_slim which otherwise cause endless
-		     LTO plugin invocation.  */
-		  if (st_shndx == SHN_COMMON)
-		    discard = 1;
-		  /* We also need to remove symbols refering to sections
-		     we'll eventually remove as with fat LTO objects
-		     we otherwise get duplicate symbols at final link
-		     (with GNU ld, gold is fine and ignores symbols in
-		     sections marked as EXCLUDE).  ld/20513  */
-		  else if (st_shndx != SHN_UNDEF
-			   && st_shndx < shnum
-			   && pfnret[st_shndx - 1] == -1)
-		    discard = 1;
-
-		  if (discard)
-		    {
-		      /* Make discarded symbols undefined and unnamed
-		         in case it is local.  */
-		      int bind = ELF_ST_BIND (*st_info);
-		      int other = STV_DEFAULT;
-		      if (bind == STB_LOCAL)
-			{
-			  /* Make discarded local symbols unnamed and
-			     defined in the first prevailing section.  */
-			  ELF_SET_FIELD (type_functions, ei_class, Sym,
-					 ent, st_name, Elf_Word, 0);
-			  ELF_SET_FIELD (type_functions, ei_class, Sym,
-					 ent, st_shndx, Elf_Half, first_shndx);
-			}
-		      else
-			{
-			  /* Make discarded global symbols hidden weak
-			     undefined and sharing the gnu_lto_ name.  */
-			  bind = STB_WEAK;
-			  other = STV_HIDDEN;
-			  if (gnu_lto)
-			    ELF_SET_FIELD (type_functions, ei_class, Sym,
-					   ent, st_name, Elf_Word,
-					   gnu_lto - strings);
-			  ELF_SET_FIELD (type_functions, ei_class, Sym,
-					 ent, st_shndx, Elf_Half, SHN_UNDEF);
-			}
-		      *st_other = other;
-		      *st_info = ELF_ST_INFO (bind, STT_NOTYPE);
-		      ELF_SET_FIELD (type_functions, ei_class, Sym,
-				     ent, st_value, Elf_Addr, 0);
+		      /* Make discarded global symbols hidden weak
+			 undefined and sharing the gnu_lto_ name.  */
+		      bind = STB_WEAK;
+		      other = STV_HIDDEN;
+		      if (gnu_lto)
+			ELF_SET_FIELD (type_functions, ei_class, Sym,
+				       ent, st_name, Elf_Word,
+				       gnu_lto - strings);
 		      ELF_SET_FIELD (type_functions, ei_class, Sym,
-				     ent, st_size, Elf_Word, 0);
+				     ent, st_shndx, Elf_Half, SHN_UNDEF);
 		    }
+		  *st_other = other;
+		  *st_info = ELF_ST_INFO (bind, STT_NOTYPE);
+		  ELF_SET_FIELD (type_functions, ei_class, Sym,
+				 ent, st_value, Elf_Addr, 0);
+		  ELF_SET_FIELD (type_functions, ei_class, Sym,
+				 ent, st_size, Elf_Word, 0);
 		}
-	      XDELETEVEC (strings);
+	      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]);
 	    }
-
-	  errmsg = simple_object_write_add_data (dobj, dest,
-						 buf, length, 1, err);
-	  XDELETEVEC (buf);
-	  if (errmsg)
+	  XDELETEVEC (strings);
+	  XDELETEVEC (shndx_table);
+	}
+      else if (sh_type == SHT_GROUP)
+	{
+	  /* Remap section indices in groups.  */
+	  unsigned char *ent;
+	  for (ent = buf + 4; ent < buf + length; ent += 4)
 	    {
-	      XDELETEVEC (names);
-	      XDELETEVEC (shdrs);
-	      return errmsg;
+	      unsigned shndx = type_functions->fetch_Elf_Word (ent);
+	      shndx = sh_map[shndx];
+	      type_functions->set_Elf_Word (ent, shndx);
 	    }
 	}
-      else
+
+      errmsg = simple_object_write_add_data (dobj, dest,
+					     buf, length, 1, err);
+      XDELETEVEC (buf);
+      if (errmsg)
 	{
-	  /* For deleted sections mark the section header table entry as
-	     unused.  That allows the link editor to remove it in a partial
-	     link.  */
-	  ELF_SET_FIELD (type_functions, ei_class, Shdr,
-			 shdr, sh_type, Elf_Word, SHT_NULL);
-	  ELF_SET_FIELD (type_functions, ei_class, Shdr,
-			 shdr, sh_info, Elf_Word, 0);
-	  ELF_SET_FIELD (type_functions, ei_class, Shdr,
-			 shdr, sh_link, Elf_Word, 0);
+	  XDELETEVEC (names);
+	  XDELETEVEC (shdrs);
+	  XDELETEVEC (symtab_indices_shndx);
+	  return errmsg;
 	}
 
       flags = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
 			       shdr, sh_flags, Elf_Addr);
-      if (ret == 0)
-	{
-	  /* The debugobj doesn't contain any code, thus no trampolines.
-	     Even when the original object needs trampolines, debugobj
-	     doesn't.  */
-	  if (strcmp (name, ".note.GNU-stack") == 0)
-	    flags &= ~SHF_EXECINSTR;
-	  flags &= ~SHF_EXCLUDE;
-	}
-      else if (ret == -1)
-	flags = SHF_EXCLUDE;
+      /* Remap the section references.  */
+      {
+	unsigned int sh_info, sh_link;
+	if (flags & SHF_INFO_LINK || sh_type == SHT_REL || sh_type == SHT_RELA)
+	  {
+	    sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+				       shdr, sh_info, Elf_Word);
+	    if (sh_info < SHN_LORESERVE
+		|| sh_info > SHN_HIRESERVE)
+	      sh_info = sh_map[sh_info];
+	    ELF_SET_FIELD (type_functions, ei_class, Shdr,
+			   shdr, sh_info, Elf_Word, sh_info);
+	  }
+	sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
+				   shdr, sh_link, Elf_Word);
+	if (sh_link < SHN_LORESERVE
+	    || sh_link > SHN_HIRESERVE)
+	  sh_link = sh_map[sh_link];
+	ELF_SET_FIELD (type_functions, ei_class, Shdr,
+		       shdr, sh_link, Elf_Word, sh_link);
+      }
+      /* The debugobj doesn't contain any code, thus no trampolines.
+	 Even when the original object needs trampolines, debugobj
+	 doesn't.  */
+      if (strcmp (name, ".note.GNU-stack") == 0)
+	flags &= ~SHF_EXECINSTR;
+      /* Clear SHF_EXCLUDE on to be preserved sections.  */
+      flags &= ~SHF_EXCLUDE;
       ELF_SET_FIELD (type_functions, ei_class, Shdr,
 		     shdr, sh_flags, Elf_Addr, flags);
     }
@@ -1456,6 +1541,8 @@ simple_object_elf_copy_lto_debug_section
   XDELETEVEC (shdrs);
   XDELETEVEC (pfnret);
   XDELETEVEC (pfnname);
+  XDELETEVEC (symtab_indices_shndx);
+  XDELETEVEC (sh_map);
 
   return NULL;
 }
Index: libiberty/simple-object.c
===================================================================
--- libiberty/simple-object.c	(revision 256378)
+++ libiberty/simple-object.c	(working copy)
@@ -253,30 +253,38 @@ simple_object_find_section (simple_objec
 /* Callback to identify and rename LTO debug sections by name.
    Returns 1 if NAME is a LTO debug section, 0 if not.  */
 
-static int
-handle_lto_debug_sections (const char **name)
+static char *
+handle_lto_debug_sections (const char *name)
 {
+  char *newname = XCNEWVEC (char, strlen (name) + 1);
+
   /* ???  So we can't use .gnu.lto_ prefixed sections as the assembler
      complains about bogus section flags.  Which means we need to arrange
      for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make
      fat lto object tooling work for the fat part).  */
-  /* ???  For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed
-     sections.  */
-  /* Copy LTO debug sections and rename them to their non-LTO name.  */
-  if (strncmp (*name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0)
+  /* Also include corresponding reloc sections.  */
+  if (strncmp (name, ".rela", sizeof (".rela") - 1) == 0)
     {
-      *name = *name + sizeof (".gnu.debuglto_") - 1;
-      return 1;
+      strncpy (newname, name, sizeof (".rela") - 1);
+      name += sizeof (".rela") - 1;
     }
-  else if (strncmp (*name, ".gnu.lto_.debug_", sizeof (".gnu.lto_.debug_") -1) == 0)
+  else if (strncmp (name, ".rel", sizeof (".rel") - 1) == 0)
     {
-      *name = *name + sizeof (".gnu.lto_") - 1;
-      return 1;
+      strncpy (newname, name, sizeof (".rel") - 1);
+      name += sizeof (".rel") - 1;
     }
+  /* ???  For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed
+     sections.  */
+  /* Copy LTO debug sections and rename them to their non-LTO name.  */
+  if (strncmp (name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0)
+    return strcat (newname, name + sizeof (".gnu.debuglto_") - 1);
+  else if (strncmp (name, ".gnu.lto_.debug_",
+		    sizeof (".gnu.lto_.debug_") -1) == 0)
+    return strcat (newname, name + sizeof (".gnu.lto_") - 1);
   /* Copy over .note.GNU-stack section under the same name if present.  */
-  else if (strcmp (*name, ".note.GNU-stack") == 0)
-    return 1;
-  return 0;
+  else if (strcmp (name, ".note.GNU-stack") == 0)
+    return strcpy (newname, name);
+  return NULL;
 }
 
 /* Copy LTO debug sections.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]