summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* libdw: Add dwarf_next_lines to read .debug_line tables without CUs.Mark Wielaard2018-06-2916-62/+833
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* libelf: Don't return unaligned data returned from elf_getdata[_rawchunk].Mark Wielaard2018-06-224-10/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* backends,bpf: add proper relocation supportYonghong Song2018-06-2110-2/+111
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* libelf: Sync elf.h from glibc.Mark Wielaard2018-06-214-2/+12
| | | | | | 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>
* 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>
* backends: add abi_cfi and register_info callbacks for RISC-VAndreas Schwab2018-06-205-1/+264
| | | | | | | | 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>
* 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-174-18/+54
| | | | | | | | | | | 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: Check there are at least 4 bytes available for DWARF_FORM_block4.Mark Wielaard2018-06-172-1/+6
| | | | | | | | | 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>
* readelf: Make sure print_form_data always consumes DW_FORM_strx[1234] data.Mark Wielaard2018-06-174-6/+20
| | | | | | | | | | 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>
* libdw: Make __libdw_dieabbrev more robust on failure.Mark Wielaard2018-06-172-2/+8
| | | | | | | | 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>
* readelf: While printing .debug_loc make sure that next_off doesn't overflow.Mark Wielaard2018-06-162-1/+8
| | | | | | | | 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>
* readelf: Handle signedness of DW_FORM_implicit_const and DW_AT_const_value.Mark Wielaard2018-06-157-22/+350
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Prepare for 0.172.elfutils-0.172Mark Wielaard2018-06-1111-2266/+2289
| | | | | | | | | | 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>
* readelf: Return correct readp (or readendp) from print_form_data.Mark Wielaard2018-06-112-5/+10
| | | | | | | | | 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>
* readelf: Fix bounds check in print_form_data.Mark Wielaard2018-06-112-7/+12
| | | | | | | | | | | | 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>
* libdw: Break long or circular DIE ref chains in dwarf_[has]attr_integrate.Mark Wielaard2018-06-113-4/+10
| | | | | | | | 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>
* readelf: Calculate max_entries instead of needed bytes (and overflowing).Mark Wielaard2018-06-112-6/+13
| | | | | | | | | | | 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>
* tests: Don't assert on bad DW_OP_GNU_parameter_ref target in varlocs.Mark Wielaard2018-06-112-1/+7
| | | | | | | | 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>
* libdw: Check validity of dwarf_getabbrev arguments.Mark Wielaard2018-06-115-3/+40
| | | | | | | 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>
* libdw: dwarf_get_units should handle existing failure to open Dwarf.Mark Wielaard2018-06-112-0/+9
| | | | | | | 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>
* libdw: Detect bad DWARF in store_implicit_value.Mark Wielaard2018-06-102-6/+26
| | | | | | | | | | 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>
* tests: Fix cfi_debug_bias assert in varlocs.Mark Wielaard2018-06-102-1/+7
| | | | | | | | 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>
* readelf, libdw: Handle too many directories or files in the line table better.Mark Wielaard2018-06-104-0/+23
| | | | | | | | | | | | | 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>
* libdw: Return an error in dwarf_getlocation_attr for missing .debug_addr.Mark Wielaard2018-06-102-4/+16
| | | | | | | | | | | | | | | | | | 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>
* readelf: Turn format_print_dwarf into print_dwarf_addr.Mark Wielaard2018-06-094-257/+242
| | | | | | | | | | | 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>
* libdw: Make sure that address_size and offset_size are 4 or 8 bytes.Mark Wielaard2018-06-092-2/+17
| | | | | | | 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>
* libdw: Check DIE address fall inside the CU before reading abbrev code.Mark Wielaard2018-06-092-1/+5
| | | | | | | 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>
* libdw: Report error in dwarf_getlocation_die for bogus opcode offset.Mark Wielaard2018-06-082-0/+13
| | | | | | | | | 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>
* tests: Use error, not assert, when trying to print a non-base type DIE.Mark Wielaard2018-06-082-1/+7
| | | | | | | | | 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>
* libdw: Explicitly check we could decode diridx in dwarf_getsrclines.Mark Wielaard2018-06-082-2/+8
| | | | | | | 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>
* readelf: Always initialize .debug_addr unit_length, even without a header.Mark Wielaard2018-06-082-5/+7
| | | | | | | | | 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>
* readelf: Set begin properly for DW_LLE_GNU_start_end_entry on addrx failure.Mark Wielaard2018-06-082-1/+6
| | | | | | | | | | 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>
* libdw: Don't leak arange if we cannot figure out which CU it belongs to.Mark Wielaard2018-06-082-1/+11
| | | | | | | | 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>
* libdw: Make sure dirarray is always properly freed in dwarf_getsrclines.Mark Wielaard2018-06-082-9/+18
| | | | | | | | | | 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>
* readelf: Don't leak lengths array when detecting an invalid hash chain.Mark Wielaard2018-06-082-2/+18
| | | | | | | | 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>
* libdw: Make sure id_path can contain max number of build id bytes.Mark Wielaard2018-06-082-1/+6
| | | | | | | | | | | The MAX_BUILD_ID_BYTES is fairly large (64), while normally build-ids are only 20 bytes long. But if we would encounter a jumbo build-id we should have enough room to construct the full build-id path. We used to substract 2 bytes from the max, because 2 chars are used as subdir. But that should be 1 (2 hex chars is just one 8 bit byte). Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Make room for DW_MACRO_hi_user opcode if used.Mark Wielaard2018-06-082-1/+6
| | | | | | | The vendor array should have room for all vendor opcode, including DW_MACRO_hi_user if used. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdwfl: Make __libdwfl_addrsym a static function in dwfl_module_addrsym.cMark Wielaard2018-06-083-12/+11
| | | | | | | __libdwfl_addrsym is only used in the dwfl_module_addrsym.c source. There is no need to mark this as a (shared) internal function. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Lookup "no" translation for no_str, not "yes".Mark Wielaard2018-06-072-3/+9
| | | | | | | Also use yes_str and no_str in print_debug_abbrev_section and print_form_data. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Don't allocate string with asprintf, but reuse buffer with sprintf.Mark Wielaard2018-06-042-106/+96
| | | | | | | | | | | Since we are single threaded we can just use a static result buffer for format_dwarf_addr as long as we make sure to print the result before calling format_dwarf_addr again. This removes lots of malloc/free calls. On my machine eu-readelf -N --debug-dump=info libxul.so goes from 57 seconds to 55 seconds. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Lookup gettext "yes" and "no" only once.Mark Wielaard2018-06-042-2/+17
| | | | | | | On my machine eu-readelf -N --debug-dump=info libxul.so > /dev/null goes from 63 seconds to 57 seconds. Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Call __fsetlocking (stdout, FSETLOCKING_BYCALLER).Mark Wielaard2018-06-042-0/+9
| | | | | | | | | | We only call printf on stdout from one thread, so we don't need internal stdio locking for stdout. On my machine eu-readelf -N --debug-dump=info libxul.so > /dev/null goes from 65 seconds to 63 seconds. Signed-off-by: Mark Wielaard <mark@klomp.org>
* tests: Drop shared libraries from self_test_files_exe.Mark Wielaard2018-06-022-7/+8
| | | | | | | | | Commit 00d89086 "tests: Split self_test_files into an exe, lib and obj list" accidentially left the shared libraries in the self_test_files_exe. Causing all shared libraries to be tested twice. Drop them and keep just four ET_EXE files: addr2line, elfcmp, objdump and readelf. Signed-off-by: Mark Wielaard <mark@klomp.org>
* Prepare for 0.171.elfutils-0.171Mark Wielaard2018-06-0113-2569/+4023
| | | | | | | Set version to 0.171. Update po/*.po files. Mention DWARF5, split dwarf and GNU DebugFission support in NEWS. Signed-off-by: Mark Wielaard <mark@klomp.org>
* libdw: Try both the relative and absolute paths when finding a .dwo file.Mark Wielaard2018-06-014-47/+92
| | | | | | | | We would give up if one of them failed. With this fixed a self-test with make check succeeds when building elfutils itself with CFLAGS set to "-gdwarf-4 -gdwarf-split -O2". Signed-off-by: Mark Wielaard <mark@klomp.org>
* readelf: Fix .debug_types printing with implicit section_info.Mark Wielaard2018-06-015-6/+149
| | | | | | | | | | | | | Commit 314e9d7d "readelf: Handle .debug_info first if any other debug section needs it" disabled section_info printing if it was already handled. But section_types was an alias for section_info. So unless section_info was explicitly printed, .debug_types wasn't. Make section_types its own thing to print .debug_types and make section_info imply section_types. Add a testcase to make sure .debug_types is now printed. Signed-off-by: Mark Wielaard <mark@klomp.org>