The elfutils webpage says:
"To report bugs: please open a bugzilla report against the elfutils
However it seems the redhat bugzilla doesn't have an elfutils
component. Therefore I'm reporting it here, hope that's okay.
The attached file will cause a huge malloc allocation with elfutils' nm
tool. This will crash if you try to run it with address sanitizer.
The reason is likely that nm will try to allocate space for something
based on the header value - no matter if that value makes any sense. A
sanity check that checks in such cases if the file itself is smaller
than the supposedly allocated memory could avoid that.
Address Sanitizer trace:
==29915==ERROR: AddressSanitizer failed to allocate 0xb18002000
(47647301632) bytes of LargeMmapAllocator: 12
"(("unable to mmap" && 0)) != (0)" (0x0, 0x0) #0 0x7f1a5001df90
0x7f1a500221f3 in __sanitizer::CheckFailed(char const*, int, char
const*, unsigned long long, unsigned long long)
0x7f1a5001868f in malloc
0x41a421 in xmalloc /f/elfutils/elfutils-0.163/lib/xmalloc.c:52 #6
0x4089a4 in show_symbols /f/elfutils/elfutils-0.163/src/nm.c:1212 #7
0x40ce47 in handle_elf /f/elfutils/elfutils-0.163/src/nm.c:1484 #8
0x4033a6 in process_file /f/elfutils/elfutils-0.163/src/nm.c:387 #9
0x4033a6 in main /f/elfutils/elfutils-0.163/src/nm.c:248 #10
0x7f1a4f2cef9f in __libc_start_main (/lib64/libc.so.6+0x1ff9f) #11
I am adding full DWARF unwinding-based backtrace support to the Glasgow
Haskell Compiler's (GHC) runtime system. GHC now emits DWARF information
in the object files it produces  and we would like to be able to
record full backtraces on both runtime system events and the user's
The goal here is to expose a function to the runtime system and user
programs allowing them to get a snapshot of the calling thread's current
call-stack. It seems that elfutils' current dwfl interfaces only allow
for extraction of frames from Core dumps (with dwfl_core_file_attach)
and ptrace'd processes (with dwfl_linux_proc_attach).
In principle, however, I can't see any reason why frames couldn't be
extracted from the current thread. Besides taking care to preserve the
registers at the out-set, it doesn't even seem that this should be
terribly difficult. Am I missing something? Does the interface for this
exist and I have simply overlooked it? Does it not yet exist but is
merely waiting for someone to implement it?
gnuld has a really bad bug where it can place a NOBITS section inside
a PT_LOAD segment. Normally that would not work. But it also makes sure
that the contents of the file is all zeros. So in practice it is actually
a PROGBITS section with all zero data. Except that other tools will think
there is an unused gap in the ELF file after the NOBITS section.
Recognize and check this pattern in elflint when --gnu is given.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
src/ChangeLog | 5 +++++
src/elflint.c | 34 ++++++++++++++++++++++++++++++++--
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index a0c32fa..5be1075 100644
@@ -1,3 +1,8 @@
+2015-08-11 Mark Wielaard <mjw(a)redhat.com>
+ * elflint.c (check_sections): When gnuld and a NOBITS section falls
+ inside a segment make sure any ELF file contents is zero.
2015-07-29 Mark Wielaard <mjw(a)redhat.com>
* unstrip.c (sections_flags_match): New function.
diff --git a/src/elflint.c b/src/elflint.c
index a916886..0d5f34d 100644
@@ -3978,9 +3978,39 @@ section [%2zu] '%s' not fully contained in segment of program header entry %d\n"
if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz
- ERROR (gettext ("\
+ if (!gnuld)
+ ERROR (gettext ("\
section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"),
- cnt, section_name (ebl, cnt), pcnt);
+ cnt, section_name (ebl, cnt), pcnt);
+ /* This is truly horrible. GNU ld might put a
+ NOBITS section in the middle of a PT_LOAD
+ segment, assuming the next gap in the file
+ actually consists of zero bits...
+ So it really is like a PROGBITS section
+ where the data is all zeros. Check those
+ zero bytes are really there. */
+ bool bad;
+ Elf_Data *databits;
+ databits = elf_getdata_rawchunk (ebl->elf,
+ bad = (databits == NULL
+ || databits->d_size != shdr->sh_size);
+ for (size_t idx = 0;
+ idx < databits->d_size && ! bad;
+ bad = ((char *) databits->d_buf)[idx] != 0;
+ if (bad)
+ ERROR (gettext ("\
+section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d and file contents is non-zero\n"),
+ cnt, section_name (ebl, cnt), pcnt);
This was an issue that came up with libabigail which uses the
Dwfl_Callbacks debuginfo_path when Dwarf has been split off into
separate debuginfo and the binary root and the debuginfo root
are different. That setup makes sense in general when inspecting
binaries/debuginfo not normally installed and/or comes from a different
distro/installation originally. In that case build-id searches might
fail and you fall back on the debuginfo path search.
The issue is that the standard dwfl debuginfo patch search doesn't
cope with separate roots/subpaths for the binaries and debug files.
It expects them to line up exactly the same.
The solution Dodji came up with is to not just search the exact
absolute binary path under the debuginfo path, but also the sub-subdirs
of the binary path. That makes sense to me. It is essentially a
simple/more flexible way of supporting chroots when the bin dir and debug
dir are using separate chroots. An alternative would be to add full
support for chroots. But that seemed a lot more work than simply making
the default debuginfo path search more flexible.
I changed the implementation slightly from what Dodji suggested
(it now only searches real sub-subdirs by using / as separator instead
of using all full subpath prefixes) and added some documentation
to explain what is going on. Dodji could you check if the changes
still make sense to you?
I also added a testcase that uses eu-addr2line --debuginfo-path
in a similar situation as what libabigail is using.
[PATCH 1/2] Fix finding split debug info files not located by the
[PATCH 2/2] tests: Add a testcase for dwfl debuginfo-path with