Skip to content

Commit 32d62ad

Browse files
committed
[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.
1 parent e724009 commit 32d62ad

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

lldb/unittests/Expression/DWARFExpressionTest.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,51 @@ using namespace lldb_private;
4040
using namespace llvm::dwarf;
4141

4242
namespace {
43+
/// A mock implementation of DWARFExpression::Delegate for testing.
44+
/// This class provides default implementations of all delegate methods,
45+
/// with the DWARF version being configurable via the constructor.
46+
class MockDwarfDelegate : public DWARFExpression::Delegate {
47+
public:
48+
static constexpr uint16_t DEFAULT_DWARF_VERSION = 5;
49+
static MockDwarfDelegate Dwarf5() { return MockDwarfDelegate(5); }
50+
static MockDwarfDelegate Dwarf2() { return MockDwarfDelegate(2); }
51+
52+
MockDwarfDelegate() : MockDwarfDelegate(DEFAULT_DWARF_VERSION) {}
53+
explicit MockDwarfDelegate(uint16_t version) : m_version(version) {}
54+
55+
uint16_t GetVersion() const override { return m_version; }
56+
57+
dw_addr_t GetBaseAddress() const override { return 0; }
58+
59+
uint8_t GetAddressByteSize() const override { return 4; }
60+
61+
llvm::Expected<std::pair<uint64_t, bool>>
62+
GetDIEBitSizeAndSign(uint64_t relative_die_offset) const override {
63+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
64+
"GetDIEBitSizeAndSign not implemented");
65+
}
66+
67+
dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const override {
68+
return 0;
69+
}
70+
71+
lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data,
72+
const lldb::offset_t data_offset,
73+
const uint8_t op) const override {
74+
return LLDB_INVALID_OFFSET;
75+
}
76+
77+
bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
78+
lldb::offset_t &offset, RegisterContext *reg_ctx,
79+
lldb::RegisterKind reg_kind,
80+
DWARFExpression::Stack &stack) const override {
81+
return false;
82+
}
83+
84+
private:
85+
uint16_t m_version;
86+
};
87+
4388
/// Mock memory implementation for testing.
4489
/// Stores predefined memory contents indexed by {address, size} pairs.
4590
class MockMemory {
@@ -191,7 +236,7 @@ class MockRegisterContext : public RegisterContext {
191236

192237
static llvm::Expected<Value> Evaluate(llvm::ArrayRef<uint8_t> expr,
193238
lldb::ModuleSP module_sp = {},
194-
DWARFUnit *unit = nullptr,
239+
DWARFExpression::Delegate *unit = nullptr,
195240
ExecutionContext *exe_ctx = nullptr,
196241
RegisterContext *reg_ctx = nullptr) {
197242
DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
@@ -536,6 +581,23 @@ TEST(DWARFExpression, DW_OP_stack_value) {
536581
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_stack_value}), llvm::Failed());
537582
}
538583

584+
// This test shows that the dwarf version is used by the expression evaluation.
585+
// Note that the different behavior tested here is not meant to imply that this
586+
// is the correct interpretation of dwarf2 vs. dwarf5, but rather it was picked
587+
// as an easy example that evaluates differently based on the dwarf version.
588+
TEST(DWARFExpression, dwarf_version) {
589+
MockDwarfDelegate dwarf2 = MockDwarfDelegate::Dwarf2();
590+
MockDwarfDelegate dwarf5 = MockDwarfDelegate::Dwarf5();
591+
592+
// In dwarf2 the constant on top of the stack is treated as a value.
593+
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1}, {}, &dwarf2), ExpectScalar(1));
594+
595+
// In dwarf5 the constant on top of the stack is implicitly converted to an
596+
// address.
597+
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1}, {}, &dwarf5),
598+
ExpectLoadAddress(1));
599+
}
600+
539601
TEST(DWARFExpression, DW_OP_piece) {
540602
EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const2u, 0x11, 0x22, DW_OP_piece, 2,
541603
DW_OP_const2u, 0x33, 0x44, DW_OP_piece, 2}),

0 commit comments

Comments
 (0)