platform/upstream/elfutils.git
5 years agostrip: Split out debug section relocation into separate helper functions.
Mark Wielaard [Thu, 25 Oct 2018 11:30:19 +0000 (13:30 +0200)]
strip: Split out debug section relocation into separate helper functions.

Extract a couple of helper functions out of handle_elf (secndx_name,
get_xndxdata and remove_debug_relocations) so they can be reused more
easily in the future.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agostrip: Always copy over any phdrs if there are any.
Mark Wielaard [Thu, 25 Oct 2018 10:37:04 +0000 (12:37 +0200)]
strip: Always copy over any phdrs if there are any.

Ignore the type of ELF file, just copy over any phdrs if the original
file contained any. Also refuse to move around any allocated sections
based on whether there are any phdrs instead of on ELF file type.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agounstrip: Add ELF_CHECK to make sure gelf_getehdr () doesn't return NULL.
Mark Wielaard [Fri, 2 Nov 2018 22:17:05 +0000 (23:17 +0100)]
unstrip: Add ELF_CHECK to make sure gelf_getehdr () doesn't return NULL.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoRecognize and parse GNU Property notes.
Mark Wielaard [Mon, 15 Oct 2018 21:35:47 +0000 (23:35 +0200)]
Recognize and parse GNU Property notes.

GNU Property notes are different from normal notes because they use
variable alignment/padding of their fields. They are 8 byte aligned,
but use 4 byte fields. The name is aligned at 4 bytes and padded so
that, the desc is aligned at 8 bytes. The whole note is padded to
8 bytes again. For normal notes all fields are both 4 bytes wide and
4 bytes aligned.

To recognize these new kind of ELF Notes a new Elf_Type is introduced,
ELF_T_NHDR8. This type is used in the xlate functions to determine
how to align and pad the various fields. Since the fields themselves
can now have different alignments we will have to keep track of the
current alignement and use either NOTE_ALIGN4 or NOTE_ALIGN8 to
determine the padding.

To set the correct Elf_Type on the Elf_Data we use either the section
sh_addralign or the segment p_align values. Assuming 8 means the
section or segment contains the new style notes, otherwise normal
notes.

When we cannot determine the "alignment" directly, like when parsing
special kernel sys files, we check the name "GNU" and type
"GNU_PROPERTY_TYPE_0" fields.

ebl_object_note now parses the new NT_GNU_PROPERTY_TYPE_0 and can
extract the GNU_PROPERTY_STACK_SIZE, GNU_PROPERTY_NO_COPY_ON_PROTECTED
and GNU_PROPERTY_X86_FEATURE_1_AND types GNU_PROPERTY_X86_FEATURE_1_IBT
and GNU_PROPERTY_X86_FEATURE_1_SHSTK.

Tests are added for extracting the note from sections or segments
as set by gcc -fcf-protection.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoaddr2line: Use elf_getshdrstrndx not Ehdr field to print section name.
Mark Wielaard [Wed, 24 Oct 2018 14:15:04 +0000 (16:15 +0200)]
addr2line: Use elf_getshdrstrndx not Ehdr field to print section name.

Using the Ehdr field directly doesn't work when there are a large number
of sections.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoreadelf: Use shstrndx to lookup section names.
Mark Wielaard [Wed, 24 Oct 2018 13:59:32 +0000 (15:59 +0200)]
readelf: Use shstrndx to lookup section names.

The function section_name would use the Ehdr e_shstrndx field to find the
index of the section index string table directly. But it should use
elf_getshdrstrndx. Adjust all callers.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agobackends: ppc use define instead of const for size of dwarf_regs array.
Mark Wielaard [Sat, 20 Oct 2018 11:20:30 +0000 (13:20 +0200)]
backends: ppc use define instead of const for size of dwarf_regs array.

The size of the dwarf_regs is a constant, but when building without
optimizations the compiler doesn't see that and will warn that it
cannot proof the stack size is bounded. Use a define instead of a
const, so the compiler will use a constant expression everywhere.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoreadelf: Make sure readp is smaller than cieend in print_debug_frame_section.
Mark Wielaard [Tue, 16 Oct 2018 12:22:33 +0000 (14:22 +0200)]
readelf: Make sure readp is smaller than cieend in print_debug_frame_section.

We could end up with a negative length in a call to memchr.

https://sourceware.org/bugzilla/show_bug.cgi?id=23782

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoreadelf: Make sure readp is smaller than cieend in print_debug_frame_section.
Mark Wielaard [Tue, 16 Oct 2018 12:22:33 +0000 (14:22 +0200)]
readelf: Make sure readp is smaller than cieend in print_debug_frame_section.

We could end up with a negative length in a call to memchr.

https://sourceware.org/bugzilla/show_bug.cgi?id=23782

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoCheck sh_entsize is not zero.
Mark Wielaard [Fri, 19 Oct 2018 13:01:29 +0000 (15:01 +0200)]
Check sh_entsize is not zero.

There were some recent bug reports where we trusted the ELF section header
to be sane and divided the sh_size by the sh_entsize to get the number of
objects in the section. This would cause a divide by zero if the file was
corrupt and the sh_entsize was zero. Add checks for any such code.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agosize: Handle recursive ELF ar files.
Mark Wielaard [Thu, 18 Oct 2018 21:15:48 +0000 (23:15 +0200)]
size: Handle recursive ELF ar files.

eu-size didn't handle an ELF ar file that contained an ar file itself
correctly. handle_ar would recursively call itself but close the ELF
file before returning. Only close the ELF file at the top-level.

https://sourceware.org/bugzilla/show_bug.cgi?id=23787

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoarlib: Check that sh_entsize isn't zero.
Mark Wielaard [Thu, 18 Oct 2018 17:01:52 +0000 (19:01 +0200)]
arlib: Check that sh_entsize isn't zero.

A bogus ELF file could have sh_entsize as zero. Don't divide by zero,
but just assume there are no symbols in the section.

https://sourceware.org/bugzilla/show_bug.cgi?id=23786

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoar: Assume epoch if ar_date is bogus.
Mark Wielaard [Sun, 14 Oct 2018 15:29:51 +0000 (17:29 +0200)]
ar: Assume epoch if ar_date is bogus.

If the ar header contains a bogus ar_date then in verbose mode we would
get a NULL pointer from localtime. Just assume the entry was created
during the epoch.

https://sourceware.org/bugzilla/show_bug.cgi?id=23754

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agofindtextrel: Check that sh_entsize isn't zero.
Mark Wielaard [Sun, 14 Oct 2018 14:58:51 +0000 (16:58 +0200)]
findtextrel: Check that sh_entsize isn't zero.

A bogus ELF file could have sh_entsize as zero. Don't divide by zero,
but just assume there are no entries in the section.

https://sourceware.org/bugzilla/show_bug.cgi?id=23755

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibdwfl: Sanity check partial core file data reads.
Mark Wielaard [Sun, 14 Oct 2018 14:45:48 +0000 (16:45 +0200)]
libdwfl: Sanity check partial core file data reads.

There were two issues when reading note data from a core file.
We didn't check if the data we already had in a buffer was big
enough. And if we did get the data, we should check if we got
everything, or just a part of the data.

https://sourceware.org/bugzilla/show_bug.cgi?id=23752

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoreadelf: Handle multiple .debug_macro sections and decode header flag.
Mark Wielaard [Sat, 13 Oct 2018 13:08:16 +0000 (15:08 +0200)]
readelf: Handle multiple .debug_macro sections and decode header flag.

In object files there could be multiple .debug_macro sections.
These are COMDAT sections used as imports. Note that the output for
DW_MACRO_import isn't ideal since the offset is printed against the
start of the .debug_macro section, but it doesn't show which one.
We currently don't have that information and no interface yet for
libdw users.

Also decode the macro header flag byte for convenience.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agounstrip: Renumber the group section indexes.
Mark Wielaard [Sat, 13 Oct 2018 08:27:47 +0000 (10:27 +0200)]
unstrip: Renumber the group section indexes.

When unstripping we might need to renumber the group section indexes.
Just like we do when stripping.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agostrip, unstrip: Handle SHT_GROUP correctly.
Mark Wielaard [Sat, 13 Oct 2018 08:27:47 +0000 (10:27 +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 <mark@klomp.org>
5 years agoHandle ADD/SUB relocations
Andreas Schwab [Tue, 2 Oct 2018 12:46:51 +0000 (14:46 +0200)]
Handle ADD/SUB relocations

This adds support for ADD and SUB relocations as seen on RISC-V.

Signed-off-by: Andreas Schwab <schwab@suse.de>
5 years agotests: backtrace-dwarf.c improve error handling in test framework.
Mark Wielaard [Fri, 21 Sep 2018 11:47:45 +0000 (13:47 +0200)]
tests: backtrace-dwarf.c improve error handling in test framework.

To debug https://sourceware.org/bugzilla/show_bug.cgi?id=23673
clean up the test framework so we know what exactly failed.

Suggested-by: Dmitry V. Levin <ldv@sourceware.org>
Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoPrepare for 0.174 elfutils-0.174
Mark Wielaard [Fri, 14 Sep 2018 10:08:15 +0000 (12:08 +0200)]
Prepare for 0.174

Set version to 0.174.
Mention new functionality in NEWS.
Update po/*.po files.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibdwfl: Document core memory and remote memory ELF shdrs reading.
Mark Wielaard [Sat, 4 Aug 2018 20:36:48 +0000 (22:36 +0200)]
libdwfl: Document core memory and remote memory ELF shdrs reading.

There are two places, dwfl_segment_report_module and elf_from_remote_memory
in libdwfl where we use the Ehdr e_shnum directly. Document why this is fine.
Getting the shdrs in those two places is really just a nice bonus and if there
are more than 0xff00 then it is unlikely we will get them all anyway.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoreadelf: Use elf_getshdrnum in print_shdr and print_phdr.
Mark Wielaard [Sat, 4 Aug 2018 20:30:15 +0000 (22:30 +0200)]
readelf: Use elf_getshdrnum in print_shdr and print_phdr.

print_shdr didn't print the correct number of sections if there were
more than SHN_LORESERVE sections. print_phdr wouldn't match up the
(allocated) sections and segements if there were more than SHN_LORESERVE
sections in the ELF file.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agostrip,unstrip: Use and set shdrstrndx consistently.
Mark Wielaard [Sat, 4 Aug 2018 18:29:25 +0000 (20:29 +0200)]
strip,unstrip: Use and set shdrstrndx consistently.

In various places in strip we used e_shstrndx instead of shdrstrndx and we
didn't setup the shdrstrndx for the debug file. In unstrip we forgot to copy
the shdrstrndx in case the -o output option was used.

Added a new testcase that adds many sections to a testfile and runs strip, elflint,
unstrip and elfcmp.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibdw: dwarf_begin_elf should use elf_getshdrstrndx to get section names.
Mark Wielaard [Sat, 4 Aug 2018 20:34:32 +0000 (22:34 +0200)]
libdw: dwarf_begin_elf should use elf_getshdrstrndx to get section names.

dwarf_begin_elf used the Ehdr e_shstrndx to get the shdr string table
section. This does not work for ELF files with more than SHN_LORESERVE
sections. Use elf_getshdrstrndx, and don't pass around the ehdr.

Add a simple testcase that fails before the patch because dwarf_begin
return an error.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoelflint: Use shnum and shstrndx instead of ehdr field directly.
Mark Wielaard [Wed, 12 Sep 2018 21:38:47 +0000 (23:38 +0200)]
elflint: Use shnum and shstrndx instead of ehdr field directly.

We already got the right shnum and shstrndx. But were still using
e_shnum in one check for ELFCLASS64 (it was correct for ELFCLASS32).
And when getting section names in check_symtab we still used
e_shstrndx in two places.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibelf: Fix shnum and section zero handling.
Mark Wielaard [Wed, 12 Sep 2018 21:38:28 +0000 (23:38 +0200)]
libelf: Fix shnum and section zero handling.

For ELF files with more than SHN_LOWRESERVE sections we always need
section zero to store the section number (it doesn't just fit in the
Ehdr e_shnum field). Make sure to create it if it doesn't exist yet
in elf_getscn. Also fix handling on shnum in updatefile for the mmap
case (we already got this correct for the non-mmap case).

This adds a new test run-copymany-sections.sh which is like
run-copyadd-sections.sh but tries to add two times 65535 sections.
It makes sure libelf can copy the whole file and elfcmp checks they
are the same. It doesn't use mmap for addsections since that doesn't
work yet. ELF_C_RDWR_MMAP needs mremap which will fail since it needs
too much space and the original mmap cannot move.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoelfcmp: Get, check and shdrstrndx for section names.
Mark Wielaard [Thu, 13 Sep 2018 11:52:46 +0000 (13:52 +0200)]
elfcmp: Get, check and shdrstrndx for section names.

elfcmp would use the Ehdr e_shstrndx field to find the shdr string
index table. Use elf_getshdrstrndx instead to be able to handle ELF
files with more than SHN_LORESERVE sections.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibebl: Use elf_getshdrstrndx in ebl_section_strip_p.
Mark Wielaard [Wed, 1 Aug 2018 14:51:03 +0000 (16:51 +0200)]
libebl: Use elf_getshdrstrndx in ebl_section_strip_p.

The ebl_section_strip_p function used the Ehdr e_shstrndx field
to get at the name of the (debug) sections. This is not correct
if there are more than SHN_LORESERVE sections. Use elf_getshdrstrndx
to get at the shstrtab section. And drop the Ehdr argument that isn't
necessary anymore.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agobackends: Use elf_getshdrstrndx to find .odp section in ppc64_init
Mark Wielaard [Sat, 4 Aug 2018 20:32:56 +0000 (22:32 +0200)]
backends: Use elf_getshdrstrndx to find .odp section in ppc64_init

The .odp section is found by name. But ppc64_init used the e_shstrndx
Ehdr field for that. This is wrong if the file contains more than
SHN_LORESERVE sections. Use elf_getshdrstrndx instead to find the
shstrtab section.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agobackends: Always use elf_getshdrstrndx in check_special_symbol.
Mark Wielaard [Sat, 4 Aug 2018 18:36:09 +0000 (20:36 +0200)]
backends: Always use elf_getshdrstrndx in check_special_symbol.

The check_special_symbol backend functions used the Ehdr e_shstrndx
field to get at the name of sections. This is not correct if there
are more than SHN_LORESERVE sections. Always use elf_getshdrstrndx
to get the shstrtab section. And drop the Ehdr argument that isn't
necessary anymore.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibelf: Fix some issues with ELF_C_RDWR_MMAP.
Mark Wielaard [Sun, 12 Aug 2018 13:35:18 +0000 (15:35 +0200)]
libelf: Fix some issues with ELF_C_RDWR_MMAP.

When ELF_C_RDWR_MMAP is used libelf might have to write overlapping memory
when moving the section data or headers. Make sure to use memmove, not
memcpy. Also the size of the underlying file might have to change. That
means we will have to also extend the mmap region with mremap. Since we
are using direct pointers into the mmapped area we cannot move the mmap,
only extend it. This might still fail if there is not enough free memory
available to extend the mmap region.

Two new test programs have been added. elfcopy which copies a whole elf
file (using either ELF_C_WRITE or ELF_C_WRITE_MMAP). And addsections which
adds new sections to an existing ELF file (using either ELF_C_RDWR or
ELF_C_RDWR_MMAP). The newly added test will fail under valgrind without
the fixes.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agotests: Add section attribute to defeat -freorder-blocks-and-partition.
Mark Wielaard [Tue, 11 Sep 2018 10:58:14 +0000 (12:58 +0200)]
tests: Add section attribute to defeat -freorder-blocks-and-partition.

GCC could partition main into an cold and hot block causing our symbol
lookup to fail in the backtrace-dwarf testcase. Add a section attribute
on "main" so that it will be kept together.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agostrip: Handle mixed allocated/non-allocated sections.
Mark Wielaard [Sun, 29 Jul 2018 22:27:52 +0000 (00:27 +0200)]
strip: Handle mixed allocated/non-allocated sections.

Normally in non-ET_REL files all allocated sections come before
all non-allocated sections. eu-strip relies on this when stripping
a file and calculating the file offsets. But recently on Fedora
there are non-allocated .gnu.build.attributes NOTE sections in
the middle of the allocated sections, with a sh_offset field that
is larger then the next section. This confuses eu-strip so much that
it might corrupt the stripped file.

Work around this by calculating the sh_offset fields in two phases
when detecting mixed allocated/non-allocated sections. First handle
the allocated ones, then use the offset after the last allocated
section to calculate the offsets of the non-allocated sections left
in the stripped file.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibdw: Check end of attributes list consistently.
Mark Wielaard [Sat, 18 Aug 2018 17:51:27 +0000 (19:51 +0200)]
libdw: Check end of attributes list consistently.

dwarf_child (__libdw_find_attr), dwarf_getabbrevattr[_data] and
dwarf_getattrs all assume the end of the attribute list is when
both the name (code) and form of the attribute are zero.

dwarf_getabbrev (__libdw_getabbrev) and dwarf_hasattr assume the
end of the attribute list is when either the name (code) or the
form of the attribute is zero.

The DWARF spec says: "The series of attribute specifications ends
with an entry containing 0 for the name and 0 for the form." So
the first check is correct.

Make sure dwarf_getabbrev and dwarf_hasattr use the same check.
This is important since all other functions expect dwarf_getabbrev
(__libdw_getabbrev) to have done a data sanity check of the attribute.
So if the ending condition is different it could cause a crash.

https://sourceware.org/bugzilla/show_bug.cgi?id=23529

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibdw, readelf: Make sure there is enough data to read full aranges header.
Mark Wielaard [Sat, 18 Aug 2018 11:27:48 +0000 (13:27 +0200)]
libdw, readelf: Make sure there is enough data to read full aranges header.

dwarf_getaranges didn't check if there was enough data left to read both
the address and segment size. readelf didn't check there was enough data
left to read the segment size.

https://sourceware.org/bugzilla/show_bug.cgi?id=23541

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoelflint: Fix check_sysv_hash[64] sanity checks to not overflow.
Mark Wielaard [Sat, 18 Aug 2018 11:17:45 +0000 (13:17 +0200)]
elflint: Fix check_sysv_hash[64] sanity checks to not overflow.

The sanity checks for how many words were needed in the section could
overflow causing errors. Fix the checks.

https://sourceware.org/bugzilla/show_bug.cgi?id=23542

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibelf: Return error if elf_compress_gnu is used on SHF_COMPRESSED section.
Mark Wielaard [Sat, 18 Aug 2018 10:42:16 +0000 (12:42 +0200)]
libelf: Return error if elf_compress_gnu is used on SHF_COMPRESSED section.

Compressing a section that is already compressed is fine, but useless.
But it isn't possible to gnu compress (or decompress) a SHF_COMPRESSED
section since there is no state kept that would tell if the section was
first GNU compressed or first gabi compressed. Calling elf_compress_gnu
on a section and then calling elf_compress on it to decompress it twice
could cause a crash (the other way around is fine). Just disallow it.

https://sourceware.org/bugzilla/show_bug.cgi?id=23528

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agolibelf: Fix documentation of elf_getshdrstrndx and elf_getshstrndx.
Mark Wielaard [Fri, 27 Jul 2018 12:43:15 +0000 (14:43 +0200)]
libelf: Fix documentation of elf_getshdrstrndx and elf_getshstrndx.

Because of copy/paste error part of the documentation for
elf_getshdrstrndx and elf_getshstrndx was actually for
elf_getshdrnum and elf_getshnum. Fix it to refer to the proper
ehdr field and deprecated function name.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agounstrip: Also check sh_size in compare_unalloc_sections.
Mark Wielaard [Tue, 24 Jul 2018 21:34:19 +0000 (23:34 +0200)]
unstrip: Also check sh_size in compare_unalloc_sections.

compare_unalloc_sections only checked sh_flags and the section names.
This would cause stripped/debug section mismatches when there were
multiple sections with the same name and flags. Fix this by also checking
the size of the section matches.

Add a testcase that has two ".group" sections created on i386 with the
gcc annobin plugin.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agounstrip: Handle SHT_GROUP sections in ET_REL files.
Mark Wielaard [Sat, 21 Jul 2018 21:40:11 +0000 (23:40 +0200)]
unstrip: Handle SHT_GROUP sections in ET_REL files.

SHT_GROUP sections are put in both the stripped and debug file.
Handle correcting the symbol table/name entry of the group only once.

The testfile was generated with the gcc annobin plugin.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoelfcompress: Don't rewrite file if no section data needs to be updated.
Mark Wielaard [Sat, 21 Jul 2018 15:07:12 +0000 (17:07 +0200)]
elfcompress: Don't rewrite file if no section data needs to be updated.

If the input and output file are the same and no section needs to
be updated we really don't need to rewrite the file.

Check whether any matching section is already compressed or decompressed.
Skip the section if it doesn't need to be changed. If no section data
needs updating end with success without rewriting/updating file.

With --force the file will still always be updated/rewritten even if
no section data needs to be (de)compressed.

Acked-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agobackends: add abi_cfi and set_initial_registers_tid callbacks for M68K
Andreas Schwab [Sat, 21 Jul 2018 21:42:07 +0000 (23:42 +0200)]
backends: add abi_cfi and set_initial_registers_tid callbacks for M68K

This fixes all testsuite failures.

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
5 years agoelfcompress: Swap fchmod and fchown calls on new file.
Mark Wielaard [Sat, 21 Jul 2018 14:10:25 +0000 (16:10 +0200)]
elfcompress: Swap fchmod and fchown calls on new file.

Calling fchmod with a suid bit on a file might silently fail or the suid
bit might be slilently cleared by a call to fchown if already set. Swap
the calls so that the owner is set first and then set the suid bit.

https://bugzilla.redhat.com/show_bug.cgi?id=1607044

Reported-and-tested-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agotests: Add core and strip tests for RISC-V
Andreas Schwab [Thu, 19 Jul 2018 10:41:02 +0000 (12:41 +0200)]
tests: Add core and strip tests for RISC-V

Signed-off-by: Andreas Schwab <schwab@suse.de>
5 years agoFix typo in riscv_register_info
Andreas Schwab [Thu, 19 Jul 2018 09:54:59 +0000 (11:54 +0200)]
Fix typo in riscv_register_info

Signed-off-by: Andreas Schwab <schwab@suse.de>
5 years agoDon't include sys/uio.h if we don't need it
Ulf Hermann [Tue, 17 Jul 2018 11:40:26 +0000 (13:40 +0200)]
Don't include sys/uio.h if we don't need it

The PID attaching only works on linux.

5 years agobackends: add core_note callback for RISC-V
Andreas Schwab [Tue, 17 Jul 2018 11:18:32 +0000 (13:18 +0200)]
backends: add core_note callback for RISC-V

Signed-off-by: Andreas Schwab <schwab@suse.de>
5 years agoRemove previous test files before running the next round
Ulf Hermann [Mon, 16 Jul 2018 10:01:21 +0000 (12:01 +0200)]
Remove previous test files before running the next round

strip explicitly creates the new files. This will not work on windows if
the files already exist.

Also, if strip fails to create the files for any reason, we would check
the previous run's files and succeed. However, the test should fail
then.

Signed-off-by: Ulf Hermann <ulf.hermann@qt.io>
5 years agotests: Update hello_riscv64.ko test file with debuginfo.
Mark Wielaard [Tue, 17 Jul 2018 10:27:51 +0000 (12:27 +0200)]
tests: Update hello_riscv64.ko test file with debuginfo.

Also document CONFIG_DEBUG_INFO=y.

Updated test file provided by Andreas Schwab <schwab@suse.de>.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agobackends: add set_initial_registers_tid callback for RISC-V
Andreas Schwab [Wed, 11 Jul 2018 10:43:06 +0000 (12:43 +0200)]
backends: add set_initial_registers_tid callback for RISC-V

This fixes the backtrace-dwarf and deleted tests, and lets
backtrace-native run a bit further.

Signed-off-by: Andreas Schwab <schwab@suse.de>
5 years agotests: Handle compressed sections in next_cfi testcase.
Mark Wielaard [Thu, 5 Jul 2018 14:24:57 +0000 (16:24 +0200)]
tests: Handle compressed sections in next_cfi testcase.

Some toolchains use compressed ELF sections by default.
This would make run-next-cfi-self.sh fail because it would try to
decode the compressed data. Fix by decompressing the section first.

https://sourceware.org/bugzilla/show_bug.cgi?id=23370

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoreadelf: Don't shadow index function from string.h
Mark Wielaard [Wed, 4 Jul 2018 14:08:05 +0000 (16:08 +0200)]
readelf: Don't shadow index function from string.h

On some ancient GCC versions (4.4.7 at least) -Wshadow warns about local
variables "shadowing" global function definitions.

  readelf.c: In function â€˜print_debug_addr_section’:
  readelf.c:5265: error: declaration of â€˜index’ shadows a global declaration
  /usr/include/string.h:489: error: shadowed declaration is here

This is silly of course, but easy to work around.

Signed-off-by: Mark Wielaard <mark@klomp.org>
5 years agoConsolidate error.h inclusion in system.h
Ross Burton [Wed, 4 Jul 2018 11:11:08 +0000 (12:11 +0100)]
Consolidate error.h inclusion in system.h

error.h isn't standard and so isn't part of the musl C library.
To easy future porting, consolidate the inclusion of error.h into system.h.

https://sourceware.org/bugzilla/show_bug.cgi?id=21008

Signed-off-by: Ross Burton <ross.burton@intel.com>
5 years agoRequire gawk in maintainer mode
Ross Burton [Wed, 4 Jul 2018 11:11:07 +0000 (12:11 +0100)]
Require gawk in maintainer mode

gawk is required to build known_dwarf.h, so check for it in configure.ac.

Signed-off-by: Ross Burton <ross.burton@intel.com>
5 years agoconfig: Add upload-release.sh script.
Mark Wielaard [Wed, 4 Jul 2018 21:08:41 +0000 (23:08 +0200)]
config: Add upload-release.sh script.

Should be run after making a release to upload the new tar.bz2,
signature file and update the latest symlinks. Make sure to run
make distcheck first. Requires a shell account on sourceware.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoPrepare for 0.173 elfutils-0.173
Mark Wielaard [Fri, 29 Jun 2018 19:02:18 +0000 (21:02 +0200)]
Prepare for 0.173

Set version to 0.173.
Mention new functionality in NEWS.
Update po/*.po files.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Recognize zero terminator to end frame table in dwarf_next_cfi.
Mark Wielaard [Thu, 28 Jun 2018 15:53:12 +0000 (17:53 +0200)]
libdw: Recognize zero terminator to end frame table in dwarf_next_cfi.

When the length is zero this is a the zero terminator that ends the
frame table. Return 1 (end of table) instead of -1 (error) in that case.
We cannot update next_off and don't want to caller to try again.

Add testcase for dwarf_next_cfi to show both .eh_frame and .debug_frame
tables and check consistency (FDEs should point to existing CIEs).
Also add a self check to make sure we can read the table from the just
build elfutils binaries.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Allow .debug_frame only Dwarf.
Mark Wielaard [Wed, 27 Jun 2018 12:41:22 +0000 (14:41 +0200)]
libdw: Allow .debug_frame only Dwarf.

.debug_frame is useful independent from the other .debug sections.

Add a simplified variant of the addrcfi testcase dwarfcfi.
dwarfcfi only uses dwarf_frame calls and no dwfl helpers.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Remove dwarf_getscn_info from libdw.h and libdw.map.
Mark Wielaard [Tue, 26 Jun 2018 14:37:21 +0000 (16:37 +0200)]
libdw: Remove dwarf_getscn_info from libdw.h and libdw.map.

This function was never actually implemented/provided by libdw.
And it doesn't look like something we really want to implement.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Limit varlocs print_expr_block recursion depth.
Mark Wielaard [Sat, 23 Jun 2018 16:07:18 +0000 (18:07 +0200)]
tests: Limit varlocs print_expr_block recursion depth.

This is only useful for bad DWARF where an expression block might have
an expression that refers to a DIE that contains the expression block
itself. But that might happen with bad DWARF generated by a fuzzer.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add dwarf_next_lines to read .debug_line tables without CUs.
Mark Wielaard [Fri, 22 Jun 2018 20:44:51 +0000 (22:44 +0200)]
libdw: Add dwarf_next_lines to read .debug_line tables without CUs.

It is sometimes useful to read .debug_line tables on their own without
having an associated CU DIE. DWARF5 line tables are self-contained.

Adjust dwarf_begin_elf to accept ELF files with just a .debug_line.

Add a new function dwarf_next_lines that returns the Dwarf_Files and
Dwarf_Lines while iterating over just the .debug_lines section. Since
we parse and cache the information it also will try to match the CU
a table is associated with. This is only necessary for DWARF4 line
tables (we will need at least the compilation dir from the CU) and
won't be done for DWARF5 line tables. It also isn't an error if there
is no associated CU (but will mean for DWARF4 line tables the dir list
and the file paths might not be complete).

A typical way to call this new function is:

  Dwarf_Off off, next_off = 0;
  Dwarf_CU *cu = NULL;
  Dwarf_Files *files;
  size_t nfiles;
  Dwarf_Lines *lines;
  size_t nlines;
  int res;
  while ((res = dwarf_next_lines (dbg, off = next_off, &next_off, &cu,
                                  &files, &nfiles, &lines, &nlines)) == 0)
    {
      /* ... handle files and lines ... */
    }

  if (res < 0)
    printf ("BAD dwarf_next_lines: %s\n", dwarf_errmsg (-1));

See libdw.h for the full documentation. For more examples on how to use
the function see the new testcases next-files and next-lines.

Also adjust the file paths for line tables missing a comp_dir.
They are no longer made "absolute" by prepending a slash '/' in front
of them. This really was not useful and didn't happen in any of the
testcases. They are now just kept relative.

Make eu-readelf --debug-dump=decodedline use dwarf_next_lines instead
of iterating over the CUs to show the (decoded) line tables. This allows
it to show decoded line tables even if there is no .debug_info section.

New tests have been added that mimic the get-files and get-lines tests
but use dwarf_next_lines instead of iterating over all CUs. They produce
identical output (modulo the CU information). Also add a new test file
that contains only a .debug_line section.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle bogus CU length in dwarf_nextcu.
Mark Wielaard [Wed, 20 Jun 2018 22:54:57 +0000 (00:54 +0200)]
libdw: Handle bogus CU length in dwarf_nextcu.

The length field could be so big that it would wrap around the next_offset.
We don't really care that length is bogus, but we don't want to use it to
calculate the next offset if it is.

Found by afl-fuzz.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibelf: Don't return unaligned data returned from elf_getdata[_rawchunk].
Mark Wielaard [Tue, 12 Jun 2018 10:54:35 +0000 (12:54 +0200)]
libelf: Don't return unaligned data returned from elf_getdata[_rawchunk].

For i386 and x86_64 we allow some unaligned data accesses.
We also return unaligned data from elf_getdata[_rawchunk].
But that might go wrong if we then access the ELF types inside.
When build with gcc -O3 for example the compiler might vectorize
loops accessing ELF words or types. The instructions used do require
the data is naturally aligned. If the function returnes unaligned
data the program will segfault and crash. This happens for example
with the code in dwfl_module_getdwarf.c that tries to iterate over
the hash buckets gotten through elf_getdata_rawchunk based on the
DT_[GNU]_HASH value.

This only happens when the underlying ELF file is mmapped, and it
is meant as optimization so that we don't have to copy data first
so that it is correctly aligned. In most cases the data is already
naturally aligned though. But it might not be for non-native ELF
files.

Given that it might even happen in our own code base and these
are public functions that can be used by code that might rely on
the data returned being correctly aligned for the ELF data type
requested just always return correctly aligned data.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agobackends,bpf: add proper relocation support
Yonghong Song [Sat, 16 Jun 2018 20:02:43 +0000 (13:02 -0700)]
backends,bpf: add proper relocation support

Due to libdw does not have proper BPF relocation support,
the pahole cannot display filenames correctly for objects
with default llvm options. So we have to invent
a special option "llc -march=bpf -mattr=dwarfris" to
prevent llvm from generating cross-section dwarf relocation
records (https://reviews.llvm.org/rL326505).
The pahole related discussion is in linux netdev
mailing list (http://lists.openwall.net/netdev/2018/06/15/38, etc.)

We would like to add proper BPF relocation support
to libdw so eventually we could retire the special llc bpf
flag "-mattr=dwarfris".

The bpf relocations are defined in
llvm_repo:include/llvm/BinaryFormat/ELFRelocs/BPF.def:
  ELF_RELOC(R_BPF_NONE,        0)
  ELF_RELOC(R_BPF_64_64,       1)
  ELF_RELOC(R_BPF_64_32,      10)

Removed the relocation type R_BPF_MAP_FD whoes name does not
confirm to llvm definition and replaced it with R_BPF_64_64.
The BPF object is just a relocatible object, not an executable or
a shared library, so assign ELF type to REL only in bpf_reloc.def.

Signed-off-by: Yonghong Song <yhs@fb.com>
6 years agolibelf: Sync elf.h from glibc.
Mark Wielaard [Thu, 21 Jun 2018 16:52:53 +0000 (18:52 +0200)]
libelf: Sync elf.h from glibc.

Add NT_PPC_PKEY, R_BPF_64_64 and R_BPF_64_32. Remove R_BPF_MAP_FD.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Break dwarf_aggregate_size recursion because of type cycles.
Mark Wielaard [Sun, 17 Jun 2018 22:58:24 +0000 (00:58 +0200)]
libdw: Break dwarf_aggregate_size recursion because of type cycles.

Found by afl-fuzz. An array type (indirectly) referring to itself in the
DIE tree could blow up the stack when dwarf_aggregate_size was called.
Limit the recursion depth to MAX_DEPTH (256) entries.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: dwarf_peel_type break long chains/cycles.
Mark Wielaard [Sun, 17 Jun 2018 22:23:48 +0000 (00:23 +0200)]
libdw: dwarf_peel_type break long chains/cycles.

Limit the number of chained modifiers to 64 (that is 8 chains for all
8 modifiers, most of which cannot be chained). This prevents loops in
the DWARF DIE DW_AT_type references.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: aggregate_size check NULL result from get_type.
Mark Wielaard [Sun, 17 Jun 2018 22:23:23 +0000 (00:23 +0200)]
libdw: aggregate_size check NULL result from get_type.

aggregate_size can be called recursively with the result of get_type.
get_type can return NULL when dwarf_peel_type fails. Found by afl-fuzz.

dwarf_aggregate_size when called directly doesn't need a NULL check
because it calls and checks the result of dwarf_peel_type directly.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agobackends: add abi_cfi and register_info callbacks for RISC-V
Andreas Schwab [Wed, 13 Jun 2018 10:28:00 +0000 (12:28 +0200)]
backends: add abi_cfi and register_info callbacks for RISC-V

From
https://github.com/riscv/riscv-isa-manual/raw/master/release/riscv-spec-v2.2.pdf
and GCC source.

Signed-off-by: Andreas Schwab <schwab@suse.de>
6 years agolibdw: Initialize filelist earlier in dwarf_getsrclines.c read_srclines.
Luiz Angelo Daros de Luca [Sun, 17 Jun 2018 09:34:08 +0000 (11:34 +0200)]
libdw: Initialize filelist earlier in dwarf_getsrclines.c read_srclines.

I'm getting this error with 0.172:

dwarf_getsrclines.c: In function 'read_srclines':
dwarf_getsrclines.c:1074:7: error: 'filelist' may be used uninitialized in this function [-Werror=maybe-uninitialized]
       free (filelist);
       ^~~~~~~~~~~~~~~

It seems that gcc is right here as there is "ifs" that go to "out"
(where filelist is freed) before freelist is initialized.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
6 years agolibdw, readelf: Don't handle DW_FORM_data16 as expression block/location.
Mark Wielaard [Fri, 15 Jun 2018 14:25:15 +0000 (16:25 +0200)]
libdw, readelf: Don't handle DW_FORM_data16 as expression block/location.

Also found by afl-fuzz on the varlocs testcase.
DW_FORM_data16 is constant form according to the DWARF5 spec.
But since it is 128bits it isn't really representable as Dwarf_Word.
So we treat it as block form. But we cannot treat it as an expression
block. Make sure readelf prints it as a regular block and that
dwarf_getlocation[s|_addr] doesn't treat it as location expression.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Check there are at least 4 bytes available for DWARF_FORM_block4.
Mark Wielaard [Tue, 12 Jun 2018 12:36:50 +0000 (14:36 +0200)]
readelf: Check there are at least 4 bytes available for DWARF_FORM_block4.

Found by afl-fuzz. When printing a DWARF_FORM_block4 we checked there
were only 2 bytes available (copy/paste from DW_FORM_block2 right
before). Obviously we need at least 4 bytes to read the length of a
DW_FORM_block4.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Make sure print_form_data always consumes DW_FORM_strx[1234] data.
Mark Wielaard [Tue, 12 Jun 2018 10:22:13 +0000 (12:22 +0200)]
readelf: Make sure print_form_data always consumes DW_FORM_strx[1234] data.

Found by afl-fuzz. When printing DW_FORM_strx[1234] data eu-readelf didn't
increase readp which meant eu-readelf would keep printing the same line
dirs or files encoded with strx[1234] names. This meant that for insane
large dir or file counts eu-readelf would just keep printing endlessly
because we never reached and of the .debug_line buffer.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Make __libdw_dieabbrev more robust on failure.
Mark Wielaard [Tue, 12 Jun 2018 10:18:31 +0000 (12:18 +0200)]
libdw: Make __libdw_dieabbrev more robust on failure.

Make sure to always set die->abbrev to DWARF_END_ABBREV on failure.
DWARF_END_ABBREV is also what the function reports on failure. And it
will prevent trying to lookup the abbrev ever again.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: While printing .debug_loc make sure that next_off doesn't overflow.
Mark Wielaard [Wed, 13 Jun 2018 13:21:37 +0000 (15:21 +0200)]
readelf: While printing .debug_loc make sure that next_off doesn't overflow.

Found by the afl fuzzer. The next offset (after a locview) comes from a
DIE loclist attribute. This could be a bogus value so large it overflows
the buffer and makes us print past the end of buffer.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Handle signedness of DW_FORM_implicit_const and DW_AT_const_value.
Mark Wielaard [Wed, 13 Jun 2018 12:03:24 +0000 (14:03 +0200)]
readelf: Handle signedness of DW_FORM_implicit_const and DW_AT_const_value.

We only handles DW_FORM_sdata as a signed form, but DW_FORM_implicit_const
is also signed by default. For DW_AT_const_value we can do a little better.
GCC encodes some const_values with signed forms, even though the type
is unsigned. Lookup the (base) type of the DIE and display the const value
as their (signed) type/size (if we can determine that).

Add a new testcase run-readelf-const-values.sh that shows that.
With the new testcase the const values would come out as follows:

  name                 (string) "i"
  const_value          (implicit_const) 18446744073709551615
  name                 (string) "j"
  const_value          (implicit_const) 18446744073709551615

  name                 (string) "sc"
  const_value          (sdata) -2
  name                 (string) "uc"
  const_value          (sdata) -2
  name                 (string) "ss"
  const_value          (sdata) -16
  name                 (string) "us"
  const_value          (sdata) -16
  name                 (string) "si"
  const_value          (sdata) -3
  name                 (string) "ui"
  const_value          (sdata) -94967296
  name                 (string) "sl"
  const_value          (sdata) -1
  name                 (string) "ul"
  const_value          (sdata) -1

With this patch they show up as:

  name                 (string) "i"
  const_value          (implicit_const) -1
  name                 (string) "j"
  const_value          (implicit_const) -1

  name                 (string) "sc"
  const_value          (sdata) -2
  name                 (string) "uc"
  const_value          (sdata) 254 (-2)
  name                 (string) "ss"
  const_value          (sdata) -16
  name                 (string) "us"
  const_value          (sdata) 65520 (-16)
  name                 (string) "si"
  const_value          (sdata) -3
  name                 (string) "ui"
  const_value          (sdata) 4200000000 (-94967296)
  name                 (string) "sl"
  const_value          (sdata) -1
  name                 (string) "ul"
  const_value          (sdata) 18446744073709551615 (-1)

(for signed/unsigned int char, short and long)

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoPrepare for 0.172. elfutils-0.172
Mark Wielaard [Mon, 11 Jun 2018 15:14:39 +0000 (17:14 +0200)]
Prepare for 0.172.

It has been only 10 days since the previous release and there are
no functional changes compared to 0.171. The speedup of eu-readelf -N
is pretty nice. And ~25 patches fix various bugs (hangs and crashes)
in dealing with bad DWARF5 data. Most have been found by running the
afl fuzzer on eu-readelf and various testcases.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Return correct readp (or readendp) from print_form_data.
Mark Wielaard [Mon, 11 Jun 2018 09:22:36 +0000 (11:22 +0200)]
readelf: Return correct readp (or readendp) from print_form_data.

print_form_data returns the new readp (or readendp on error) to show how
much data was consumed. But when reading the .debug_str_offsets section
we would reuse readp and readendp. This meant the wrong readp would be
returned to the caller.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Fix bounds check in print_form_data.
Mark Wielaard [Mon, 11 Jun 2018 00:14:34 +0000 (02:14 +0200)]
readelf: Fix bounds check in print_form_data.

The afl fuzzer found that we did a wrong check in print_form_data when
comparing the remaining bytes in the buffer to an (unsigned) value read.
We were casting the value to ptrdiff_t which is a signed value and so
might turn a really big unsigned value into a negative number. Since we
know the difference between readendp and readp is zero or greater, we
should cast the pointer difference to size_t (and unsigned type) instead
before comparing with the unsigned value.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Break long or circular DIE ref chains in dwarf_[has]attr_integrate.
Mark Wielaard [Sun, 10 Jun 2018 14:59:12 +0000 (16:59 +0200)]
libdw: Break long or circular DIE ref chains in dwarf_[has]attr_integrate.

Bad DWARF could create a very long or circular DIE ref chain by linking
DW_AT_abstract_origin or DW_AT_specification to the DIE itself. Break
the chain after seeing a large number (16) of DIEs.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Calculate max_entries instead of needed bytes (and overflowing).
Mark Wielaard [Fri, 8 Jun 2018 21:30:37 +0000 (23:30 +0200)]
readelf: Calculate max_entries instead of needed bytes (and overflowing).

The afl fuzzer found that we would overflow the needed bytes when
calculating how many index entries would fit in the .debug_loclists
and .debug_rnglists tables. To fix this just calculate the max number
of entries. If the offset entry count is larger than that, do emit
an error, but print up to max_entries of offsets (so the user can
more clearly see what is wrong with their table).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Don't assert on bad DW_OP_GNU_parameter_ref target in varlocs.
Mark Wielaard [Fri, 8 Jun 2018 19:13:25 +0000 (21:13 +0200)]
tests: Don't assert on bad DW_OP_GNU_parameter_ref target in varlocs.

If the target of a DW_OP_GNU_parameter_ref isn't a DW_TAG_formal_parameter
that is bad data (which varlocs should error on). But it isn't an internal
consistency check (for which varlocs should assert).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Check validity of dwarf_getabbrev arguments.
Mark Wielaard [Fri, 8 Jun 2018 18:45:48 +0000 (20:45 +0200)]
libdw: Check validity of dwarf_getabbrev arguments.

When the given Dwarf_Die was invalid we might crash and when the offset
was totally bogus we might succeed with a random abbrev.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: dwarf_get_units should handle existing failure to open Dwarf.
Mark Wielaard [Fri, 8 Jun 2018 18:14:58 +0000 (20:14 +0200)]
libdw: dwarf_get_units should handle existing failure to open Dwarf.

The other dwarf unit/cu iterators handle a NULL Dwarf handle as an
existing error and return NULL. Don't crash.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Detect bad DWARF in store_implicit_value.
Mark Wielaard [Fri, 8 Jun 2018 13:10:43 +0000 (15:10 +0200)]
libdw: Detect bad DWARF in store_implicit_value.

The afl fuzzer running against the varlocs test detected we didn't report
the value block of a DW_OP_implicit_value consistently when the DWARF was
bad. Although this doesn't cause a crash it might result in consumers
using dwarf_getlocation_implicit_value seeing an inconsistent block length
value. To fix this detect and report bad DWARF data earlier.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Fix cfi_debug_bias assert in varlocs.
Mark Wielaard [Fri, 8 Jun 2018 13:07:16 +0000 (15:07 +0200)]
tests: Fix cfi_debug_bias assert in varlocs.

It is only a consistency issue if we actually have an cfi_debug and the
cfi_debug_bias is not zero (because they come from the same file as the
other debug data).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf, libdw: Handle too many directories or files in the line table better.
Mark Wielaard [Fri, 8 Jun 2018 12:04:40 +0000 (14:04 +0200)]
readelf, libdw: Handle too many directories or files in the line table better.

The afl fuzzer found that the way we handle "too many" directories or files
in the (DWARF5 style) line table badly. In the case of eu-readelf we would
print an endless stream of "bad directory" or "bad file". Just stop printing
when the end of data is reached. In the case of dwarf_getsrclines we would
allocate a giant amount of memory, even if there was no data to actually
read in. Sanity check that the directory and file counts seem reasonable
compared to the amount of data left (assume we need at least 1 byte of
data per form describing the dirs or files).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Return an error in dwarf_getlocation_attr for missing .debug_addr.
Mark Wielaard [Fri, 8 Jun 2018 00:11:44 +0000 (02:11 +0200)]
libdw: Return an error in dwarf_getlocation_attr for missing .debug_addr.

When constructing a "fake" Dwarf_Attribute for DW_OP_GNU_const_index,
DW_OP_constx, DW_OP_GNU_addr_index or DW_OP_addrx, we would create a
fake attribute pointing to the actual data in the .debug_addr section.

We would even do that if there was no .debug_addr section assuming
dwarf_formaddr or dwarf_formudata would generate an error. But when
there is no .debug_addr there is also no fake_addr_cu, so the
dwarf_form* functions cannot check the value is correct (and crash).

Fix by returning an error early from dwarf_getlocation_attr indicating
bad DWARF data.

Found by the afl fuzzer running on the varlocs testcase.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Turn format_print_dwarf into print_dwarf_addr.
Mark Wielaard [Thu, 7 Jun 2018 21:09:41 +0000 (23:09 +0200)]
readelf: Turn format_print_dwarf into print_dwarf_addr.

We don't really need to setup a buffer, print into it and then print it
out to stdout. Simplify the code by directly printing the address (and
symbol name).

This also showed a small error in the output of DW_LLE_startx_length.
It had two unintended trailing dots.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Make sure that address_size and offset_size are 4 or 8 bytes.
Mark Wielaard [Wed, 6 Jun 2018 23:23:05 +0000 (01:23 +0200)]
libdw: Make sure that address_size and offset_size are 4 or 8 bytes.

When interning a CU make sure that address_size and offset_size are
either 4 or 8 bytes. We really don't (want to) handle any other size.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Check DIE address fall inside the CU before reading abbrev code.
Mark Wielaard [Thu, 7 Jun 2018 14:57:23 +0000 (16:57 +0200)]
libdw: Check DIE address fall inside the CU before reading abbrev code.

The afl fuzzer found a case where we tried reading an uleb for the DIE
abbrev code without properly checking the DIE address is inside the CU.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Report error in dwarf_getlocation_die for bogus opcode offset.
Mark Wielaard [Wed, 6 Jun 2018 21:51:12 +0000 (23:51 +0200)]
libdw: Report error in dwarf_getlocation_die for bogus opcode offset.

Found by afl fuzzer on varlocs test. varlocs sanity checks that the
given offset in the opcode corresponds to the cuoffset of the returned
DIE. In case the opcode offset was bogus this might fail because we
might wrap around and return a random DIE instead of reporting an error.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Use error, not assert, when trying to print a non-base type DIE.
Mark Wielaard [Wed, 6 Jun 2018 21:35:35 +0000 (23:35 +0200)]
tests: Use error, not assert, when trying to print a non-base type DIE.

When using the varlocs test with a fuzzer using assert for internal
sanity checks is great to find issues. But when encountering bad data
using an assert is wrong. Just use error to show we handle the data
correctly (by reporting it is bad, instead of crashing).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Explicitly check we could decode diridx in dwarf_getsrclines.
Mark Wielaard [Tue, 5 Jun 2018 21:34:46 +0000 (23:34 +0200)]
libdw: Explicitly check we could decode diridx in dwarf_getsrclines.

It is highly unlikely dwarf_formudata fails because we setup the attribute
ourselves, but better to explicitly mark diridx as bad if it does.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Always initialize .debug_addr unit_length, even without a header.
Mark Wielaard [Tue, 5 Jun 2018 21:21:05 +0000 (23:21 +0200)]
readelf: Always initialize .debug_addr unit_length, even without a header.

We would print a "fake" .debug_addr header, but didn't always setup the
unit_length (in case there was a mix of GNU DebugFission and DWARF5 tables).
Make sure to always set the unit_length (we do always calculate the next
unit offset already).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Set begin properly for DW_LLE_GNU_start_end_entry on addrx failure.
Mark Wielaard [Tue, 5 Jun 2018 20:50:43 +0000 (22:50 +0200)]
readelf: Set begin properly for DW_LLE_GNU_start_end_entry on addrx failure.

When printing the GNU DebugFission location entries we want to print the
start idx as begin, if we cannot find the address index.
A copy/paste error set up end instead of begin in that case causing us
to print garbage (in the unlikely event the .debug_addr table wasn't
found for this entry).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Don't leak arange if we cannot figure out which CU it belongs to.
Mark Wielaard [Tue, 5 Jun 2018 20:41:45 +0000 (22:41 +0200)]
libdw: Don't leak arange if we cannot figure out which CU it belongs to.

In the unlikely case that __libdw_findcu fails to find the associated
CU we would leak one arange because it wasn't linked into the arangelist
list yet. Make sure to free it immediately.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Make sure dirarray is always properly freed in dwarf_getsrclines.
Mark Wielaard [Tue, 5 Jun 2018 20:27:25 +0000 (22:27 +0200)]
libdw: Make sure dirarray is always properly freed in dwarf_getsrclines.

If there were more than 256 directories in the table and there was
illegal DWARF before we read them all, then we might not free the
dirarray (or the wrong one). Fix by defining the dirarray early
(before the first data sanity check) and making sure it is not
(still) equal to dirstack before freeing.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Don't leak lengths array when detecting an invalid hash chain.
Mark Wielaard [Tue, 5 Jun 2018 19:52:46 +0000 (21:52 +0200)]
readelf: Don't leak lengths array when detecting an invalid hash chain.

In both handle_sysv_hash and handle_sysv_hash64 we check the has chain
isn't too long. If it is we would report an error and leak the lengths
array. Just clean up the array even in the error case.

Signed-off-by: Mark Wielaard <mark@klomp.org>