[Lldb-commits] [lldb] [lldb] Add mock dwarf delegate for testing dwarf expressions (PR #168468)
David Peixotto via lldb-commits
lldb-commits at lists.llvm.org
Mon Nov 17 16:59:57 PST 2025
https://github.com/dmpots created https://github.com/llvm/llvm-project/pull/168468
This commit adds a `MockDwarfDelegate` class that can be used to control what dwarf version is used when evaluating an expression. We also add a simple test that shows how dwarf version can change the result of the expression.
>From b97ac12e0d0028505507bcd12622c576a7a16e51 Mon Sep 17 00:00:00 2001
From: David Peixotto <peix at meta.com>
Date: Fri, 14 Nov 2025 13:21:17 -0800
Subject: [PATCH] [lldb] Add mock dwarf delegate for testing dwarf expressions
This commit adds a `MockDwarfDelegate` class that can be used to control
what dwarf version is used when evaluating an expression. We also add a
simple test that shows how dwarf version can change the result of the
expression.
---
.../Expression/DWARFExpressionTest.cpp | 60 ++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 13110ef7cbb0a..88bbf863e4435 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -39,6 +39,51 @@ using namespace lldb_private;
using namespace llvm::dwarf;
namespace {
+/// A mock implementation of DWARFExpression::Delegate for testing.
+/// This class provides default implementations of all delegate methods,
+/// with the DWARF version being configurable via the constructor.
+class MockDwarfDelegate : public DWARFExpression::Delegate {
+public:
+ static constexpr uint16_t DEFAULT_DWARF_VERSION = 5;
+ static MockDwarfDelegate Dwarf5() { return MockDwarfDelegate(5); }
+ static MockDwarfDelegate Dwarf2() { return MockDwarfDelegate(2); }
+
+ MockDwarfDelegate() : MockDwarfDelegate(DEFAULT_DWARF_VERSION) {}
+ explicit MockDwarfDelegate(uint16_t version) : m_version(version) {}
+
+ uint16_t GetVersion() const override { return m_version; }
+
+ dw_addr_t GetBaseAddress() const override { return 0; }
+
+ uint8_t GetAddressByteSize() const override { return 4; }
+
+ llvm::Expected<std::pair<uint64_t, bool>>
+ GetDIEBitSizeAndSign(uint64_t relative_die_offset) const override {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "GetDIEBitSizeAndSign not implemented");
+ }
+
+ dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const override {
+ return 0;
+ }
+
+ lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data,
+ const lldb::offset_t data_offset,
+ const uint8_t op) const override {
+ return LLDB_INVALID_OFFSET;
+ }
+
+ bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+ lldb::offset_t &offset, RegisterContext *reg_ctx,
+ lldb::RegisterKind reg_kind,
+ DWARFExpression::Stack &stack) const override {
+ return false;
+ }
+
+private:
+ uint16_t m_version;
+};
+
struct MockProcess : Process {
MockProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
: Process(target_sp, listener_sp) {}
@@ -164,7 +209,7 @@ class MockRegisterContext : public RegisterContext {
static llvm::Expected<Value> Evaluate(llvm::ArrayRef<uint8_t> expr,
lldb::ModuleSP module_sp = {},
- DWARFUnit *unit = nullptr,
+ DWARFExpression::Delegate *unit = nullptr,
ExecutionContext *exe_ctx = nullptr,
RegisterContext *reg_ctx = nullptr) {
DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
@@ -505,6 +550,19 @@ TEST(DWARFExpression, DW_OP_stack_value) {
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_stack_value}), llvm::Failed());
}
+TEST(DWARFExpression, dwarf_version) {
+ MockDwarfDelegate dwarf2 = MockDwarfDelegate::Dwarf2();
+ MockDwarfDelegate dwarf5 = MockDwarfDelegate::Dwarf5();
+
+ // In dwarf2 the constant on top of the stack is treated as a value.
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1}, {}, &dwarf2), ExpectScalar(1));
+
+ // In dwarf5 the constant on top of the stack is implicitly converted to an
+ // address.
+ EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1}, {}, &dwarf5),
+ ExpectLoadAddress(1));
+}
+
TEST(DWARFExpression, DW_OP_piece) {
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x11, 0x22, DW_OP_piece, 2,
DW_OP_const2u, 0x33, 0x44, DW_OP_piece, 2}),
More information about the lldb-commits
mailing list