Hi, While coming up with a test case for rhbz#807823 "elflint doesn't recognize SHF_INFO_LINK on relocation sections", I came across another issue. Not just with elflint, but also with readelf -d. If there is a SHT_NOBITS section before the .dynamic section then gelf_offscn will miss it. The solution is similar to commit e9c4e8 (Do not match empty sections at OFFSET), skip SHT_NOBITS sections too if there is a "real" section at the same offset that does have content. Does the solution look sane?
The test binary is a testcase for both this issue and the original rhbz#807823. Both tests fail before and succeed after the fixes. Patch attached and in git on the mjw/offscn_nobits branch for those that want to check out the test binary. Cheers, Mark
commit 191d1f0b9163593eee8c4f5cbe3e95cabf6ae9a9 Author: Mark Wielaard <[email protected]> Date: Mon Apr 2 17:11:25 2012 +0200 elf32_offscn.c: Do not match SHT_NOBITS sections at OFFSET. readelf -d doesn't work if a SHT_NOBITS section is right before the actual .dynamic section at the same offset. elflint also fails on such binaries. So skip SHT_NOBITS sections at the same offset in [g]elf[32|64]_offscn(). diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 19b76e8..89dd35f 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2012-04-02 Mark Wielaard <[email protected]> + + * elf32_offscn.c: Do not match SHT_NOBITS sections at OFFSET unless + there are no nonempty sections at that offset. + 2012-03-21 Roland McGrath <[email protected]> * elf-knowledge.h (SECTION_STRIP_P): Remove < SHT_NUM check. diff --git a/libelf/elf32_offscn.c b/libelf/elf32_offscn.c index 86eff8b..5dcfc4a 100644 --- a/libelf/elf32_offscn.c +++ b/libelf/elf32_offscn.c @@ -101,7 +101,8 @@ elfw2(LIBELFBITS,offscn) (elf, offset) /* If this section is empty, the following one has the same sh_offset. We presume the caller is looking for a nonempty section, so keep looking if this one is empty. */ - if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0) + if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0 + && runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_type != SHT_NOBITS) goto out; } diff --git a/tests/ChangeLog b/tests/ChangeLog index 8d2b83f..6f6c592 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,10 @@ +2012-04-02 Mark Wielaard <[email protected]> + + * Makefile.am (TESTS): Add run-readelf-d.sh. + (EXTRA_DIST): Add testlib_dynseg.so.bz2 and run-readelf-d.sh. + * run-readelf-d.sh: New test. + * run-elflint-test.sh: Check new testfile. + 2012-03-21 Tom Tromey <[email protected]> * typeiter.c: New file. diff --git a/tests/Makefile.am b/tests/Makefile.am index f2c211b..980aa12 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -86,7 +86,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-disasm-x86.sh run-disasm-x86-64.sh \ run-early-offscn.sh run-dwarf-getmacros.sh \ run-test-flag-nobits.sh run-prelink-addr-test.sh \ - run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh + run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh \ + run-readelf-d.sh # run-show-ciefde.sh if !STANDALONE @@ -162,7 +163,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ testfile55-32.prelink.bz2 testfile55-64.bz2 \ testfile55-64.debug.bz2 testfile55-64.prelink.bz2 \ testfile56.bz2 testfile57.bz2 testfile58.bz2 \ - run-typeiter.sh testfile59.bz2 + run-typeiter.sh testfile59.bz2 \ + run-readelf-d.sh testlib_dynseg.so.bz2 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \ bindir=$(DESTDIR)$(bindir) \ diff --git a/tests/run-elflint-test.sh b/tests/run-elflint-test.sh index e0e1c54..0c872fe 100755 --- a/tests/run-elflint-test.sh +++ b/tests/run-elflint-test.sh @@ -44,4 +44,8 @@ testrun ../src/elflint -q --gnu-ld testfile42 testfiles testfile46 testrun ../src/elflint -q testfile46 +# see also run-readelf-d.sh +testfiles testlib_dynseg.so +testrun ../src/elflint -q --gnu-ld testlib_dynseg.so + exit 0 diff --git a/tests/run-readelf-d.sh b/tests/run-readelf-d.sh new file mode 100755 index 0000000..9022e70 --- /dev/null +++ b/tests/run-readelf-d.sh @@ -0,0 +1,78 @@ +#! /bin/sh +# Copyright (C) 2012 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# Red Hat elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# <http://www.openinventionnetwork.com>. + +. $srcdir/test-subr.sh + +# #include <stdio.h> +# +# __thread int i; +# +# void print_i () +# { +# printf("%d\n", i); +# } +# +# gcc -fPIC -shared -o testlib_dynseg.so testlib_dynseg.c +# With ld --version +# GNU gold (GNU Binutils 2.22.52.20120402) 1.11 + +testfiles testlib_dynseg.so + +testrun_compare ../src/readelf -d testlib_dynseg.so <<\EOF + +Dynamic segment contains 28 entries: + Addr: 0x00000000000017e0 Offset: 0x0007e0 Link to section: [ 3] '.dynstr' + Type Value + PLTGOT 0x00000000000019c8 + PLTRELSZ 72 (bytes) + JMPREL 0x0000000000000568 + PLTREL RELA + RELA 0x00000000000004d8 + RELASZ 144 (bytes) + RELAENT 24 (bytes) + RELACOUNT 1 + SYMTAB 0x0000000000000228 + SYMENT 24 (bytes) + STRTAB 0x0000000000000360 + STRSZ 190 (bytes) + GNU_HASH 0x0000000000000420 + NEEDED Shared library: [libc.so.6] + NEEDED Shared library: [ld-linux-x86-64.so.2] + INIT 0x00000000000005b0 + FINI 0x0000000000000748 + VERSYM 0x0000000000000460 + VERDEF 0x000000000000047c + VERDEFNUM 1 + VERNEED 0x0000000000000498 + VERNEEDNUM 2 + NULL + NULL + NULL + NULL + NULL + NULL +EOF + +exit 0 diff --git a/tests/testlib_dynseg.so.bz2 b/tests/testlib_dynseg.so.bz2 new file mode 100755 index 0000000..94296a4 Binary files /dev/null and b/tests/testlib_dynseg.so.bz2 differ
_______________________________________________ elfutils-devel mailing list [email protected] https://fedorahosted.org/mailman/listinfo/elfutils-devel
