110 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "RegisterContextWasm.h"10#include "Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h"11#include "ProcessWasm.h"12#include "ThreadWasm.h"13#include "lldb/Utility/LLDBLog.h"14#include "lldb/Utility/Log.h"15#include "lldb/Utility/RegisterValue.h"16#include "llvm/Support/Error.h"17#include <memory>18 19using namespace lldb;20using namespace lldb_private;21using namespace lldb_private::process_gdb_remote;22using namespace lldb_private::wasm;23 24RegisterContextWasm::RegisterContextWasm(25 ThreadGDBRemote &thread, uint32_t concrete_frame_idx,26 GDBRemoteDynamicRegisterInfoSP reg_info_sp)27 : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false,28 false) {}29 30RegisterContextWasm::~RegisterContextWasm() = default;31 32uint32_t RegisterContextWasm::ConvertRegisterKindToRegisterNumber(33 lldb::RegisterKind kind, uint32_t num) {34 return num;35}36 37size_t RegisterContextWasm::GetRegisterCount() {38 // Wasm has no registers.39 return 0;40}41 42const RegisterInfo *RegisterContextWasm::GetRegisterInfoAtIndex(size_t reg) {43 uint32_t tag = GetWasmVirtualRegisterTag(reg);44 if (tag == eWasmTagNotAWasmLocation)45 return m_reg_info_sp->GetRegisterInfoAtIndex(46 GetWasmVirtualRegisterIndex(reg));47 48 auto it = m_register_map.find(reg);49 if (it == m_register_map.end()) {50 WasmVirtualRegisterKinds kind = static_cast<WasmVirtualRegisterKinds>(tag);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 58size_t RegisterContextWasm::GetRegisterSetCount() { return 0; }59 60const RegisterSet *RegisterContextWasm::GetRegisterSet(size_t reg_set) {61 // Wasm has no registers.62 return nullptr;63}64 65bool RegisterContextWasm::ReadRegister(const RegisterInfo *reg_info,66 RegisterValue &value) {67 // The only real registers is the PC.68 if (reg_info->name)69 return GDBRemoteRegisterContext::ReadRegister(reg_info, value);70 71 // Read the virtual registers.72 ThreadWasm *thread = static_cast<ThreadWasm *>(&GetThread());73 ProcessWasm *process = static_cast<ProcessWasm *>(thread->GetProcess().get());74 if (!thread)75 return false;76 77 uint32_t frame_index = m_concrete_frame_idx;78 WasmVirtualRegisterInfo *wasm_reg_info =79 static_cast<WasmVirtualRegisterInfo *>(80 const_cast<RegisterInfo *>(reg_info));81 82 llvm::Expected<DataBufferSP> maybe_buffer = process->GetWasmVariable(83 wasm_reg_info->kind, frame_index, wasm_reg_info->index);84 if (!maybe_buffer) {85 LLDB_LOG_ERROR(GetLog(LLDBLog::Process), maybe_buffer.takeError(),86 "Failed to read Wasm local: {0}");87 return false;88 }89 90 DataBufferSP buffer_sp = *maybe_buffer;91 DataExtractor reg_data(buffer_sp, process->GetByteOrder(),92 process->GetAddressByteSize());93 wasm_reg_info->byte_size = buffer_sp->GetByteSize();94 wasm_reg_info->encoding = lldb::eEncodingUint;95 96 Status error = value.SetValueFromData(97 *reg_info, reg_data, reg_info->byte_offset, /*partial_data_ok=*/false);98 return error.Success();99}100 101void RegisterContextWasm::InvalidateAllRegisters() {}102 103bool RegisterContextWasm::WriteRegister(const RegisterInfo *reg_info,104 const RegisterValue &value) {105 // The only real registers is the PC.106 if (reg_info->name)107 return GDBRemoteRegisterContext::WriteRegister(reg_info, value);108 return false;109}110