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 <mjw@redhat.com>
This commit is contained in:
Mark Wielaard
2015-07-29 17:51:27 +02:00
parent 3496992ae6
commit f9fc50c3ec
8 changed files with 71 additions and 7 deletions
+9
View File
@@ -1,3 +1,12 @@
2015-07-29 Mark Wielaard <mjw@redhat.com>
* unstrip.c (sections_flags_match): New function.
(sections_match): Use sections_flags_match.
(find_alloc_sections_prelink): Only clear matched sections if there
is an undo section.
(copy_elided_sections): Add SHF_INFO_LINK to shdr_mem.sh_flags if
necessary.
2015-06-27 Pino Toscano <toscano.pino@tiscali.it>
* src/strings.c: Define MAP_POPULATE if not defined already.
+29 -5
View File
@@ -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 (&sections[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)
+10
View File
@@ -1,3 +1,13 @@
2015-07-29 Mark Wielaard <mjw@redhat.com>
* run-unstrip-test3.sh: New test.
* testfile-info-link.bz2: New file.
* testfile-info-link.debuginfo.bz2: Likewise.
* testfile-info-link.stripped.bz2: Likewise.
* Makefile.am (TESTS): Add run-unstrip-test3.sh.
(EXTRA_DIST): Add run-unstrip-test3.sh, testfile-info-link.bz2,
testfile-info-link.debuginfo.bz2, testfile-info-link.stripped.bz2.
2015-06-27 Pino Toscano <toscano.pino@tiscali.it>
* tests/run-deleted.sh: Skip when detecting a not implemented
+6 -2
View File
@@ -78,7 +78,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
run-strip-test6.sh run-strip-test7.sh run-strip-test8.sh \
run-strip-test9.sh run-strip-test10.sh \
run-strip-groups.sh run-strip-reloc.sh \
run-unstrip-test.sh run-unstrip-test2.sh run-unstrip-M.sh \
run-unstrip-test.sh run-unstrip-test2.sh \
run-unstrip-test3.sh run-unstrip-M.sh \
run-ecp-test.sh run-ecp-test2.sh run-alldts.sh \
run-elflint-test.sh run-elflint-self.sh run-ranlib-test.sh \
run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \
@@ -161,7 +162,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-strip-test9.sh run-strip-test10.sh \
run-strip-reloc.sh hello_i386.ko.bz2 hello_x86_64.ko.bz2 \
hello_ppc64.ko.bz2 hello_s390.ko.bz2 hello_aarch64.ko.bz2 \
run-unstrip-test.sh run-unstrip-test2.sh run-unstrip-M.sh\
run-unstrip-test.sh run-unstrip-test2.sh \
testfile-info-link.bz2 testfile-info-link.debuginfo.bz2 \
testfile-info-link.stripped.bz2 run-unstrip-test3.sh \
run-unstrip-M.sh \
run-elflint-self.sh run-ranlib-test.sh run-ranlib-test2.sh \
run-ranlib-test3.sh run-ranlib-test4.sh \
run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \
+17
View File
@@ -0,0 +1,17 @@
# Buggy binutils objdump might strip SHF_INFO_LINK from relocation sections.
# With gcc5 we might have a .rela.plt section with that flag set.
#
# int main()
# {
# return 0;
# }
#
# gcc -o testfile-info-link -g testprog.c
# objcopy --only-keep-debug testfile-info-link testfile-info-link.debuginfo
# eu-strip --strip-debug -o testfile-info-link.stripped testfile-info-link
original=testfile-info-link
stripped=testfile-info-link.stripped
debugfile=testfile-info-link.debuginfo
. $srcdir/run-unstrip-test.sh
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.