blob: 22effe7340ed71ff2f3a40cf5f9c8fa35ed36839 [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H
#define LLDB_SOURCE_PLUGINS_PROCESS_WASM_PROCESSWASM_H
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Utility/WasmVirtualRegisters.h"
namespace lldb_private {
namespace wasm {
/// Each WebAssembly module has separated address spaces for Code and Memory.
/// A WebAssembly module also has a Data section which, when the module is
/// loaded, gets mapped into a region in the module Memory.
enum WasmAddressType : uint8_t { Memory = 0x00, Object = 0x01, Invalid = 0xff };
/// For the purpose of debugging, we can represent all these separated 32-bit
/// address spaces with a single virtual 64-bit address space. The
/// wasm_addr_t provides this encoding using bitfields.
struct wasm_addr_t {
uint64_t offset : 32;
uint64_t module_id : 30;
uint64_t type : 2;
wasm_addr_t(lldb::addr_t addr)
: offset(addr & 0x00000000ffffffff),
module_id((addr & 0x00ffffff00000000) >> 32), type(addr >> 62) {}
wasm_addr_t(WasmAddressType type, uint32_t module_id, uint32_t offset)
: offset(offset), module_id(module_id), type(type) {}
WasmAddressType GetType() { return static_cast<WasmAddressType>(type); }
operator lldb::addr_t() { return *(uint64_t *)this; }
};
static_assert(sizeof(wasm_addr_t) == 8, "");
/// ProcessWasm provides the access to the Wasm program state
/// retrieved from the Wasm engine.
class ProcessWasm : public process_gdb_remote::ProcessGDBRemote {
public:
ProcessWasm(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
~ProcessWasm() override = default;
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec *crash_file_path,
bool can_connect);
static void Initialize();
static void DebuggerInitialize(Debugger &debugger);
static void Terminate();
static llvm::StringRef GetPluginNameStatic();
static llvm::StringRef GetPluginDescriptionStatic();
llvm::StringRef GetPluginName() override;
size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
Status &error) override;
bool CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) override;
/// Retrieve the current call stack from the WebAssembly remote process.
llvm::Expected<std::vector<lldb::addr_t>> GetWasmCallStack(lldb::tid_t tid);
/// Query the value of a WebAssembly variable from the WebAssembly
/// remote process.
llvm::Expected<lldb::DataBufferSP>
GetWasmVariable(WasmVirtualRegisterKinds kind, int frame_index, int index);
protected:
std::shared_ptr<process_gdb_remote::ThreadGDBRemote>
CreateThread(lldb::tid_t tid) override;
private:
friend class UnwindWasm;
friend class ThreadWasm;
process_gdb_remote::GDBRemoteDynamicRegisterInfoSP &GetRegisterInfo() {
return m_register_info_sp;
}
ProcessWasm(const ProcessWasm &);
const ProcessWasm &operator=(const ProcessWasm &) = delete;
};
} // namespace wasm
} // namespace lldb_private
#endif