Skip to content

Commit d839f65

Browse files
committed
[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
1 parent d7d7436 commit d839f65

File tree

2 files changed

+136
-7
lines changed

2 files changed

+136
-7
lines changed

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -847,10 +847,12 @@ bool DWARFExpression::Evaluate(
847847

848848
Process *process = nullptr;
849849
StackFrame *frame = nullptr;
850+
Target *target = nullptr;
850851

851852
if (exe_ctx) {
852853
process = exe_ctx->GetProcessPtr();
853854
frame = exe_ctx->GetFramePtr();
855+
target = exe_ctx->GetTargetPtr();
854856
}
855857
if (reg_ctx == nullptr && frame)
856858
reg_ctx = frame->GetRegisterContext().get();
@@ -906,12 +908,19 @@ bool DWARFExpression::Evaluate(
906908
// address and whose size is the size of an address on the target machine.
907909
case DW_OP_addr:
908910
stack.push_back(Scalar(opcodes.GetAddress(&offset)));
909-
stack.back().SetValueType(Value::ValueType::FileAddress);
910-
// Convert the file address to a load address, so subsequent
911-
// DWARF operators can operate on it.
912-
if (frame)
913-
stack.back().ConvertToLoadAddress(module_sp.get(),
914-
frame->CalculateTarget().get());
911+
if (target &&
912+
target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
913+
// wasm file sections aren't mapped into memory, therefore addresses can
914+
// never point into a file section and are always LoadAddresses.
915+
stack.back().SetValueType(Value::ValueType::LoadAddress);
916+
} else {
917+
stack.back().SetValueType(Value::ValueType::FileAddress);
918+
// Convert the file address to a load address, so subsequent
919+
// DWARF operators can operate on it.
920+
if (frame)
921+
stack.back().ConvertToLoadAddress(module_sp.get(),
922+
frame->CalculateTarget().get());
923+
}
915924
break;
916925

917926
// The DW_OP_addr_sect_offset4 is used for any location expressions in
@@ -2507,7 +2516,14 @@ bool DWARFExpression::Evaluate(
25072516
uint64_t index = opcodes.GetULEB128(&offset);
25082517
lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
25092518
stack.push_back(Scalar(value));
2510-
stack.back().SetValueType(Value::ValueType::FileAddress);
2519+
if (target &&
2520+
target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
2521+
// wasm file sections aren't mapped into memory, therefore addresses can
2522+
// never point into a file section and are always LoadAddresses.
2523+
stack.back().SetValueType(Value::ValueType::LoadAddress);
2524+
} else {
2525+
stack.back().SetValueType(Value::ValueType::FileAddress);
2526+
}
25112527
} break;
25122528

25132529
// OPCODE: DW_OP_GNU_const_index

lldb/unittests/Expression/DWARFExpressionTest.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "lldb/Expression/DWARFExpression.h"
1010
#include "Plugins/Platform/Linux/PlatformLinux.h"
11+
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
1112
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
1213
#include "TestingSupport/Symbol/YAMLModuleTester.h"
1314
#include "lldb/Core/Debugger.h"
@@ -401,3 +402,115 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
401402
Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx),
402403
llvm::HasValue(GetScalar(32, 0x07060504, false)));
403404
}
405+
406+
TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr) {
407+
// Set up a wasm target
408+
ArchSpec arch("wasm32-unknown-unknown-wasm");
409+
lldb::PlatformSP host_platform_sp =
410+
platform_linux::PlatformLinux::CreateInstance(true, &arch);
411+
ASSERT_TRUE(host_platform_sp);
412+
Platform::SetHostPlatform(host_platform_sp);
413+
lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
414+
ASSERT_TRUE(debugger_sp);
415+
lldb::TargetSP target_sp;
416+
lldb::PlatformSP platform_sp;
417+
debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
418+
lldb_private::eLoadDependentsNo,
419+
platform_sp, target_sp);
420+
421+
ExecutionContext exe_ctx(target_sp, false);
422+
// DW_OP_addr takes a single operand of address size width:
423+
uint8_t expr[] = {DW_OP_addr, 0x40, 0x0, 0x0, 0x0};
424+
DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
425+
/*addr_size*/ 4);
426+
Value result;
427+
Status status;
428+
ASSERT_TRUE(DWARFExpression::Evaluate(
429+
&exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
430+
/*unit*/ nullptr, lldb::eRegisterKindLLDB,
431+
/*initial_value_ptr*/ nullptr,
432+
/*object_address_ptr*/ nullptr, result, &status))
433+
<< status.ToError();
434+
435+
ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
436+
}
437+
438+
TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
439+
const char *yamldata = R"(
440+
--- !ELF
441+
FileHeader:
442+
Class: ELFCLASS64
443+
Data: ELFDATA2LSB
444+
Type: ET_EXEC
445+
Machine: EM_386
446+
DWARF:
447+
debug_abbrev:
448+
- Table:
449+
- Code: 0x00000001
450+
Tag: DW_TAG_compile_unit
451+
Children: DW_CHILDREN_no
452+
Attributes:
453+
- Attribute: DW_AT_addr_base
454+
Form: DW_FORM_sec_offset
455+
456+
debug_info:
457+
- Version: 5
458+
AddrSize: 4
459+
UnitType: DW_UT_compile
460+
Entries:
461+
- AbbrCode: 0x00000001
462+
Values:
463+
- Value: 0x8 # Offset of the first Address past the header
464+
- AbbrCode: 0x0
465+
466+
debug_addr:
467+
- Version: 5
468+
AddressSize: 4
469+
Entries:
470+
- Address: 0x1234
471+
- Address: 0x5678
472+
)";
473+
474+
// Can't use DWARFExpressionTester from above because subsystems overlap with
475+
// the fixture.
476+
SubsystemRAII<ObjectFileELF, SymbolFileDWARF> subsystems;
477+
llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
478+
EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
479+
auto module_sp = std::make_shared<Module>(file->moduleSpec());
480+
auto *dwarf_cu = llvm::cast<SymbolFileDWARF>(module_sp->GetSymbolFile())
481+
->DebugInfo()
482+
.GetUnitAtIndex(0);
483+
ASSERT_TRUE(dwarf_cu);
484+
dwarf_cu->ExtractDIEsIfNeeded();
485+
486+
// Set up a wasm target
487+
ArchSpec arch("wasm32-unknown-unknown-wasm");
488+
lldb::PlatformSP host_platform_sp =
489+
platform_linux::PlatformLinux::CreateInstance(true, &arch);
490+
ASSERT_TRUE(host_platform_sp);
491+
Platform::SetHostPlatform(host_platform_sp);
492+
lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
493+
ASSERT_TRUE(debugger_sp);
494+
lldb::TargetSP target_sp;
495+
lldb::PlatformSP platform_sp;
496+
debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
497+
lldb_private::eLoadDependentsNo,
498+
platform_sp, target_sp);
499+
500+
ExecutionContext exe_ctx(target_sp, false);
501+
// DW_OP_addrx takes a single leb128 operand, the index in the addr table:
502+
uint8_t expr[] = {DW_OP_addrx, 0x01};
503+
DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
504+
/*addr_size*/ 4);
505+
Value result;
506+
Status status;
507+
ASSERT_TRUE(DWARFExpression::Evaluate(
508+
&exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor, dwarf_cu,
509+
lldb::eRegisterKindLLDB,
510+
/*initial_value_ptr*/ nullptr,
511+
/*object_address_ptr*/ nullptr, result, &status))
512+
<< status.ToError();
513+
514+
ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
515+
ASSERT_EQ(result.GetScalar().UInt(), 0x5678u);
516+
}

0 commit comments

Comments
 (0)