From c59734bbefbbc3c78d3da6dcb4f0d23f0cd62339 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Oct 17 2018 14:25:57 +0000 Subject: Add elfutils-0.174-strip-unstrip-group.patch --- diff --git a/elfutils-0.174-strip-unstrip-group.patch b/elfutils-0.174-strip-unstrip-group.patch new file mode 100644 index 0000000..9fcd25c --- /dev/null +++ b/elfutils-0.174-strip-unstrip-group.patch @@ -0,0 +1,189 @@ +commit c06ab0bbb4761a69d2f188675d21d1a9131e9ecb +Author: Mark Wielaard +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 + +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. diff --git a/elfutils.spec b/elfutils.spec index 64c8bd3..f31fe7d 100644 --- a/elfutils.spec +++ b/elfutils.spec @@ -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 - 0.174-2 +- Add elfutils-0.174-strip-unstrip-group.patch. + * Fri Sep 14 2018 Mark Wielaard - 0.174-1 - New upstream release - libelf, libdw and all tools now handle extended shnum and shstrndx