platform/upstream/elfutils.git
6 years agoreadelf, libdw: Add GNU DebugFission .debug_loc support.
Mark Wielaard [Mon, 28 May 2018 22:59:28 +0000 (00:59 +0200)]
readelf, libdw: Add GNU DebugFission .debug_loc support.

GNU DebugFission .debug_loc location lists uses the .debug_loc section
in the split dwarf .dwo file. The encoding is a mix of old style DWARF
.debug_loc and new style .debug_loclists.

Add two testcases for the readelf and libdw decoders.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Fix regression with multiple files and implicit debug_info reading.
Mark Wielaard [Tue, 29 May 2018 07:44:38 +0000 (09:44 +0200)]
readelf: Fix regression with multiple files and implicit debug_info reading.

Commit 314e9d7d "readelf: Handle .debug_info first if any other debug
section needs it" introduced a regression when handling multiple files.
The implicit and explicit printing of debuginfo weren't reset and so
the second file would not show (or scan) the .debug_info section when
needed.

Fix by resetting the implicit and explicit section printing flags.
Add a testcase that prints the .debug_loc section for two files and
check that the CUs are resolved.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Fix memory corruption in libdw_find_split_unit.
Mark Wielaard [Sun, 20 May 2018 19:57:39 +0000 (21:57 +0200)]
libdw: Fix memory corruption in libdw_find_split_unit.

Found by valgrind when trying to match a split unit from a .dwo file
that doesn't contain the split unit (as first) match. We would close
the split Dwarf too early, before we had inspected all units in it.

Add a testcase that simulates this. Which failed (at least under valgrind
as run by make distcheck) before the fix.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Handle .debug_str_offsets.
Mark Wielaard [Mon, 30 Apr 2018 00:54:07 +0000 (02:54 +0200)]
readelf: Handle .debug_str_offsets.

The .debug_str_offsets tables are indirect string offsets into the
.debug_str section. For DWARF5 they can be in both the main, skeleton
and split dwarf (.dwo) files.

For DWARF4 with the GNU DebugFission extension the tables will not have
an header and they will only be in the split DWARF (.dwo) file, never in
the main (skeleton) file.

For DWARF5 the (non-split) unit DIE will have a DW_AT_str_offsets_base
attribute pointing at the actual index (after the header). The split
unit will never have this attribute (and use the table at offset zero).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf handle .debug_addr section.
Mark Wielaard [Fri, 27 Apr 2018 22:10:41 +0000 (00:10 +0200)]
readelf handle .debug_addr section.

Add debug-dump=addr which will show the .debug_addr section tables.
The only tricky bit is the fact that GNU DebugFission, a DWARF4
extension, didn't produce unit table headers. So if we see a mixed
DWARF4/5 .debug_addr table we have to reconstruct the table length
from the CU DIE DW_AT_[GNU_]_addr_base offsets.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle .debug_loclists in dwarf_getlocation.
Mark Wielaard [Sat, 7 Apr 2018 21:48:27 +0000 (23:48 +0200)]
libdw: Handle .debug_loclists in dwarf_getlocation.

Handle all new DW_LLE opcodes in .debug_loclists in dwarf_getlocation.
__libdw_read_begin_end_pair_inc now also handles a default location
(which is simply the range [0,-1]). Since expression blocks can now
also come from the .debug_loclists section add a new fake_loclists_cu
necessary for checking bounds while parsing expression blocks.

Adapt varlocs test to handle debug-only files.
Test testfileranges5.debug and testfilesplitranges5.debug with it.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Handle .debug_loclists.
Mark Wielaard [Fri, 24 Nov 2017 18:29:57 +0000 (19:29 +0100)]
readelf: Handle .debug_loclists.

The new DWARF5 .debug_loclists sections are like .debug_rnglists, but
plus locations. For Split Dwarf GCC generates the .debug_loclists fully
in the split .dwo file. Any references to addresses need to be resolved
through the skeleton .debug_addr section.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdwfl: Allow partial relocations also for debug files.
Mark Wielaard [Sun, 27 May 2018 12:05:21 +0000 (14:05 +0200)]
libdwfl: Allow partial relocations also for debug files.

__libdwfl_relocate is called for get_dwarf and get_elf. We allow not all
relocations to be resolved for Elf files, but required all relocations
(in the debug sections) to be fully resoled in Dwarf files. This used to
mostly work out with .o ET_REL files when the main Elf was gotten before
the Dwarf. But with .dwo files, we (readelf) might open the .o file just
for the (skeleton) Dwarf. In this case it could happen not all relocations
in the debug sections could be resolved (.debug_info and .debug_addr might
contain referenes to undefined symbols). So allow partial relocations
also for debug files.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Find skeleton units when inspecting split .dwo (--dwarf-skeleton).
Mark Wielaard [Sun, 8 Apr 2018 22:03:43 +0000 (00:03 +0200)]
readelf: Find skeleton units when inspecting split .dwo (--dwarf-skeleton).

To get the right context (especially addresses) when looking at a .dwo file
we really need the skeleton file.  If we can find it (simply replace .dwo
with .o) then use that to get to the split DWARF units so that libdw sets
up all relevant information to resolve.

Also adds a --dwarf-skeleton option so the user can explicitly give a
skeleton file to use (for example when all .o files are linked and removed
already).  Unfortunately this might not work if libdw cannot get from the
skeleton file to the .dwo file (because they have been moved around).
In that case eu-readelf "cheats", it will link up the libdw datastructures
so that the skeleton and split DWARF units are setup correctly anyway.
This does introduce a problem when trying to cleanup the Dwarf handle
ownership graph. So we will deliberately leak memory by not closing the
underlying Dwfl in that case.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle .debug_rnglists in dwarf_ranges.
Mark Wielaard [Fri, 6 Apr 2018 16:53:34 +0000 (18:53 +0200)]
libdw: Handle .debug_rnglists in dwarf_ranges.

Handle all new DW_RLE opcodes in .debug_rnglists in dwarf_ranges. Extract
code for reading .debug_addr indexes from dwarf_formaddr as __libdw_addrx
to reuse in __libdw_read_begin_end_pair_inc. And add new testcase for
"plain" DWARF5 and add a new test all-dwarf-ranges to test split DWARF5.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Add .debug_rnglists support.
Mark Wielaard [Fri, 24 Nov 2017 10:16:06 +0000 (11:16 +0100)]
readelf: Add .debug_rnglists support.

Parse the .debug_rnglists section for DWARF5 --debug-dump=ranges.
Add testcase to show both "normal" and "split" DWARF variants are
handled for DWARF4 and DWARF5.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years ago__libdw_cu_addr_base: Cast offset to uintptr_t before returning as pointer.
Mark Wielaard [Fri, 25 May 2018 13:46:09 +0000 (15:46 +0200)]
__libdw_cu_addr_base: Cast offset to uintptr_t before returning as pointer.

Fixes a GCC compile issue on the elfutils-debian-i686 buildbot builder:

dwarf_getlocation_attr.c: In function ‘addr_valp’:
dwarf_getlocation_attr.c:62:12: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
     return (unsigned char *) offset;
            ^
cc1: all warnings being treated as errors

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle all address FORMs for dwarf_highpc, handle errors better.
Mark Wielaard [Tue, 22 May 2018 12:34:06 +0000 (14:34 +0200)]
libdw: Handle all address FORMs for dwarf_highpc, handle errors better.

dwarf_highpc can use any address FORM, not just DW_FORM_addr. Just try
whether the address can be resolved as address. Always set error when
attribute couldn't be found or resolved. When calculating the base
address for a CU don't try to second guess the error code, just treat
an error the same as the attribute not being there.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support.
Mark Wielaard [Sun, 20 May 2018 21:30:01 +0000 (23:30 +0200)]
libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support.

DW_OP_addrx/constx and GNU DebugFission DW_OP_GNU_addr/const_index take
as argument an index into the .debug_addr section for the associated CU.
This index gets resolved through dwarf_getlocation_attr. A new fake addr
CU is created per Dwarf for use with this new attribute. For split DWARF
files, the IDX_debug_addr gets replaced with the skeleton section and the
addr base is resolved immediately when constructing the split DWARF CU.
Move __libdw_cu_addr_base to libdwP.h to share with eu-readelf. Also
make it possible to resolve addrx[1234]/GNU_addr_index also as constant
indexes to (also) show when displaying these attributes in eu-readelf.

A new varlocs tests is added to test the resolving for both the DWARF4
and DWARF5 DW_OP variants. And now that addrx forms are resolved in
split DWARF files add the new DIEs with "single ranges" (those DIEs that
have a lowpc/highpc attribute pair) to run-all-dwarf-ranges.sh.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: print split CUs when given --debug-dump=info+
Mark Wielaard [Fri, 19 Jan 2018 14:45:16 +0000 (15:45 +0100)]
readelf: print split CUs when given --debug-dump=info+

To show the difference between "regular" CUs and split CUs print
offsets and references between { and } instead of [ and ].

When --debug-dump=info+ is given (implied by -w) instead of
--debug-dump=info any skeleton unit will be immediately followed
by the corresponding split compile unit (from the .dwo file).

DWARF section [27] '.debug_info' at offset 0x1075:
 [Offset]
 Compilation unit at offset 0:
 Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
 Unit type: skeleton (4), Unit id: 0xc152129eb4b99599
 [     b]  compile_unit         abbrev: 1
           ranges               (sec_offset) range list [     0]
           low_pc               (addr) +000000000000000000
           stmt_list            (sec_offset) 0
           GNU_dwo_name         (strp) "foo.dwo"
           comp_dir             (strp) "/tmp"
           GNU_pubnames         (flag_present) yes
           GNU_addr_base        (sec_offset) 0
           GNU_dwo_id           (data8) 0xc152129eb4b99599
           GNU_ranges_base      (sec_offset) 0
 Split compilation unit at offset 0:
 Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
 Unit type: skeleton (4), Unit id: 0xc152129eb4b99599
 {     b}  compile_unit         abbrev: 1
           producer             (GNU_str_index) "GNU C11 7.3.0 -gsplit-dwarf -g"
           language             (data1) C99 (12)
           name                 (GNU_str_index) "foo.c"
           comp_dir             (GNU_str_index) "/tmp"
           GNU_dwo_id           (data8) 0xc152129eb4b99599
 {    18}    subprogram           abbrev: 2
             external             (flag_present) yes
             name                 (GNU_str_index) "main"
             decl_file            (data1) foo.c (1)
             decl_line            (data1) 1
             type                 (ref4) {    2b}
             high_pc              (data8) 3
             frame_base           (exprloc)
              [ 0] call_frame_cfa
             GNU_all_call_sites   (flag_present) yes
 {    2b}    base_type            abbrev: 3
             byte_size            (data1) 4
             encoding             (data1) signed (5)
             name                 (string) "int"

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add new dwarf_cu_info function.
Mark Wielaard [Sun, 20 May 2018 08:35:34 +0000 (10:35 +0200)]
libdw: Add new dwarf_cu_info function.

This allows getting a (split) subdie lazily, only when needed.
All arguments to dwarf_get_units are optional. When not given
then unit DIE and sub DIE are not looked up. This new function
allows them to be looked up when not immediately retrieved with
dwarf_get_units, or for a Dwarf_CU gotten through some other way.

Add a new testcase to make sure the results of calling dwarf_cu_info
and dwarf_get_units are consistent.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Initialize ranges_base, add invalid DWARF test and fix expected output.
Mark Wielaard [Thu, 24 May 2018 13:20:25 +0000 (15:20 +0200)]
libdw: Initialize ranges_base, add invalid DWARF test and fix expected output.

We never initialized the CU ranges_base, which meant we didn't actually
calculate it correctly. This caused bad ranges on some DIEs. The expected
output in the testcase was wrong. We also crashed on invalid dwarf.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle GNU DebugFission split ranges.
Mark Wielaard [Fri, 18 May 2018 22:46:02 +0000 (00:46 +0200)]
libdw: Handle GNU DebugFission split ranges.

GNU DebugFission split dwarf handles DW_FORM_sec_offset specially for
attributes that point to ranges. The .debug_ranges section is not in
the .dwo file, but in the main/skeleton object file. The sec_offset is
not relocated (in the ELF file), but is an offset against the skeleton
DIE DW_AT_GNU_ranges_base attribute. dwarf_formudata is changed so it
still looks like a normal offset ptr into the .debug_ranges section.
dwarf_ranges is adapted to look for the .debug_ranges in the main object
file. dwarf_highpc and dwarf_lowpc now handle the highpc and lowpc
attributes being inherited for the split unit DIE from the skeleton.

A new testcase is added to iterate over all ranges in a split GNU
DebugFission file.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle split dwarf debuglines.
Mark Wielaard [Thu, 17 May 2018 22:26:56 +0000 (00:26 +0200)]
libdw: Handle split dwarf debuglines.

Split DWARF .dwo files do contain a .debug_line section, but only with
the file table, there is no actual line program. Also split DWARF CU DIEs
don't have a DW_AT_stmt_list attribute. To get at the file (and dir) table
for a split unit DIE take just the files from the .debug_line section
(at offset zero). To get the full line table use the skeleton DIE (which
does have a DW_AT_stmt_list).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Cache ELF directory early. Explicitly set it in dwfl.
Mark Wielaard [Thu, 17 May 2018 17:23:46 +0000 (19:23 +0200)]
libdw: Cache ELF directory early. Explicitly set it in dwfl.

The logic that finds alt files and dwo files relies on having an open
file descriptor. But after all needed ELF data has been read the
underlying Elf file descriptor can be closed. libdwfl in particular
closes file descriptor fairly aggressively. So capture the directory
early on. And make dwfl set it if it has recorded it. Which it will
do now before closing a file descriptor for the main Dwfl_Module file.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Search skeleton DIE for split compile unit DIE attributes.
Mark Wielaard [Mon, 14 May 2018 21:58:25 +0000 (23:58 +0200)]
libdw: Search skeleton DIE for split compile unit DIE attributes.

dwarf_attr_integrate and dwarf_hasattr_integrate should also search
for attributes from the skeleton DIE in case the given DIE is a split
compile unit DIE. Split compile unit DIEs inherit various attributes
from their skeleton unit DIE in DWARF5.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoMark __libdw_find_split_unit mark as internal_function.
Mark Wielaard [Sat, 19 May 2018 16:35:51 +0000 (18:35 +0200)]
Mark __libdw_find_split_unit mark as internal_function.

The prototype and definition should match. On i386 this is important
because it changes the calling convention.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: dwarf_get_units find split units from .dwo.
Mark Wielaard [Thu, 18 Jan 2018 14:03:43 +0000 (15:03 +0100)]
libdw: dwarf_get_units find split units from .dwo.

For a skeleton DIE dwarf_get_units should provide the split DIE as subdie.
This implements that by trying to find the (named) .dwo file and finding
the matching CU in it. The .dwo file is search relative to the current
DWARF or using the comp_dir of the skeleton DIE.

Also fixes a small issue with str_offsets_base_off which is tested in the
new testcase (by getting the name of the split CU DIE).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Recognize GNU DebugFission split units.
Mark Wielaard [Mon, 14 May 2018 15:29:05 +0000 (17:29 +0200)]
libdw: Recognize GNU DebugFission split units.

The split dwarf dwo unit id and type are not in the CU header itself, but
can be found in the CU DIE DW_AT_GNU_dwo attributes. Use this to set the
correct unit_type and id for GNU DebugFission split units. Also show this
information in eu-readelf when printing units.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add GNU DebugFission attributes, tags, forms and operands.
Mark Wielaard [Mon, 14 May 2018 15:18:11 +0000 (17:18 +0200)]
libdw: Add GNU DebugFission attributes, tags, forms and operands.

Most are handled just like their DWARF5 counterparts.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw, readelf: Handle .debug_*.dwo section name variants.
Mark Wielaard [Sat, 12 May 2018 22:05:10 +0000 (00:05 +0200)]
libdw, readelf: Handle .debug_*.dwo section name variants.

The .debug_*.dwo section names are handled just like their none .dwo
variants.  The section contents is the same as sections without the .dwo
name, but they are only found in split-dwarf files.  This patch allows
opening and inspecting split-dwarf files.  It doesn't yet connect the
split-dwarf with their skeleton (or the other way around).  It also
doesn't yet handle any special split-dwarf attributes or tags.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoelflint: fix typo in error diagnostics
Dmitry V. Levin [Tue, 15 May 2018 20:18:43 +0000 (23:18 +0300)]
elflint: fix typo in error diagnostics

Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
6 years agobackends: add checks for _GLOBAL_OFFSET_TABLE_ and __global_pointer$ on riscv
Andreas Schwab [Tue, 15 May 2018 11:47:02 +0000 (13:47 +0200)]
backends: add checks for _GLOBAL_OFFSET_TABLE_ and __global_pointer$ on riscv

Signed-off-by: Andreas Schwab <schwab@suse.de>
6 years agoreadelf: Fix 32bit compile issues.
Mark Wielaard [Tue, 15 May 2018 09:47:08 +0000 (11:47 +0200)]
readelf: Fix 32bit compile issues.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf, libdw: Handle DWARF5 .debug_macro.
Mark Wielaard [Wed, 6 Dec 2017 11:30:12 +0000 (12:30 +0100)]
readelf, libdw: Handle DWARF5 .debug_macro.

Almost identical to GNU .debug_macro extension. Just accept and use
DW_AT_macros where we accept or use DW_AT_GNU_macros. And be a little
stricter in which FORMs we accept (this could have caused problems
with the GNU variant too). Deals with DW_FORM_strx[1234], but not yet
with imported macros through DW_MACRO_import_sup.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Add DWARF5 .debug_line support.
Mark Wielaard [Thu, 26 Apr 2018 09:53:49 +0000 (11:53 +0200)]
readelf: Add DWARF5 .debug_line support.

This only changes the parsing of the directory and file name tables.
It does this by sharing the printing of (non-CU based) from data from
the .debug_macro code. Adding support for printing strx[1234] form data
by sharing the code that detects the correct str_offsets_base in libdw.

The header format is also cleaned up a bit so that it better lines out.
Testcases adjusted and new ones added.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Fix crashing on illegal/zero Dwarf_Die.
Mark Wielaard [Wed, 9 May 2018 21:27:12 +0000 (23:27 +0200)]
libdw: Fix crashing on illegal/zero Dwarf_Die.

In some cases we create an illegal Dwarf_Die by clearing all fields.
The idea is that dwarf_tag () on such a Dwarf_Die will return
DW_TAG_invalid, to indicate that the Dwarf_Die is unusable (and other
functions will also return errors).  But when "reconstructing" the
Dwarf_Die addr we might use the cu before realizing the Dwarf_Die is
invalid.  Fix this with an explicit NULL check and add a testcase.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoaddr2line: Add explicit fflush for stdout when reading from stdin.
Mark Wielaard [Sat, 12 May 2018 19:30:17 +0000 (21:30 +0200)]
addr2line: Add explicit fflush for stdout when reading from stdin.

To make it possible to use eu-addr2line interactively through a pipe we
need to explicitly flush stdout after handling each line from stdin.

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

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Use raw section data if nothing is available through libdw.
Mark Wielaard [Tue, 24 Apr 2018 14:14:19 +0000 (16:14 +0200)]
readelf: Use raw section data if nothing is available through libdw.

For various debug data sections readelf has its own parsers that don't
rely on libdw data structures or functions. But we still like to get the
data through libdw since that will be uncompressed and/or relocated.
But there can be reasons for libdw to have rejected the section data.
In that case we want to try to parse the "raw" section data.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Handle .debug_info first if any other debug section needs it.
Mark Wielaard [Sat, 28 Apr 2018 21:02:41 +0000 (23:02 +0200)]
readelf: Handle .debug_info first if any other debug section needs it.

Some debug sections need information from the CU DIEs to properly
parse the data. Normally the .debug_info section is one of the first.
But some DWARF producers reorder the sections and put it after some
other debug sections. Make sure we first handle .debug_info if it
is needed by any other debug section.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle DW_FORM_[ref|strp]_sup[48] as DW_FORM_GNU_[ref|strp]_alt.
Mark Wielaard [Tue, 8 May 2018 13:34:03 +0000 (15:34 +0200)]
libdw: Handle DW_FORM_[ref|strp]_sup[48] as DW_FORM_GNU_[ref|strp]_alt.

Although we don't yet handle DWARF5 supplemental files, they are like
mostly like GNU alt files.  This way using any of the supplemental files
will at least generate an appropriate error message.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle DWARF5 line tables in dwarf_getsrclines.
Mark Wielaard [Sat, 5 May 2018 22:33:27 +0000 (00:33 +0200)]
libdw: Handle DWARF5 line tables in dwarf_getsrclines.

In DWARF5 the actual line number table format doesn't change, except for
not allowing DW_LNE_define_file (but we still just accept it). The
changes are the header having new fields for address and segment
selector sizes, and new formats for the directory and file names tables.

The directory and file name tables are much more flexible in DWARF5, but
we only interpret the actual names and file/dir index relationships,
skipping/ignoring any other information. There also is no new interface
yet to get at the new directory and file properties.

There is some small confusion about the file name table indexing. Older
DWARF versions explicitly called the first file name table 1. DWARF5
implies the first index is 0 (but for file attributes, zero means not
associated with a file). We get away with that by having an actual zero
index for older DWARF versions (the null_fill). It looks like gcc gets
around it by explicitly duplicating the first (0) and second (1) file
name entry in the table. This can also be seen in the new testcase.

The patch looks big because of moving a few initializations around
and because the code that is different for older/newer DWARF got moved
under if statements. But the original old DWARF code path didn't really
change.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibebl: Add new DWARF5 debug section names to default_debugscn_p.
Mark Wielaard [Wed, 25 Apr 2018 10:54:24 +0000 (12:54 +0200)]
libebl: Add new DWARF5 debug section names to default_debugscn_p.

This adds the new DWARF5 debug section names .debug_addr, .debug_line_str,
.debug_loclists, .debug_names, .debug_rnglists and .debug_str_offsets. This
makes sure eu-strip knows to strip them away.

Note that it doesn't add the .dwo variants, nor the .dwp only section
names .debug_cu_index and .debug_tu_index, nor the .debug_sup section
for supplemental DWARF files.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Handle .debug_line_str section.
Mark Wielaard [Wed, 25 Apr 2018 10:40:38 +0000 (12:40 +0200)]
readelf: Handle .debug_line_str section.

It is just a .debug_str section with another name.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle DW_FORM_line_strp.
Mark Wielaard [Wed, 25 Apr 2018 10:31:42 +0000 (12:31 +0200)]
libdw: Handle DW_FORM_line_strp.

DW_FORM_line_strp strings come from a separate .debug_line_str section.
Make error messages more distinct (no .debug_str, no .debug_line_str or
not a string form).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoAdd support for RISC-V
Andreas Schwab [Thu, 19 Apr 2018 15:47:52 +0000 (17:47 +0200)]
Add support for RISC-V

This implements initial support for the RISC-V architecture.  It has
been tested with qemu linux-user emulation
<https://build.opensuse.org/package/live_build_log/openSUSE:Factory:RISCV/elfutils/standard/riscv64>,
with the following unresolved issues

FAIL: run-strip-strmerge.sh
===========================

elflint /home/abuild/rpmbuild/BUILD/elfutils-0.170/tests/elfstrmerge
section [32] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x51c0 does not match .got section address 0x5010
section [32] '.symtab': symbol 119: st_value out of bounds
FAIL run-strip-strmerge.sh (exit status: 1)

FAIL: run-elflint-self.sh
=========================

section [33] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x6220 does not match .got section address 0x6008
section [33] '.symtab': symbol 135: st_value out of bounds
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/addr2line
section [33] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x91d8 does not match .got section address 0x9040
section [33] '.symtab': symbol 163: st_value out of bounds
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elfcmp
section [33] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x1a2a0 does not match .got section address 0x1a040
section [33] '.symtab': symbol 267: st_value out of bounds
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint
section [33] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0xd418 does not match .got section address 0xd0f0
section [33] '.symtab': symbol 238: st_value out of bounds
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/nm
section [33] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0xa2d0 does not match .got section address 0xa0b0
section [33] '.symtab': symbol 193: st_value out of bounds
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/objdump
section [33] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x2e5b8 does not match .got section address 0x2e058
section [33] '.symtab': symbol 410: st_value out of bounds
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/readelf
section [32] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x171b8 does not match .got section address 0x17010
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/libelf/libelf.so
section [32] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0x3a5b0 does not match .got section address 0x3a0d8
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/libdw/libdw.so
section [31] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0xd0c8 does not match .got section address 0xd008
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/backends/libebl_i386.so
section [31] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol value 0xf0c8 does not match .got section address 0xf008
*** failure in /home/abuild/rpmbuild/BUILD/elfutils-0.170/src/elflint --quiet --gnu-ld /home/abuild/rpmbuild/BUILD/elfutils-0.170/backends/libebl_x86_64.so
FAIL run-elflint-self.sh (exit status: 1)

FAIL: run-native-test.sh
========================

/home/abuild/rpmbuild/BUILD/elfutils-0.170/tests/allregs: dwfl_module_register_names: no backend registers known
FAIL run-native-test.sh (exit status: 1)

FAIL: run-backtrace-native-core.sh
==================================

backtrace: backtrace.c:111: callback_verify: Assertion `symname && strcmp (symname, "raise") == 0' failed.
./test-subr.sh: line 84: 26040 Aborted                 (core dumped) LD_LIBRARY_PATH="${built_library_path}${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH" $VALGRIND_CMD "$@"
backtrace-child-core.26027: no main
rmdir: failed to remove 'test-26016': Directory not empty
FAIL run-backtrace-native-core.sh (exit status: 1)

In addition, all tests that use ptrace are failing as linux-user
emulation does not implement it.

There are no regressions for a x86_64 build.

Signed-off-by: Andreas Schwab <schwab@suse.de>
6 years agolibelf: Sync elf.h from glibc
Andreas Schwab [Thu, 19 Apr 2018 15:47:47 +0000 (17:47 +0200)]
libelf: Sync elf.h from glibc

Signed-off-by: Andreas Schwab <schwab@suse.de>
6 years agotests: Test readelf --debug-dump=[decoded]line with min_inst_len > 1.
Mark Wielaard [Mon, 16 Apr 2018 09:40:22 +0000 (11:40 +0200)]
tests: Test readelf --debug-dump=[decoded]line with min_inst_len > 1.

This testcase tests the fix for the readelf --debug-dump=line bug fixed
in commit 40b1f18 "readelf: Fix advance_pc to use op_addr_advance, not
just op_advance."

This tests both the --debug-dump=line (readelf) implementation and the
--debug-dump=decodedline (libdw) implementation. The first fails without
the bug fix. The second was already correct.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Fix advance_pc to use op_addr_advance, not just op_advance.
Mark Wielaard [Mon, 16 Apr 2018 08:25:35 +0000 (10:25 +0200)]
readelf: Fix advance_pc to use op_addr_advance, not just op_advance.

Found by John Mellor-Crummey.

The reason this bug wasn't found earlier is because gcc fixes
minimum_instr_len and max_ops_per_instr to 1 for all architectures
(in theory max_ops_per_instr could be overridden, but I didn't find
any architecture that does). And op_index always seems zero (it looks
like it is really only for special VLWI architectures).

So in all cases I saw it means that:

op_addr_advance = minimum_instr_len * ((op_index + op_advance)
                                       / max_ops_per_instr)
                = 1 * ((0 + op_advance) / 1)
                = op_advance

Completely masking the bug.

The libdw dwarf_getsrclines.c implementation does get this right.
Because it doesn't care about the data representation and so does
the calculation directly.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Only lookup files and show errors in attr_callback when not silent.
Mark Wielaard [Fri, 13 Apr 2018 12:56:48 +0000 (14:56 +0200)]
readelf: Only lookup files and show errors in attr_callback when not silent.

We recently added a couple more sanity checks and show an error when
attributes that represent files cannot be resolved. We should only do
this when the attr_callback should print the attribute information.
When not (for example when not showing the .debug_info section, but
only collecting information about the CUs containing pointers into
other sections) we don't need to lookup the file names, nor print
the errors/warnings.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoaarch64: Add default cfi rule to restore SP from CFA address.
Mark Wielaard [Wed, 11 Apr 2018 08:37:45 +0000 (10:37 +0200)]
aarch64: Add default cfi rule to restore SP from CFA address.

The CFA is set by default to the stack pointer of the previous frame.
So that is also how we can always restore the SP. This default aarch64
CFI rule is necessary on Fedora 28 with GCC8 to make the run-deleted.sh
and run-backtrace-dwarf.sh testcases work.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdwfl: Handle unwind frame when the return address register isn't set.
Mark Wielaard [Tue, 10 Apr 2018 14:13:34 +0000 (16:13 +0200)]
libdwfl: Handle unwind frame when the return address register isn't set.

When we have unwound the frame and then cannot set the return address
we wouldn't set any error. That meant that a dwfl_thread_getframes ()
call could end in an error, but without any dwfl_errno set, producing
the "no error" error message.

If we cannot set the return address at the end of unwinding the frame
that means that either the return address register is bogus (error),
or that the return address is undefined (end of the call stack).

This fixes the run-backtrace-native-biarch.sh testcase for me on an
i386 on x86_64 setup with gcc 7.2.1 and glibc 2.17.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Restructure address range reading for .debug_loc and .debug_ranges.
Mark Wielaard [Mon, 2 Apr 2018 21:08:40 +0000 (23:08 +0200)]
libdw: Restructure address range reading for .debug_loc and .debug_ranges.

This caches the CU base address, makes error checking slight more relaxed
and restructures the code so it will be easier to add different forms
of ranges. Adds a new test for the new CU base address code.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Make sure to initialize Dwarf_CU addr_base and str_off_base.
Mark Wielaard [Wed, 4 Apr 2018 14:43:38 +0000 (16:43 +0200)]
libdw: Make sure to initialize Dwarf_CU addr_base and str_off_base.

The __libdw_cu_addr_base () and __libdw_cu_str_off_base () functions
rely on these fields being initialized to -1 when the values have not
yet been set up. Shows up as a valgrind warning.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add support for reading DW_FORM_strx[1234] in .debug_str_offsets.
Mark Wielaard [Wed, 14 Mar 2018 21:45:56 +0000 (22:45 +0100)]
libdw: Add support for reading DW_FORM_strx[1234] in .debug_str_offsets.

Recognize the new .debug_str_offsets section. The CU will now hold a new
str_off_base offset in that section for that CU. dwarf_form_string will
decode DW_FORM_strx[1234] and return strings using that str_off_base
from the .debug_addr.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add support for reading DW_FORM_addrx[1234] in .debug_addr.
Mark Wielaard [Fri, 24 Nov 2017 10:18:39 +0000 (11:18 +0100)]
libdw: Add support for reading DW_FORM_addrx[1234] in .debug_addr.

Recognize the new .debug_addr section. The CU will now hold a new
address base offset in that section for that CU. dwarf_form_addr will
decode DW_FORM_addrx[1234] and return addresses using that address
base from the .debug_addr. A new internal function read_3ubyte_unaligned
will try to read a 24-bit value depending on endianness of the underlying
file.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Extend documentation to explain relative file paths and comp_dir.
Mark Wielaard [Thu, 29 Mar 2018 12:09:12 +0000 (14:09 +0200)]
libdw: Extend documentation to explain relative file paths and comp_dir.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Break sysv[64] symbol hash bucket chain loops.
Mark Wielaard [Wed, 28 Mar 2018 19:27:48 +0000 (21:27 +0200)]
readelf: Break sysv[64] symbol hash bucket chain loops.

The bucket chain should not contain loops. If it does we should mark the
hash bucket chain as invalid. This is easily checked by noticing when we
have seen more than the number of chain elements. Which equals the max
number as symbols in the table.

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

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdwfl: Use process_vm_readv when available.
Mark Wielaard [Sat, 17 Mar 2018 23:24:08 +0000 (00:24 +0100)]
libdwfl: Use process_vm_readv when available.

If possible use process_vm_readv to read 4K blocks instead of fetching
each word individually with ptrace. For unwinding this often means we
only have to do one process_vm_readv of the stack instead of dozens of
ptrace calls. There is one 4K cache per process, cleared whenever a
thread is detached.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Print dwarf_dieoffset as %PRIx64, not %zx.
Mark Wielaard [Tue, 27 Mar 2018 14:22:16 +0000 (16:22 +0200)]
readelf: Print dwarf_dieoffset as %PRIx64, not %zx.

On 32bit architectures size_t is not 64bit...

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Report error when decl_file or call_file attribute is invalid.
Mark Wielaard [Tue, 20 Mar 2018 12:29:25 +0000 (13:29 +0100)]
readelf: Report error when decl_file or call_file attribute is invalid.

Report an error for why the DW_AT_decl_file or DW_AT_call_file cannot
be resolved to a file name. This is likely invalid DWARF, a missing
DW_AT_stmt_list attribute on the CU or a missing .debug_line section.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibebl: Handle SYMTAB_SHNDX in ebl_dynamic_tag_name.
Mark Wielaard [Fri, 16 Mar 2018 18:42:17 +0000 (19:42 +0100)]
libebl: Handle SYMTAB_SHNDX in ebl_dynamic_tag_name.

SYMTAB_SHNDX was introduced when elf.h was imported, but not yet handled
in ebl_dynamic_tag_name. Handle it and add an eu_static_assert to make
sure stdtags always contains DT_NUM entries.

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

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add new DWARF5 Dwarf expression operations.
Mark Wielaard [Wed, 15 Nov 2017 11:13:38 +0000 (12:13 +0100)]
libdw: Add new DWARF5 Dwarf expression operations.

DW_OP_implicit_pointer, DW_OP_entry_value, DW_OP_const_type,
DW_OP_regval_type, DW_OP_deref_type, DW_OP_xderef_type,
DW_OP_convert and OP_reinterpret are implemented like their
pre-DWARF5 GNU variants.

DW_OP_xderef_type is implemented as a (non-CU relative) variant of
DW_OP_deref_type.

DW_OP_addrx and DW_OP_constx are recognized but not interpreted yet.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdwfl: Use realpath (name, NULL) instead of canonicalize_file_name (name).
Mark Wielaard [Mon, 5 Mar 2018 13:23:14 +0000 (14:23 +0100)]
libdwfl: Use realpath (name, NULL) instead of canonicalize_file_name (name).

Some systems apparently don't provide canonicalize_file_name. Since
canonicalize_file_name (path) is defined as realpath(path, NULL) just
use realpath everywhere.

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

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Add some support for locviews.
Mark Wielaard [Wed, 28 Feb 2018 23:14:52 +0000 (00:14 +0100)]
readelf: Add some support for locviews.

This adds minimal support for locviews as output by GCC8.
It changes readelf to keep track of loclistptrs from DW_AT_GNU_locviews
and prints the locview pairs for those. Since there is no terminator
we have to keep track of where the next loclist entry starts.
The --debug-dump=loc output looks as follows:

 CU [   714] base: +0x0000000000003020 <elf_hash>
 [    b4] view pair 1, 2
 [    b6] range 4, 7f
          +0x0000000000003024 <elf_hash+0x4>..
          +0x000000000000309e <elf_hash+0x7e>
           [ 0] reg5
 [    d9] view pair 3, 1
          view pair 1, 2
 [    dd] range 4, 4c
          +0x0000000000003024 <elf_hash+0x4>..
          +0x000000000000306b <elf_hash+0x4b>
           [ 0] reg5
          range 4c, 7f
          +0x000000000000306c <elf_hash+0x4c>..
          +0x000000000000309e <elf_hash+0x7e>
           [ 0] reg2

Note that in the above output the view pairs correspond to the ranges
immediately following in the loc list. This is how GCC8 currently
outputs the locview pairs and ranges, but this is not guaranteed and
you'll need to look at the location and GNU_locviews attributes of the
DIE to know which really match up together. We might want to adjust the
output to make this more clear.

This does not yet add an locview accessor to libdw. It just recognizes
the DW_AT_GNU_locviews attribute as a loclistptr when encoded as a
sec_offset form.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoelflint: Make sure we can read a whole element when iterating over group.
Mark Wielaard [Mon, 26 Feb 2018 21:53:10 +0000 (22:53 +0100)]
elflint: Make sure we can read a whole element when iterating over group.

Change the for loop so that we can always read a full element.

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

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibebl: Allow SHT_NOTE as relocation target type.
Mark Wielaard [Wed, 21 Feb 2018 15:31:44 +0000 (16:31 +0100)]
libebl: Allow SHT_NOTE as relocation target type.

eu-elflint uses ebl_check_reloc_target_type to determine whether a section
is a valid relocation target. In Fedora rawhide there are new ELF notes
(annobin) which have relocations against them in ET_REL files. eu-elflint
currently flags these as invalid. It looks like that is not correct.
I cannot find any reason an SHT_NOTE section cannot have relocations
against it. So this patch allows them.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add support for DWARF5 DW_FORM_data16.
Mark Wielaard [Thu, 28 Dec 2017 16:44:06 +0000 (17:44 +0100)]
libdw: Add support for DWARF5 DW_FORM_data16.

The DWARF5 spec says DW_FORM_data16 is constant class (128bit value).
But we treat it as if it is block class. So to use a attribute that is
encoded as DW_FORM_data16 use dwarf_formblock, not dwarf_form[us]data.

We cannot use dwarf_form[us]data since they return a Dwarf_Word/Sword,
which are only 64bits.

This does mean we don't try to convert the value but just return it as
a block of 16 raw bytes.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle DWARF5 DW_FORM_implicit_const. Add dwarf_getabbrevattr_data.
Mark Wielaard [Sun, 26 Nov 2017 16:51:11 +0000 (17:51 +0100)]
libdw: Handle DWARF5 DW_FORM_implicit_const. Add dwarf_getabbrevattr_data.

Handle the new DW_FORM_implicit_const. The value of this form is embedded
in the abbrev data (as sleb128) and not in the info DIE data. This also
adds a new function dwarf_getabbrevattr_data which allows getting any
data/value associated with a form. eu-readelf will use this new function
to show the DW_FORM_implicit_const value.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Recognize new DWARF5 attribute forms.
Mark Wielaard [Sun, 26 Nov 2017 16:40:56 +0000 (17:40 +0100)]
libdw: Recognize new DWARF5 attribute forms.

This just makes sure we know how the new forms are encoded.
It doesn't yet handle them in the dwarf_form* functions.
But it does make it possible to skip them when reading DWARF5.

DW_FORM_implicit_const has zero size (the value is in the abbrev,
not in the info). DW_FORM_addrx[1234], DW_FORM_strx[1234],
DW_FORM_ref_sup[48] and DW_FORM_data16 have constant size.
DW_FORM_strp_sup and DW_FORM_line_strp are offset size.
DW_FORM_addrx, DW_FORM_strx, DW_FORM_loclistx and DW_FORM_rnglistx
encode a uleb128.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add new dwarf_get_units function to iterate over all units.
Mark Wielaard [Tue, 30 Jan 2018 11:05:57 +0000 (12:05 +0100)]
libdw: Add new dwarf_get_units function to iterate over all units.

The dwarf_nextcu and dwarf_next_unit functions provide information to
construct the offset to construct the associated CU DIE using dwarf_offdie
or dwarf_offdie_types.  This requires the user to know beforehand where
to DIE data is stored (in the .debug_info or .debug_types section).
For type units one also needs to use the type offset to create the actual
type DIE. In DWARF5 DIEs can come from even more data locations. And there
are also skeleton units which require the user to find the associated
split compile unit DIE (which would come from a different file).

The new dwarf_get_units function simplifies iterating over the units in
a DWARF file. It doesn't require the user to know where the DIE data is
stored, it will automagically iterate over all know data sources (sections)
returning the Dwarf_CU and the associated Dwarf_Die if requested. If the
user requests to know the associated "subdie" it will also be resolved.

This implementation returns the correct subdie for type units. A future
version will also handle skeleton units and return the associated skeleton
DIE and split unit DIE.

readelf has been adapted to use the new iterator and print the new DWARF5
unit header information (which it gets through dwarf_cu_die). The new
interface hides which section exactly to iterate on (by design). readelf
works around that by "cheating". It sets up a Dwarf_CU so that it gets
the data from the right section, using the (normally) internal data
structure.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Parse new DWARF5 units and CU DIEs.
Mark Wielaard [Mon, 29 Jan 2018 14:59:05 +0000 (15:59 +0100)]
libdw: Parse new DWARF5 units and CU DIEs.

Parse DWARF5 units, add the unit_type to the Dwarf_CU and generalize some
code calculating the header length and getting at the first DIE of a unit.
Unit headers can have different sizes depending on the unit type.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibelf: Sync elf.h from glibc.
Mark Wielaard [Fri, 16 Feb 2018 23:23:19 +0000 (00:23 +0100)]
libelf: Sync elf.h from glibc.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Accept any core if no core with the "correct" pid can be found.
Mark Wielaard [Fri, 16 Feb 2018 19:34:25 +0000 (20:34 +0100)]
tests: Accept any core if no core with the "correct" pid can be found.

In some containers our view of pids is confused. We see the container
pid namespace, but the core is generated using the host pid namespace.
Since tests are run in a new fresh directory any core here is most like
is ours.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoInclude sys/ptrace.h as early as possible.
Mark Wielaard [Thu, 15 Feb 2018 13:44:18 +0000 (14:44 +0100)]
Include sys/ptrace.h as early as possible.

On some systems, at least on Fedora 27 ppc64le with glibc 2.26-24 and
kernel 4.14.18-300, including sys/ptrace.h late (after signal.h or
sys/wait.h for example) will cause issues and produce errors like:

In file included from /usr/include/asm/sigcontext.h:12:0,
                 from /usr/include/bits/sigcontext.h:30,
                 from /usr/include/signal.h:287,
                 from /usr/include/sys/wait.h:36,
                 from linux-pid-attach.c:38:
/usr/include/sys/ptrace.h:73:3: error: expected identifier before numeric constant
   PTRACE_GETREGS = 12,
   ^

Swapping the include order fixes these issues.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add dwarf_die_addr_die function.
Mark Wielaard [Thu, 25 Jan 2018 00:13:10 +0000 (01:13 +0100)]
libdw: Add dwarf_die_addr_die function.

Currently storing a lot of Dwarf_Dies might be inefficient since it
costs a lot of memory since the sizeof (Dwarf_Die) == 32 bytes on 64bit
arches. You can try storing just the Dwarf_Off from dwarf_dieoffset.
Which is just 8 bytes. But then you have to keep track of whether to
call dwarf_dieoffset, if the Dwarf_Die came from the main .debug_info,
or call dwarf_dieoffset_types, if it came from .debug_types. And you'll
have to keep track of whether it came from the main Dwarf or the alt
Dwarf (dwz multi file). With DWARF5 or GNU DebugFission split-dwarf
you will also need to know which split Dwarf file the original DIE
came from.

A Dwarf_Die consists of an addr pointer where the actual DIE data
comes from, a CU pointer that provides context (and has a pointer
to the Dwarf file the Die is associated with) and a (cached)
Dwarf_Abbrev pointer that is initialized when the Dwarf_Die is
first read and describes how to interpret the DIE data.

libdw already keeps track of the data pointers (sections) of a
Dwarf file and given an offset it can already reconstruct the
other Dwarf_Die fields. So this patch introduces dwarf_die_addr_die.
Given a Dwarf_Die addr dwarf_die_addr_die returns a (reconstructed)
Dwarf_Die, or NULL if the given addr didn't come from a valid
Dwarf_Die. In particular it will make sure that the correct Dwarf_CU
pointer is set for the Dwarf_Die, the Dwarf_Abbrev pointer will not
be set up yet (it will only be once the Dwarf_Die is used to read
attributes, children or siblings).

This functions can be used to keep a reference to a Dwarf_Die which
you want to refer to later. The addr, and the result of this function,
is only valid while the associated Dwarf is valid.

Since libdw already had to lookup the Dwarf_CU given an offset, this
function is as efficient as dwarf_dieoffset (or dwarf_dieoffset_types)
without having to know the original origin of the Dwarf_Die. It will
search both the .debug_info and .debug_types data sections from both
the main Dwarf or the alt Dwarf file. Once split dwarf support is added
it will also look in any split dwarf .dwo (or the .dwp) file.

The only limitation, compared to using a Dwarf_Off and dwarf_dieoffset,
is that it only works during runtime while the main Dwarf object is
valid (till dwarf_end has been called on it).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoUse fallthrough attribute.
Joshua Watt [Fri, 9 Feb 2018 16:27:18 +0000 (10:27 -0600)]
Use fallthrough attribute.

Use __attribute__ ((fallthrough)) to indicate switch case fall through
instead of a comment. This ensures that the fallthrough warning is not
triggered even if the file is pre-processed (hence stripping the
comments) before it is compiled.

The actual fallback implementation is hidden behind a FALLBACK macro in
case the compiler doesn't support it.

Finally, the -Wimplict-fallthrough warning was upgraded to only allow
the attribute to satisfy it; a comment alone is no longer sufficient.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
6 years agolibdw: Resolve alt file on first use.
Mark Wielaard [Fri, 19 Jan 2018 22:59:21 +0000 (23:59 +0100)]
libdw: Resolve alt file on first use.

Add a new alt_fd field to the Dwarf struct. This tracks whether we tried
to open the alt file ourselves. This is used in dwarf_getalt to see if
we should try to find and open the alt file ourselves (if the user hasn't
called dwarf_setalt yet). dwarf_formref_die and dwarf_formstring now call
dwarf_getalt instead of accessing the alt_dwarf Dwarf field directly.

For applications using libdwfl nothing changes (dwfl will find, set and
clean up the alt file). For programs that set the alt file themselves
already through other means, nothing changes. But for applications that
don't create the Dwarf through libdwfl and don't set the alt file already
libdw will now try to find and set it on first access. If found the
application will now not get errors for missing alt files.

Add a simple testcase based on the existing allfcts test which already
tries to set the alt file, but is too simplistic to find it in some
subdir (relative to the main debug file).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Check symtabshdr instead of symtabndx in elfstrmerge.c.
Mark Wielaard [Thu, 25 Jan 2018 13:37:17 +0000 (14:37 +0100)]
tests: Check symtabshdr instead of symtabndx in elfstrmerge.c.

Some gcc omptimization levels (-Og in particular) didn't see that when
symtabndx != 0, then symtabshdr was certain to be initialized. Change
the symtabndx == 0 check to symtabshdr == NULL and initialize symtabshdr
to work around that.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Fix crash on reading loc data or range data with bad/no CUs.
Mark Wielaard [Thu, 25 Jan 2018 12:24:19 +0000 (13:24 +0100)]
readelf: Fix crash on reading loc data or range data with bad/no CUs.

In print_debug_ranges_section and print_debug_loc_section we try to
get the associated CU through skip_listptr_hole for the first data data.
If no CU at all can be found (because the .debug_info section was bogus)
this would keep the Dwarf_CU uninitialized causing a crash later on
when it was compared to the last_cu and used because it was unequal.
Fix this by explicitly initializing cu to last_cu (which is NULL on
first use).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: dwarf_formsdata should return a signed value
Petr Machata [Sun, 14 Jan 2018 02:22:05 +0000 (03:22 +0100)]
libdw: dwarf_formsdata should return a signed value

The function dwarf_formsdata is used for decoding signed values, but
except for the variable-length DW_FORM_sdata, it uses unsigned
primitives to decode the value. This is not a problem for 64-bit values,
but the smaller values come decoded wrong. Fix by changing to signed
primitives for decoding the fixed-length forms.

Add a test case that uses dwarf_aggregate_size to determine an array
size whose lower bound is -1, encoded using DW_FORM_data1, and upper
bound 255 with DW_FORM_data2. When the -1 is decoded wrongly, it comes
back as 255, and the array size is 1. The correct array size should be
257.

Signed-off-by: Petr Machata <pmachata@gmail.com>
6 years agolibdw: Reduce size of struct Dwarf_Abbrev.
Mark Wielaard [Tue, 26 Dec 2017 15:49:46 +0000 (16:49 +0100)]
libdw: Reduce size of struct Dwarf_Abbrev.

If we don't cache the attrcnt and use bitfields for the has_children and
code we can reduce the size of struct Dwarf Abbrev from 32 to 24 bytes on
64bit architectures and from 28 to 20 bytes on 32bit arches.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: New get_uleb128_unchecked to use with already checked Dwarf_Abbrev.
Mark Wielaard [Tue, 26 Dec 2017 10:52:06 +0000 (11:52 +0100)]
libdw: New get_uleb128_unchecked to use with already checked Dwarf_Abbrev.

When creating a Dwarf_Abbrev in dwarf_getabbrev (__libdw_getabbrev) we
already check it is fully readable from the .debug_abbrev section. So
whenever we reread it later using the attrp pointer we don't have to
check it again. Introduce get_uleb128_unchecked to use for ulebs we
know are safe to read directly.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Use dwarf_form_name for printing (unknown) forms.
Mark Wielaard [Mon, 1 Jan 2018 21:39:24 +0000 (22:39 +0100)]
readelf: Use dwarf_form_name for printing (unknown) forms.

Use dwarf_form_name consistently to print forms. attr_callback was
using its own string conversion, print_debug_macro_section was using
dwarf_form_string instead of dwarf_form_name.

The difference between dwarf_form_string and dwarf_form_name is that
the first returns NULL if the form is unknown and the second returns
an hexadecimal string representation in that case.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Try to use coredumpctl to extract core files.
Mark Wielaard [Sat, 23 Dec 2017 22:16:24 +0000 (23:16 +0100)]
tests: Try to use coredumpctl to extract core files.

If systemd-coredump is installed we have to use coredumpctl to extract
the core file to test. Unfortunately systemd-coredump/coredumpctl seem
to be somewhat fragile if multiple core dumps are generated/extracted
at the same time. So use a lock file to only run one core dump test at
a time (under make -j).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Format offset as DIE index (hex).
Mark Wielaard [Thu, 28 Dec 2017 23:46:19 +0000 (00:46 +0100)]
readelf: Format offset as DIE index (hex).

That makes it so much easier to find the actual DIE offset in the output.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Check there is .debug_info/types section data in __libdw_offdie.
Mark Wielaard [Thu, 28 Dec 2017 23:34:14 +0000 (00:34 +0100)]
libdw: Check there is .debug_info/types section data in __libdw_offdie.

If a Dwarf_Die was requested from an offset into a section data that
didn't exist we would crash. Crashing is bad even if given bad input.
Just return an error in that case.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoDon't overflow in __libdw_in_section and __libdw_offset_in_section.
Ulf Hermann [Tue, 9 May 2017 16:28:33 +0000 (18:28 +0200)]
Don't overflow in __libdw_in_section and __libdw_offset_in_section.

This exposes a bug in dwarf_formstring as detected by the dwarf-getmacros
test before we made sure to use the correct sec_idx for the CU.

Signed-off-by: Ulf Hermann <ulf.hermann@qt.io>
Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Add explicit section index to struct Dwarf_CU.
Mark Wielaard [Wed, 20 Dec 2017 15:50:57 +0000 (16:50 +0100)]
libdw: Add explicit section index to struct Dwarf_CU.

The DIE (attribute) data might come from either the main .debug_info
section or for DWARFv4 from a separate .debug_types section. Or in
case of the fake_loc_cu from the .debug_loc section and in the case
of macros from the .debug_macinfo or .debug_macro section.

We didn't handle the last two "fake" CU cases correctly when sanity
checking offsets in __libdw_read_address and __libdw_read_offset.

Add an explicit sec_idx field to struct Dwarf_CU that is always set
to the actual section that the data came from.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Try to continue after encountering bogus ELF Note data.
Mark Wielaard [Mon, 18 Dec 2017 11:39:13 +0000 (12:39 +0100)]
readelf: Try to continue after encountering bogus ELF Note data.

There might be other sections or segments with ELF Notes that are
readable. Also adjust error message depending on whether or not we
actually got any data for the ELF Note segment or section.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: dwarf_aggregate_size should not peel the given DIE.
Mark Wielaard [Mon, 11 Dec 2017 22:58:34 +0000 (23:58 +0100)]
libdw: dwarf_aggregate_size should not peel the given DIE.

Reserve memory for a new DIE first. The caller might not care, but it
isn't really nice to change the DIE the caller gave us.

See also https://sourceware.org/bugzilla/show_bug.cgi?id=22546#c5

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: dwarf_aggregate_size() works with multi-dimensional arrays
Dima Kogan [Fri, 8 Dec 2017 09:45:10 +0000 (01:45 -0800)]
libdw: dwarf_aggregate_size() works with multi-dimensional arrays

If we have a multidimensional array of dimensions (a,b,c) the number of elements
should be a*b*c, but prior to this patch dwarf_aggregate_size() would report
a+b+c instead.

This patch fixes the bug and adds a test that demonstrates the bug (the test
fails without the functional part of this patch).

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

Signed-off-by: Dima Kogan <dima@secretsauce.net>
6 years agoreadelf: Handle DW_OP_call2 and DW_OP_call4 correctly.
Mark Wielaard [Thu, 7 Dec 2017 15:31:54 +0000 (16:31 +0100)]
readelf: Handle DW_OP_call2 and DW_OP_call4 correctly.

DW_OP_call2 and DW_OP_call4 didn't correctly advance the data pointer.
This caused print_ops to produce garbage operands. Also format the
arguments as DIE offsets. That makes it easier to follow the call to the
actual dwarf_procedure DIE.

Testcase from https://sourceware.org/bugzilla/show_bug.cgi?id=22532

The testcase only checks the eu-readelf output is correct for the
byte_size attribute. But it might be interesting to write a full
expression parser to check the actual sizes.

 [    3e]    structure_type
             name                 (strp) "pck__rec"
             byte_size            (exprloc)
              [   0] push_object_address
              [   1] deref_size 1
              [   3] call4 [    95]
              [   8] plus_uconst 7
              [  10] const1s -4
              [  12] and

 [    95]    dwarf_procedure
             location             (exprloc)
              [   0] dup
              [   1] lit1
              [   2] ne
              [   3] bra 10
              [   6] lit4
              [   7] skip 31
              [  10] dup
              [  11] lit4
              [  12] ne
              [  13] bra 20
              [  16] lit0
              [  17] skip 31
              [  20] dup
              [  21] lit3
              [  22] eq
              [  23] bra 30
              [  26] lit0
              [  27] skip 31
              [  30] lit4
              [  31] swap
              [  32] drop

The "answer" depends on the Discr value (first byte at object address),
and is rounded up to 4 or 8 bytes.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Hook up -g, --section-groups to display the section groups.
Mark Wielaard [Wed, 29 Nov 2017 23:10:58 +0000 (00:10 +0100)]
readelf: Hook up -g, --section-groups to display the section groups.

It was already possible to display the section groups using -a, but
the argp options didn't yet have an -g, --section-groups entry to
just display the section groups.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Print CU, base address and unresolved .debug_loc entries.
Mark Wielaard [Wed, 29 Nov 2017 15:37:50 +0000 (16:37 +0100)]
readelf: Print CU, base address and unresolved .debug_loc entries.

Also adjust the formatting for the resolved addresses to print them
on separate lines so they nicely line up even when the addresses are
resolved to symbol+offset names. And print the operands starting on
a new line.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Print CU, base address and unresolved .debug_range entries.
Mark Wielaard [Wed, 29 Nov 2017 15:27:33 +0000 (16:27 +0100)]
readelf: Print CU, base address and unresolved .debug_range entries.

Also adjust the formatting for the resolved addresses to print them
on separate lines so they nicely line up even when the addresses are
resolved to symbol+offset names.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Print actual file for decl_file and call_file attributes.
Mark Wielaard [Wed, 29 Nov 2017 15:06:36 +0000 (16:06 +0100)]
readelf: Print actual file for decl_file and call_file attributes.

When we see a DW_AT_decl_file or DW_AT_call_file attribute print the
actual file name. The current interface gives us a full (absolute) patch,
but we only want to show the file name for now to not clutter the output
too much. This helps a lot when trying to determine where something was
declared if you are just looking at the DIE tree. Otherwise you'll have
to cross match the number by hand with the corresponding line table entry.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Print abbrev code for DIE with --debug-dump=info.
Mark Wielaard [Wed, 29 Nov 2017 14:58:40 +0000 (15:58 +0100)]
readelf: Print abbrev code for DIE with --debug-dump=info.

If there is anything wrong with a DIE it is useful to know what the abbrev
code was so you can lookup the abbrev description.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Adjust print_ops formatting.
Mark Wielaard [Wed, 29 Nov 2017 14:43:26 +0000 (15:43 +0100)]
readelf: Adjust print_ops formatting.

Use only 2 spaces for index (there are never 10000, the most seen in the
wild is 64). Adjust re-indenting after GNU_entry_value.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdwfl: Don't dereference possibly unaligned auxv entry pointer from core.
Mark Wielaard [Mon, 20 Nov 2017 13:11:02 +0000 (14:11 +0100)]
libdwfl: Don't dereference possibly unaligned auxv entry pointer from core.

The notes in a core file that contain the auxv entries might not be
naturally aligned. The code already tried to account for that, but
the GCC 8 undefined behaviour sanitizer found we were till dereferencing
the actual auxv entry pointer directly. Fix this by calculating all pointers
by hand and not use an array of auxv entries trick.

This makes make distcheck (which enables sanitize-undefined by default)
pass again using GCC8.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Print attribute name and form in error message.
Mark Wielaard [Tue, 21 Nov 2017 10:13:00 +0000 (11:13 +0100)]
readelf: Print attribute name and form in error message.

Now an error getting the attribute value will not only print the DIE offset
and the reason, but also the attribute name and form. e.g.

  DIE [b] cannot get attribute 'ranges' (sec_offset) value: .debug_ranges
  section missing

Also we don't abort, but try to print the other attributes of the DIE
anyway. It might just be one attribute whose value cannot be resolved.

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agoreadelf: Print DIE offset in attribute reading error messages.
Mark Wielaard [Tue, 3 Oct 2017 14:55:25 +0000 (16:55 +0200)]
readelf: Print DIE offset in attribute reading error messages.

When processing large files it is useful to know the DIE offset if
printing of attributes fails (especially when redirecting the output).
With this change the error message looks like:

  eu-readelf: DIE [2aeb8ef1] cannot get attribute value: invalid DWARF

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Fix cfi_debug => cfi_debug_bias typo in varlocs assert.
Mark Wielaard [Thu, 16 Nov 2017 12:20:11 +0000 (13:20 +0100)]
tests: Fix cfi_debug => cfi_debug_bias typo in varlocs assert.

We want to check whether the bias is zero, not whether we have dwarf
debug_frame cfi.

This triggered on a ppc64/ppc64le self-check since it has both
debug_frame and eh_frame cfi (other arches often only have eh_frame).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agotests: Add varlocs-self and exprlocs-self tests.
Mark Wielaard [Wed, 8 Nov 2017 10:25:33 +0000 (11:25 +0100)]
tests: Add varlocs-self and exprlocs-self tests.

Make sure the testcases (library functions they use) don't crash,
triggers self-check/asserts or leaks memory under valgrind. This
also helps making sure newer DWARF constructs are handled (when
building with -gdwarf-5).

Signed-off-by: Mark Wielaard <mark@klomp.org>
6 years agolibdw: Handle DW_OP_GNU_variable_value.
Mark Wielaard [Thu, 2 Nov 2017 15:24:41 +0000 (16:24 +0100)]
libdw: Handle DW_OP_GNU_variable_value.

Handle DW_OP_GNU_variable_value in dwarf_getlocation[_attr,_die].
DW_OP_GNU_variable_value takes one argument a DIE reference that
describes a value given by a location of const_value attribute.

To test handling of the new operand the varlocs test is adapted
to print out all DIEs and attributes with expressions or location
lists (the original varlocs test only prints out variables and
arguments of function DIEs).

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