[Lldb-commits] [lldb] d839f65 - [wasm] Always treat DWARF expression addresses as load addresses
Philip Pfaffe via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 2 05:14:58 PDT 2022
Author: Philip Pfaffe
Date: 2022-11-02T12:11:53Z
New Revision: d839f654586a4f3a84b334fcc2c986343a1d7f98
URL: https://github.com/llvm/llvm-project/commit/d839f654586a4f3a84b334fcc2c986343a1d7f98
DIFF: https://github.com/llvm/llvm-project/commit/d839f654586a4f3a84b334fcc2c986343a1d7f98.diff
LOG: [wasm] Always treat DWARF expression addresses as load addresses
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
Added:
Modified:
lldb/source/Expression/DWARFExpression.cpp
lldb/unittests/Expression/DWARFExpressionTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 1ccda944cd013..3f302e53c00e1 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -847,10 +847,12 @@ bool DWARFExpression::Evaluate(
Process *process = nullptr;
StackFrame *frame = nullptr;
+ Target *target = nullptr;
if (exe_ctx) {
process = exe_ctx->GetProcessPtr();
frame = exe_ctx->GetFramePtr();
+ target = exe_ctx->GetTargetPtr();
}
if (reg_ctx == nullptr && frame)
reg_ctx = frame->GetRegisterContext().get();
@@ -906,12 +908,19 @@ bool DWARFExpression::Evaluate(
// address and whose size is the size of an address on the target machine.
case DW_OP_addr:
stack.push_back(Scalar(opcodes.GetAddress(&offset)));
- stack.back().SetValueType(Value::ValueType::FileAddress);
- // Convert the file address to a load address, so subsequent
- // DWARF operators can operate on it.
- if (frame)
- stack.back().ConvertToLoadAddress(module_sp.get(),
- frame->CalculateTarget().get());
+ if (target &&
+ target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
+ // wasm file sections aren't mapped into memory, therefore addresses can
+ // never point into a file section and are always LoadAddresses.
+ stack.back().SetValueType(Value::ValueType::LoadAddress);
+ } else {
+ stack.back().SetValueType(Value::ValueType::FileAddress);
+ // Convert the file address to a load address, so subsequent
+ // DWARF operators can operate on it.
+ if (frame)
+ stack.back().ConvertToLoadAddress(module_sp.get(),
+ frame->CalculateTarget().get());
+ }
break;
// The DW_OP_addr_sect_offset4 is used for any location expressions in
@@ -2507,7 +2516,14 @@ bool DWARFExpression::Evaluate(
uint64_t index = opcodes.GetULEB128(&offset);
lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
stack.push_back(Scalar(value));
- stack.back().SetValueType(Value::ValueType::FileAddress);
+ if (target &&
+ target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
+ // wasm file sections aren't mapped into memory, therefore addresses can
+ // never point into a file section and are always LoadAddresses.
+ stack.back().SetValueType(Value::ValueType::LoadAddress);
+ } else {
+ stack.back().SetValueType(Value::ValueType::FileAddress);
+ }
} break;
// OPCODE: DW_OP_GNU_const_index
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 35a064fc14bd8..4251eb0aecda9 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -8,6 +8,7 @@
#include "lldb/Expression/DWARFExpression.h"
#include "Plugins/Platform/Linux/PlatformLinux.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/Symbol/YAMLModuleTester.h"
#include "lldb/Core/Debugger.h"
@@ -401,3 +402,115 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx),
llvm::HasValue(GetScalar(32, 0x07060504, false)));
}
+
+TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr) {
+ // Set up a wasm target
+ ArchSpec arch("wasm32-unknown-unknown-wasm");
+ lldb::PlatformSP host_platform_sp =
+ platform_linux::PlatformLinux::CreateInstance(true, &arch);
+ ASSERT_TRUE(host_platform_sp);
+ Platform::SetHostPlatform(host_platform_sp);
+ lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
+ ASSERT_TRUE(debugger_sp);
+ lldb::TargetSP target_sp;
+ lldb::PlatformSP platform_sp;
+ debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
+ lldb_private::eLoadDependentsNo,
+ platform_sp, target_sp);
+
+ ExecutionContext exe_ctx(target_sp, false);
+ // DW_OP_addr takes a single operand of address size width:
+ uint8_t expr[] = {DW_OP_addr, 0x40, 0x0, 0x0, 0x0};
+ DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
+ /*addr_size*/ 4);
+ Value result;
+ Status status;
+ ASSERT_TRUE(DWARFExpression::Evaluate(
+ &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
+ /*unit*/ nullptr, lldb::eRegisterKindLLDB,
+ /*initial_value_ptr*/ nullptr,
+ /*object_address_ptr*/ nullptr, result, &status))
+ << status.ToError();
+
+ ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
+}
+
+TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
+ const char *yamldata = R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_386
+DWARF:
+ debug_abbrev:
+ - Table:
+ - Code: 0x00000001
+ Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_addr_base
+ Form: DW_FORM_sec_offset
+
+ debug_info:
+ - Version: 5
+ AddrSize: 4
+ UnitType: DW_UT_compile
+ Entries:
+ - AbbrCode: 0x00000001
+ Values:
+ - Value: 0x8 # Offset of the first Address past the header
+ - AbbrCode: 0x0
+
+ debug_addr:
+ - Version: 5
+ AddressSize: 4
+ Entries:
+ - Address: 0x1234
+ - Address: 0x5678
+)";
+
+ // Can't use DWARFExpressionTester from above because subsystems overlap with
+ // the fixture.
+ SubsystemRAII<ObjectFileELF, SymbolFileDWARF> subsystems;
+ llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
+ EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
+ auto module_sp = std::make_shared<Module>(file->moduleSpec());
+ auto *dwarf_cu = llvm::cast<SymbolFileDWARF>(module_sp->GetSymbolFile())
+ ->DebugInfo()
+ .GetUnitAtIndex(0);
+ ASSERT_TRUE(dwarf_cu);
+ dwarf_cu->ExtractDIEsIfNeeded();
+
+ // Set up a wasm target
+ ArchSpec arch("wasm32-unknown-unknown-wasm");
+ lldb::PlatformSP host_platform_sp =
+ platform_linux::PlatformLinux::CreateInstance(true, &arch);
+ ASSERT_TRUE(host_platform_sp);
+ Platform::SetHostPlatform(host_platform_sp);
+ lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
+ ASSERT_TRUE(debugger_sp);
+ lldb::TargetSP target_sp;
+ lldb::PlatformSP platform_sp;
+ debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
+ lldb_private::eLoadDependentsNo,
+ platform_sp, target_sp);
+
+ ExecutionContext exe_ctx(target_sp, false);
+ // DW_OP_addrx takes a single leb128 operand, the index in the addr table:
+ uint8_t expr[] = {DW_OP_addrx, 0x01};
+ DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
+ /*addr_size*/ 4);
+ Value result;
+ Status status;
+ ASSERT_TRUE(DWARFExpression::Evaluate(
+ &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor, dwarf_cu,
+ lldb::eRegisterKindLLDB,
+ /*initial_value_ptr*/ nullptr,
+ /*object_address_ptr*/ nullptr, result, &status))
+ << status.ToError();
+
+ ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
+ ASSERT_EQ(result.GetScalar().UInt(), 0x5678u);
+}
More information about the lldb-commits
mailing list