Age | Commit message (Collapse) | Author |
|
|
|
You misused your toys and I'm now taking them away, reflect on what you
did wrong for a bit.
|
|
The previous solution of "lol whats a UB" was not nice and tripped over
itself when it was run under UBSAN, fix this by doing explicit
byte-by-byte reads where needed.
|
|
And limit the `void*` to the functions that interface the system (i.e.
ptrace wrappers).
This generally makes the code less riddled with casts.
|
|
|
|
|
|
The format of the address range section is different between DWARF
version 4 and version 5. This meant that we parsed programs compiled
with `-gdwarf-4` incorrectly.
|
|
The parameter of this operator is an unsigned LEB128 integer, so it can
be more than 1 byte in length. If we only read 1 byte, we might mess up
the offsets for the instructions following it.
|
|
|
|
Our implementation (naively) assumes that there is a one-to-one
correspondence between compilation units and line programs, and that
their orders are identical. This is not the case for embedded resources,
as Clang only creates line programs for it, but not compilation units.
This mismatch caused an assertion failure, which made generating
backtraces for GUI applications impossible. This commit introduces a
hack that skips creating CompilationUnit objects for LinePrograms that
come from embedded resources.
|
|
With this change, our DWARF 5 support is nearly feature-complete.
|
|
Clang emits this form at all debug levels.
|
|
These forms were introduced in DWARF5, and have a fair deal of
advantages over the more traditional encodings: they reduce the size of
the binary and the number of relocations.
GCC does not emit these with `-g1` by default, but Clang does at all
debug levels.
|
|
This will be needed when we add `DW_FORM_strx*` and `DW_FORM_addrx*`
support, which requires us to fetch `DW_AT_str_offsets_base` and
`DW_AT_addr_base` attributes from the parent compilation unit. This
can't be done as we read the values, because it would create infinite
recursion (as we might try to parse the compilation unit's
`DW_FORM_strx*` encoded name before we get to the attribute). Having
getters ensures that we will perform lookups if they are needed.
|
|
|
|
Previously, we only supported DIEs with a contiguous address ranges and
ignored ones with a non-contiguous set of ranges.
We now check if a DIE has the DW_AT_ranges attribute, and if it does we
parse its range list.
This improves the quality of our backtraces - we previously missed many
inlined function calls because their DIEs had non-contigues address
ranges.
|
|
This adds support for parsing DWARF "range lists", which are identified
by the DW_AT_ranges form.
They contain code addresses for DIEs whose location is not contiguous.
|
|
The base address of the compilation unit is used in some range lists
entry types.
|
|
These API's are used in a variety of ways when building the die cache.
Each AbbreviationEntry has vector and other members, so avoid copying
it at all costs.
|
|
This algorithm is both iterative and recursive, so allocating on every
recursion, or when iterating each child is extremely costly.
Instead allow the on stack DIE to be re-initialized so it can be reused.
|
|
This helps us avoid weird truncation issues and fixes a bug on Clang
builds where truncation while reading caused the DIE offsets following
large LEB128 numbers to be incorrect. This removes the need for the
separate `LongUnsignedNumber` type.
|
|
This LineProgram instruction is emitted by Clang. Although we currently
have no use for it (it's mostly a debugger feature), we need to handle
this opcode, as otherwise CrashReporter wouldn't work.
|
|
|
|
|
|
This fixes a couple of warnings emitted by Clang.
|
|
|
|
This enables building more of the userspace applications for x86_64.
|
|
|
|
This function returns a DIE object from the cache with the given offset
in the debug_info section.
|
|
This function returns the die object whose address range intersects
with the given address.
This function will also construct the DIE cache, if it hasn't been
constructed yet.
|
|
There is one cache that indexes DIE objects by the start address of
their range, and another cache that indexes by their offset in the
debug_info section.
Both caches are implemented with RedBlackTree, and are optional - they
will only be populated if 'build_cached_dies' is invoked.
|
|
In the current implementation, only DIE objects that are created via
DIE::for_each_child() will have parent offsets.
DIE objects that are created with CompilationUnit::get_die_at_offset()
do not currently store a parent offset.
We may improve this in the future, but this is enough for what we
currently need.
|
|
In some contexts, it's helpful to also know the "Attribute Form",
in addition to the "Attribute Type".
An example for such context is the interpretation of the
"DW_AT_high_pc" attribute, which has different meaning if the form
is an address or a constant.
|
|
This function returns the directory path & filename for a given file
index.
|
|
Previously, the LineProgram objects were short-lived, and only created
inside DebugInfo::prepare_lines() to create a vector of sorted LineInfo
data.
However, Dwarf::LineProgram also contains other useful data, such as
index-to-string mapping of source directories and filenames.
This commit makes each Dwarf::CompilationUnit own its
Dwarf::LineProgram.
DebugInfo::prepare_lines() then iterates over the compilation units to
prepare its sorted vector of lines.
|
|
This fixes an issue were some LibDebug objects (for example,
Dwarf::CompilationUnit) held a reference to their parent
Dwarf::DwarfInfo object, which was constructed on the stack and later
moved to the heap.
|
|
|
|
|
|
Avoid promotion of static strings to AK::String, instead use
AK::StringView and operator ""sv, to force string view's instead
which avoids allocation of String. This code path isn't hot enough
that it makes a huge difference, but every bit counts.
|
|
These two header files relied on transitive header includes.
|
|
This code path is very hot, and since we're seeing a lot of the same
strings repeatedly (and they're heading into a FlyString for storage)
let's construct those using FlyString(StringView) to avoid temporary
String objects.
|
|
|
|
We were using ELF::Image::section(0) to indicate the "undefined"
section, when what we really wanted was just Optional<Section>.
So let's use Optional instead. :^)
|
|
This adds support for the basic_block register to the Dwarf line
number state machine.
|
|
While symbolicating a crash dump for UserspaceEmulator I came across
another data form we didn't support.
ImplicitConst encodes a LEB128 value in the abbreviation record
rather than - like all other values - in the .debug_info section.
|
|
|
|
|
|
|
|
|
|
|