Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add V8/WebAssembly debugging support to LLDB #53

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions lldb/include/lldb/Expression/DWARFExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,14 @@ class DWARFExpression {
bool Evaluate(ExecutionContextScope *exe_scope,
lldb::addr_t loclist_base_load_addr,
const Value *initial_value_ptr, const Value *object_address_ptr,
Value &result, Status *error_ptr) const;
uint64_t byte_size, Value &result, Status *error_ptr) const;

/// Wrapper for the static evaluate function that uses member variables to
/// populate many operands
bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::addr_t loclist_base_load_addr,
const Value *initial_value_ptr, const Value *object_address_ptr,
Value &result, Status *error_ptr) const;
uint64_t byte_size, Value &result, Status *error_ptr) const;

/// Evaluate a DWARF location expression in a particular context
///
Expand Down Expand Up @@ -211,6 +211,10 @@ class DWARFExpression {
/// A value to put on top of the interpreter stack before evaluating
/// the expression, if the expression is parametrized. Can be NULL.
///
/// \param[in] byte_size
/// The size, in bytes, of the result of the expression to evaluate.
/// Currently only used for WebAssembly targets.
///
/// \param[in] result
/// A value into which the result of evaluating the expression is
/// to be placed.
Expand All @@ -226,8 +230,8 @@ class DWARFExpression {
const DWARFUnit *dwarf_cu,
const lldb::RegisterKind reg_set,
const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
Status *error_ptr);
const Value *object_address_ptr, uint64_t byte_size,
Value &result, Status *error_ptr);

bool GetExpressionData(DataExtractor &data) const {
data = m_data;
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Utility/ArchSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ class ArchSpec {

eCore_arc, // little endian ARC

eCore_wasm32,

kNumCores,

kCore_invalid,
Expand Down
9 changes: 9 additions & 0 deletions lldb/source/API/SystemInitializerFull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
#include "Plugins/DynamicLoader/WASM-DYLD/DynamicLoaderWasmDYLD.h"
#include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
#include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
Expand All @@ -69,6 +70,7 @@
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/ObjectFile/WASM/ObjectFileWasm.h"
#include "Plugins/OperatingSystem/Python/OperatingSystemPython.h"
#include "Plugins/Platform/Android/PlatformAndroid.h"
#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
Expand All @@ -90,6 +92,7 @@
#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
#include "Plugins/SymbolVendor/WASM/SymbolVendorWasm.h"
#include "Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h"
#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
#include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h"
Expand Down Expand Up @@ -173,6 +176,7 @@ llvm::Error SystemInitializerFull::Initialize() {
ObjectFileELF::Initialize();
ObjectFileMachO::Initialize();
ObjectFilePECOFF::Initialize();
wasm::ObjectFileWASM::Initialize();

ObjectContainerBSDArchive::Initialize();
ObjectContainerUniversalMachO::Initialize();
Expand Down Expand Up @@ -232,6 +236,7 @@ llvm::Error SystemInitializerFull::Initialize() {
SymbolFileDWARF::Initialize();
SymbolFilePDB::Initialize();
SymbolFileSymtab::Initialize();
SymbolVendorWasm::Initialize();
UnwindAssemblyInstEmulation::Initialize();
UnwindAssembly_x86::Initialize();

Expand Down Expand Up @@ -280,6 +285,7 @@ llvm::Error SystemInitializerFull::Initialize() {
DynamicLoaderMacOSXDYLD::Initialize();
DynamicLoaderMacOS::Initialize();
DynamicLoaderPOSIXDYLD::Initialize();
DynamicLoaderWasmDYLD::Initialize();
DynamicLoaderStatic::Initialize();
DynamicLoaderWindowsDYLD::Initialize();

Expand Down Expand Up @@ -324,6 +330,7 @@ void SystemInitializerFull::Terminate() {
ThreadSanitizerRuntime::Terminate();
UndefinedBehaviorSanitizerRuntime::Terminate();
MainThreadCheckerRuntime::Terminate();
SymbolVendorWasm::Terminate();
SymbolVendorELF::Terminate();
breakpad::SymbolFileBreakpad::Terminate();
SymbolFileDWARF::Terminate();
Expand Down Expand Up @@ -372,6 +379,7 @@ void SystemInitializerFull::Terminate() {
DynamicLoaderMacOSXDYLD::Terminate();
DynamicLoaderMacOS::Terminate();
DynamicLoaderPOSIXDYLD::Terminate();
DynamicLoaderWasmDYLD::Terminate();
DynamicLoaderStatic::Terminate();
DynamicLoaderWindowsDYLD::Terminate();

Expand All @@ -396,6 +404,7 @@ void SystemInitializerFull::Terminate() {
ObjectFileELF::Terminate();
ObjectFileMachO::Terminate();
ObjectFilePECOFF::Terminate();
wasm::ObjectFileWASM::Terminate();

ObjectContainerBSDArchive::Terminate();
ObjectContainerUniversalMachO::Terminate();
Expand Down
29 changes: 27 additions & 2 deletions lldb/source/Core/Value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h"
Expand All @@ -30,6 +31,9 @@
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"

#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"

#include <memory>
#include <string>

Expand Down Expand Up @@ -563,8 +567,29 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
Process *process = exe_ctx->GetProcessPtr();

if (process) {
const size_t bytes_read =
process->ReadMemory(address, dst, byte_size, error);
bool isWasm = false;
StackFrame *frame = exe_ctx->GetFramePtr();
if (frame) {
const llvm::Triple::ArchType machine =
frame->CalculateTarget()->GetArchitecture().GetMachine();
isWasm = (machine == llvm::Triple::wasm32); // wasm64 not supported
}

size_t bytes_read = 0;

if (isWasm) {
process_gdb_remote::GDBRemoteCommunicationClient *gdb_comm =
&((process_gdb_remote::ProcessGDBRemote *)process)
->GetGDBRemote();
int frame_index = frame->GetConcreteFrameIndex();
if (gdb_comm->WasmReadMemory(frame_index, address, dst,
byte_size)) {
bytes_read = byte_size;
}
} else {
bytes_read = process->ReadMemory(address, dst, byte_size, error);
}

if (bytes_read != byte_size)
error.SetErrorStringWithFormat(
"read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Core/ValueObjectVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ bool ValueObjectVariable::UpdateValue() {
target);
}
Value old_value(m_value);
uint64_t byte_size = GetByteSize();
if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
nullptr, m_value, &m_error)) {
nullptr, byte_size, m_value, &m_error)) {
m_resolved_value = m_value;
m_value.SetContext(Value::eContextTypeVariable, variable);

Expand Down
92 changes: 85 additions & 7 deletions lldb/source/Expression/DWARFExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"

using namespace lldb;
Expand Down Expand Up @@ -914,7 +916,8 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
parent_frame->GetRegisterContext().get(),
/*loclist_base_addr=*/LLDB_INVALID_ADDRESS,
/*initial_value_ptr=*/nullptr,
/*object_address_ptr=*/nullptr, result, error_ptr)) {
/*object_address_ptr=*/nullptr, 0, result,
error_ptr)) {
LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: call site param evaluation failed");
return false;
Expand All @@ -927,18 +930,20 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope,
lldb::addr_t loclist_base_load_addr,
const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
const Value *object_address_ptr,
uint64_t byte_size, Value &result,
Status *error_ptr) const {
ExecutionContext exe_ctx(exe_scope);
return Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, initial_value_ptr,
object_address_ptr, result, error_ptr);
object_address_ptr, byte_size, result, error_ptr);
}

bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
RegisterContext *reg_ctx,
lldb::addr_t loclist_base_load_addr,
const Value *initial_value_ptr,
const Value *object_address_ptr, Value &result,
const Value *object_address_ptr,
uint64_t byte_size, Value &result,
Status *error_ptr) const {
ModuleSP module_sp = m_module_wp.lock();

Expand Down Expand Up @@ -994,7 +999,8 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
return DWARFExpression::Evaluate(
exe_ctx, reg_ctx, module_sp,
DataExtractor(m_data, offset, length), m_dwarf_cu, m_reg_kind,
initial_value_ptr, object_address_ptr, result, error_ptr);
initial_value_ptr, object_address_ptr, byte_size, result,
error_ptr);
}
offset += length;
}
Expand All @@ -1007,15 +1013,16 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
// Not a location list, just a single expression.
return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, m_data,
m_dwarf_cu, m_reg_kind, initial_value_ptr,
object_address_ptr, result, error_ptr);
object_address_ptr, byte_size, result,
error_ptr);
}

bool DWARFExpression::Evaluate(
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
const Value *initial_value_ptr, const Value *object_address_ptr,
Value &result, Status *error_ptr) {
uint64_t byte_size, Value &result, Status *error_ptr) {

if (opcodes.GetByteSize() == 0) {
if (error_ptr)
Expand All @@ -1032,9 +1039,17 @@ bool DWARFExpression::Evaluate(
process = exe_ctx->GetProcessPtr();
frame = exe_ctx->GetFramePtr();
}

if (reg_ctx == nullptr && frame)
reg_ctx = frame->GetRegisterContext().get();

const llvm::Triple::ArchType machine =
frame->CalculateTarget()->GetArchitecture().GetMachine();
bool isWasm = (machine == llvm::Triple::wasm32); // wasm64 not supported yet.
process_gdb_remote::GDBRemoteCommunicationClient *gdb_comm = isWasm
? &((process_gdb_remote::ProcessGDBRemote *)process)->GetGDBRemote()
: nullptr;

if (initial_value_ptr)
stack.push_back(*initial_value_ptr);

Expand Down Expand Up @@ -1690,6 +1705,38 @@ bool DWARFExpression::Evaluate(
// DESCRIPTION: pops the top stack entry, adds it to the unsigned LEB128
// constant operand and pushes the result.
case DW_OP_plus_uconst:
if (isWasm) {
if (byte_size < 4) {
byte_size = 4; // default to 32 bit
}

const uint64_t uconst_value = opcodes.GetULEB128(&offset);

// Get current user-space stack frame pointer
Scalar value;
if (!frame || !frame->GetFrameBaseValue(value, error_ptr) ||
value.GetType() != Scalar::e_ulonglong) {
return false;
}

if (byte_size <= 4096) {
uint8_t buffer[4096];
int frame_index = frame->GetConcreteFrameIndex();
if (!gdb_comm->WasmReadMemory(
frame_index, value.ULongLong() + uconst_value, buffer,
byte_size)) {
return false;
}
stack.push_back({buffer, static_cast<int>(byte_size)});
} else {
if (error_ptr)
error_ptr->SetErrorString("DW_OP_plus_uconst value size shouldn't "
"be bigger than 4096 bytes.");
return false;
}
break;
}

if (stack.empty()) {
if (error_ptr)
error_ptr->SetErrorString(
Expand Down Expand Up @@ -2572,6 +2619,37 @@ bool DWARFExpression::Evaluate(
stack.back().SetValueType(Value::eValueTypeLoadAddress);
} break;

case DW_OP_WASM_location: {
if (isWasm) {
int frame_index = frame->GetConcreteFrameIndex();
uint64_t wasm_op = opcodes.GetULEB128(&offset);
uint64_t index = opcodes.GetULEB128(&offset);
uint64_t value = 0;
switch (wasm_op) {
case 0: // Local
if (!gdb_comm->GetWasmLocal(frame_index, index, value)) {
return false;
}
break;
case 1: // Global
if (!gdb_comm->GetWasmGlobal(frame_index, index, value)) {
return false;
}
break;
case 2: // Operand Stack
if (!gdb_comm->GetWasmStackValue(frame_index, index, value)) {
return false;
}
break;
default:
return false;
}
stack.push_back(Scalar(value));
} else {
return false;
}
} break;

// OPCODE: DW_OP_addrx (DW_OP_GNU_addr_index is the legacy name.)
// OPERANDS: 1
// ULEB128: index to the .debug_addr section
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/DynamicLoader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ add_subdirectory(POSIX-DYLD)
add_subdirectory(Static)
add_subdirectory(Hexagon-DYLD)
add_subdirectory(Windows-DYLD)
add_subdirectory(WASM-DYLD)
9 changes: 9 additions & 0 deletions lldb/source/Plugins/DynamicLoader/WASM-DYLD/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
add_lldb_library(lldbPluginDynamicLoaderWasmDYLD PLUGIN
DynamicLoaderWasmDYLD.cpp

LINK_LIBS
lldbCore
lldbTarget
LINK_COMPONENTS
Support
)
Loading