summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@windriver.com>2013-03-25 22:35:13 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-03-26 17:53:40 +0000
commitac4d2d44c88cace8dbce0c8e7df3fd1f2ed244b4 (patch)
treedded5ea615dc3d1880aed0a40a14f7ef2999038b
parent11ba0231244b8a27939969353e3aa668ce78f7c6 (diff)
downloadopenembedded-core-ac4d2d44c88cace8dbce0c8e7df3fd1f2ed244b4.tar.gz
openembedded-core-ac4d2d44c88cace8dbce0c8e7df3fd1f2ed244b4.tar.bz2
openembedded-core-ac4d2d44c88cace8dbce0c8e7df3fd1f2ed244b4.zip
rpm: Fix debugedit buildid processing
[ YOCTO #4089 ] When constructing a new buildid, the items being hashed need to be returned to their native endian. In the process we were munging the sh_type field that we relied on to determine if a section was loadable or not. The patch avoids this behavior by only modifying a copy of the local endian data. Signed-off-by: Mark Hatle <mark.hatle@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/rpm/rpm/debugedit-segv.patch92
1 files changed, 78 insertions, 14 deletions
diff --git a/meta/recipes-devtools/rpm/rpm/debugedit-segv.patch b/meta/recipes-devtools/rpm/rpm/debugedit-segv.patch
index bd9169381f..2d620a5354 100644
--- a/meta/recipes-devtools/rpm/rpm/debugedit-segv.patch
+++ b/meta/recipes-devtools/rpm/rpm/debugedit-segv.patch
@@ -1,19 +1,15 @@
-There are cases, especially on PPC and MIPS, where the data address
-returned is 0, but the size is not 0.
+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.
-It appears to happen when the sections headers are similar to:
+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.
- [21] .data PROGBITS 000239c0 0139c0 000010 00 WA 0 0 8
- [22] .got PROGBITS 000239d0 0139d0 000014 04 WAX 0 0 4
- [23] .plt NOBITS 000239e4 0139e4 000234 00 WAX 0 0 4
- [24] .bss NOBITS 00023c18 0139e4 0001c8 00 WA 0 0 8
- [25] .comment PROGBITS 00000000 0139e4 000011 01 MS 0 0 1
- [26] .debug_aranges PROGBITS 00000000 0139f8 000d68 00 0 0 8
+Note: in all other places a backup copy was used, just not buildid processing.
-Sections 23 and 24 (.plt and .bss) which are NOBITS have a loaded data address
-of 0, but a size != 0.
-
-This could be a bug in libelf...
+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
@@ -23,7 +19,7 @@ Index: rpm-5.4.9/tools/debugedit.c
===================================================================
--- rpm-5.4.9.orig/tools/debugedit.c
+++ rpm-5.4.9/tools/debugedit.c
-@@ -1434,7 +1434,8 @@ handle_build_id (DSO *dso, Elf_Data *bui
+@@ -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 };
@@ -33,3 +29,71 @@ Index: rpm-5.4.9/tools/debugedit.c
}
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)