Add elfutils-0.174-strip-unstrip-group.patch
This commit is contained in:
parent
7a679f4677
commit
c59734bbef
189
elfutils-0.174-strip-unstrip-group.patch
Normal file
189
elfutils-0.174-strip-unstrip-group.patch
Normal file
@ -0,0 +1,189 @@
|
||||
commit c06ab0bbb4761a69d2f188675d21d1a9131e9ecb
|
||||
Author: Mark Wielaard <mark@klomp.org>
|
||||
Date: Sat Oct 13 10:27:47 2018 +0200
|
||||
|
||||
strip, unstrip: Handle SHT_GROUP correctly.
|
||||
|
||||
The usage of annobin in Fedora showed a couple of bugs when using
|
||||
eu-strip and eu-unstrip on ET_REL files that contain multiple group
|
||||
sections.
|
||||
|
||||
When stripping we should not remove the SHF_GROUP flag from sections
|
||||
even if the group section itself might be removed. Either the section
|
||||
itself gets removed, and so the flag doesn't matter. Or it gets moved
|
||||
together with the group section into the debug file, and then it still
|
||||
needs to have the flag set. Also we would "renumber" the section group
|
||||
flag field (which isn't a section index, and so shouldn't be changed).
|
||||
|
||||
Often the group sections have the exact same name (".group"), flags
|
||||
(none) and sometimes the same sizes. Which makes matching them hard.
|
||||
Extract the group signature and compare those when comparing two
|
||||
group sections.
|
||||
|
||||
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
||||
|
||||
diff --git a/src/strip.c b/src/strip.c
|
||||
index 1f7b3ca..fdebc5e 100644
|
||||
--- a/src/strip.c
|
||||
+++ b/src/strip.c
|
||||
@@ -792,9 +792,13 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
|
||||
|
||||
if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
|
||||
{
|
||||
- /* The section group section will be removed. */
|
||||
+ /* The section group section might be removed.
|
||||
+ Don't remove the SHF_GROUP flag. The section is
|
||||
+ either also removed, in which case the flag doesn't matter.
|
||||
+ Or it moves with the group into the debug file, then
|
||||
+ it will be reconnected with the new group and should
|
||||
+ still have the flag set. */
|
||||
shdr_info[cnt].group_idx = 0;
|
||||
- shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1368,7 +1372,9 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
|
||||
&& shdr_info[cnt].data->d_buf != NULL);
|
||||
|
||||
Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
|
||||
- for (size_t inner = 0;
|
||||
+ /* First word is the section group flag.
|
||||
+ Followed by section indexes, that need to be renumbered. */
|
||||
+ for (size_t inner = 1;
|
||||
inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
|
||||
++inner)
|
||||
if (grpref[inner] < shnum)
|
||||
diff --git a/src/unstrip.c b/src/unstrip.c
|
||||
index e6f0947..03a0346 100644
|
||||
--- a/src/unstrip.c
|
||||
+++ b/src/unstrip.c
|
||||
@@ -696,6 +696,7 @@ struct section
|
||||
{
|
||||
Elf_Scn *scn;
|
||||
const char *name;
|
||||
+ const char *sig;
|
||||
Elf_Scn *outscn;
|
||||
Dwelf_Strent *strent;
|
||||
GElf_Shdr shdr;
|
||||
@@ -720,7 +721,8 @@ compare_alloc_sections (const struct section *s1, const struct section *s2,
|
||||
|
||||
static int
|
||||
compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2,
|
||||
- const char *name1, const char *name2)
|
||||
+ const char *name1, const char *name2,
|
||||
+ const char *sig1, const char *sig2)
|
||||
{
|
||||
/* Sort by sh_flags as an arbitrary ordering. */
|
||||
if (shdr1->sh_flags < shdr2->sh_flags)
|
||||
@@ -734,6 +736,10 @@ compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2,
|
||||
if (shdr1->sh_size > shdr2->sh_size)
|
||||
return 1;
|
||||
|
||||
+ /* Are they both SHT_GROUP sections? Then compare signatures. */
|
||||
+ if (sig1 != NULL && sig2 != NULL)
|
||||
+ return strcmp (sig1, sig2);
|
||||
+
|
||||
/* Sort by name as last resort. */
|
||||
return strcmp (name1, name2);
|
||||
}
|
||||
@@ -751,7 +757,8 @@ compare_sections (const void *a, const void *b, bool rel)
|
||||
return ((s1->shdr.sh_flags & SHF_ALLOC)
|
||||
? compare_alloc_sections (s1, s2, rel)
|
||||
: compare_unalloc_sections (&s1->shdr, &s2->shdr,
|
||||
- s1->name, s2->name));
|
||||
+ s1->name, s2->name,
|
||||
+ s1->sig, s2->sig));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -986,6 +993,44 @@ get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab)
|
||||
return shstrtab->d_buf + shdr->sh_name;
|
||||
}
|
||||
|
||||
+/* Returns the signature of a group section, or NULL if the given
|
||||
+ section isn't a group. */
|
||||
+static const char *
|
||||
+get_group_sig (Elf *elf, GElf_Shdr *shdr)
|
||||
+{
|
||||
+ if (shdr->sh_type != SHT_GROUP)
|
||||
+ return NULL;
|
||||
+
|
||||
+ Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link);
|
||||
+ if (symscn == NULL)
|
||||
+ error (EXIT_FAILURE, 0, _("bad sh_link for group section: %s"),
|
||||
+ elf_errmsg (-1));
|
||||
+
|
||||
+ GElf_Shdr symshdr_mem;
|
||||
+ GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
|
||||
+ if (symshdr == NULL)
|
||||
+ error (EXIT_FAILURE, 0, _("couldn't get shdr for group section: %s"),
|
||||
+ elf_errmsg (-1));
|
||||
+
|
||||
+ Elf_Data *symdata = elf_getdata (symscn, NULL);
|
||||
+ if (symdata == NULL)
|
||||
+ error (EXIT_FAILURE, 0, _("bad data for group symbol section: %s"),
|
||||
+ elf_errmsg (-1));
|
||||
+
|
||||
+ GElf_Sym sym_mem;
|
||||
+ GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
|
||||
+ if (sym == NULL)
|
||||
+ error (EXIT_FAILURE, 0, _("couldn't get symbol for group section: %s"),
|
||||
+ elf_errmsg (-1));
|
||||
+
|
||||
+ const char *sig = elf_strptr (elf, symshdr->sh_link, sym->st_name);
|
||||
+ if (sig == NULL)
|
||||
+ error (EXIT_FAILURE, 0, _("bad symbol name for group section: %s"),
|
||||
+ elf_errmsg (-1));
|
||||
+
|
||||
+ return sig;
|
||||
+}
|
||||
+
|
||||
/* Fix things up when prelink has moved some allocated sections around
|
||||
and the debuginfo file's section headers no longer match up.
|
||||
This fills in SECTIONS[0..NALLOC-1].outscn or exits.
|
||||
@@ -1111,6 +1156,7 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
|
||||
sec->scn = elf_getscn (main, i + 1); /* Really just for ndx. */
|
||||
sec->outscn = NULL;
|
||||
sec->strent = NULL;
|
||||
+ sec->sig = get_group_sig (main, &sec->shdr);
|
||||
++undo_nalloc;
|
||||
}
|
||||
}
|
||||
@@ -1336,6 +1382,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
|
||||
sections[i].scn = scn;
|
||||
sections[i].outscn = NULL;
|
||||
sections[i].strent = NULL;
|
||||
+ sections[i].sig = get_group_sig (stripped, shdr);
|
||||
}
|
||||
|
||||
const struct section *stripped_symtab = NULL;
|
||||
@@ -1354,7 +1401,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
|
||||
|
||||
/* Locate a matching unallocated section in SECTIONS. */
|
||||
inline struct section *find_unalloc_section (const GElf_Shdr *shdr,
|
||||
- const char *name)
|
||||
+ const char *name,
|
||||
+ const char *sig)
|
||||
{
|
||||
size_t l = nalloc, u = stripped_shnum - 1;
|
||||
while (l < u)
|
||||
@@ -1362,7 +1410,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
|
||||
size_t i = (l + u) / 2;
|
||||
struct section *sec = §ions[i];
|
||||
int cmp = compare_unalloc_sections (shdr, &sec->shdr,
|
||||
- name, sec->name);
|
||||
+ name, sec->name,
|
||||
+ sig, sec->sig);
|
||||
if (cmp < 0)
|
||||
u = i;
|
||||
else if (cmp > 0)
|
||||
@@ -1435,7 +1484,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
|
||||
else
|
||||
{
|
||||
/* Look for the section that matches. */
|
||||
- sec = find_unalloc_section (shdr, name);
|
||||
+ sec = find_unalloc_section (shdr, name,
|
||||
+ get_group_sig (unstripped, shdr));
|
||||
if (sec == NULL)
|
||||
{
|
||||
/* An additional unallocated section is fine if not SHT_NOBITS.
|
@ -1,7 +1,7 @@
|
||||
Name: elfutils
|
||||
Summary: A collection of utilities and DSOs to handle ELF files and DWARF data
|
||||
Version: 0.174
|
||||
%global baserelease 1
|
||||
%global baserelease 2
|
||||
URL: http://elfutils.org/
|
||||
%global source_url ftp://sourceware.org/pub/elfutils/%{version}/
|
||||
License: GPLv3+ and (GPLv2+ or LGPLv3+)
|
||||
@ -21,6 +21,7 @@ Source: %{?source_url}%{name}-%{version}.tar.bz2
|
||||
|
||||
# Patches
|
||||
Patch1: elfutils-0.173-new-notes-hack.patch
|
||||
Patch2: elfutils-0.174-strip-unstrip-group.patch
|
||||
|
||||
Requires: elfutils-libelf%{depsuffix} = %{version}-%{release}
|
||||
Requires: elfutils-libs%{depsuffix} = %{version}-%{release}
|
||||
@ -190,6 +191,7 @@ profiling) of processes.
|
||||
|
||||
# Apply patches
|
||||
%patch1 -p1 -b .notes_hack
|
||||
%patch2 -p1 -b .strip_unstrip_group
|
||||
|
||||
# In case the above patches added any new test scripts, make sure they
|
||||
# are executable.
|
||||
@ -322,6 +324,9 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Oct 17 2018 Mark Wielaard <mjw@fedoraproject.org> - 0.174-2
|
||||
- Add elfutils-0.174-strip-unstrip-group.patch.
|
||||
|
||||
* Fri Sep 14 2018 Mark Wielaard <mjw@fedoraproject.org> - 0.174-1
|
||||
- New upstream release
|
||||
- libelf, libdw and all tools now handle extended shnum and shstrndx
|
||||
|
Loading…
Reference in New Issue
Block a user