During the recalculation of the buildid, it's necessary to change the word
back to the original endian.  However, if we do this in-place, we've also
affected the headers that we're also working on.  The side effect of this is
we can no longer rely on 'sh_type' as it may have been changed.

This patch ensures that any time we translate the loaded data to the machine
format, we only do it in a backup copy and never the original copy.

Note: in all other places a backup copy was used, just not buildid processing.

Also the process (...) function was modified to verify the data is not
NULL as well.  This is an extra check and is not strictly necessary.

Upstream-Status: Pending

Signed-off-by: Mark Hatle <mark.hatle@windriver.com>

Index: rpm-5.4.9/tools/debugedit.c
===================================================================
--- rpm-5.4.9.orig/tools/debugedit.c
+++ rpm-5.4.9/tools/debugedit.c
@@ -1432,21 +1432,24 @@ handle_build_id (DSO *dso, Elf_Data *bui
     auto inline void process (const void *data, size_t size)
     {
       memchunk chunk = { .data = (void *) data, .size = size };
-      hashFunctionContextUpdateMC (&ctx, &chunk);
+      if (data != NULL && size != 0)
+        hashFunctionContextUpdateMC (&ctx, &chunk);
     }
     union
     {
       GElf_Ehdr ehdr;
       GElf_Phdr phdr;
       GElf_Shdr shdr;
-    } u;
-    Elf_Data x = { .d_version = EV_CURRENT, .d_buf = &u };
-
-    x.d_type = ELF_T_EHDR;
-    x.d_size = sizeof u.ehdr;
-    u.ehdr = dso->ehdr;
-    u.ehdr.e_phoff = u.ehdr.e_shoff = 0;
-    if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL)
+    } u1, u2;
+    Elf_Data src  = { .d_version = EV_CURRENT, .d_buf = &u1 };
+    Elf_Data dest = { .d_version = EV_CURRENT, .d_buf = &u2 };
+
+    src.d_type = ELF_T_EHDR;
+    src.d_size = sizeof u1.ehdr;
+    dest.d_size = sizeof u2.ehdr;
+    u1.ehdr = dso->ehdr;
+    u1.ehdr.e_phoff = u1.ehdr.e_shoff = 0;
+    if (elf64_xlatetom (&dest, &src, dso->ehdr.e_ident[EI_DATA]) == NULL)
       {
       bad:
 	fprintf (stderr, "Failed to compute header checksum: %s\n",
@@ -1454,29 +1457,31 @@ handle_build_id (DSO *dso, Elf_Data *bui
 	exit (1);
       }
 
-    x.d_type = ELF_T_PHDR;
-    x.d_size = sizeof u.phdr;
+    src.d_type = ELF_T_PHDR;
+    src.d_size = sizeof u1.phdr;
+    dest.d_size = sizeof u2.phdr;
     for (i = 0; i < dso->ehdr.e_phnum; ++i)
       {
-	if (gelf_getphdr (dso->elf, i, &u.phdr) == NULL)
+	if (gelf_getphdr (dso->elf, i, &u1.phdr) == NULL)
 	  goto bad;
-	if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL)
+	if (elf64_xlatetom (&dest, &src, dso->ehdr.e_ident[EI_DATA]) == NULL)
 	  goto bad;
-	process (x.d_buf, x.d_size);
+	process (dest.d_buf, dest.d_size);
       }
 
-    x.d_type = ELF_T_SHDR;
-    x.d_size = sizeof u.shdr;
+    src.d_type = ELF_T_SHDR;
+    src.d_size = sizeof u1.shdr;
+    dest.d_size = sizeof u2.shdr;
     for (i = 0; i < dso->ehdr.e_shnum; ++i)
       if (dso->scn[i] != NULL)
 	{
-	  u.shdr = dso->shdr[i];
-	  u.shdr.sh_offset = 0;
-	  if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL)
+	  u1.shdr = dso->shdr[i];
+	  u1.shdr.sh_offset = 0;
+	  if (elf64_xlatetom (&dest, &src, dso->ehdr.e_ident[EI_DATA]) == NULL)
 	    goto bad;
-	  process (x.d_buf, x.d_size);
+	  process (dest.d_buf, dest.d_size);
 
-	  if (u.shdr.sh_type != SHT_NOBITS)
+	  if (u1.shdr.sh_type != SHT_NOBITS)
 	    {
 	      Elf_Data *d = elf_rawdata (dso->scn[i], NULL);
 	      if (d == NULL)
