From 73d5406ef38417bb9abf44de52b89a35ea4f9205 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Aug 03 2015 12:02:25 +0000 Subject: Add elfutils-0.163-unstrip-shf_info_link.patch --- diff --git a/elfutils-0.163-unstrip-shf_info_link.patch b/elfutils-0.163-unstrip-shf_info_link.patch new file mode 100644 index 0000000..e3a27ff --- /dev/null +++ b/elfutils-0.163-unstrip-shf_info_link.patch @@ -0,0 +1,91 @@ +commit f9fc50c3eced243c0648fb0fbfe2c9877c25e1e4 +Author: Mark Wielaard +Date: Wed Jul 29 17:51:27 2015 +0200 + + unstrip: Handle debuginfo files with missing SHF_INFO_LINK section flags. + + With GCC 5 there might be a .rela.plt section with SHF_INFO_LINK set. + Buggy binutils objdump might strip it from the section in the debug file. + Ignore such differences for relocation sections and put the flag back + if necessary. + + Also improve the error message a little by only discarding the already + matched sections if there is an prelink undo section. Otherwise we will + report all sections as not matching if the file wasn't prelinked instead + of just the non-matching sections. + + New testfiles generated by gcc5 and binutils objdump added. + + Signed-off-by: Mark Wielaard + +diff --git a/src/unstrip.c b/src/unstrip.c +index 4a8e5fa..8833094 100644 +--- a/src/unstrip.c ++++ b/src/unstrip.c +@@ -867,12 +867,28 @@ compare_symbols_output (const void *a, const void *b) + + #undef CMP + ++/* Return true if the flags of the sections match, ignoring the SHF_INFO_LINK ++ flag if the section contains relocation information. */ ++static bool ++sections_flags_match (Elf64_Xword sh_flags1, Elf64_Xword sh_flags2, ++ Elf64_Word sh_type) ++{ ++ if (sh_type == SHT_REL || sh_type == SHT_RELA) ++ { ++ sh_flags1 &= ~SHF_INFO_LINK; ++ sh_flags2 &= ~SHF_INFO_LINK; ++ } ++ ++ return sh_flags1 == sh_flags2; ++} ++ + /* Return true iff the flags, size, and name match. */ + static bool + sections_match (const struct section *sections, size_t i, + const GElf_Shdr *shdr, const char *name) + { +- return (sections[i].shdr.sh_flags == shdr->sh_flags ++ return (sections_flags_match (sections[i].shdr.sh_flags, shdr->sh_flags, ++ sections[i].shdr.sh_type) + && (sections[i].shdr.sh_size == shdr->sh_size + || (sections[i].shdr.sh_size < shdr->sh_size + && section_can_shrink (§ions[i].shdr))) +@@ -930,10 +946,6 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, + struct section *sections, + size_t nalloc, size_t nsections) + { +- /* Clear assignments that might have been bogus. */ +- for (size_t i = 0; i < nalloc; ++i) +- sections[i].outscn = NULL; +- + Elf_Scn *undo = NULL; + for (size_t i = nalloc; i < nsections; ++i) + { +@@ -952,6 +964,10 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab, + size_t undo_nalloc = 0; + if (undo != NULL) + { ++ /* Clear assignments that might have been bogus. */ ++ for (size_t i = 0; i < nalloc; ++i) ++ sections[i].outscn = NULL; ++ + Elf_Data *undodata = elf_rawdata (undo, NULL); + ELF_CHECK (undodata != NULL, + _("cannot read '.gnu.prelink_undo' section: %s")); +@@ -1500,6 +1516,14 @@ more sections in stripped file than debug file -- arguments reversed?")); + shdr_mem.sh_size = sec->shdr.sh_size; + shdr_mem.sh_info = sec->shdr.sh_info; + shdr_mem.sh_link = sec->shdr.sh_link; ++ ++ /* Buggy binutils objdump might have stripped the SHF_INFO_LINK ++ put it back if necessary. */ ++ if ((sec->shdr.sh_type == SHT_REL || sec->shdr.sh_type == SHT_RELA) ++ && sec->shdr.sh_flags != shdr_mem.sh_flags ++ && (sec->shdr.sh_flags & SHF_INFO_LINK) != 0) ++ shdr_mem.sh_flags |= SHF_INFO_LINK; ++ + if (sec->shdr.sh_link != SHN_UNDEF) + shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1]; + if (shdr_mem.sh_flags & SHF_INFO_LINK)