summaryrefslogtreecommitdiff
path: root/libdw
Commit message (Collapse)AuthorAgeFilesLines
* Fix automake warningsDmitry V. Levin2020-12-102-3/+8
| | | | | | | | | | | | | | | | | | | Apparently, commit 2f02e81510946a4c8e9157ad0b72d92894b9acd7 that removed $(EXEEXT) suffix from shared libraries was incomplete: it missed the fact that some libraries were included into noinst_PROGRAMS, resulting to the following automake warnings: libasm/Makefile.am:66: warning: deprecated feature: target 'libasm.so' overrides 'libasm.so$(EXEEXT)' libdw/Makefile.am:114: warning: deprecated feature: target 'libdw.so' overrides 'libdw.so$(EXEEXT)' libelf/Makefile.am:116: warning: deprecated feature: target 'libelf.so' overrides 'libelf.so$(EXEEXT)' Fix this by renaming noinst_PROGRAMS to noinst_DATA and removing no longer needed lib{asm,dw,elf}_so_SOURCES variables and add lib{asm,dw,elf).so to CLEANFILES. Fixes: 2f02e8151094 ("Drop $(EXEEXT) suffix from shared libraries") Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> Signed-off-by: Mark Wielaard <mark@klomp.org>
* Drop $(EXEEXT) suffix from shared librariesDmitry V. Levin2020-12-062-1/+5
| | | | | | | | | According to GNU Automake documentation [1], $(EXEEXT) is the suffix that should be used for executables, it is not applicable for shared libraries. [1] https://www.gnu.org/software/automake/manual/html_node/EXEEXT.html Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
* Support building when fts and obstack aren't part of libc.Érico Rolim2020-11-032-1/+5
| | | | | | | | - Make configure.ac test for fts and obstack availability; - Add fts and obstack ldflags to all files that need them; - Add missing argp ldflags to programs in debuginfod/. Signed-off-by: Érico Rolim <erico.erc@gmail.com>
* Fix leb128 readingTom Tromey2020-10-293-8/+49
| | | | | | | | | | | | PR 26773 points out that some sleb128 values are decoded incorrectly. This version of the fix only examines the sleb128 conversion. Overlong encodings are not handled, and the uleb128 decoders are not touched. The approach taken here is to do the work in an unsigned type, and then rely on an implementation-defined cast to convert to signed. Signed-off-by: Tom Tromey <tom@tromey.com>
* libdw: dwarf_frame_register takes an array of at least 3 Dwarf_OpsMark Wielaard2020-10-263-4/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | GCC11 will warn about a mismatch in the declaration of dwarf_frame_register: dwarf_frame_register.c:37:61: error: argument 3 of type ‘Dwarf_Op *’ declared as a pointer [-Werror=array-parameter=] 37 | dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op *ops_mem, | ~~~~~~~~~~^~~~~~~ libdw.h:1068:43: note: previously declared as an array ‘Dwarf_Op[3]’ 1068 | Dwarf_Op ops_mem[3], | ~~~~~~~~~^~~~~~~~~~ When fixing that it will show an actual bug in the addrcfi testcase: addrcfi.c:98:16: error: ‘dwarf_frame_register’ accessing 96 bytes in a region of size 64 [-Werror=stringop-overflow=] 98 | int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ addrcfi.c:98:16: note: referencing argument 3 of type ‘Dwarf_Op *’ 1069 | extern int dwarf_frame_register (Dwarf_Frame *frame, int regno, | ^~~~~~~~~~~~~~~~~~~~ Fix the declaration, fix the bug and add an extra comment to the description in libdw.h. Signed-off-by: Mark Wielaard <mark@klomp.org>
* Fix bug in read_3ubyte_unaligned_incTom Tromey2020-10-242-1/+6
| | | | | | | The read_3ubyte_unaligned_inc macro calls read_2ubyte_unaligned, but it should call read_3ubyte_unaligned. Signed-off-by: Tom Tromey <tom@tromey.com>
* libdw,readelf: Recognize DW_CFA_AARCH64_negate_ra_stateMark Wielaard2020-09-076-18/+51
| | | | | | | | | | | | | | | | | | | | DW_CFA_AARCH64_negate_ra_state is used on aarch64 to indicate whether or not the return address is mangled or not. This has the same value as the DW_CFA_GNU_window_save. So we have to pass around the e_machine value of the process or core we are inspecting to know which one to use. Note that it isn't actually implemented yet. It needs ARMv8.3 hardware. If we don't have such hardware it is enough to simply ignore the DW_CFA_AARCH64_negate_ra_state (and not confuse it with DW_CFA_GNU_window_save) to get backtraces to work on aarch64. Add a testcase for eu-readelf --debug-dump=frames to show the value is correctly recognized. Also don't warn we cannot find any DWARF if we are just dumping frames (those will come from .eh_frame if there is no .debug_frame). Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Remove duplicate local wildcards from map file.Mark Wielaard2020-09-032-10/+8
| | | | | | We only need one local: * entry to capture all private local symbols. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Rename check_constant_offset to is_constant_offset.Mark Wielaard2020-08-252-9/+18
| | | | | | | | | The check_constant_offset code in dwarf_getlocation.c code is not very intuitive, rename it to is_constant_offset and update the documentation. https://sourceware.org/bugzilla/show_bug.cgi?id=26321 Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdwfl: read_address should use increasing address in intuit_kernel_boundsMark Wielaard2020-06-281-0/+5
| | | | | | | | | | | | | | | | In kernels from 4.14 up to 4.19 in /proc/kallsyms there are special __entry_SYSCALL_64_trampoline symbols. The problem is that they come after the last kernel address, but before the module addresses. And they are (much) smaller than the start address we found. This confuses intuit_kernel_bounds and makes it fail. Make sure to check read_address returns an increasing address when searching for the end. https://sourceware.org/bugzilla/show_bug.cgi?id=26177 Reported-by: Vitaly Chikunov <vt@altlinux.org> Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Add missing FALLTHROUGH in execute_cfi.Mark Wielaard2020-06-192-0/+5
| | | | Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Skip imported compiler_units in libdw_visit_scopes walking DIE treeMark Wielaard2020-05-082-1/+10
| | | | | | | | | | | Some gcc -flto versions imported other top-level compile units, skip those. Otherwise we'll visit various DIE trees multiple times. Note in the testcase that with newer GCC versions function foo is fully inlined and does appear only once (as declared, but not as separate subprogram). Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Use correct CU to resolve file names in dwarf_decl_file.Mark Wielaard2020-05-084-2/+21
| | | | | | | | | | | | | dwarf_decl_file uses dwarf_attr_integrate to get the DW_AT_decl_file attribute. This means the attribute might come from a different DIE in a different CU. If so, we need to use the CU associated with the attribute, not the original DIE, to resolve the file name. Also add a bit more documentation to dwarf_attr_integrate explaining that the attribute returned might come from a different CU (and even different Dwarf). Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Call Dwarf oom_handler() when malloc fails in __libdw_alloc_tail.Mark Wielaard2020-04-262-0/+10
| | | | | | | | | GCC10 -fanalyzer found a possibly-NULL dereference after a failed malloc in __libdw_alloc_tail. In this case we should call the Dwarf oom_handler as is done in other places where an essential malloc call fails. The oom_handler cannot return and will likely just abort. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw, readelf: Handle GCC LTO .gnu.debuglto_ prefix.Mark Wielaard2020-04-222-0/+8
| | | | | | | | | GCC puts (partial) DWARF debuginfo into sections prefixed with .gnu.debuglto_. Handle those sections as if they are normal .debug sections (which they are). This allows showing the DWARF that gcc puts into ET_REL files compiled with -flto. Signed-off-by: Mark Wielaard <mark@klomp.org>
* debuginfod 1/2: client sideAaron Merey2019-11-222-1/+5
| | | | | | | | | | | | Introduce the debuginfod/ subdirectory, containing the client for a new debuginfo-over-http service, in shared-library and command-line forms. Two functions in libdwfl make calls into the client library to fetch elf/dwarf files by buildid, as a fallback. Instead of normal dynamic linking (thus pulling in a variety of curl dependencies), the libdwfl hooks use dlopen/dlsym. Server & tests coming in patch 2. Signed-off-by: Aaron Merey <amerey@redhat.com> Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
* libdw: Introduce libdw_unalloc to stop Dwarf_Abbrev leaks.Mark Wielaard2019-11-124-1/+43
| | | | | | | | | In the case of reading an invalid abbrev or when reading an abbrev concurrently the Dwarf_Abbrev just created might leak because it isn't needed after all. Introduce libdw_unalloc and libdw_typed_unalloc to unallocate such Dwarf_Abbrevs so they don't leak. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Rewrite the memory handler to be more robust.Jonathon Anderson2019-11-085-53/+122
| | | | | | | | Pthread's thread-local variables are highly limited, which makes it difficult to use many Dwarfs. This replaces that with a less efficient (or elegant) but more robust method. Signed-off-by: Jonathon Anderson <jma14@rice.edu>
* libdw: Add and use a concurrent version of the dynamic-size hash table.Srđan Milaković2019-11-088-9/+25
| | | | | Signed-off-by: Srđan Milaković <sm108@rice.edu> Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Don't free uninitialized Dwarf_Abbrev_Hash's of "fake" CUs.Jonathon Anderson2019-11-023-12/+35
| | | | | | | | | | | fake_{loc,loclists,addr}_cu are Dwarf_CUs that are created separate from all the others, so their contents are minimal and mostly initialized by a calloc. On dwarf_end however, they are freed through the same code path as all the others, so they call DAH_free like all the others. This changes that so that these three are exempt from DAH and split-DWARF matters, and swaps the calloc for a malloc so Memcheck will catch any others. Signed-off-by: Jonathon Anderson <jma14@rice.edu>
* libdw: Rewrite the memory handler to be thread-safe.Jonathon Anderson2019-10-246-36/+68
| | | | Signed-off-by: Jonathon Anderson <jma14@rice.edu>
* Don't use dlopen() for libebl modulesOmar Sandoval2019-08-292-7/+18
| | | | | | | | | | | | Currently, architecture-specific code for libebl exists in separate libebl_$ARCH.so libraries which libebl loads with dlopen() at runtime. This makes it impossible to have standalone, statically-linked binaries which use libdwfl if they depend on any architecture-specific functionality. Additionally, when these libraries cannot be found, the failure modes are non-obvious. So, let's get rid of libebl_$arch.so and move it all into libdw.so/libdw.a, which simplifies things considerably. Signed-off-by: Omar Sandoval <osandov@fb.com>
* Add PIC and non-PIC variants of libcpu and libeblOmar Sandoval2019-08-282-1/+5
| | | | | | | | | Currently, libcpu and libebl are always compiled as PIC. An upcoming change will add the objects from libcpu.a and libebl.a to libdw.a, which should not be PIC unless configured that way. So, make libcpu.a and libebl.a non-PIC and add libcpu_pic.a and libebl_pic.a. Signed-off-by: Omar Sandoval <osandov@fb.com>
* libdw: fix latent bug in dwarf_getcfi.c not setting default_same_value.Jonathon Anderson2019-08-262-0/+5
| | | | Signed-off-by: Jonathon Anderson <jma14@rice.edu>
* libdwelf: Make dwelf_elf_begin return NULL only when there is an error.Mark Wielaard2019-08-132-0/+8
| | | | | | | | | | | | | | | | | | | | | | | dwelf_elf_begin was slightly different from elf_begin in case the file turned out to not be an ELF file. elf_begin would return an Elf handle with ELF_K_NONE. But dwelf_elf_begin would return NULL. This made it impossible to tell the difference between a file or decompression error and a (decompressed) file not being an ELF file. Since dwelf_elf_begin could still return different kinds of ELF files (ELF_K_ELF or ELF_K_AR - and theoretically ELF_K_COFF) this was not really useful anyway. So make it so that dwelf_elf_begin always returns an Elf handle unless there was a real error reading or decompressing the file. Otherwise return NULL to make clear there was a real error. Make sure that the decompression function returns DWFL_E_BADELF only when the file isn't compressed. In which case the Elf handle won't be replaced and can be returned (as ELF_K_NONE). Add a new version to dwelf_elf_begin so programs can rely on it returning NULL only for real errors. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdwelf: Add dwelf_elf_e_machine_string and use it in readelf.Mark Wielaard2019-07-102-1/+11
| | | | | | | | | | | | | | | | To print eh human readable description of the ELF e_machine header field we used the ebl name. But this is not set for most EM constants. Introduce a new function dwelf_elf_e_machine_string that does work for all known EM values. Use that in eu-readelf to print a string representation of the e_machine value. Since this was the only usage of ebl->name, remove that from struct ebl. Also add a testcase that makes sure dwelf_elf_e_machine_string works for all EM values in the libelf/elf.h header so we will immediately notice when a new value appears. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Add DW_AT_GNU_numerator, DW_AT_GNU_denominator and DW_AT_GNU_bias.Mark Wielaard2019-05-162-0/+11
| | | | | | https://sourceware.org/bugzilla/show_bug.cgi?id=24550 Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Remove unused variable initialization in dwarf_siblingof.Mark Wielaard2019-04-282-1/+5
| | | | | | We immediately reassign the value of addr after declaration. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Call check_constant_offset with direct pointers.Mark Wielaard2019-04-282-1/+6
| | | | | | | | In dwarf_getlocation_addr pass the pointers to llbufs and listlens indirectly by passing a pointer to the first array element. Simplify the code by passing the pointers directly. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Reject DW_OP_implicit_value in CFI.Mark Wielaard2019-04-282-0/+7
| | | | | | | | | | When we encounter a DW_OP_implicit_value we call store_implicit_value () which will try to store the value as part of the Dwarf dbg. But if we are examining CFI there will be no Dwarf dbg. And DW_OP_implicit_value should not be part of CFI. So explicitly reject it in store_implicit_value if dbg is NULL. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Check there is enough space for CU 64bit length, version and type.Mark Wielaard2019-02-012-3/+20
| | | | | | | | | | | We only checked we could read the initial length and after knowing the version and type whether the unit header was the right size. Also check there are at least enough bytes to read the 64bit length, version and unit type bytes. https://sourceware.org/bugzilla/show_bug.cgi?id=24140 Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Check terminating NUL byte in dwarf_getsrclines for dir/file table.Mark Wielaard2019-01-222-3/+13
| | | | | | | | | | | | | For DWARF version < 5 the .debug_line directory and file tables consist of a terminating NUL byte after all strings. The code used to just skip this without checking it actually existed. This could case a spurious read past the end of data. Fix the same issue in readelf. https://sourceware.org/bugzilla/show_bug.cgi?id=24102 Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Enable building with -Og.Mark Wielaard2018-11-233-2/+7
| | | | | | | | | | | | When building with -Og gcc is unable to see that __libdw_dieabbrev () will initialize what the second argument points to when no error occurs as called by dwarf_child and dwarf_getattrs. Causing an possibly uninitialized error. Just initialize readp/die_addr to NULL, which is the value we would return if an error occurs anyway. https://sourceware.org/bugzilla/show_bug.cgi?id=23914 Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdwelf: New function dwelf_elf_begin.Mark Wielaard2018-11-092-0/+9
| | | | | | | | | | | | | | | | | | This introduces a new function dwelf_elf_begin which creates a (read-only) ELF handle from a possibly compressed file handle or a file that start with a linux kernel header. This can be used in eu-readelf to (re)open a (pure) ELF. eu-readelf uses libdwfl to relocate addresses in the original file in case it is ET_REL. But to show the "raw" data it might need to (re)open the file. Which could fail if the file was compressed. And produced an obscure error message: "cannot create EBL handle". This rewrites __libdw_open_file a little so that the given file handle will never be closed (whether on success or failure) and introduces a new internal function __libdw_open_elf that dwelf_elf_begin wraps. Signed-off-by: Mark Wielaard <mark@klomp.org>
* Also find CFI in sections of type SHT_X86_64_UNWINDMilian Wolff2018-11-092-1/+5
| | | | | | | | | | | | | | | | | | | | | | On my system with g++ (GCC) 8.2.1 20180831 with GNU gold (GNU Binutils 2.31.1) 1.16, the .eh_frame section does not have type PROGBITS but rather is using X86_64_UNWIND nowadays: ``` $ echo "int main(){ return 0; }" > test.c $ gcc test.c $ readelf --sections a.out | grep .eh_frame [14] .eh_frame X86_64_UNWIND 0000000000000670 00000670 [15] .eh_frame_hdr X86_64_UNWIND 0000000000000724 00000724 ``` Without this patch, libdw refuses to use the available unwind information, leading to broken backtraces while unwinding. With the patch applied, unwinding works once more in such situations. Signed-off-by: Milian Wolff <milian.wolff@kdab.com> Signed-off-by: Mark Wielaard <mark@klomp.org> Tested-by: Milian Wolff <milian.wolff@kdab.com>
* libdw: dwarf_begin_elf should use elf_getshdrstrndx to get section names.Mark Wielaard2018-09-142-8/+28
| | | | | | | | | | | 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>
* libdw: Check end of attributes list consistently.Mark Wielaard2018-08-183-3/+10
| | | | | | | | | | | | | | | | | | | | | | | 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>
* libdw, readelf: Make sure there is enough data to read full aranges header.Mark Wielaard2018-08-182-0/+9
| | | | | | | | | | 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>
* Consolidate error.h inclusion in system.hRoss Burton2018-07-052-1/+4
| | | | | | | | | 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>
* libdw: Recognize zero terminator to end frame table in dwarf_next_cfi.Mark Wielaard2018-06-292-0/+12
| | | | | | | | | | | | | 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>
* libdw: Allow .debug_frame only Dwarf.Mark Wielaard2018-06-292-1/+7
| | | | | | | | | .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>
* libdw: Remove dwarf_getscn_info from libdw.h and libdw.map.Mark Wielaard2018-06-293-4/+5
| | | | | | | 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>
* libdw: Add dwarf_next_lines to read .debug_line tables without CUs.Mark Wielaard2018-06-297-24/+248
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* libdw: Handle bogus CU length in dwarf_nextcu.Mark Wielaard2018-06-252-0/+10
| | | | | | | | | | 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>
* libdw: Break dwarf_aggregate_size recursion because of type cycles.Mark Wielaard2018-06-202-9/+27
| | | | | | | | 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>
* libdw: dwarf_peel_type break long chains/cycles.Mark Wielaard2018-06-202-9/+18
| | | | | | | | 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>
* libdw: aggregate_size check NULL result from get_type.Mark Wielaard2018-06-202-0/+7
| | | | | | | | | | 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>
* libdw: Initialize filelist earlier in dwarf_getsrclines.c read_srclines.Luiz Angelo Daros de Luca2018-06-182-1/+6
| | | | | | | | | | | | | | 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>
* libdw, readelf: Don't handle DW_FORM_data16 as expression block/location.Mark Wielaard2018-06-172-13/+39
| | | | | | | | | | | 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>
* readelf: Make sure print_form_data always consumes DW_FORM_strx[1234] data.Mark Wielaard2018-06-172-0/+9
| | | | | | | | | | 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>