When parsing an optimized value and reading a piece from a file address,
LLDB tries to read the data from memory using that address.
This patch converts file address to load address before reading the
memory.
Fixes#111313Fixes#97484
This fixes all the places that hit the new assertion added in
https://github.com/llvm/llvm-project/pull/106524 in tests. That is,
cases where the value passed to the APInt constructor is not an N-bit
signed/unsigned integer, where N is the bit width and signedness is
determined by the isSigned flag.
The fixes either set the correct value for isSigned, set the
implicitTrunc flag, or perform more calculations inside APInt.
Note that the assertion is currently still disabled by default, so this
patch is mostly NFC.
This fixes the following assertion: "Cannot create Expected<T> from
Error success value." The problem was that GetFrameBaseValue return
false without updating the Status argument. This patch eliminates the
opportunity for mistakes by returning an llvm:Error.
This PR is in reference to porting LLDB on AIX.
Link to discussions on llvm discourse and github:
1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
2. #101657
The complete changes for porting are present in this draft PR:
https://github.com/llvm/llvm-project/pull/102601
The changes on this PR are intended to avoid namespace collision for
certain typedefs between lldb and other platforms:
1. tid_t --> lldb::tid_t
2. offset_t --> lldb::offset_t
This PR extends Dwarf.def to include the number of operands and the arity (the
number of entries on the DWARF stack).
- The arity is used in LLDB's DWARF expression evaluator.
- The number of operands is unused, but is present in the table to avoid
confusing the arity with the operands. Keeping the latter up to date should
be straightforward as it maps directly to a table present in the DWARF
standard.
This patch make all errors start with a lowercase letter and removes
trailing periods and newlines. This fixes inconsistencies between error
messages and facilitate concatenating them.
Change the signature of `DWARFExpression::Evaluate` and
`DWARFExpressionList::Evaluate` to return an `llvm::Expected` instead of a
boolean. This eliminates the `Status` output parameter and generally improves
error handling.
We received a bug report where someone was trying to print a global
variable without a process. This would succeed in a debug build but fail
in a on optimized build. We traced the issue back to the location being
described by a DW_OP_addr + DW_OP_piece.
The issue is that the DWARF expression evaluator only support reading
pieces from a load address. There's no reason it cannot do the same for
a file address, and indeed, that solves the problem.
I unsuccessfully tried to craft a test case to illustrate the original
example, using a global struct and trying to trick the compiler into
breaking it apart with SROA. Instead I wrote a unit test that uses a
mock target to read memory from.
rdar://127435923
The algorithm to find the DW_OP_entry_value requires you to find the
nearest non-inlined frame. It did that by counting the number of stack
frames so that it could use that as a loop stopper.
That is unnecessary and inefficient. Unnecessary because GetFrameAtIndex
will return a null frame when you step past the oldest frame, so you
already have the "got to the end" signal without counting all the stack
frames.
And counting all the stack frames can be expensive.
As a followup of https://github.com/llvm/llvm-project/pull/67851, I'm
defining a new namespace `lldb_plugin::dwarf` for the classes in this
Plugins/SymbolFile/DWARF folder. This change is very NFC and helped me
with exporting the necessary symbols for my out-of-tree language plugin.
The only class that I didn't change is ClangDWARFASTParser, because that
shouldn't be in the same namespace as the generic language-agnostic
dwarf parser.
It would be a good idea if other plugins follow the same namespace
scheme.
This rewrites DW_OP_addrx inside DWARFExpression as an DW_OP_addr so
that we can update addresses that are originally located in the
debug_addr section.
The full discussion behind this can be found in
https://discourse.llvm.org/t/dwarfexpression-and-dw-op-addrx/71627/12, but a
summary follows.
When SymbolFileDWARF::ParseVariableDIE creates DWARFExpressions for
variables whose location is an OP_addr, it knows how to remap
addresses appropriately in the DebugMap case. It then calls
DWARFExpression::Update_DW_OP_addr, which updates the value associated
with OP_addr.
However, when we have an OP_addrx, the update function does
nothing. This makes sense, as the DWARFExpression does not have a
mutable view of the debug_addr section. In non-DebugMap flows this is
not an issue, as the debug_addr contains the correct addresses of
variables. In DebugMap flows, this is problematic because the work
done by RelinkOSOAddress is lost. By updating the OP to OP_addr, we
can also update the address as required,
We also explored the alternative of relinking the debug_addr section
when we are initializing OSOs (InitOSO). However, this creates an
inconsistent story for users of
DWARFExpression::GetLocation_DW_OP_addr. This function returns an
address without telling callers whether that address came from an
OP_addr or an OP_addrx. If we preemptively relink OP_addrx results
without doing the same for OP_addr results, then callers can’t know
whether the address they got was an executable address or an object
file address. In other words, they can’t know whether they need to
call LinkOSOFileAddress on those results or not.
This patch addresses the majority of test failures when enabling DWARF
5 for MachO (over 200 test failures).
Differential Revision: https://reviews.llvm.org/D155198
In two calls to ReadMemory in DWARFExpression.cpp, the buffer size
passed to ReadMemory is not checked and can be bigger than the actual
size of the buffer. This caused a buffer overflow bug, which we
found through Address Sanitizer. This patch fixes the problem by
checking the address size when it is first read out of the DWARF, and
setting an error and returning immediatley if the size is invalid.
This is the second attempt to fix this issue; I reverted the first one,
as it was not quite correct.
Differential Revision: https://reviews.llvm.org/D154907
This reverts commit ee476996be.
That commit was not the right way to fix the issue (it could result in
reading too many bytes). A better fix is in the works.
Original review: https://reviews.llvm.org/D153840
A very old commit (9422dd64f8) changed the signature of this function in a
number of ways. This patch aims to improve it:
1. Reword the documentation, which still mentions old parameters that no longer
exist, and to elaborate upon the behavior of this function.
2. Remove the unnecessary parameter `op_addr_idx`. This parameter is odd in a
couple of ways: we never use it with a value that is non-zero, and the matching
`Update_DW_OP_addr` function doesn't use a similar parameter. We also document
that this new behavior. If we ever decide to handle multiple "DW_OP_addr", we
can introduce the complexity again.
Differential Revision: https://reviews.llvm.org/D154265
In two calls to ReadMemory in DWARFExpression.cpp, the buffer size
passed to ReadMemory is not actually the size of the buffer (I suspect
a copy/paste error where the variable name was not properly
updated). This caused a buffer overflow bug, which we found throuth
Address Sanitizer. This patch fixes the problem by passing the
correct buffer size to the calls to ReadMemory (and to the
DataExtractor).
Differential Revision: https://reviews.llvm.org/D153840
This patch resolves an issue where a value
is incorrectly displayed if it is represented
by DW_OP_div.
This issue is caused by lldb evaluating
operands of DW_OP_div as unsigned
and performed unintended unsigned
division.
This issue is resolved by creating two
temporary signed scalar and performing
signed division.
(Addresses GH#61727)
Differential Revision: https://reviews.llvm.org/D147370
This patch resolves an issue where a value
is incorrectly displayed if it is represented
by DW_OP_div.
This issue is caused by lldb evaluating
operands of DW_OP_div as unsigned
and performed unintended unsigned
division.
This issue is resolved by creating two
temporary signed scalar and performing
signed division.
(Addresses GH#61727)
Differential Revision: https://reviews.llvm.org/D147370
lldb may crash when performing `image lookup --verbose --address $ADDR`.
The ExecutionContext that gets passed into DWARFExpression::Evaluate may
be valid but unpopulated. However, in one specific case, we were
assuming that it has a valid Target and using it without checking first.
We reach this codepath when we attempt to get information about an
address that doesn't map to a CompileUnit in the module containing the
requested address. lldb then checks to see if it maps to a global
variable, so lldb has to evaluate the location of each global variable
in the module. If a location expression contains DW_OP_deref_size that
uses a FileAddress, we hit this code path. The simplest test case is to
take a module that has a global variable with DW_OP_deref_size in its
location expression, attempt to read an address that doesn't map to a
CompileUnit (e.g. 0x0) and ensure we don't crash.
Differential Revision: https://reviews.llvm.org/D143792
DWARFExpression::Evaluate will convert DW_OP_addr addresses in
a DWARF expression into load addresses on the expression stack
when there is a StackFrame in the ExecutionContext, this from
a change in 2018 in https://reviews.llvm.org/D46362. At the
time this was handling a case that came up in swift programs,
and is no longer necessary. I generalized this conversion to
a load address when a Target is available in
https://reviews.llvm.org/D137682 to make a test case possible;
this change broke a use case that Ted reported.
This change removes my test case, and removes this conversion
of a DW_OP_addr into a load address in some instances.
Differential Revision: https://reviews.llvm.org/D139226
Parsing DWARF expressions currently does not support DW_OPs that are vendor
extensions. With this change expression parsing calls into SymbolFileDWARF for
unknown opcodes, which is the semantically "closest" plugin that we have right
now. Plugins can then extend SymbolFileDWARF to add support for vendor
extensions.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D137247
When we cannot allocate memory in the inferior process, the IR
interpreter's IRMemoryMap::FindSpace will create an lldb local
buffer and assign it an address range in the inferior address
space. When the interpreter sees an address in that range, it
will read/write from the local buffer instead of the target. If
this magic address overlaps with actual data in the target, the
target cannot be accessed through expressions.
Instead of using a high memory address that is validly addressable,
this patch uses an address that cannot be accessed on 64-bit systems
that don't actually use all 64 bits of the virtual address.
Differential Revision: https://reviews.llvm.org/D137682
rdar://96248287
When resolving absolute addresses for DW_OP_addr or DW_OP_addrx, these are always load addresses rather than file addresses in wasm.
Reviewed By: DavidSpickett
Differential Revision: https://reviews.llvm.org/D135664
This patch had to be reverted because on gcc 7.5.0 we see an error converting from std::unique_ptr<MCRegisterInfo> to Expected<std::unique_ptr<MCRegisterInfo>> as the return type for the function createRegInfo. This has now been fixed.
I went over the output of the following mess of a command:
(ulimit -m 2000000; ulimit -v 2000000; git ls-files -z | parallel
--xargs -0 cat | aspell list --mode=none --ignore-case | grep -E
'^[A-Za-z][a-z]*$' | sort | uniq -c | sort -n | grep -vE '.{25}' |
aspell pipe -W3 | grep : | cut -d' ' -f2 | less)
and proceeded to spend a few days looking at it to find probable typos
and fixed a few hundred of them in all of the llvm project (note, the
ones I found are not anywhere near all of them, but it seems like a
good start).
Differential revision: https://reviews.llvm.org/D131122
Debugging some DWARF5 binaries was causing errors to appear when DWARFExpression::Evaluate was called:
error: GetDIE for DIE 0x31 is outside of its CU 0x123450
The issue is in the DWARF expression evaluator. Fixed with this.
Differential Revision: https://reviews.llvm.org/D133623
DW_OP_skip/DW_OP_bra can move offset to the end of the data, which means that this was the last instruction to execute and the interpreter should terminate.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D130285
When looking for a variable location in a DWARF location list,
we search the list of ranges to find one that includes the pc.
With a function mid-stack, the "pc" is the return pc instead of
the call instruction, and in optimized code this can be another
function or a different basic block (with different variable
locations). Back up the "pc" value mid-stack to find the correct
location list entry.
Differential Revision: https://reviews.llvm.org/D124597
rdar://63903416
Currently DW_OP_deref_size just drops the ValueType::FileAddress case and does
not attempt to handle it. This adds support for this case and a test that
verifies this support.
I did a little refactoring since DW_OP_deref and DW_OP_deref_size have some
overlap in code.
Also see: rdar://66870821
Differential Revision: https://reviews.llvm.org/D121408
Applied modernize-use-default-member-init clang-tidy check over LLDB.
It appears in many files we had already switched to in class member init but
never updated the constructors to reflect that. This check is already present in
the lldb/.clang-tidy config.
Differential Revision: https://reviews.llvm.org/D121481
We have using namespace llvm::dwarf in dwarf.h header globally. Replacing that
with a using namespace within lldb_private::dwarf and moving to a
using namespace lldb_private::dwarf in .cpp files and fully qualified names
in the few header files.
Differential Revision: https://reviews.llvm.org/D120836