//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "SymbolFileWasm.h" #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Utility/WasmVirtualRegisters.h" #include "lldb/Utility/LLDBLog.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::plugin::dwarf; SymbolFileWasm::SymbolFileWasm(ObjectFileSP objfile_sp, SectionList *dwo_section_list) : SymbolFileDWARF(objfile_sp, dwo_section_list) {} SymbolFileWasm::~SymbolFileWasm() = default; lldb::offset_t SymbolFileWasm::GetVendorDWARFOpcodeSize(const DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op) const { if (op != llvm::dwarf::DW_OP_WASM_location) return LLDB_INVALID_OFFSET; lldb::offset_t offset = data_offset; const uint8_t wasm_op = data.GetU8(&offset); switch (wasm_op) { case 0: // LOCAL case 1: // GLOBAL_FIXED case 2: // OPERAND_STACK data.GetULEB128(&offset); break; case 3: // GLOBAL_RELOC data.GetU32(&offset); break; default: return LLDB_INVALID_OFFSET; } return offset - data_offset; } bool SymbolFileWasm::ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes, lldb::offset_t &offset, RegisterContext *reg_ctx, lldb::RegisterKind reg_kind, std::vector &stack) const { if (op != llvm::dwarf::DW_OP_WASM_location) return false; uint32_t index = 0; uint8_t tag = eWasmTagNotAWasmLocation; /// |DWARF Location Index | WebAssembly Construct | /// |---------------------|-----------------------| /// |0 | Local | /// |1 or 3 | Global | /// |2 | Operand Stack | const uint8_t wasm_op = opcodes.GetU8(&offset); switch (wasm_op) { case 0: // LOCAL index = opcodes.GetULEB128(&offset); tag = eWasmTagLocal; break; case 1: // GLOBAL_FIXED index = opcodes.GetULEB128(&offset); tag = eWasmTagGlobal; break; case 2: // OPERAND_STACK index = opcodes.GetULEB128(&offset); tag = eWasmTagOperandStack; break; case 3: // GLOBAL_RELOC index = opcodes.GetU32(&offset); tag = eWasmTagGlobal; break; default: return false; } const uint32_t reg_num = GetWasmRegister(tag, index); Value tmp; llvm::Error error = DWARFExpression::ReadRegisterValueAsScalar( reg_ctx, reg_kind, reg_num, tmp); if (error) { LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), std::move(error), "{0}"); return false; } stack.push_back(tmp); return true; }