[Lldb-commits] [lldb] 1995fd9 - [lldb] Extract DW_OP_deref evaluation code (NFC) (#146801)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 3 13:46:50 PDT 2025
Author: Jonas Devlieghere
Date: 2025-07-03T13:46:47-07:00
New Revision: 1995fd9ac6be4ff0822589f00d5fcaa12688eb87
URL: https://github.com/llvm/llvm-project/commit/1995fd9ac6be4ff0822589f00d5fcaa12688eb87
DIFF: https://github.com/llvm/llvm-project/commit/1995fd9ac6be4ff0822589f00d5fcaa12688eb87.diff
LOG: [lldb] Extract DW_OP_deref evaluation code (NFC) (#146801)
The DWARF expression evaluator is essentially a large state machine
implemented as a switch statement. For anything but trivial operations,
having the evaluation logic implemented inline is difficult to follow,
especially when there are nested switches. This commit moves evaluation
of `DW_OP_deref` out-of-line, similar to `Evaluate_DW_OP_entry_value`.
Added:
Modified:
lldb/include/lldb/Expression/DWARFExpression.h
lldb/source/Expression/DWARFExpression.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 0adbe3e8df2ee..37853c0b5a8fc 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -35,6 +35,8 @@ namespace lldb_private {
/// location expression or a location list and interprets it.
class DWARFExpression {
public:
+ using Stack = std::vector<Value>;
+
class Delegate {
public:
Delegate() = default;
@@ -53,7 +55,7 @@ class DWARFExpression {
virtual bool ParseVendorDWARFOpcode(uint8_t op,
const DataExtractor &opcodes,
lldb::offset_t &offset,
- std::vector<Value> &stack) const = 0;
+ Stack &stack) const = 0;
Delegate(const Delegate &) = delete;
Delegate &operator=(const Delegate &) = delete;
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 2df27513a0b3f..52891fcefd68b 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -589,7 +589,7 @@ bool DWARFExpression::LinkThreadLocalStorage(
return true;
}
-static llvm::Error Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
+static llvm::Error Evaluate_DW_OP_entry_value(DWARFExpression::Stack &stack,
ExecutionContext *exe_ctx,
RegisterContext *reg_ctx,
const DataExtractor &opcodes,
@@ -654,7 +654,7 @@ static llvm::Error Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
addr_t return_pc = LLDB_INVALID_ADDRESS;
uint32_t current_frame_idx = current_frame->GetFrameIndex();
- for (uint32_t parent_frame_idx = current_frame_idx + 1;;parent_frame_idx++) {
+ for (uint32_t parent_frame_idx = current_frame_idx + 1;; parent_frame_idx++) {
parent_frame = thread->GetStackFrameAtIndex(parent_frame_idx);
// If this is null, we're at the end of the stack.
if (!parent_frame)
@@ -860,6 +860,66 @@ ResolveLoadAddress(ExecutionContext *exe_ctx, lldb::ModuleSP &module_sp,
return load_addr;
}
+static llvm::Error Evaluate_DW_OP_deref(DWARFExpression::Stack &stack,
+ ExecutionContext *exe_ctx,
+ lldb::ModuleSP module_sp,
+ Process *process) {
+ if (stack.empty())
+ return llvm::createStringError("expression stack empty for DW_OP_deref");
+
+ const Value::ValueType value_type = stack.back().GetValueType();
+ switch (value_type) {
+ case Value::ValueType::HostAddress: {
+ void *src = (void *)stack.back().GetScalar().ULongLong();
+ intptr_t ptr;
+ ::memcpy(&ptr, src, sizeof(void *));
+ stack.back().GetScalar() = ptr;
+ stack.back().ClearContext();
+ } break;
+ case Value::ValueType::FileAddress: {
+ auto file_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ Address so_addr;
+ auto maybe_load_addr = ResolveLoadAddress(exe_ctx, module_sp, "DW_OP_deref",
+ file_addr, so_addr);
+ if (!maybe_load_addr)
+ return maybe_load_addr.takeError();
+ stack.back().GetScalar() = *maybe_load_addr;
+ // Fall through to load address promotion code below.
+ }
+ [[fallthrough]];
+ case Value::ValueType::Scalar:
+ // Promote Scalar to LoadAddress and fall through.
+ stack.back().SetValueType(Value::ValueType::LoadAddress);
+ [[fallthrough]];
+ case Value::ValueType::LoadAddress: {
+ if (!exe_ctx)
+ return llvm::createStringError("NULL execution context for DW_OP_deref");
+ if (!process)
+ return llvm::createStringError("NULL process for DW_OP_deref");
+ lldb::addr_t pointer_addr =
+ stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ Status error;
+ lldb::addr_t pointer_value =
+ process->ReadPointerFromMemory(pointer_addr, error);
+ if (pointer_value == LLDB_INVALID_ADDRESS)
+ return llvm::joinErrors(
+ llvm::createStringError(
+ "Failed to dereference pointer from 0x%" PRIx64
+ " for DW_OP_deref",
+ pointer_addr),
+ error.takeError());
+ if (ABISP abi_sp = process->GetABI())
+ pointer_value = abi_sp->FixCodeAddress(pointer_value);
+ stack.back().GetScalar() = pointer_value;
+ stack.back().ClearContext();
+ } break;
+ case Value::ValueType::Invalid:
+ return llvm::createStringError("invalid value type for DW_OP_deref");
+ }
+
+ return llvm::Error::success();
+}
+
/// Helper function to move common code used to load sized data from a uint8_t
/// buffer.
///
@@ -890,7 +950,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
if (opcodes.GetByteSize() == 0)
return llvm::createStringError(
"no location, value may have been optimized out");
- std::vector<Value> stack;
+
+ Stack stack;
Process *process = nullptr;
StackFrame *frame = nullptr;
@@ -1019,69 +1080,9 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
// retrieved from the dereferenced address is the size of an address on the
// target machine.
case DW_OP_deref: {
- if (stack.empty())
- return llvm::createStringError(
- "expression stack empty for DW_OP_deref");
- Value::ValueType value_type = stack.back().GetValueType();
- switch (value_type) {
- case Value::ValueType::HostAddress: {
- void *src = (void *)stack.back().GetScalar().ULongLong();
- intptr_t ptr;
- ::memcpy(&ptr, src, sizeof(void *));
- stack.back().GetScalar() = ptr;
- stack.back().ClearContext();
- } break;
- case Value::ValueType::FileAddress: {
- auto file_addr = stack.back().GetScalar().ULongLong(
- LLDB_INVALID_ADDRESS);
-
- Address so_addr;
- auto maybe_load_addr = ResolveLoadAddress(
- exe_ctx, module_sp, "DW_OP_deref", file_addr, so_addr);
-
- if (!maybe_load_addr)
- return maybe_load_addr.takeError();
-
- stack.back().GetScalar() = *maybe_load_addr;
- // Fall through to load address promotion code below.
- }
- [[fallthrough]];
- case Value::ValueType::Scalar:
- // Promote Scalar to LoadAddress and fall through.
- stack.back().SetValueType(Value::ValueType::LoadAddress);
- [[fallthrough]];
- case Value::ValueType::LoadAddress:
- if (exe_ctx) {
- if (process) {
- lldb::addr_t pointer_addr =
- stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- Status error;
- lldb::addr_t pointer_value =
- process->ReadPointerFromMemory(pointer_addr, error);
- if (pointer_value != LLDB_INVALID_ADDRESS) {
- if (ABISP abi_sp = process->GetABI())
- pointer_value = abi_sp->FixCodeAddress(pointer_value);
- stack.back().GetScalar() = pointer_value;
- stack.back().ClearContext();
- } else {
- return llvm::createStringError(
- "Failed to dereference pointer from 0x%" PRIx64
- " for DW_OP_deref: %s\n",
- pointer_addr, error.AsCString());
- }
- } else {
- return llvm::createStringError("NULL process for DW_OP_deref");
- }
- } else {
- return llvm::createStringError(
- "NULL execution context for DW_OP_deref");
- }
- break;
-
- case Value::ValueType::Invalid:
- return llvm::createStringError("invalid value type for DW_OP_deref");
- }
-
+ if (llvm::Error err =
+ Evaluate_DW_OP_deref(stack, exe_ctx, module_sp, process))
+ return err;
} break;
// OPCODE: DW_OP_deref_size
@@ -1966,8 +1967,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
case Value::ValueType::Scalar: {
uint32_t bit_size = piece_byte_size * 8;
uint32_t bit_offset = 0;
- if (!scalar.ExtractBitfield(
- bit_size, bit_offset)) {
+ if (!scalar.ExtractBitfield(bit_size, bit_offset)) {
return llvm::createStringError(
"unable to extract %" PRIu64 " bytes from a %" PRIu64
" byte scalar value.",
@@ -2409,8 +2409,7 @@ bool DWARFExpression::MatchesOperand(
return MatchUnaryOp(
MatchOpType(Instruction::Operand::Type::Dereference),
MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
- MatchRegOp(*reg),
- MatchImmOp(offset)))(operand);
+ MatchRegOp(*reg), MatchImmOp(offset)))(operand);
} else {
return MatchRegOp(*reg)(operand);
}
More information about the lldb-commits
mailing list