SOURCES: elfutils-strip-copy-symtab.patch (NEW) - from FC, with te...

qboosh qboosh at pld-linux.org
Fri Nov 17 17:45:22 CET 2006


Author: qboosh                       Date: Fri Nov 17 16:45:22 2006 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- from FC, with tests part omitted

---- Files affected:
SOURCES:
   elfutils-strip-copy-symtab.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/elfutils-strip-copy-symtab.patch
diff -u /dev/null SOURCES/elfutils-strip-copy-symtab.patch:1.1
--- /dev/null	Fri Nov 17 17:45:22 2006
+++ SOURCES/elfutils-strip-copy-symtab.patch	Fri Nov 17 17:45:17 2006
@@ -0,0 +1,193 @@
+2006-09-19  Jakub Jelinek  <jakub at redhat.com>
+
+	* strip.c (handle_elf): Formatting.  If any relocation sections
+	stripped into separate debug info reference symtab that is kept,
+	emit symtab/strtab also into the separate debug info file.
+
+--- elfutils/src/strip.c
++++ elfutils/src/strip.c
+@@ -399,6 +399,7 @@ handle_elf (int fd, Elf *elf, const char
+     Elf_Scn *newscn;
+     struct Ebl_Strent *se;
+     Elf32_Word *newsymidx;
++    void *debug_data;
+   } *shdr_info = NULL;
+   Elf_Scn *scn;
+   size_t cnt;
+@@ -826,8 +827,39 @@ handle_elf (int fd, Elf *elf, const char
+      The ones that are not removed in the stripped file are SHT_NOBITS.  */
+   if (debug_fname != NULL)
+     {
++      /* libbfd and apps using it don't cope with separate debuginfo objects
++	 with relocation sections against SHT_NOBITS .symtab/.strtab
++	 - libbfd isn't able to look up the .symtab/.strtab in the stripped
++	 object instead.  As a workaround, emit .symtab/.strtab in both
++	 places.  */
+       for (cnt = 1; cnt < shnum; ++cnt)
+ 	{
++	  if (shdr_info[cnt].idx == 0
++	      && (shdr_info[cnt].shdr.sh_type == SHT_REL
++		  || shdr_info[cnt].shdr.sh_type == SHT_RELA)
++	      && (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
++	    {
++	      Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
++	      struct shdr_info *si = &shdr_info[symtabidx];
++	      si->debug_data = "";
++	      shdr_info[si->old_sh_link].debug_data = "";
++	      if (si->symtab_idx)
++		shdr_info[si->symtab_idx].debug_data = "";
++
++	      if (si->shdr.sh_type != SHT_SYMTAB
++		  || (si->shdr.sh_flags & SHF_ALLOC)
++		  || shdr_info[si->old_sh_link].shdr.sh_type != SHT_STRTAB
++		  || (shdr_info[si->old_sh_link].shdr.sh_flags & SHF_ALLOC)
++		  || (si->symtab_idx
++		      && (shdr_info[si->symtab_idx].shdr.sh_flags
++			  & SHF_ALLOC)))
++		error (EXIT_FAILURE, 0,
++		       gettext ("invalid symtab/strtab referenced by nonallocated section"));
++	    }
++	}
++
++      for (cnt = 1; cnt < shnum; ++cnt)
++	{
+ 	  scn = elf_newscn (debugelf);
+ 	  if (scn == NULL)
+ 	    error (EXIT_FAILURE, 0,
+@@ -835,7 +867,8 @@ handle_elf (int fd, Elf *elf, const char
+ 		   elf_errmsg (-1));
+ 
+ 	  bool discard_section = (shdr_info[cnt].idx > 0
+-				  && cnt != ehdr->e_shstrndx);
++				  && cnt != ehdr->e_shstrndx
++				  && shdr_info[cnt].debug_data == NULL);
+ 
+ 	  /* Set the section header in the new file.  */
+ 	  GElf_Shdr debugshdr = shdr_info[cnt].shdr;
+@@ -864,6 +897,13 @@ handle_elf (int fd, Elf *elf, const char
+ 	  *debugdata = *shdr_info[cnt].data;
+ 	  if (discard_section)
+ 	    debugdata->d_buf = NULL;
++	  else if (shdr_info[cnt].debug_data != NULL)
++	    {
++	      shdr_info[cnt].debug_data = xmalloc (debugdata->d_size);
++	      memcpy (shdr_info[cnt].debug_data, debugdata->d_buf,
++		      debugdata->d_size);
++	      debugdata->d_buf = shdr_info[cnt].debug_data;
++	    }
+ 	}
+ 
+       /* Finish the ELF header.  Fill in the fields not handled by
+@@ -1055,7 +1095,7 @@ handle_elf (int fd, Elf *elf, const char
+ 	    shdr_info[shdr_info[cnt].shdr.sh_info].idx;
+ 
+ 	/* Get the data from the old file if necessary.  We already
+-           created the data for the section header string table.  */
++	   created the data for the section header string table.  */
+ 	if (cnt < shnum)
+ 	  {
+ 	    if (shdr_info[cnt].data == NULL)
+@@ -1264,6 +1304,13 @@ handle_elf (int fd, Elf *elf, const char
+ 	      if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
+ 		continue;
+ 
++	      /* If the symbol table is not discarded, but additionally
++		 duplicated in separate debug file and this section
++		 is discarded, don't adjust anything.  */
++	      if (shdr_info[cnt].idx == 0
++		  && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
++		continue;
++
+ 	      Elf32_Word *newsymidx
+ 		= shdr_info[shdr_info[cnt].old_sh_link].newsymidx;
+ 	      Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
+@@ -1322,6 +1369,13 @@ handle_elf (int fd, Elf *elf, const char
+ 	      if (shdr_info[symtabidx].newsymidx == NULL)
+ 		continue;
+ 
++	      /* If the symbol table is not discarded, but additionally
++		 duplicated in separate debug file and this section
++		 is discarded, don't adjust anything.  */
++	      if (shdr_info[cnt].idx == 0
++		  && shdr_info[symtabidx].debug_data != NULL)
++		continue;
++
+ 	      assert (shdr_info[cnt].idx > 0);
+ 
+ 	      /* The hash section in the new file.  */
+@@ -1447,7 +1501,7 @@ handle_elf (int fd, Elf *elf, const char
+ 			  chain[hidx] = inner;
+ 			}
+ 		    }
+-	        }
++		}
+ 	    }
+ 	  else if (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym)
+ 	    {
+@@ -1460,6 +1514,13 @@ handle_elf (int fd, Elf *elf, const char
+ 	      if (shdr_info[symtabidx].newsymidx == NULL)
+ 		continue;
+ 
++	      /* If the symbol table is not discarded, but additionally
++		 duplicated in separate debug file and this section
++		 is discarded, don't adjust anything.  */
++	      if (shdr_info[cnt].idx == 0
++		  && shdr_info[symtabidx].debug_data != NULL)
++		continue;
++
+ 	      assert (shdr_info[cnt].idx > 0);
+ 
+ 	      /* The symbol version section in the new file.  */
+@@ -1504,20 +1565,27 @@ handle_elf (int fd, Elf *elf, const char
+ 	  else if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
+ 	    {
+ 	      /* Check whether the associated symbol table changed.  */
+-	      if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx != NULL)
+-		{
+-		  /* Yes the symbol table changed.  Update the section
+-		     header of the section group.  */
+-		  scn = elf_getscn (newelf, shdr_info[cnt].idx);
+-		  GElf_Shdr shdr_mem;
+-		  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+-		  assert (shdr != NULL);
++	      if (shdr_info[shdr_info[cnt].old_sh_link].newsymidx == NULL)
++		continue;
+ 
+-		  size_t stabidx = shdr_info[cnt].old_sh_link;
+-		  shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
++	      /* If the symbol table is not discarded, but additionally
++		 duplicated in separate debug file and this section
++		 is discarded, don't adjust anything.  */
++	      if (shdr_info[cnt].idx == 0
++		  && shdr_info[shdr_info[cnt].old_sh_link].debug_data != NULL)
++		continue;
+ 
+-		  (void) gelf_update_shdr (scn, shdr);
+-		}
++	      /* Yes the symbol table changed.  Update the section
++		 header of the section group.  */
++	      scn = elf_getscn (newelf, shdr_info[cnt].idx);
++	      GElf_Shdr shdr_mem;
++	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
++	      assert (shdr != NULL);
++
++	      size_t stabidx = shdr_info[cnt].old_sh_link;
++	      shdr->sh_info = shdr_info[stabidx].newsymidx[shdr->sh_info];
++
++	      (void) gelf_update_shdr (scn, shdr);
+ 	    }
+ 	}
+     }
+@@ -1647,7 +1715,10 @@ handle_elf (int fd, Elf *elf, const char
+ 	 table indices.  */
+       if (any_symtab_changes)
+ 	for (cnt = 1; cnt <= shdridx; ++cnt)
+-	  free (shdr_info[cnt].newsymidx);
++	  {
++	    free (shdr_info[cnt].newsymidx);
++	    free (shdr_info[cnt].debug_data);
++	  }
+ 
+       /* Free the memory.  */
+       if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
+
================================================================


More information about the pld-cvs-commit mailing list