LLDB mainline
RegisterContextWasm.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "ProcessWasm.h"
12#include "ThreadWasm.h"
14#include "lldb/Utility/Log.h"
16#include "llvm/Support/Error.h"
17#include <memory>
18
19using namespace lldb;
20using namespace lldb_private;
22using namespace lldb_private::wasm;
23
25 uint32_t concrete_frame_idx,
26 DynamicRegisterInfoSP reg_info_sp)
27 : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,
28 false) {}
29
31
33 lldb::RegisterKind kind, uint32_t num) {
34 return num;
35}
36
38 // Wasm has no registers.
39 return 0;
40}
41
43 uint32_t tag = GetWasmVirtualRegisterTag(reg);
44 if (tag == eWasmTagNotAWasmLocation)
45 return m_reg_info_sp->GetRegisterInfoAtIndex(
47
48 auto it = m_register_map.find(reg);
49 if (it == m_register_map.end()) {
51 std::tie(it, std::ignore) = m_register_map.insert(
52 {reg, std::make_unique<WasmVirtualRegisterInfo>(
53 kind, GetWasmVirtualRegisterIndex(reg))});
54 }
55 return it->second.get();
56}
57
59
61 // Wasm has no registers.
62 return nullptr;
63}
64
66 RegisterValue &value) {
67 ThreadWasm &wasm_thread = static_cast<ThreadWasm &>(GetThread());
68
69 // The only real register is the PC.
70 if (reg_info->name) {
71 // A caller frame's PC is the unwound return address, which the base
72 // register context cannot provide because it only sees the innermost
73 // frame's live PC. Use the PC the unwinder recorded for this frame.
74 if (m_concrete_frame_idx > 0) {
76 if (pc != LLDB_INVALID_ADDRESS) {
77 value.SetUInt(pc, reg_info->byte_size);
78 return true;
79 }
80 }
81 return GDBRemoteRegisterContext::ReadRegister(reg_info, value);
82 }
83
84 // Read the virtual registers.
85 ProcessWasm *process =
86 static_cast<ProcessWasm *>(wasm_thread.GetProcess().get());
87 if (!process)
88 return false;
89
90 uint32_t frame_index = m_concrete_frame_idx;
91 WasmVirtualRegisterInfo *wasm_reg_info =
92 static_cast<WasmVirtualRegisterInfo *>(
93 const_cast<RegisterInfo *>(reg_info));
94
95 llvm::Expected<DataBufferSP> maybe_buffer = process->GetWasmVariable(
96 wasm_reg_info->kind, frame_index, wasm_reg_info->index);
97 if (!maybe_buffer) {
98 LLDB_LOG_ERROR(GetLog(LLDBLog::Process), maybe_buffer.takeError(),
99 "Failed to read Wasm local: {0}");
100 return false;
101 }
102
103 DataBufferSP buffer_sp = *maybe_buffer;
104 DataExtractor reg_data(buffer_sp, process->GetByteOrder(),
105 process->GetAddressByteSize());
106 wasm_reg_info->byte_size = buffer_sp->GetByteSize();
107 wasm_reg_info->encoding = lldb::eEncodingUint;
108
110 *reg_info, reg_data, reg_info->byte_offset, /*partial_data_ok=*/false);
111 return error.Success();
112}
113
115
117 const RegisterValue &value) {
118 // The only real registers is the PC.
119 if (reg_info->name)
120 return GDBRemoteRegisterContext::WriteRegister(reg_info, value);
121 return false;
122}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
An data extractor class.
lldb::ByteOrder GetByteOrder() const
Definition Process.cpp:3926
uint32_t GetAddressByteSize() const
Definition Process.cpp:3930
bool SetUInt(uint64_t uint, uint32_t byte_size)
Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
An error handling class.
Definition Status.h:118
lldb::ProcessSP GetProcess() const
Definition Thread.h:162
bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) override
bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) override
GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx, lldb::DynamicRegisterInfoSP reg_info_sp, bool read_all_at_once, bool write_all_at_once)
ProcessWasm provides the access to the Wasm program state retrieved from the Wasm engine.
Definition ProcessWasm.h:21
llvm::Expected< lldb::DataBufferSP > GetWasmVariable(WasmVirtualRegisterKinds kind, int frame_index, int index)
Query the value of a WebAssembly variable from the WebAssembly remote process.
const RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
const RegisterSet * GetRegisterSet(size_t reg_set) override
bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) override
RegisterContextWasm(process_gdb_remote::ThreadGDBRemote &thread, uint32_t concrete_frame_idx, lldb::DynamicRegisterInfoSP reg_info_sp)
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) override
std::unordered_map< size_t, std::unique_ptr< WasmVirtualRegisterInfo > > m_register_map
ProcessWasm provides the access to the Wasm program state retrieved from the Wasm engine.
Definition ThreadWasm.h:19
lldb::addr_t GetConcreteFramePC(uint32_t concrete_frame_idx)
Return the program counter the Wasm unwinder recorded for the given concrete frame index,...
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
uint32_t GetWasmVirtualRegisterTag(size_t reg)
uint32_t GetWasmVirtualRegisterIndex(size_t reg)
std::shared_ptr< lldb_private::DynamicRegisterInfo > DynamicRegisterInfoSP
@ eEncodingUint
unsigned integer
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
RegisterKind
Register numbering types.
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
const char * name
Name of this register, can't be NULL.
Registers are grouped into register sets.