public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/4] strip: Split out debug section relocation into separate helper functions.
  2018-10-26 21:51 Add eu-strip --reloc-debug-sections-only option Mark Wielaard
  2018-10-26 21:51 ` [PATCH 1/4] strip: Always copy over any phdrs if there are any Mark Wielaard
  2018-10-26 21:51 ` [PATCH 3/4] strip: Extract code to update shdrstrndx into new common function Mark Wielaard
@ 2018-10-26 21:51 ` Mark Wielaard
  2018-10-26 21:59 ` [PATCH 4/4] strip: Add --reloc-debug-sections-only option Mark Wielaard
  2018-11-06 11:11 ` Add eu-strip " Mark Wielaard
  4 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2018-10-26 21:51 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

Extract a couple of helper functions out of handle_elf (secndx_name,
get_xndxdata and remove_debug_relocations) so they can be reused more
easily in the future.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 src/ChangeLog |   7 +
 src/strip.c   | 541 +++++++++++++++++++++++++++++++---------------------------
 2 files changed, 299 insertions(+), 249 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 5a57e8f..f55ff6c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,12 @@
 2018-10-24  Mark Wielaard  <mark@klomp.org>
 
+	* strip.c (handle_elf): Extract code into separate functions...
+	(secndx_name): ... new function.
+	(get_xndxdata): Likewise.
+	(remove_debug_relocations): Likewise.
+
+2018-10-24  Mark Wielaard  <mark@klomp.org>
+
 	* strip.c (handle_elf): Always copy over phdrs if there are any
 	and check phnum instead of e_type to determine whether to move
 	allocated sections.
diff --git a/src/strip.c b/src/strip.c
index cb479de..a7b69a6 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -354,6 +354,297 @@ parse_opt (int key, char *arg, struct argp_state *state)
   return 0;
 }
 
+static const char *
+secndx_name (Elf *elf, size_t ndx)
+{
+  size_t shstrndx;
+  GElf_Shdr mem;
+  Elf_Scn *sec = elf_getscn (elf, ndx);
+  GElf_Shdr *shdr = gelf_getshdr (sec, &mem);
+  if (shdr == NULL || elf_getshdrstrndx (elf, &shstrndx) < 0)
+    return "???";
+  return elf_strptr (elf, shstrndx, shdr->sh_name) ?: "???";
+}
+
+/* Get the extended section index table data for a symbol table section.  */
+static Elf_Data *
+get_xndxdata (Elf *elf, Elf_Scn *symscn)
+{
+  Elf_Data *xndxdata = NULL;
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
+  if (shdr != NULL && shdr->sh_type == SHT_SYMTAB)
+    {
+      size_t scnndx = elf_ndxscn (symscn);
+      Elf_Scn *xndxscn = NULL;
+      while ((xndxscn = elf_nextscn (elf, xndxscn)) != NULL)
+	{
+	  GElf_Shdr xndxshdr_mem;
+	  GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
+
+	  if (xndxshdr != NULL
+	      && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
+	      && xndxshdr->sh_link == scnndx)
+	    {
+	      xndxdata = elf_getdata (xndxscn, NULL);
+	      break;
+	    }
+	}
+    }
+
+  return xndxdata;
+}
+
+/* Remove any relocations between debug sections in ET_REL
+   for the debug file when requested.  These relocations are always
+   zero based between the unallocated sections.  */
+static void
+remove_debug_relocations (Ebl *ebl, Elf *elf, GElf_Ehdr *ehdr,
+			  const char *fname, size_t shstrndx)
+{
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      /* We need the actual section and header from the elf
+	 not just the cached original in shdr_info because we
+	 might want to change the size.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+	{
+	  /* Make sure that this relocation section points to a
+	     section to relocate with contents, that isn't
+	     allocated and that is a debug section.  */
+	  Elf_Scn *tscn = elf_getscn (elf, shdr->sh_info);
+	  GElf_Shdr tshdr_mem;
+	  GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
+	  if (tshdr->sh_type == SHT_NOBITS
+	      || tshdr->sh_size == 0
+	      || (tshdr->sh_flags & SHF_ALLOC) != 0)
+	    continue;
+
+	  const char *tname =  elf_strptr (elf, shstrndx,
+					   tshdr->sh_name);
+	  if (! tname || ! ebl_debugscn_p (ebl, tname))
+	    continue;
+
+	  /* OK, lets relocate all trivial cross debug section
+	     relocations. */
+	  Elf_Data *reldata = elf_getdata (scn, NULL);
+	  if (reldata == NULL || reldata->d_buf == NULL)
+	    INTERNAL_ERROR (fname);
+
+	  /* Make sure we adjust the uncompressed debug data
+	     (and recompress if necessary at the end).  */
+	  GElf_Chdr tchdr;
+	  int tcompress_type = 0;
+	  if (gelf_getchdr (tscn, &tchdr) != NULL)
+	    {
+	      tcompress_type = tchdr.ch_type;
+	      if (elf_compress (tscn, 0, 0) != 1)
+		INTERNAL_ERROR (fname);
+	    }
+
+	  Elf_Data *tdata = elf_getdata (tscn, NULL);
+	  if (tdata == NULL || tdata->d_buf == NULL
+	      || tdata->d_type != ELF_T_BYTE)
+	    INTERNAL_ERROR (fname);
+
+	  /* Pick up the symbol table and shndx table to
+	     resolve relocation symbol indexes.  */
+	  Elf64_Word symt = shdr->sh_link;
+	  Elf_Data *symdata, *xndxdata;
+	  Elf_Scn * symscn = elf_getscn (elf, symt);
+	  symdata = elf_getdata (symscn, NULL);
+	  xndxdata = get_xndxdata (elf, symscn);
+	  if (symdata == NULL)
+	    INTERNAL_ERROR (fname);
+
+	  /* Apply one relocation.  Returns true when trivial
+	     relocation actually done.  */
+	  bool relocate (GElf_Addr offset, const GElf_Sxword addend,
+			 bool is_rela, int rtype, int symndx)
+	  {
+	    /* R_*_NONE relocs can always just be removed.  */
+	    if (rtype == 0)
+	      return true;
+
+	    /* We only do simple absolute relocations.  */
+	    int addsub = 0;
+	    Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub);
+	    if (type == ELF_T_NUM)
+	      return false;
+
+	    /* These are the types we can relocate.  */
+#define TYPES   DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half);		\
+		DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword);		\
+		DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
+
+	    /* And only for relocations against other debug sections.  */
+	    GElf_Sym sym_mem;
+	    Elf32_Word xndx;
+	    GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
+					      symndx, &sym_mem,
+					      &xndx);
+	    Elf32_Word sec = (sym->st_shndx == SHN_XINDEX
+			      ? xndx : sym->st_shndx);
+
+	    if (ebl_debugscn_p (ebl, secndx_name (elf, sec)))
+	      {
+		size_t size;
+
+#define DO_TYPE(NAME, Name) GElf_##Name Name;
+		union { TYPES; } tmpbuf;
+#undef DO_TYPE
+
+		switch (type)
+		  {
+#define DO_TYPE(NAME, Name)				\
+		    case ELF_T_##NAME:			\
+		      size = sizeof (GElf_##Name);	\
+		      tmpbuf.Name = 0;			\
+		      break;
+		    TYPES;
+#undef DO_TYPE
+		  default:
+		    return false;
+		  }
+
+		if (offset > tdata->d_size
+		    || tdata->d_size - offset < size)
+		  {
+		    cleanup_debug ();
+		    error (EXIT_FAILURE, 0, gettext ("bad relocation"));
+		  }
+
+		/* When the symbol value is zero then for SHT_REL
+		   sections this is all that needs to be checked.
+		   The addend is contained in the original data at
+		   the offset already.  So if the (section) symbol
+		   address is zero and the given addend is zero
+		   just remove the relocation, it isn't needed
+		   anymore.  */
+		if (addend == 0 && sym->st_value == 0)
+		  return true;
+
+		Elf_Data tmpdata =
+		  {
+		    .d_type = type,
+		    .d_buf = &tmpbuf,
+		    .d_size = size,
+		    .d_version = EV_CURRENT,
+		  };
+		Elf_Data rdata =
+		  {
+		    .d_type = type,
+		    .d_buf = tdata->d_buf + offset,
+		    .d_size = size,
+		    .d_version = EV_CURRENT,
+		  };
+
+		GElf_Addr value = sym->st_value;
+		if (is_rela)
+		  {
+		    /* For SHT_RELA sections we just take the
+		       given addend and add it to the value.  */
+		    value += addend;
+		    /* For ADD/SUB relocations we need to fetch the
+		       current section contents.  */
+		    if (addsub != 0)
+		      {
+			Elf_Data *d = gelf_xlatetom (elf, &tmpdata,
+						     &rdata,
+						     ehdr->e_ident[EI_DATA]);
+			if (d == NULL)
+			  INTERNAL_ERROR (fname);
+			assert (d == &tmpdata);
+		      }
+		  }
+		else
+		  {
+		    /* For SHT_REL sections we have to peek at
+		       what is already in the section at the given
+		       offset to get the addend.  */
+		    Elf_Data *d = gelf_xlatetom (elf, &tmpdata,
+						 &rdata,
+						 ehdr->e_ident[EI_DATA]);
+		    if (d == NULL)
+		      INTERNAL_ERROR (fname);
+		    assert (d == &tmpdata);
+		  }
+
+		switch (type)
+		  {
+#define DO_TYPE(NAME, Name)					 \
+		    case ELF_T_##NAME:				 \
+		      if (addsub < 0)				 \
+			tmpbuf.Name -= (GElf_##Name) value;	 \
+		      else					 \
+			tmpbuf.Name += (GElf_##Name) value;	 \
+		      break;
+		    TYPES;
+#undef DO_TYPE
+		  default:
+		    abort ();
+		  }
+
+		/* Now finally put in the new value.  */
+		Elf_Data *s = gelf_xlatetof (elf, &rdata,
+					     &tmpdata,
+					     ehdr->e_ident[EI_DATA]);
+		if (s == NULL)
+		  INTERNAL_ERROR (fname);
+		assert (s == &rdata);
+
+		return true;
+	      }
+	    return false;
+	  }
+
+	  if (shdr->sh_entsize == 0)
+	    INTERNAL_ERROR (fname);
+
+	  size_t nrels = shdr->sh_size / shdr->sh_entsize;
+	  size_t next = 0;
+	  if (shdr->sh_type == SHT_REL)
+	    for (size_t relidx = 0; relidx < nrels; ++relidx)
+	      {
+		GElf_Rel rel_mem;
+		GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
+		if (! relocate (r->r_offset, 0, false,
+				GELF_R_TYPE (r->r_info),
+				GELF_R_SYM (r->r_info)))
+		  {
+		    if (relidx != next)
+		      gelf_update_rel (reldata, next, r);
+		    ++next;
+		  }
+	      }
+	  else
+	    for (size_t relidx = 0; relidx < nrels; ++relidx)
+	      {
+		GElf_Rela rela_mem;
+		GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
+		if (! relocate (r->r_offset, r->r_addend, true,
+				GELF_R_TYPE (r->r_info),
+				GELF_R_SYM (r->r_info)))
+		  {
+		    if (relidx != next)
+		      gelf_update_rela (reldata, next, r);
+		    ++next;
+		  }
+	      }
+
+	  nrels = next;
+	  shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize;
+	  gelf_update_shdr (scn, shdr);
+
+	  if (tcompress_type != 0)
+	    if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1)
+	      INTERNAL_ERROR (fname);
+	}
+    }
+}
 
 static int
 process_file (const char *fname)
@@ -1978,255 +2269,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
      zero based between the unallocated sections.  */
   if (debug_fname != NULL && removing_sections
       && reloc_debug && ehdr->e_type == ET_REL)
-    {
-      scn = NULL;
-      cnt = 0;
-      while ((scn = elf_nextscn (debugelf, scn)) != NULL)
-	{
-	  cnt++;
-	  /* We need the actual section and header from the debugelf
-	     not just the cached original in shdr_info because we
-	     might want to change the size.  */
-	  GElf_Shdr shdr_mem;
-	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
-	  if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
-	    {
-	      /* Make sure that this relocation section points to a
-		 section to relocate with contents, that isn't
-		 allocated and that is a debug section.  */
-	      Elf_Scn *tscn = elf_getscn (debugelf, shdr->sh_info);
-	      GElf_Shdr tshdr_mem;
-	      GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
-	      if (tshdr->sh_type == SHT_NOBITS
-		  || tshdr->sh_size == 0
-		  || (tshdr->sh_flags & SHF_ALLOC) != 0)
-		continue;
-
-	      const char *tname =  elf_strptr (debugelf, shstrndx,
-					       tshdr->sh_name);
-	      if (! tname || ! ebl_debugscn_p (ebl, tname))
-		continue;
-
-	      /* OK, lets relocate all trivial cross debug section
-		 relocations. */
-	      Elf_Data *reldata = elf_getdata (scn, NULL);
-	      if (reldata == NULL || reldata->d_buf == NULL)
-		INTERNAL_ERROR (fname);
-
-	      /* Make sure we adjust the uncompressed debug data
-		 (and recompress if necessary at the end).  */
-	      GElf_Chdr tchdr;
-	      int tcompress_type = 0;
-	      if (gelf_getchdr (tscn, &tchdr) != NULL)
-		{
-		  tcompress_type = tchdr.ch_type;
-		  if (elf_compress (tscn, 0, 0) != 1)
-		    INTERNAL_ERROR (fname);
-		}
-
-	      Elf_Data *tdata = elf_getdata (tscn, NULL);
-	      if (tdata == NULL || tdata->d_buf == NULL
-		  || tdata->d_type != ELF_T_BYTE)
-		INTERNAL_ERROR (fname);
-
-	      /* Pick up the symbol table and shndx table to
-		 resolve relocation symbol indexes.  */
-	      Elf64_Word symt = shdr->sh_link;
-	      Elf_Data *symdata, *xndxdata;
-	      elf_assert (symt < shnum + 2);
-	      elf_assert (shdr_info[symt].symtab_idx < shnum + 2);
-	      symdata = (shdr_info[symt].debug_data
-			 ?: shdr_info[symt].data);
-	      xndxdata = (shdr_info[shdr_info[symt].symtab_idx].debug_data
-			  ?: shdr_info[shdr_info[symt].symtab_idx].data);
-
-	      /* Apply one relocation.  Returns true when trivial
-		 relocation actually done.  */
-	      bool relocate (GElf_Addr offset, const GElf_Sxword addend,
-			     bool is_rela, int rtype, int symndx)
-	      {
-		/* R_*_NONE relocs can always just be removed.  */
-		if (rtype == 0)
-		  return true;
-
-		/* We only do simple absolute relocations.  */
-		int addsub = 0;
-		Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub);
-		if (type == ELF_T_NUM)
-		  return false;
-
-		/* These are the types we can relocate.  */
-#define TYPES   DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half);		\
-		DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword);		\
-		DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
-
-		/* And only for relocations against other debug sections.  */
-		GElf_Sym sym_mem;
-		Elf32_Word xndx;
-		GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
-						  symndx, &sym_mem,
-						  &xndx);
-		Elf32_Word sec = (sym->st_shndx == SHN_XINDEX
-				  ? xndx : sym->st_shndx);
-		if (sec >= shnum + 2)
-		  INTERNAL_ERROR (fname);
-
-		if (ebl_debugscn_p (ebl, shdr_info[sec].name))
-		  {
-		    size_t size;
-
-#define DO_TYPE(NAME, Name) GElf_##Name Name;
-		    union { TYPES; } tmpbuf;
-#undef DO_TYPE
-
-		    switch (type)
-		      {
-#define DO_TYPE(NAME, Name)				\
-			case ELF_T_##NAME:		\
-			  size = sizeof (GElf_##Name);	\
-			  tmpbuf.Name = 0;		\
-			  break;
-			TYPES;
-#undef DO_TYPE
-		      default:
-			return false;
-		      }
-
-		    if (offset > tdata->d_size
-			|| tdata->d_size - offset < size)
-		      {
-			cleanup_debug ();
-			error (EXIT_FAILURE, 0, gettext ("bad relocation"));
-		      }
-
-		    /* When the symbol value is zero then for SHT_REL
-		       sections this is all that needs to be checked.
-		       The addend is contained in the original data at
-		       the offset already.  So if the (section) symbol
-		       address is zero and the given addend is zero
-		       just remove the relocation, it isn't needed
-		       anymore.  */
-		    if (addend == 0 && sym->st_value == 0)
-		      return true;
-
-		    Elf_Data tmpdata =
-		      {
-			.d_type = type,
-			.d_buf = &tmpbuf,
-			.d_size = size,
-			.d_version = EV_CURRENT,
-		      };
-		    Elf_Data rdata =
-		      {
-			.d_type = type,
-			.d_buf = tdata->d_buf + offset,
-			.d_size = size,
-			.d_version = EV_CURRENT,
-		      };
-
-		    GElf_Addr value = sym->st_value;
-		    if (is_rela)
-		      {
-			/* For SHT_RELA sections we just take the
-			   given addend and add it to the value.  */
-			value += addend;
-			/* For ADD/SUB relocations we need to fetch the
-			   current section contents.  */
-			if (addsub != 0)
-			  {
-			    Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata,
-							 &rdata,
-							 ehdr->e_ident[EI_DATA]);
-			    if (d == NULL)
-			      INTERNAL_ERROR (fname);
-			    assert (d == &tmpdata);
-			  }
-		      }
-		    else
-		      {
-			/* For SHT_REL sections we have to peek at
-			   what is already in the section at the given
-			   offset to get the addend.  */
-			Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata,
-						     &rdata,
-						     ehdr->e_ident[EI_DATA]);
-			if (d == NULL)
-			  INTERNAL_ERROR (fname);
-			assert (d == &tmpdata);
-		      }
-
-		    switch (type)
-		      {
-#define DO_TYPE(NAME, Name)					 \
-			case ELF_T_##NAME:			 \
-			  if (addsub < 0)			 \
-			    tmpbuf.Name -= (GElf_##Name) value; \
-			  else					 \
-			    tmpbuf.Name += (GElf_##Name) value; \
-			  break;
-			TYPES;
-#undef DO_TYPE
-		      default:
-			abort ();
-		      }
-
-		    /* Now finally put in the new value.  */
-		    Elf_Data *s = gelf_xlatetof (debugelf, &rdata,
-						 &tmpdata,
-						 ehdr->e_ident[EI_DATA]);
-		    if (s == NULL)
-		      INTERNAL_ERROR (fname);
-		    assert (s == &rdata);
-
-		    return true;
-		  }
-		return false;
-	      }
-
-	      if (shdr->sh_entsize == 0)
-		INTERNAL_ERROR (fname);
-
-	      size_t nrels = shdr->sh_size / shdr->sh_entsize;
-	      size_t next = 0;
-	      if (shdr->sh_type == SHT_REL)
-		for (size_t relidx = 0; relidx < nrels; ++relidx)
-		  {
-		    GElf_Rel rel_mem;
-		    GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
-		    if (! relocate (r->r_offset, 0, false,
-				    GELF_R_TYPE (r->r_info),
-				    GELF_R_SYM (r->r_info)))
-		      {
-			if (relidx != next)
-			  gelf_update_rel (reldata, next, r);
-			++next;
-		      }
-		  }
-	      else
-		for (size_t relidx = 0; relidx < nrels; ++relidx)
-		  {
-		    GElf_Rela rela_mem;
-		    GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
-		    if (! relocate (r->r_offset, r->r_addend, true,
-				    GELF_R_TYPE (r->r_info),
-				    GELF_R_SYM (r->r_info)))
-		      {
-			if (relidx != next)
-			  gelf_update_rela (reldata, next, r);
-			++next;
-		      }
-		  }
-
-	      nrels = next;
-	      shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize;
-	      gelf_update_shdr (scn, shdr);
-
-	      if (tcompress_type != 0)
-		if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1)
-		  INTERNAL_ERROR (fname);
-	    }
-	}
-    }
+    remove_debug_relocations (ebl, debugelf, ehdr, fname, shstrndx);
 
   /* Now that we have done all adjustments to the data,
      we can actually write out the debug file.  */
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] strip: Always copy over any phdrs if there are any.
  2018-10-26 21:51 Add eu-strip --reloc-debug-sections-only option Mark Wielaard
@ 2018-10-26 21:51 ` Mark Wielaard
  2018-10-26 21:51 ` [PATCH 3/4] strip: Extract code to update shdrstrndx into new common function Mark Wielaard
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2018-10-26 21:51 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

Ignore the type of ELF file, just copy over any phdrs if the original
file contained any. Also refuse to move around any allocated sections
based on whether there are any phdrs instead of on ELF file type.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 src/ChangeLog |  6 +++++
 src/strip.c   | 70 +++++++++++++++++++++++++++++++++++------------------------
 2 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 602312e..5a57e8f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2018-10-24  Mark Wielaard  <mark@klomp.org>
+
+	* strip.c (handle_elf): Always copy over phdrs if there are any
+	and check phnum instead of e_type to determine whether to move
+	allocated sections.
+
 2018-10-16  Mark Wielaard  <mark@klomp.org>
 
 	* readelf.c (print_debug_frame_section): Make sure readp is never
diff --git a/src/strip.c b/src/strip.c
index fdebc5e..cb479de 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -588,49 +588,63 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   else
     newelf = elf_clone (elf, ELF_C_EMPTY);
 
-  if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)
-      || (ehdr->e_type != ET_REL
-	  && unlikely (gelf_newphdr (newelf, phnum) == 0)))
+  if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0))
     {
-      error (0, 0, gettext ("cannot create new file '%s': %s"),
+      error (0, 0, gettext ("cannot create new ehdr for file '%s': %s"),
 	     output_fname ?: fname, elf_errmsg (-1));
       goto fail;
     }
 
   /* Copy over the old program header if needed.  */
-  if (ehdr->e_type != ET_REL)
-    for (cnt = 0; cnt < phnum; ++cnt)
-      {
-	GElf_Phdr phdr_mem;
-	GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
-	if (phdr == NULL
-	    || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
-	  INTERNAL_ERROR (fname);
-      }
+  if (phnum > 0)
+    {
+      if (unlikely (gelf_newphdr (newelf, phnum) == 0))
+	{
+	  error (0, 0, gettext ("cannot create new phdr for file '%s': %s"),
+		 output_fname ?: fname, elf_errmsg (-1));
+	  goto fail;
+	}
+
+      for (cnt = 0; cnt < phnum; ++cnt)
+	{
+	  GElf_Phdr phdr_mem;
+	  GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+	  if (phdr == NULL
+	      || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
+	    INTERNAL_ERROR (fname);
+	}
+    }
 
   if (debug_fname != NULL)
     {
       /* Also create an ELF descriptor for the debug file */
       debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
-      if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)
-	  || (ehdr->e_type != ET_REL
-	      && unlikely (gelf_newphdr (debugelf, phnum) == 0)))
+      if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0))
 	{
-	  error (0, 0, gettext ("cannot create new file '%s': %s"),
+	  error (0, 0, gettext ("cannot create new ehdr for file '%s': %s"),
 		 debug_fname, elf_errmsg (-1));
 	  goto fail_close;
 	}
 
       /* Copy over the old program header if needed.  */
-      if (ehdr->e_type != ET_REL)
-	for (cnt = 0; cnt < phnum; ++cnt)
-	  {
-	    GElf_Phdr phdr_mem;
-	    GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
-	    if (phdr == NULL
-		|| unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
-	      INTERNAL_ERROR (fname);
-	  }
+      if (phnum > 0)
+	{
+	  if (unlikely (gelf_newphdr (debugelf, phnum) == 0))
+	    {
+	      error (0, 0, gettext ("cannot create new phdr for file '%s': %s"),
+		     debug_fname, elf_errmsg (-1));
+	      goto fail_close;
+	    }
+
+	  for (cnt = 0; cnt < phnum; ++cnt)
+	    {
+	      GElf_Phdr phdr_mem;
+	      GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+	      if (phdr == NULL
+		  || unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
+		INTERNAL_ERROR (fname);
+	    }
+	}
     }
 
   /* Number of sections.  */
@@ -738,7 +752,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 	 to keep the layout of all allocated sections as similar as
 	 possible to the original file.  In relocatable object files
 	 everything can be moved.  */
-      if (ehdr->e_type == ET_REL
+      if (phnum == 0
 	  || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
 	shdr_info[cnt].shdr.sh_offset = 0;
 
@@ -2328,7 +2342,7 @@ while computing checksum for debug information"));
   /* The ELF library better follows our layout when this is not a
      relocatable object file.  */
   elf_flagelf (newelf, ELF_C_SET,
-	       (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0)
+	       (phnum > 0 ? ELF_F_LAYOUT : 0)
 	       | (permissive ? ELF_F_PERMISSIVE : 0));
 
   /* Finally write the file.  */
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Add eu-strip --reloc-debug-sections-only option
@ 2018-10-26 21:51 Mark Wielaard
  2018-10-26 21:51 ` [PATCH 1/4] strip: Always copy over any phdrs if there are any Mark Wielaard
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Mark Wielaard @ 2018-10-26 21:51 UTC (permalink / raw)
  To: elfutils-devel

Hi,

eu-strip already supports --reloc-debug-sections to resolve all
relocations between .debug_ sections while creating a separate
.debug file with -f. It is sometimes useful to do the same without
doing any other stripping.

  --reloc-debug-sections-only
                         Similar to --reloc-debug-sections, but resolve all
                         trivial relocations between debug sections in
                         place.  No other stripping is performed (operation
                         is not reversable, incompatible with -f, -g,
                         --remove-comment and --remove-section)

For example to ease debugging, tracing and profiling some distributions
ship an uncompressed vmlinux ELF file which includes DWARF debuginfo.
Since the vmlinux ELF kernel is relocatable, the relocations between the
.debug sections are also still left in. On Fedora this file is 662M.
eu-strip --reloc-debug-sections-only will remove more than 250MB of
(unneeded) relocations between the .debug sections.

To reuse as much code as possible this patch series first refactors
some of the code. It also makes it so that the type of ELF file doesn't
matter for doing relocations (normally it only makes sense for ET_REL
files, but the vmlinux ELF image is an ET_EXEC with SHT_RELA sections).

It also adds a new testcase to run-strip-reloc.sh to make sure that the
result of creating a separate debug file using --reloc-debug-sections
is identical to creating a separate debug file and then running eu-strip
with --reloc-debug-sections-only.

[PATCH 1/4] strip: Always copy over any phdrs if there are any
[PATCH 2/4] strip: Split out debug section relocation into separate helper
[PATCH 3/4] strip: Extract code to update shdrstrndx into new common function
[PATCH 4/4] strip: Add --reloc-debug-sections-only option

 Cheers,

 Mark

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/4] strip: Extract code to update shdrstrndx into new common function.
  2018-10-26 21:51 Add eu-strip --reloc-debug-sections-only option Mark Wielaard
  2018-10-26 21:51 ` [PATCH 1/4] strip: Always copy over any phdrs if there are any Mark Wielaard
@ 2018-10-26 21:51 ` Mark Wielaard
  2018-10-26 21:51 ` [PATCH 2/4] strip: Split out debug section relocation into separate helper functions Mark Wielaard
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2018-10-26 21:51 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 src/ChangeLog |  5 ++++
 src/strip.c   | 94 +++++++++++++++++++++++++++++++----------------------------
 2 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index f55ff6c..766c839 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,10 @@
 2018-10-24  Mark Wielaard  <mark@klomp.org>
 
+	* strip.c (handle_elf): Extract code to update shdrstrndx into...
+	(update_shdrstrndx): ... this new function.
+
+2018-10-24  Mark Wielaard  <mark@klomp.org>
+
 	* strip.c (handle_elf): Extract code into separate functions...
 	(secndx_name): ... new function.
 	(get_xndxdata): Likewise.
diff --git a/src/strip.c b/src/strip.c
index a7b69a6..1151206 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -395,6 +395,37 @@ get_xndxdata (Elf *elf, Elf_Scn *symscn)
   return xndxdata;
 }
 
+/* Updates the shdrstrndx for the given Elf by updating the Ehdr and
+   possibly the section zero extension field.  Returns zero on success.  */
+static int
+update_shdrstrndx (Elf *elf, size_t shdrstrndx)
+{
+  GElf_Ehdr ehdr;
+  if (gelf_getehdr (elf, &ehdr) == 0)
+    return 1;
+
+  if (shdrstrndx < SHN_LORESERVE)
+    ehdr.e_shstrndx = shdrstrndx;
+  else
+    {
+      ehdr.e_shstrndx = SHN_XINDEX;
+      Elf_Scn *scn0 = elf_getscn (elf, 0);
+      GElf_Shdr shdr0_mem;
+      GElf_Shdr *shdr0 = gelf_getshdr (scn0, &shdr0_mem);
+      if (shdr0 == NULL)
+	return 1;
+
+      shdr0->sh_link = shdrstrndx;
+      if (gelf_update_shdr (scn0, shdr0) == 0)
+	return 1;
+    }
+
+  if (unlikely (gelf_update_ehdr (elf, &ehdr) == 0))
+    return 1;
+
+  return 0;
+}
+
 /* Remove any relocations between debug sections in ET_REL
    for the debug file when requested.  These relocations are always
    zero based between the unallocated sections.  */
@@ -1444,6 +1475,14 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
       debugehdr->e_entry = ehdr->e_entry;
       debugehdr->e_flags = ehdr->e_flags;
 
+      if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
+	{
+	  error (0, 0, gettext ("%s: error while updating ELF header: %s"),
+		 debug_fname, elf_errmsg (-1));
+	  result = 1;
+	  goto fail_close;
+	}
+
       size_t shdrstrndx;
       if (elf_getshdrstrndx (elf, &shdrstrndx) < 0)
 	{
@@ -1453,36 +1492,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 	  goto fail_close;
 	}
 
-      if (shstrndx < SHN_LORESERVE)
-	debugehdr->e_shstrndx = shdrstrndx;
-      else
+      if (update_shdrstrndx (debugelf, shdrstrndx) != 0)
 	{
-	  debugehdr->e_shstrndx = SHN_XINDEX;
-	  Elf_Scn *scn0 = elf_getscn (debugelf, 0);
-	  GElf_Shdr shdr0_mem;
-	  GElf_Shdr *shdr0 = gelf_getshdr (scn0, &shdr0_mem);
-	  if (shdr0 == NULL)
-	    {
-	      error (0, 0, gettext ("%s: error getting zero section: %s"),
-		     debug_fname, elf_errmsg (-1));
-	      result = 1;
-	      goto fail_close;
-	    }
-
-	  shdr0->sh_link = shdrstrndx;
-	  if (gelf_update_shdr (scn0, shdr0) == 0)
-	    {
-	      error (0, 0, gettext ("%s: error while updating zero section: %s"),
-		     debug_fname, elf_errmsg (-1));
-	      result = 1;
-	      goto fail_close;
-	    }
-
-	}
-
-      if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
-	{
-	  error (0, 0, gettext ("%s: error while creating ELF header: %s"),
+	  error (0, 0, gettext ("%s: error updating shdrstrndx: %s"),
 		 debug_fname, elf_errmsg (-1));
 	  result = 1;
 	  goto fail_close;
@@ -2348,26 +2360,18 @@ while computing checksum for debug information"));
 		      & ~((GElf_Off) (offsize - 1)));
   newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
 
-  /* The new section header string table index.  */
-  if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
-    newehdr->e_shstrndx = idx;
-  else
+  if (gelf_update_ehdr (newelf, newehdr) == 0)
     {
-      /* The index does not fit in the ELF header field.  */
-      shdr_info[0].scn = elf_getscn (elf, 0);
-
-      if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
-	INTERNAL_ERROR (fname);
-
-      shdr_info[0].shdr.sh_link = idx;
-      (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
-
-      newehdr->e_shstrndx = SHN_XINDEX;
+      error (0, 0, gettext ("%s: error while creating ELF header: %s"),
+	     output_fname ?: fname, elf_errmsg (-1));
+      cleanup_debug ();
+      return 1;
     }
 
-  if (gelf_update_ehdr (newelf, newehdr) == 0)
+  /* The new section header string table index.  */
+  if (update_shdrstrndx (newelf, idx) != 0)
     {
-      error (0, 0, gettext ("%s: error while creating ELF header: %s"),
+      error (0, 0, gettext ("%s: error updating shdrstrndx: %s"),
 	     output_fname ?: fname, elf_errmsg (-1));
       cleanup_debug ();
       return 1;
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/4] strip: Add --reloc-debug-sections-only option.
  2018-10-26 21:51 Add eu-strip --reloc-debug-sections-only option Mark Wielaard
                   ` (2 preceding siblings ...)
  2018-10-26 21:51 ` [PATCH 2/4] strip: Split out debug section relocation into separate helper functions Mark Wielaard
@ 2018-10-26 21:59 ` Mark Wielaard
  2018-11-06 14:21   ` Mark Wielaard
  2018-11-06 11:11 ` Add eu-strip " Mark Wielaard
  4 siblings, 1 reply; 8+ messages in thread
From: Mark Wielaard @ 2018-10-26 21:59 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

This option does the same thing as --reloc-debug-sections without doing
any other strip operation. This is useful when you want to remove the
debug section relocations in a separate ET_REL debug file that was created
without --reloc-debug-sections, or for a file (like the linux debug vmlinux)
that you don't want to strip, but for which the debug section relocations
can be resolved already.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 src/ChangeLog            |  11 ++++
 src/strip.c              | 155 +++++++++++++++++++++++++++++++++++++++++++++--
 tests/ChangeLog          |   4 ++
 tests/run-strip-reloc.sh |  11 ++++
 4 files changed, 175 insertions(+), 6 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 766c839..0eed9ae 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+2018-10-26  Mark Wielaard  <mark@klomp.org>
+
+	* strip.c (OPT_RELOC_DEBUG_ONLY): New define.
+	(options): Add reloc-debug-sections-only.
+	(reloc_debug_only): New static bool.
+	(main): Check reloc_debug_only is the only strip option used.
+	(parse_opt): Handle OPT_RELOC_DEBUG_ONLY.
+	(handle_debug_relocs): New function.
+	(handle_elf): Add local variables lastsec_offset and lastsec_size.
+	Handle reloc_debug_only.
+
 2018-10-24  Mark Wielaard  <mark@klomp.org>
 
 	* strip.c (handle_elf): Extract code to update shdrstrndx into...
diff --git a/src/strip.c b/src/strip.c
index 1151206..e953c4d 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -1,5 +1,5 @@
 /* Discard section not used at runtime from object files.
-   Copyright (C) 2000-2012, 2014, 2015, 2016, 2017 Red Hat, Inc.
+   Copyright (C) 2000-2012, 2014, 2015, 2016, 2017, 2018 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
 
@@ -61,6 +61,7 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
 #define OPT_STRIP_SECTIONS	0x102
 #define OPT_RELOC_DEBUG 	0x103
 #define OPT_KEEP_SECTION 	0x104
+#define OPT_RELOC_DEBUG_ONLY    0x105
 
 
 /* Definitions of arguments for argp functions.  */
@@ -82,6 +83,8 @@ static const struct argp_option options[] =
     N_("Copy modified/access timestamps to the output"), 0 },
   { "reloc-debug-sections", OPT_RELOC_DEBUG, NULL, 0,
     N_("Resolve all trivial relocations between debug sections if the removed sections are placed in a debug file (only relevant for ET_REL files, operation is not reversable, needs -f)"), 0 },
+  { "reloc-debug-sections-only", OPT_RELOC_DEBUG_ONLY, NULL, 0,
+    N_("Similar to --reloc-debug-sections, but resolve all trivial relocations between debug sections in place.  No other stripping is performed (operation is not reversable, incompatible with -f, -g, --remove-comment and --remove-section)"), 0 },
   { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
     N_("Remove .comment section"), 0 },
   { "remove-section", 'R', "SECTION", 0, N_("Remove the named section.  SECTION is an extended wildcard pattern.  May be given more than once.  Only non-allocated sections can be removed."), 0 },
@@ -159,6 +162,9 @@ static bool permissive;
 /* If true perform relocations between debug sections.  */
 static bool reloc_debug;
 
+/* If true perform relocations between debug sections only.  */
+static bool reloc_debug_only;
+
 /* Sections the user explicitly wants to keep or remove.  */
 struct section_pattern
 {
@@ -240,6 +246,12 @@ main (int argc, char *argv[])
     error (EXIT_FAILURE, 0,
 	   gettext ("--reloc-debug-sections used without -f"));
 
+  if (reloc_debug_only &&
+      (debug_fname != NULL || remove_secs != NULL
+       || remove_comment == true || remove_debug == true))
+    error (EXIT_FAILURE, 0,
+	   gettext ("--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --remove-section"));
+
   /* Tell the library which version we are expecting.  */
   elf_version (EV_CURRENT);
 
@@ -307,6 +319,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
       reloc_debug = true;
       break;
 
+    case OPT_RELOC_DEBUG_ONLY:
+      reloc_debug_only = true;
+      break;
+
     case OPT_REMOVE_COMMENT:
       remove_comment = true;
       break;
@@ -774,6 +790,116 @@ process_file (const char *fname)
   return result;
 }
 
+/* Processing for --reloc-debug-sections-only.  */
+static int
+handle_debug_relocs (Elf *elf, Ebl *ebl, Elf *new_elf,
+		     GElf_Ehdr *ehdr, const char *fname, size_t shstrndx,
+		     GElf_Off *last_offset, GElf_Xword *last_size)
+{
+
+  /* Copy over the ELF header.  */
+  if (gelf_update_ehdr (new_elf, ehdr) == 0)
+    {
+      error (0, 0, "couldn't update new ehdr: %s", elf_errmsg (-1));
+      return 1;
+    }
+
+  /* Copy over sections and record end of allocated sections.  */
+  GElf_Off lastoffset = 0;
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      /* Get the header.  */
+      GElf_Shdr shdr;
+      if (gelf_getshdr (scn, &shdr) == NULL)
+	{
+	  error (0, 0, "couldn't get shdr: %s", elf_errmsg (-1));
+	  return 1;
+	}
+
+      /* Create new section.  */
+      Elf_Scn *new_scn = elf_newscn (new_elf);
+      if (new_scn == NULL)
+	{
+	  error (0, 0, "couldn't create new section: %s", elf_errmsg (-1));
+	  return 1;
+	}
+
+      if (gelf_update_shdr (new_scn, &shdr) == 0)
+	{
+	  error (0, 0, "couldn't update shdr: %s", elf_errmsg (-1));
+	  return 1;
+	}
+
+      /* Copy over section data.  */
+      Elf_Data *data = NULL;
+      while ((data = elf_getdata (scn, data)) != NULL)
+	{
+	  Elf_Data *new_data = elf_newdata (new_scn);
+	  if (new_data == NULL)
+	    {
+	      error (0, 0, "couldn't create new section data: %s",
+		     elf_errmsg (-1));
+	      return 1;
+	    }
+	  *new_data = *data;
+	}
+
+      /* Record last offset of allocated section.  */
+      if ((shdr.sh_flags & SHF_ALLOC) != 0)
+	{
+	  GElf_Off filesz = (shdr.sh_type != SHT_NOBITS
+			     ? shdr.sh_size : 0);
+	  if (lastoffset < shdr.sh_offset + filesz)
+	    lastoffset = shdr.sh_offset + filesz;
+	}
+    }
+
+  /* Make sure section header name table is setup correctly, we'll
+     need it to determine whether to relocate sections.  */
+  if (update_shdrstrndx (new_elf, shstrndx) != 0)
+    {
+      error (0, 0, "error updating shdrstrndx: %s", elf_errmsg (-1));
+      return 1;
+    }
+
+  /* Adjust the relocation sections.  */
+  remove_debug_relocations (ebl, new_elf, ehdr, fname, shstrndx);
+
+  /* Adjust the offsets of the non-allocated sections, so they come after
+     the allocated sections.  */
+  scn = NULL;
+  while ((scn = elf_nextscn (new_elf, scn)) != NULL)
+    {
+      /* Get the header.  */
+      GElf_Shdr shdr;
+      if (gelf_getshdr (scn, &shdr) == NULL)
+	{
+	  error (0, 0, "couldn't get shdr: %s", elf_errmsg (-1));
+	  return 1;
+	}
+
+      /* Adjust non-allocated section offsets to be after any allocated.  */
+      if ((shdr.sh_flags & SHF_ALLOC) == 0)
+	{
+	  shdr.sh_offset = ((lastoffset + shdr.sh_addralign - 1)
+			    & ~((GElf_Off) (shdr.sh_addralign - 1)));
+	  if (gelf_update_shdr (scn, &shdr) == 0)
+	    {
+	      error (0, 0, "couldn't update shdr: %s", elf_errmsg (-1));
+	      return 1;
+	    }
+
+	  GElf_Off filesz = (shdr.sh_type != SHT_NOBITS
+			     ? shdr.sh_size : 0);
+	  lastoffset = shdr.sh_offset + filesz;
+	  *last_offset = shdr.sh_offset;
+	  *last_size = filesz;
+	}
+    }
+
+  return 0;
+}
 
 /* Maximum size of array allocated on stack.  */
 #define MAX_STACK_ALLOC	(400 * 1024)
@@ -790,6 +916,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   tmp_debug_fname = NULL;
   int result = 0;
   size_t shdridx = 0;
+  GElf_Off lastsec_offset = 0;
+  Elf64_Xword lastsec_size = 0;
   size_t shstrndx;
   struct shdr_info
   {
@@ -848,7 +976,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
      the --reloc-debug-sections option are currently the only reasons
      we need EBL so don't open the backend unless necessary.  */
   Ebl *ebl = NULL;
-  if (remove_debug || reloc_debug)
+  if (remove_debug || reloc_debug || reloc_debug_only)
     {
       ebl = ebl_openbackend (elf);
       if (ebl == NULL)
@@ -937,6 +1065,18 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 	}
     }
 
+  if (reloc_debug_only)
+    {
+      if (handle_debug_relocs (elf, ebl, newelf, ehdr, fname, shstrndx,
+			       &lastsec_offset, &lastsec_size) != 0)
+	{
+	  result = 1;
+	  goto fail_close;
+	}
+      idx = shstrndx;
+      goto done; /* Skip all actual stripping operations.  */
+    }
+
   if (debug_fname != NULL)
     {
       /* Also create an ELF descriptor for the debug file */
@@ -2339,6 +2479,10 @@ while computing checksum for debug information"));
 	}
     }
 
+  lastsec_offset = shdr_info[shdridx].shdr.sh_offset;
+  lastsec_size = shdr_info[shdridx].shdr.sh_size;
+
+ done:
   /* Finally finish the ELF header.  Fill in the fields not handled by
      libelf from the old file.  */
   newehdr = gelf_getehdr (newelf, &newehdr_mem);
@@ -2355,8 +2499,7 @@ while computing checksum for debug information"));
 
   /* We need to position the section header table.  */
   const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
-  newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
-		       + shdr_info[shdridx].shdr.sh_size + offsize - 1)
+  newehdr->e_shoff = ((lastsec_offset + lastsec_size + offsize - 1)
 		      & ~((GElf_Off) (offsize - 1)));
   newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
 
@@ -2418,7 +2561,7 @@ while computing checksum for debug information"));
 	      || (pwrite_retry (fd, zero, sizeof zero,
 				offsetof (Elf32_Ehdr, e_shentsize))
 		  != sizeof zero)
-	      || ftruncate (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
+	      || ftruncate (fd, lastsec_offset) < 0)
 	    {
 	      error (0, errno, gettext ("while writing '%s'"),
 		     output_fname ?: fname);
@@ -2438,7 +2581,7 @@ while computing checksum for debug information"));
 	      || (pwrite_retry (fd, zero, sizeof zero,
 				offsetof (Elf64_Ehdr, e_shentsize))
 		  != sizeof zero)
-	      || ftruncate (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
+	      || ftruncate (fd, lastsec_offset) < 0)
 	    {
 	      error (0, errno, gettext ("while writing '%s'"),
 		     output_fname ?: fname);
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 751a081..0870d4c 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-26  Mark Wielaard  <mark@klomp.org>
+
+	* run-strip-reloc.sh: Add a test for --reloc-debug-sections-only.
+
 2018-10-12  Mark Wielaard  <mark@klomp.org>
 
 	* run-readelf-zdebug.sh: Adjust flags output.
diff --git a/tests/run-strip-reloc.sh b/tests/run-strip-reloc.sh
index bbc9f58..6e54ab4 100755
--- a/tests/run-strip-reloc.sh
+++ b/tests/run-strip-reloc.sh
@@ -32,6 +32,8 @@ runtest() {
   outfile2=out.stripped2
   debugfile2=out.debug2
 
+  echo "runtest $infile"
+
   rm -f $outfile1 $debugfile1 $outfile2 $debugfile2
 
   testrun ${abs_top_builddir}/src/strip -o $outfile1 -f $debugfile1 $infile ||
@@ -67,6 +69,15 @@ runtest() {
 
   testrun_compare cat readelf.out1 < readelf.out2 ||
   { echo "*** failure readelf -w compare $infile"; status=1; }
+
+  testrun ${abs_top_builddir}/src/strip --reloc-debug-sections-only \
+	  $debugfile1 ||
+  { echo "*** failure strip --reloc-debug-sections-only $debugfile1"; \
+    status=1; }
+
+  cmp $debugfile1 $debugfile2 ||
+  { echo "*** failure --reloc-debug-sections[-only] $debugfile1 $debugfile2"; \
+    status=1; }
 }
 
 # Most simple hello world kernel module for various architectures.
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Add eu-strip --reloc-debug-sections-only option
  2018-10-26 21:51 Add eu-strip --reloc-debug-sections-only option Mark Wielaard
                   ` (3 preceding siblings ...)
  2018-10-26 21:59 ` [PATCH 4/4] strip: Add --reloc-debug-sections-only option Mark Wielaard
@ 2018-11-06 11:11 ` Mark Wielaard
  4 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2018-11-06 11:11 UTC (permalink / raw)
  To: elfutils-devel

On Fri, 2018-10-26 at 23:50 +0200, Mark Wielaard wrote:
> eu-strip already supports --reloc-debug-sections to resolve all
> relocations between .debug_ sections while creating a separate
> .debug file with -f. It is sometimes useful to do the same without
> doing any other stripping.
> 
>   --reloc-debug-sections-only
>                          Similar to --reloc-debug-sections, but resolve all
>                          trivial relocations between debug sections in
>                          place.  No other stripping is performed (operation
>                          is not reversable, incompatible with -f, -g,
>                          --remove-comment and --remove-section)
> 
> For example to ease debugging, tracing and profiling some distributions
> ship an uncompressed vmlinux ELF file which includes DWARF debuginfo.
> Since the vmlinux ELF kernel is relocatable, the relocations between the
> .debug sections are also still left in. On Fedora this file is 662M.
> eu-strip --reloc-debug-sections-only will remove more than 250MB of
> (unneeded) relocations between the .debug sections.
> 
> To reuse as much code as possible this patch series first refactors
> some of the code. It also makes it so that the type of ELF file doesn't
> matter for doing relocations (normally it only makes sense for ET_REL
> files, but the vmlinux ELF image is an ET_EXEC with SHT_RELA sections).
> 
> It also adds a new testcase to run-strip-reloc.sh to make sure that the
> result of creating a separate debug file using --reloc-debug-sections
> is identical to creating a separate debug file and then running eu-strip
> with --reloc-debug-sections-only.
> 
> [PATCH 1/4] strip: Always copy over any phdrs if there are any
> [PATCH 2/4] strip: Split out debug section relocation into separate helper
> [PATCH 3/4] strip: Extract code to update shdrstrndx into new common function
> [PATCH 4/4] strip: Add --reloc-debug-sections-only option

I pushed these 4 patches to master.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] strip: Add --reloc-debug-sections-only option.
  2018-10-26 21:59 ` [PATCH 4/4] strip: Add --reloc-debug-sections-only option Mark Wielaard
@ 2018-11-06 14:21   ` Mark Wielaard
  2018-11-09 16:40     ` Mark Wielaard
  0 siblings, 1 reply; 8+ messages in thread
From: Mark Wielaard @ 2018-11-06 14:21 UTC (permalink / raw)
  To: elfutils-devel

On Fri, 2018-10-26 at 23:50 +0200, Mark Wielaard wrote:
> diff --git a/tests/ChangeLog b/tests/ChangeLog
> index 751a081..0870d4c 100644
> --- a/tests/ChangeLog
> +++ b/tests/ChangeLog
> @@ -1,3 +1,7 @@
> +2018-10-26  Mark Wielaard  <mark@klomp.org>
> +
> +	* run-strip-reloc.sh: Add a test for --reloc-debug-sections-only.
> +
>  2018-10-12  Mark Wielaard  <mark@klomp.org>
>  
>  	* run-readelf-zdebug.sh: Adjust flags output.
> diff --git a/tests/run-strip-reloc.sh b/tests/run-strip-reloc.sh
> index bbc9f58..6e54ab4 100755
> --- a/tests/run-strip-reloc.sh
> +++ b/tests/run-strip-reloc.sh
> @@ -32,6 +32,8 @@ runtest() {
>    outfile2=out.stripped2
>    debugfile2=out.debug2
>  
> +  echo "runtest $infile"
> +
>    rm -f $outfile1 $debugfile1 $outfile2 $debugfile2
>  
>    testrun ${abs_top_builddir}/src/strip -o $outfile1 -f $debugfile1 $infile ||
> @@ -67,6 +69,15 @@ runtest() {
>  
>    testrun_compare cat readelf.out1 < readelf.out2 ||
>    { echo "*** failure readelf -w compare $infile"; status=1; }
> +
> +  testrun ${abs_top_builddir}/src/strip --reloc-debug-sections-only \
> +	  $debugfile1 ||
> +  { echo "*** failure strip --reloc-debug-sections-only $debugfile1"; \
> +    status=1; }
> +
> +  cmp $debugfile1 $debugfile2 ||
> +  { echo "*** failure --reloc-debug-sections[-only] $debugfile1 $debugfile2"; \
> +    status=1; }
>  }
>  
>  # Most simple hello world kernel module for various architectures.

The buildbot didn't sent any failure emails (I am still looking into
why), but this new cmp test failed on debian-armhf, fedora-ppc64 and
fedora-ppc64le:
https://builder.wildebeest.org/buildbot/#/builders/15/builds/81
https://builder.wildebeest.org/buildbot/#/builders/12/builds/242
https://builder.wildebeest.org/buildbot/#/builders/11/builds/244

It succeeds on everything else. Still investigating.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] strip: Add --reloc-debug-sections-only option.
  2018-11-06 14:21   ` Mark Wielaard
@ 2018-11-09 16:40     ` Mark Wielaard
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Wielaard @ 2018-11-09 16:40 UTC (permalink / raw)
  To: elfutils-devel

[-- Attachment #1: Type: text/plain, Size: 708 bytes --]

On Tue, Nov 06, 2018 at 03:21:24PM +0100, Mark Wielaard wrote:
> The buildbot didn't sent any failure emails (I am still looking into
> why), but this new cmp test failed on debian-armhf, fedora-ppc64 and
> fedora-ppc64le:
> https://builder.wildebeest.org/buildbot/#/builders/15/builds/81
> https://builder.wildebeest.org/buildbot/#/builders/12/builds/242
> https://builder.wildebeest.org/buildbot/#/builders/11/builds/244
> 
> It succeeds on everything else. Still investigating.

The buildbot did sent email. I was too fast.
The issue was kind of subtle, but is easily fixable.
I committed the attached patch with some extra testcases to
(hopefully) get the build green again on all arches.

Cheers,

Mark

[-- Attachment #2: 0001-libelf-Explicitly-update-section-data-after-de-compr.patch --]
[-- Type: text/x-diff, Size: 16475 bytes --]

From c6e3290a9722df58191c1ac181ce587f406d7b7a Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Fri, 9 Nov 2018 08:18:22 +0000
Subject: [PATCH] libelf: Explicitly update section data after (de)compression.

We need to explictly trigger a section data reload after updating the
ELF section rawdata to make sure it gets written out to disk on an
elf_update. Doing this showed one bug/inefficiently when the underlying
file has a different endianness. In that case for debug sections we
would convert by allocating a new buffer and just copying over the
raw data into a new buffer. This is not really necessary and would
hide any relocations done on the rawdata by libdwfl.

Added a couple of new ppc64 big endian testfiles that show the issue.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libelf/ChangeLog                       |   7 ++
 libelf/elf_compress.c                  |   6 ++
 libelf/elf_getdata.c                   |   3 +-
 tests/ChangeLog                        |  10 +++
 tests/Makefile.am                      |   5 +-
 tests/run-readelf-zdebug-rel.sh        | 106 +++++++++++++++++++++++++
 tests/run-strip-reloc.sh               |   4 +
 tests/testfile-debug-rel-ppc64-g.o.bz2 | Bin 0 -> 1400 bytes
 tests/testfile-debug-rel-ppc64-z.o.bz2 | Bin 0 -> 1420 bytes
 tests/testfile-debug-rel-ppc64.o.bz2   | Bin 0 -> 1103 bytes
 10 files changed, 139 insertions(+), 2 deletions(-)
 create mode 100644 tests/testfile-debug-rel-ppc64-g.o.bz2
 create mode 100644 tests/testfile-debug-rel-ppc64-z.o.bz2
 create mode 100644 tests/testfile-debug-rel-ppc64.o.bz2

diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index af5650360..53da9a65f 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-09  Mark Wielaard  <mark@klomp.org>
+
+	* elf_compress.c (__libelf_reset_rawdata): Make rawdata change
+	explicit by calling __libelf_set_data_list.
+	* elf_getdata.c (convert_data): Don't convert if type is ELF_T_BYTE
+	even if endianness is different.
+
 2018-10-18  Mark Wielaard  <mark@klomp.org>
 
 	* libelf.h (Elf_Type): Add ELF_T_NHDR8.
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index fd412e8a6..d96245df2 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -326,6 +326,12 @@ __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
 
   scn->rawdata_base = buf;
   scn->flags |= ELF_F_MALLOCED;
+
+  /* Pretend we (tried to) read the data from the file and setup the
+     data (might have to convert the Chdr to native format).  */
+  scn->data_read = 1;
+  scn->flags |= ELF_F_FILEDATA;
+  __libelf_set_data_list_rdlock (scn, 1);
 }
 
 int
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 4f80aaf2d..2043bba2d 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -146,7 +146,8 @@ convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
 {
   const size_t align = __libelf_type_align (eclass, type);
 
-  if (data == MY_ELFDATA)
+  /* Do we need to convert the data and/or adjust for alignment?  */
+  if (data == MY_ELFDATA || type == ELF_T_BYTE)
     {
       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
 	/* No need to copy, we can use the raw data.  */
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 23e911336..7ce39808d 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,13 @@
+2018-11-09  Mark Wielaard  <mark@klomp.org>
+
+	* testfile-debug-rel-ppc64-g.o.bz2: New test file.
+	* testfile-debug-rel-ppc64-z.o.bz2: Likewise.
+	* testfile-debug-rel-ppc64.o.bz2: Likewise.
+	* Makefile.am (EXTRA_DIST): Add testfile-debug-rel-ppc64-g.o.bz2,
+	testfile-debug-rel-ppc64-z.o.bz2 and testfile-debug-rel-ppc64.o.bz2.
+	* run-strip-reloc.sh: Also test on testfile-debug-rel-ppc64.o.
+	* run-readelf-zdebug-rel.sh: Also test on testfile-debug-rel-ppc64*.o.
+
 2018-10-26  Mark Wielaard  <mark@klomp.org>
 
 	* run-strip-reloc.sh: Add a test for --reloc-debug-sections-only.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a2a381ac8..d3ac345df 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -412,7 +412,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
 	     testfile-riscv64.bz2 testfile-riscv64-s.bz2 \
 	     testfile-riscv64-core.bz2 \
 	     run-copyadd-sections.sh run-copymany-sections.sh \
-	     run-typeiter-many.sh run-strip-test-many.sh
+	     run-typeiter-many.sh run-strip-test-many.sh \
+	     testfile-debug-rel-ppc64-g.o.bz2 \
+	     testfile-debug-rel-ppc64-z.o.bz2 \
+	     testfile-debug-rel-ppc64.o.bz2
 
 if USE_VALGRIND
 valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1'
diff --git a/tests/run-readelf-zdebug-rel.sh b/tests/run-readelf-zdebug-rel.sh
index 3f20078c4..53fa42a27 100755
--- a/tests/run-readelf-zdebug-rel.sh
+++ b/tests/run-readelf-zdebug-rel.sh
@@ -146,4 +146,110 @@ cat loc.out | sed -e "s/'.debug_loc' at offset 0x185/'.zdebug_loc' at offset 0x1
 
 cat loc.out | sed -e "s/at offset 0x185/at offset 0x150/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-z.o
 
+# Same as above, but on ppc64
+testfiles testfile-debug-rel-ppc64.o
+testfiles testfile-debug-rel-ppc64-g.o testfile-debug-rel-ppc64-z.o
+
+cat > info.out << \EOF
+
+DWARF section [ 6] '.debug_info' at offset 0x80:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [     b]  compile_unit         abbrev: 1
+           producer             (strp) "GNU C11 7.3.1 20180712 (Red Hat 7.3.1-6) -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -g -Og"
+           language             (data1) C99 (12)
+           name                 (strp) "testfile-zdebug-rel.c"
+           comp_dir             (strp) "/home/mjw"
+           low_pc               (addr) 000000000000000000
+           high_pc              (data8) 44 (0x000000000000002c)
+           stmt_list            (sec_offset) 0
+ [    2d]    subprogram           abbrev: 2
+             external             (flag_present) yes
+             name                 (strp) "main"
+             decl_file            (data1) testfile-zdebug-rel.c (1)
+             decl_line            (data1) 4
+             prototyped           (flag_present) yes
+             type                 (ref4) [    82]
+             low_pc               (addr) 000000000000000000
+             high_pc              (data8) 44 (0x000000000000002c)
+             frame_base           (exprloc) 
+              [ 0] call_frame_cfa
+             GNU_all_call_sites   (flag_present) yes
+             sibling              (ref4) [    82]
+ [    4e]      formal_parameter     abbrev: 3
+               name                 (strp) "argc"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 4
+               type                 (ref4) [    82]
+               location             (sec_offset) location list [     0]
+ [    5d]      formal_parameter     abbrev: 4
+               name                 (strp) "argv"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 4
+               type                 (ref4) [    89]
+               location             (exprloc) 
+                [ 0] reg4
+ [    6a]      variable             abbrev: 5
+               name                 (string) "a"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 6
+               type                 (ref4) [    9c]
+               const_value          (sdata) 18446744073709551607 (-9)
+ [    74]      variable             abbrev: 6
+               name                 (string) "b"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 7
+               type                 (ref4) [    9c]
+               location             (sec_offset) location list [    4e]
+ [    82]    base_type            abbrev: 7
+             byte_size            (data1) 4
+             encoding             (data1) signed (5)
+             name                 (string) "int"
+ [    89]    pointer_type         abbrev: 8
+             byte_size            (data1) 8
+             type                 (ref4) [    8f]
+ [    8f]    pointer_type         abbrev: 8
+             byte_size            (data1) 8
+             type                 (ref4) [    95]
+ [    95]    base_type            abbrev: 9
+             byte_size            (data1) 1
+             encoding             (data1) unsigned_char (8)
+             name                 (strp) "char"
+ [    9c]    base_type            abbrev: 9
+             byte_size            (data1) 8
+             encoding             (data1) unsigned (7)
+             name                 (strp) "long unsigned int"
+EOF
+
+cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-ppc64.o
+
+cat info.out | sed -e "s/'.debug_info'/'.zdebug_info'/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-ppc64-g.o
+
+cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-ppc64-z.o
+
+cat > loc.out << \EOF
+
+DWARF section [ 9] '.debug_loc' at offset 0x1af:
+
+ CU [     b] base: 000000000000000000
+ [     0] range 0, 4
+           [ 0] reg3
+          range 4, 14
+           [ 0] breg3 -42
+           [ 2] stack_value
+          range 14, 2c
+           [ 0] GNU_entry_value:
+                [ 0] reg3
+           [ 3] stack_value
+ [    4e] range 8, 18
+           [ 0] reg3
+EOF
+
+cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-ppc64.o
+
+cat loc.out | sed -e "s/'.debug_loc' at offset 0x1af/'.zdebug_loc' at offset 0x15f/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-ppc64-g.o
+
+cat loc.out | sed -e "s/at offset 0x1af/at offset 0x177/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-ppc64-z.o
+
 exit 0
diff --git a/tests/run-strip-reloc.sh b/tests/run-strip-reloc.sh
index 6e54ab4af..6f299aba2 100755
--- a/tests/run-strip-reloc.sh
+++ b/tests/run-strip-reloc.sh
@@ -135,4 +135,8 @@ testrun ${abs_top_builddir}/src/elfcompress -o strip-compressed.o -t zlib \
 runtest strip-uncompressed.o 1
 runtest strip-compressed.o 1
 
+# See run-readelf-zdebug-rel.sh
+testfiles testfile-debug-rel-ppc64.o
+runtest testfile-debug-rel-ppc64.o 1
+
 exit $status
diff --git a/tests/testfile-debug-rel-ppc64-g.o.bz2 b/tests/testfile-debug-rel-ppc64-g.o.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..8c5ec99e7d413fcf6b2109dc5af751c4cecff508
GIT binary patch
literal 1400
zcmV-;1&8`VT4*^jL0KkKS->=g0RRKT|NsC0|L*($fBpae_y7Oz|M&Xu-~awu{hE3E
za&G(df2hy{o7{jmZM(SdK~brxqtZ0fO-4=X1i&&z$ueev8&lF~VrjH`gHh-Krip+7
z9+8msFief9>SSbTk?EjJ8bfMr05q6JX^2uN$kRXu(gr{SBSwLvKmZ1S13&-(4FCYp
z0000000000007k09#c~^^rxzRsphC;+MZL=Y2s>njSo=J&;jZI3?_{RhL2DHVgLXQ
z05Td40MKcsOrEA7XaE2pXlMY?(?)=3WHJCU41j3RWCjQWMnD>ApazD3XaS%A02u%P
zGzNgs7$j0gr>Tf#G;KmQf_qV<!Zg|wXpJ<{rk+hkN2!ULh7iPhj2b4I9-ta}jWjb;
z5u;5pJw`wbm_tkiG&ISk5X|9hv*!vEk`CP}mDq)-oNn-y8Dau!X;J5NrCAD?apNkC
zO&dm0z=j&CPHyfQ?cNqC2YaOziz*!UCi10XK0Ei<kn-+(TT5)b>nZsMG!P&NB3PoA
z5K{p>VBe_Z@#F|6nlfdK+EEaIi4Y2S9HN1wk%{+Hj*Y>#z!V9>1h~#44wp24BTd}w
zgV@0)DPx6Bj{?HDp#T5?94d9_{&?_@zrnCs+Rar6^HHU5Q%2htmDg`1LQ@@p(okqJ
z*|$>S6_YFyl?O$b5+s7bh=U-&Z2}88KpOyTY-~vl`Hl^-u_n?+y`)?*0n~WC1Q1uV
z&S*$K3D8L!>&PS^oY09{9Mnqo#a8ZiH%F~>N9xaB$F<zeG%Z(2LmMb8>*aRjq$k%r
zDA3{nzKragV?10Ym#p{YlWDNiEnrcfV<Mo@PWBm|>LJsqswI>{yMh5%F(Qj6-(i$y
zsm#uFY6<e@I+j3nxcKdBVZ(E_lWD^3gsRvmI`>>Up;ag)Ck~_W&)h~Lm6u`Q+shDJ
zG=l=lo0u3X5Wn*wSJb=kB?U8>(6aybHX_<MYJO@T6uM~8X}a1`0BlHn?3yl6@v{>I
zbe06LQ|D`gk92H@Bn`Ub=D8NAwXLd(eJbg&X&T81@seKM*N{ms9{P#z+!D^U?je3M
z53%TgPiE<06^{hD#m_s1s~3)Wv~sbyNXotGJ4Q+38Zs?>+d-O9ww1deGIBhdAFIN|
z%-~aBE+leoD&4$NGJ_w_ug%||Eb^gN5*L*_7Y}|jYrk-#?XtH0XRxx6Tk2#rROSIs
zK0n1@Nhzgb1HNTmlhs{{5)3JV_!I>xns&hf%;=IdGR_M#1OkTLuDbEbfz5NxX_0L7
zVMmgXhhoa*0$r>Z4F*Yg`0sbumL-=Itd788sHKp|g~Alc!5OA;TIyx1JnAVyUOo@H
zMU15+#d)6cBB-OAK|&Ym`%ijR(T_jIJZ@1nqJH9$*Dl$IZXtj~L_afdJx_bG;r^NN
zfb!l9WiKs*Qh^r5hENj*Za}9a8xDtXDb^3!Ru=C5H1AAl0kDYPQYVSAk1r&3mRSr=
zN&H;WTi%|_C3xW`5l|v^-AeToQb__(^`%D2YKjc8C6|G_QwH$>0{$nwH3Kl&^RTRU
zZcIC%3<wTwR%VA~;L9uy)S@z|9J_uU&Db8R$jU#bL1RaJwPl?M6hlPM+{cd=!S~BF
zp?V2UrUjDaDs$0RNtT!(xn>~EI8^)|u8~S$Md{6RGZ5S!MWH!v9ZdPspKq$u!+uc|
zHYu?|J?P|OOYO0~9rGNr7fopH1MNIRLi#D4Sr6+O0t=&(r}TReYKCEIr4Rg})?%t+
zbq(80lSvv-i@>dyaW1p?Q;@mAoh$(>`zx9!<y8`;hnkpvf$)Hm;S^Nd;_gVN3KAFw
GkiZ}~a)z(~

literal 0
HcmV?d00001

diff --git a/tests/testfile-debug-rel-ppc64-z.o.bz2 b/tests/testfile-debug-rel-ppc64-z.o.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..df50465fceffe5446a06103346ce85b57dcf753d
GIT binary patch
literal 1420
zcmV;71#|jBT4*^jL0KkKS!MiGE&v1DfB*mg|L*hu|NZ~p_kaKI|M&Xu-~OI^{hoRI
za&G_pf2hy{y4~OhFK*p9VkxPV^-mQ2B>gg@)bed8H1#vnRMC(RQ_^~mQ_z}iA?iG!
z(Wj{OG&IxH^nsI4Q%^`9pc+3^^%?+rntFpl>Uu$@Y967JLqpW^M#T!IP|)&$pfqRz
z01r?DCV&6{05WNy0B9Oy00000000000MKLrA}NT~KT2=aHi@a|k5TE8WHNe;69~X2
z3AGw%$Y{}k34jP-69E__3FvAx85(5C>R|><03m=(D3oXb02qdV00T`1fEoY*Jwc!V
z&@=$h0000Q0000000004ibxRkH5e3V#);|ZDYSrj29fF-dWM-j6B-7iYI;voN2p}=
zF_JVGnlx$Z2AUp(Fi%s^h7syL6GK2`1|hWu9(RPJC_xr5VN)+~<YD6mhJ=YzsF-{;
zSk4OJfH~kbr$eEDgEmI+;wgk^!29$&4n!$6u!#im&mEYW3UpY(0Kg#x_$nA7&qQSY
z-m7Blpg*L+kQw<52tfpz7;K>i+&JifXexkuq9}qR6BuT)qy-!(pbY2-lTdx5nGo^{
zZ?KPs0^A@ch!z`731_b)o{1pXozH)CQVJl(V2T+&006S8Fai{`85?^)PXbbvPX@#m
z*VnXCyIDzH&8E2PwBBz9Vo6W6U^J8(R(j_(#1%}hN<<%i%z+X@uwsKC#G4WV(hvs3
zhQ`Lg6Ml10ZH<XGAjYs(3`j8@y>t+3SQ|DW2hki5mIe$GNF!(o9v^)YrDCLeTT0vS
zXEhYN?^D<*6#~;UB`%AwkQvI!5hBQ7olB~Tz#!hPC<2o4gF6=!Z&g#v#^1>!j(rfd
zik7yEF)>lJOlP5-f>vZ|3dsuo0tyBVi4BT#5KUz^G8Rm{dQOb>4lT)_b6Ek@Wo>ct
z@Yz4_Ohx-fJ%onXRn8$aQ&uP<O@qUs!nUlGB6jM!+U7_jz-a|TChcId4@UZ%xKd(y
zcM=1)>ERnf?!Vgji8L-3e<dFFOu0h3c<QJCNRfOwV$11hXhcGRF&2YfK=iK`6F3D3
z27rs0G3O)1?%9!ERpO9s->4nb6l~Txa=Wo&?)eWsW(~@TEP0sF85|VAx|}tvBV<0Q
z_wmzF;?onMZb%z~M{-QKE=at}3qh-(X|%hy9xKm)YV3Hn`AGhG>)CG?4h20!BqAV#
z`Bp@^tRkx<eWb(#_~s@{sRK%+<&>!OFV(kon^H_<lu|K>5K~64x>sIn($V(h)Em9v
z(<~r5nQMXU6uiVK(=?6?tbm&XIr2-73VILP_4Zpsn=OVcJZUqan71m%o8#e_IW%R(
z(yBG-OF;{o0y&`w5<(#YXn;&Xgarl;;J)@CQq^XhCNUCaGBd6a0q8j}c12Z#h-?fP
zqcLxNsOa?8d1td7>;Z{%YHI%)iQF8KQ*)6)^-fA<T%spgg-1^yj<Ua&UNo#^-cTJ?
zB=v1Gh)F6CvVjOK;V4^tghi}0vJi$Ozh%|o$Scw2y{RGcfI$a9z~^44Qo#}<Ob#)5
zV@VjGmm}r!21N>h;)D#M03z=4`m)Oq8j3i^VBP(H*Gp~VOIFHt#wfiboD006>d50o
zdTjBqYJZ1y>{cKTf2UvF!{TN&CUB!I!m4#9;P&r+%Ca^J{+i<qpE}*-TqGKd8hdM{
zIqW#N<Sj|OUsy>HyOBpAJ#}dhJs@l!%KvH?zAN!Xe!f*lB`b&NIn;}0l@hq=X`>L)
zqy!tW^s_{HHeD972boDL4vnuWZ-~m%=DQTjn0S>x3J!bYuS}P@qF}e*qrI5=x@;Cm
a;M(q!sx2UDCc(J>@pmLsg$V{<#X{hSoOrqb

literal 0
HcmV?d00001

diff --git a/tests/testfile-debug-rel-ppc64.o.bz2 b/tests/testfile-debug-rel-ppc64.o.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..8340d0cee0e0f509b96a230e47473f1318211fb4
GIT binary patch
literal 1103
zcmV-V1hD%;T4*^jL0KkKStF?k-2enHfBgUd|Lphw{r~&z-y#41|Mt=-!sgB~ga|+Y
zXvok5njQsd?Vgd|AdxXmpfx>BG&Bt~GzN@AAZXE`83uun01X2`4FRCZpa@AdHjE}}
zO@wNCo~D{<pa1}9001-q000dEpa21;f(fN3=+d5$(9mH30004?000000002c&;S66
zc~fcvG|*(x>KQZu7$KkoMnDY#rkXM|8feH2AbOf;$Yf*^B$Fh`Jxx6m(1w6AX_25b
z007VcXaE2KpwKiK0LW-FOy3cj)iglUBM0)p^`T|3D=Z>;BIYsNdsZw$RI$T{$p}-=
zaI02~LIsD;NDsax!Vyg7Y|Culj^shU8+ya;h!_(h0U}s1LVQ7sS<mKqBh4Psb~7i~
zCxOIDJUHtDGtpK_T)M5bWA!}QYX$9}yLR!70ttYom>NhrcC__bx{(STC<Emzz|4jN
zSS?m+?XT~hGZsEWK>(pNXq69;7Y+;n009n~Hx#MJ3KV7{037m{#%5%MQwYdl(@wf>
zCH*laQLTe)K@3LYjO#figw1+WLoiGzi`^S{_cSCJEJVx*XgP5JR$u|gl+slknSj*I
zB1|eo6gX)lHVut~X(rMG9f(Ky(E3e!v0++S#p6p6p&jCx2oZ9`by$m6Lr7Y8mHUJs
z=bRWq0*=o*MuCg4?XoQLE_U*x9~<arRMkV1MPHRKwRpFt3qPd5pMp|Cch2l+asay-
zdgmCNklmd0AXu5|0Jwwm<s;NdL_snZWFUbAtdl4y7_syf6UGt~60pWwLP#fQpkUY&
zv{GfF=DgIfSVSq)DFyc>2H=69S^?{TcxeM<#7GDQ=piP+3#Qg70?4Hn9#bSW`?Q25
z?kYkT6{FgUq&Wlu7|^?x^<;m#9=U>JG{PN|Lax)5JjJZE(}5<~o;)UnDFFe6IF=C*
zf&{^69^mxC2Ocg36kbbKYL!`vNd!UX7&oX!kR*&V>w@%@`U;;M;v9gSgkGTL88;33
z?N8sVjgV3SuxMM$MP~|&j|gIf)jP?oAZfI&nKoctd!w#b-Ieg*$gD`1wkl2=`qo~8
zl;KR8RL-WZ#o-OswV4!Ts5B$2XoG|zCMU{K9mJ(aFk`JY=n4ULLWL<17>20{@*qG5
z(grc^uM(wkfp&(!FFbOLnXV48t<zry9o6`UsOUjoEUQjxG&J%grprw#_BuA!6^d4(
zGnpk60Xm+%DKMJf#iEv2iR1ebzS0lTU<!=W_Xr$Q;DZ1F@K2IRY|9Hkn`k{TSqO{r
z8glIr)Cdc!IQYYqS%s2OXmbU4Lb((~AsP-r><4R{noiGHU5o>jCNRN1sDQaew8&Km
zEeZwzlmr%Slv<aS!oW7kFkGha0g;pZp*D53`h$SNcUcfMF)*bqC{d(AXd;}51-NR|
V3FaVFfe6F@7ji{7P>>_32;B%%*1`Y)

literal 0
HcmV?d00001

-- 
2.19.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-11-09 16:40 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-26 21:51 Add eu-strip --reloc-debug-sections-only option Mark Wielaard
2018-10-26 21:51 ` [PATCH 1/4] strip: Always copy over any phdrs if there are any Mark Wielaard
2018-10-26 21:51 ` [PATCH 3/4] strip: Extract code to update shdrstrndx into new common function Mark Wielaard
2018-10-26 21:51 ` [PATCH 2/4] strip: Split out debug section relocation into separate helper functions Mark Wielaard
2018-10-26 21:59 ` [PATCH 4/4] strip: Add --reloc-debug-sections-only option Mark Wielaard
2018-11-06 14:21   ` Mark Wielaard
2018-11-09 16:40     ` Mark Wielaard
2018-11-06 11:11 ` Add eu-strip " Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).