| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
ndirs is read from the debug data and should be size checked before use.
https://sourceware.org/bugzilla/show_bug.cgi?id=23248
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
|
|
|
|
|
|
|
| |
Add explicit test in get-units-invalid for dwarf_cuoffset and
dwarf_dieoffset. Make sure dwarf_dieoffset returns (Dwarf_Off) -1
on failure.
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
dwarf_die_addr_die can be used to turn an Dwarf_Die addr back into a
full Dwarf_Die, just given the original Dwarf debug handle. This now
also works for Dwarf_Dies which originated from a split Dwarf. Whenever
a split Dwarf_CU is found the Dwarf it originated from is registered
with the Dwarf that the skeleton Dwarf_CU came from. All registered
split Dwarfs are then searched by dwarf_die_addr_die if the addr didn't
match the main Dwarf or the alt Dwarf.
One limitation in this implementation is that only DIEs that come from
the main .debug_info in the .dwo are supported. Theoretically there could
also be DIEs in an .debug_type or from other/multiple (comdat) sections.
New tests are added for dwarf-4, dwarf-5, split-dwarf-4, split-dwarf-5
and version 4 and 5 dwo files.
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
| |
Most are handled just like their DWARF5 counterparts.
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|