Skip to content

Commit a2a7cf5

Browse files
committed
[lldb] Support DW_OP_WASM_location in DWARFExpression
Add support for DW_OP_WASM_location in DWARFExpression. This PR rebases #78977 and cleans up the unit test.
1 parent cf6a4bb commit a2a7cf5

File tree

14 files changed

+596
-164
lines changed

14 files changed

+596
-164
lines changed

lldb/include/lldb/Expression/DWARFExpression.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ class DWARFExpression {
5252
GetVendorDWARFOpcodeSize(const DataExtractor &data,
5353
const lldb::offset_t data_offset,
5454
const uint8_t op) const = 0;
55-
virtual bool ParseVendorDWARFOpcode(uint8_t op,
56-
const DataExtractor &opcodes,
57-
lldb::offset_t &offset,
58-
Stack &stack) const = 0;
55+
virtual bool
56+
ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
57+
lldb::offset_t &offset, RegisterContext *reg_ctx,
58+
lldb::RegisterKind reg_kind, Stack &stack) const = 0;
5959

6060
Delegate(const Delegate &) = delete;
6161
Delegate &operator=(const Delegate &) = delete;
@@ -163,6 +163,10 @@ class DWARFExpression {
163163

164164
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const;
165165

166+
static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
167+
lldb::RegisterKind reg_kind,
168+
uint32_t reg_num, Value &value);
169+
166170
private:
167171
/// A data extractor capable of reading opcode bytes
168172
DataExtractor m_data;

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {
9191
m_reg_kind = reg_kind;
9292
}
9393

94-
static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
95-
lldb::RegisterKind reg_kind,
96-
uint32_t reg_num, Value &value) {
94+
llvm::Error
95+
DWARFExpression::ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
96+
lldb::RegisterKind reg_kind,
97+
uint32_t reg_num, Value &value) {
9798
if (reg_ctx == nullptr)
9899
return llvm::createStringError("no register context in frame");
99100

@@ -2300,9 +2301,40 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
23002301
break;
23012302
}
23022303

2304+
case DW_OP_WASM_location: {
2305+
uint8_t wasm_op = opcodes.GetU8(&offset);
2306+
uint32_t index;
2307+
2308+
/* LLDB doesn't have an address space to represents WebAssembly locals,
2309+
* globals and operand stacks.
2310+
* We encode these elements into virtual registers:
2311+
* | tag: 2 bits | index: 30 bits |
2312+
* where tag is:
2313+
* 0: Not a WebAssembly ___location
2314+
* 1: Local
2315+
* 2: Global
2316+
* 3: Operand stack value
2317+
*/
2318+
if (wasm_op == 3) {
2319+
index = opcodes.GetU32(&offset);
2320+
wasm_op = 2; // Global
2321+
} else {
2322+
index = opcodes.GetULEB128(&offset);
2323+
}
2324+
2325+
reg_num = (((wasm_op + 1) & 0x03) << 30) | (index & 0x3fffffff);
2326+
2327+
if (llvm::Error error =
2328+
ReadRegisterValueAsScalar(reg_ctx, reg_kind, reg_num, tmp))
2329+
return std::move(error);
2330+
stack.push_back(tmp);
2331+
break;
2332+
}
2333+
23032334
default:
23042335
if (dwarf_cu) {
2305-
if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, stack)) {
2336+
if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, reg_ctx,
2337+
reg_kind, stack)) {
23062338
break;
23072339
}
23082340
}

lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,13 @@ DataExtractor ObjectFileWasm::ReadImageData(offset_t offset, uint32_t size) {
376376
DataBufferSP buffer_sp(data_up.release());
377377
data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
378378
}
379+
} else if (offset < m_data.GetByteSize()) {
380+
size =
381+
std::min(static_cast<uint64_t>(size), m_data.GetByteSize() - offset);
382+
return DataExtractor(m_data.GetDataStart() + offset, size, GetByteOrder(),
383+
GetAddressByteSize());
379384
}
380385
}
381-
382386
data.SetByteOrder(GetByteOrder());
383387
return data;
384388
}

lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
3535
SymbolFileDWARF.cpp
3636
SymbolFileDWARFDwo.cpp
3737
SymbolFileDWARFDebugMap.cpp
38+
SymbolFileWasm.cpp
3839
UniqueDWARFASTType.cpp
3940

4041
LINK_COMPONENTS

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,11 @@ DWARFUnit::GetVendorDWARFOpcodeSize(const DataExtractor &data,
736736

737737
bool DWARFUnit::ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
738738
lldb::offset_t &offset,
739+
RegisterContext *reg_ctx,
740+
lldb::RegisterKind reg_kind,
739741
std::vector<Value> &stack) const {
740742
return GetSymbolFileDWARF().ParseVendorDWARFOpcode(op, opcodes, offset,
741-
stack);
743+
reg_ctx, reg_kind, stack);
742744
}
743745

744746
bool DWARFUnit::ParseDWARFLocationList(

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,11 @@ class DWARFUnit : public DWARFExpression::Delegate, public UserID {
164164
const lldb::offset_t data_offset,
165165
const uint8_t op) const override;
166166

167-
bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
168-
lldb::offset_t &offset,
169-
std::vector<Value> &stack) const override;
167+
virtual bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
168+
lldb::offset_t &offset,
169+
RegisterContext *reg_ctx,
170+
lldb::RegisterKind reg_kind,
171+
std::vector<Value> &stack) const override;
170172

171173
bool ParseDWARFLocationList(const DataExtractor &data,
172174
DWARFExpressionList &loc_list) const;

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
3434
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
35+
#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
3536

3637
#include "lldb/Host/FileSystem.h"
3738
#include "lldb/Host/Host.h"
@@ -41,6 +42,7 @@
4142

4243
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
4344
#include "Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h"
45+
#include "Plugins/SymbolFile/DWARF/SymbolFileWasm.h"
4446
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
4547
#include "lldb/Symbol/Block.h"
4648
#include "lldb/Symbol/CompileUnit.h"
@@ -327,6 +329,9 @@ llvm::StringRef SymbolFileDWARF::GetPluginDescriptionStatic() {
327329
}
328330

329331
SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFileSP objfile_sp) {
332+
if (llvm::isa<lldb_private::wasm::ObjectFileWasm>(*objfile_sp))
333+
return new SymbolFileWasm(std::move(objfile_sp),
334+
/*dwo_section_list*/ nullptr);
330335
return new SymbolFileDWARF(std::move(objfile_sp),
331336
/*dwo_section_list*/ nullptr);
332337
}

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ class SymbolFileDWARF : public SymbolFileCommon {
329329

330330
virtual bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
331331
lldb::offset_t &offset,
332+
RegisterContext *reg_ctx,
333+
lldb::RegisterKind reg_kind,
332334
std::vector<Value> &stack) const {
333335
return false;
334336
}
@@ -556,6 +558,7 @@ class SymbolFileDWARF : public SymbolFileCommon {
556558
/// an index that identifies the .DWO or .o file.
557559
std::optional<uint64_t> m_file_index;
558560
};
561+
559562
} // namespace dwarf
560563
} // namespace lldb_private::plugin
561564

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ uint64_t SymbolFileDWARFDwo::GetDebugInfoSize(bool load_all_debug_info) {
9797
}
9898

9999
bool SymbolFileDWARFDwo::ParseVendorDWARFOpcode(
100-
uint8_t op, const lldb_private::DataExtractor &opcodes,
101-
lldb::offset_t &offset, std::vector<lldb_private::Value> &stack) const {
102-
return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset, stack);
100+
uint8_t op, const DataExtractor &opcodes, lldb::offset_t &offset,
101+
RegisterContext *reg_ctx, lldb::RegisterKind reg_kind,
102+
std::vector<Value> &stack) const {
103+
return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset,
104+
reg_ctx, reg_kind, stack);
103105
}
104106

105107
llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
5050
uint64_t GetDebugInfoSize(bool load_all_debug_info = false) override;
5151

5252
bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
53-
lldb::offset_t &offset,
53+
lldb::offset_t &offset, RegisterContext *reg_ctx,
54+
lldb::RegisterKind reg_kind,
5455
std::vector<Value> &stack) const override;
5556

5657
void FindGlobalVariables(ConstString name,

0 commit comments

Comments
 (0)