20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/ADT/StringSwitch.h"
24#include "llvm/BinaryFormat/Magic.h"
25#include "llvm/BinaryFormat/Wasm.h"
26#include "llvm/Support/CheckedArithmetic.h"
27#include "llvm/Support/Endian.h"
28#include "llvm/Support/Format.h"
50 const uint64_t value = data.GetULEB128(&offset);
51 if (value > std::numeric_limits<uint32_t>::max())
52 return llvm::createStringError(
"ULEB exceeds 32 bits");
57static inline llvm::Expected<uint32_t>
58GetULEB32(llvm::DataExtractor &data, llvm::DataExtractor::Cursor &c) {
59 const uint64_t value = data.getULEB128(c);
62 if (value > std::numeric_limits<uint32_t>::max())
63 return llvm::createStringError(
"ULEB exceeds 32 bits");
68static inline llvm::Expected<std::string>
69GetWasmString(llvm::DataExtractor &data, llvm::DataExtractor::Cursor &c) {
70 llvm::Expected<uint32_t> len =
GetULEB32(data, c);
72 return len.takeError();
74 llvm::SmallVector<uint8_t, 32> str_storage;
75 data.getU8(c, str_storage, *len);
79 return std::string(toStringRef(llvm::ArrayRef(str_storage)));
90 uint8_t opcode = data.
GetU8(&offset);
92 case llvm::wasm::WASM_OPCODE_I32_CONST:
93 case llvm::wasm::WASM_OPCODE_I64_CONST:
96 case llvm::wasm::WASM_OPCODE_GLOBAL_GET:
99 case llvm::wasm::WASM_OPCODE_F32_CONST:
100 case llvm::wasm::WASM_OPCODE_F64_CONST:
104 case llvm::wasm::WASM_OPCODE_REF_NULL:
111 opcode = data.
GetU8(&offset);
112 if (opcode == llvm::wasm::WASM_OPCODE_END)
113 return init_expr_offset;
118 while (opcode != llvm::wasm::WASM_OPCODE_END && data.
ValidOffset(offset))
119 opcode = data.
GetU8(&offset);
128 if (llvm::identify_magic(toStringRef(data)) != llvm::file_magic::wasm_object)
131 const uint8_t *Ptr = data.data() +
sizeof(llvm::wasm::WasmMagic);
133 uint32_t version = llvm::support::endian::read32le(Ptr);
134 return version == llvm::wasm::WasmVersion;
157 if (!extractor_sp || !extractor_sp->HasData()) {
160 LLDB_LOGF(log,
"Failed to create ObjectFileWasm instance for file %s",
164 extractor_sp = std::make_shared<DataExtractor>(data_sp);
168 assert(extractor_sp);
171 "Failed to create ObjectFileWasm instance: invalid Wasm header");
177 if (extractor_sp->GetByteSize() < length) {
181 "Failed to create ObjectFileWasm instance: cannot read file %s",
185 extractor_sp = std::make_shared<DataExtractor>(data_sp);
190 module_sp, extractor_sp, data_offset, file, file_offset, length));
191 ArchSpec spec = objfile_up->GetArchitecture();
192 if (spec && objfile_up->SetModulesArchitecture(spec)) {
194 "%p ObjectFileWasm::CreateInstance() module = %p (%s), file = %s",
195 static_cast<void *
>(objfile_up.get()),
196 static_cast<void *
>(objfile_up->GetModule().get()),
197 objfile_up->GetModule()->GetSpecificationDescription().c_str(),
198 file ? file->
GetPath().c_str() :
"<NULL>");
199 return objfile_up.release();
202 LLDB_LOGF(log,
"Failed to create ObjectFileWasm instance");
213 std::unique_ptr<ObjectFileWasm> objfile_up(
215 ArchSpec spec = objfile_up->GetArchitecture();
216 if (spec && objfile_up->SetModulesArchitecture(spec))
217 return objfile_up.release();
224 const uint32_t kBufferSize = 1024;
227 llvm::DataExtractor data = section_header_data.
GetAsLLVM();
228 llvm::DataExtractor::Cursor c(0);
234 uint8_t section_id = data.getU8(c);
235 uint64_t payload_len = data.getULEB128(c);
237 return !llvm::errorToBool(c.takeError());
239 if (payload_len > std::numeric_limits<uint32_t>::max())
242 if (section_id == llvm::wasm::WASM_SEC_CUSTOM) {
247 llvm::Expected<std::string> sect_name =
GetWasmString(data, c);
250 "failed to parse section name: {0}");
254 if (payload_len < c.tell() - prev_offset)
257 uint32_t section_length = payload_len - (c.tell() - prev_offset);
260 *offset_ptr += (c.tell() + section_length);
261 }
else if (section_id <= llvm::wasm::WASM_SEC_LAST_KNOWN) {
263 static_cast<uint32_t
>(payload_len),
265 *offset_ptr += (c.tell() + payload_len);
300 :
ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset),
309 :
ObjectFile(module_sp, process_sp, header_addr,
340 llvm::DataExtractor data = import_data.
GetAsLLVM();
341 llvm::DataExtractor::Cursor c(0);
343 llvm::Expected<uint32_t> count =
GetULEB32(data, c);
345 return count.takeError();
348 for (uint32_t i = 0; c && i < *count; ++i) {
351 llvm::Expected<std::string> module_name =
GetWasmString(data, c);
353 return llvm::joinErrors(
354 llvm::createStringError(
"failed to parse module name"),
355 module_name.takeError());
356 llvm::Expected<std::string> field_name =
GetWasmString(data, c);
358 return llvm::joinErrors(
359 llvm::createStringError(
"failed to parse field name"),
360 field_name.takeError());
364 const uint8_t kind = data.getU8(c);
366 case llvm::wasm::WASM_EXTERNAL_FUNCTION:
370 case llvm::wasm::WASM_EXTERNAL_GLOBAL:
375 case llvm::wasm::WASM_EXTERNAL_TAG:
379 case llvm::wasm::WASM_EXTERNAL_TABLE:
382 case llvm::wasm::WASM_EXTERNAL_MEMORY: {
384 const uint8_t flags = data.getU8(c);
386 if (flags & llvm::wasm::WASM_LIMITS_FLAG_HAS_MAX)
392 return llvm::joinErrors(
394 llvm::createStringError(
"unknown import kind %u", kind));
399 return c.takeError();
412 const uint32_t local_count = data.
GetULEB128(&offset);
413 for (uint32_t i = 0; i < local_count; ++i) {
417 return offset - locals_start;
420static llvm::Expected<std::vector<WasmFunction>>
424 llvm::Expected<uint32_t> function_count =
GetULEB32(data, offset);
426 return function_count.takeError();
428 std::vector<WasmFunction> functions;
429 functions.reserve(*function_count);
431 for (uint32_t i = 0; i < *function_count; ++i) {
436 llvm::Expected<uint32_t> function_size =
GetULEB32(data, offset);
438 return function_size.takeError();
444 return code_offset.takeError();
446 functions.push_back({offset, *function_size, *code_offset});
448 std::optional<lldb::offset_t> next_offset =
449 llvm::checkedAddUnsigned<lldb::offset_t>(offset, *function_size);
451 return llvm::createStringError(
"function offset overflows 64 bits");
452 offset = *next_offset;
477 llvm::Expected<uint32_t> segment_count =
GetULEB32(data, offset);
479 return segment_count.takeError();
481 std::vector<WasmSegment> segments;
482 segments.reserve(*segment_count);
484 for (uint32_t i = 0; i < *segment_count; ++i) {
485 llvm::Expected<uint32_t> flags =
GetULEB32(data, offset);
487 return flags.takeError();
495 segment.type = (*flags & llvm::wasm::WASM_DATA_SEGMENT_IS_PASSIVE)
499 if (*flags & llvm::wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) {
501 llvm::Expected<uint32_t> memidx =
GetULEB32(data, offset);
503 return memidx.takeError();
504 segment.memory_index = *memidx;
510 llvm::Expected<uint32_t> segment_size =
GetULEB32(data, offset);
512 return segment_size.takeError();
514 segment.section_offset = offset;
518 std::optional<lldb::offset_t> next_offset =
519 llvm::checkedAddUnsigned<lldb::offset_t>(offset, *segment_size);
521 return llvm::createStringError(
"segment offset overflows 64 bits");
522 offset = *next_offset;
534 llvm::Expected<uint32_t> memory_count =
GetULEB32(data, offset);
536 return memory_count.takeError();
537 if (*memory_count == 0)
538 return llvm::createStringError(
"module declares no linear memory");
543 llvm::Expected<uint32_t> min_pages =
GetULEB32(data, offset);
545 return min_pages.takeError();
547 return static_cast<uint64_t
>(*min_pages) * llvm::wasm::WasmDefaultPageSize;
554 case llvm::wasm::WASM_TYPE_I32:
555 case llvm::wasm::WASM_TYPE_F32:
557 case llvm::wasm::WASM_TYPE_I64:
558 case llvm::wasm::WASM_TYPE_F64:
570 std::optional<uint64_t> value;
572 switch (data.
GetU8(&offset)) {
573 case llvm::wasm::WASM_OPCODE_I32_CONST:
574 value =
static_cast<uint32_t
>(data.
GetSLEB128(&offset));
576 case llvm::wasm::WASM_OPCODE_I64_CONST:
577 value =
static_cast<uint64_t
>(data.
GetSLEB128(&offset));
579 case llvm::wasm::WASM_OPCODE_F32_CONST:
580 value = data.
GetU32(&offset);
582 case llvm::wasm::WASM_OPCODE_F64_CONST:
583 value = data.
GetU64(&offset);
585 case llvm::wasm::WASM_OPCODE_GLOBAL_GET:
586 case llvm::wasm::WASM_OPCODE_REF_NULL:
595 uint8_t opcode = data.
GetU8(&offset);
596 while (opcode != llvm::wasm::WASM_OPCODE_END && data.
ValidOffset(offset))
597 opcode = data.
GetU8(&offset);
598 if (opcode != llvm::wasm::WASM_OPCODE_END)
605static llvm::Expected<std::vector<WasmGlobal>>
609 llvm::Expected<uint32_t> count =
GetULEB32(data, offset);
611 return count.takeError();
614 std::vector<WasmGlobal> globals;
616 for (uint32_t i = 0; i < *count; ++i) {
618 return llvm::createStringError(
619 "global section holds %zu of its %u globals", globals.size(), *count);
625 globals.push_back(global);
631static llvm::Expected<std::vector<Symbol>>
633 DataExtractor &name_data,
const std::vector<WasmFunction> &functions,
634 std::vector<WasmSegment> &segments,
635 const std::vector<WasmGlobal> &globals,
636 uint32_t num_imported_functions, uint32_t num_imported_globals) {
638 llvm::DataExtractor data = name_data.
GetAsLLVM();
639 llvm::DataExtractor::Cursor c(0);
640 std::vector<Symbol> symbols;
641 while (c && c.tell() < data.size()) {
642 const uint8_t type = data.getU8(c);
643 llvm::Expected<uint32_t> size =
GetULEB32(data, c);
645 return size.takeError();
648 case llvm::wasm::WASM_NAMES_FUNCTION: {
649 const uint64_t count = data.getULEB128(c);
650 if (count > std::numeric_limits<uint32_t>::max())
651 return llvm::joinErrors(
653 llvm::createStringError(
"function count overflows uint32_t"));
655 for (uint64_t i = 0; c && i < count; ++i) {
656 llvm::Expected<uint32_t> idx =
GetULEB32(data, c);
658 return idx.takeError();
661 return name.takeError();
662 if (*idx >= num_imported_functions + functions.size())
665 if (*idx < num_imported_functions) {
676 const WasmFunction &func = functions[*idx - num_imported_functions];
685 symbols.back().SetPrologueByteSize(func.
code_offset);
689 case llvm::wasm::WASM_NAMES_DATA_SEGMENT: {
690 llvm::Expected<uint32_t> count =
GetULEB32(data, c);
692 return count.takeError();
693 for (uint32_t i = 0; c && i < *count; ++i) {
694 llvm::Expected<uint32_t> idx =
GetULEB32(data, c);
696 return idx.takeError();
699 return name.takeError();
700 if (*idx >= segments.size())
703 segments[i].name = *name;
707 case llvm::wasm::WASM_NAMES_GLOBAL: {
708 llvm::Expected<uint32_t> count =
GetULEB32(data, c);
710 return count.takeError();
711 for (uint32_t i = 0; c && i < *count; ++i) {
712 llvm::Expected<uint32_t> idx =
GetULEB32(data, c);
714 return idx.takeError();
717 return name.takeError();
721 if (*idx < num_imported_globals)
723 const uint32_t global_idx = *idx - num_imported_globals;
724 if (global_idx >= globals.size())
733 global_section_sp, *idx,
740 case llvm::wasm::WASM_NAMES_LOCAL:
742 std::optional<lldb::offset_t> offset =
743 llvm::checkedAddUnsigned<lldb::offset_t>(c.tell(), *size);
745 return llvm::joinErrors(
746 c.takeError(), llvm::createStringError(
"offset overflows 64 bits"));
752 return c.takeError();
768 if (Name.consume_front(
".debug_") || Name.consume_front(
".zdebug_"))
777 return llvm::StringSwitch<SectionType>(Name)
783std::optional<ObjectFileWasm::section_info>
786 if (sect_info.id == section_id)
792std::optional<ObjectFileWasm::section_info>
795 if (sect_info.name == section_name)
816 offset_t file_offset = sect_info.offset & 0xffffffff;
817 addr_t vm_addr = sect_info.offset;
818 size_t vm_size = sect_info.size;
820 if (llvm::wasm::WASM_SEC_CODE == sect_info.id) {
833 section_name = sect_info.name;
840 SectionSP section_sp = std::make_shared<Section>(
859 std::vector<WasmFunction> functions;
860 std::vector<WasmSegment> segments;
863 if (std::optional<section_info> info =
866 llvm::Expected<std::vector<WasmFunction>> maybe_functions =
868 if (!maybe_functions) {
870 "Failed to parse Wasm code section: {0}");
872 functions = *maybe_functions;
878 if (std::optional<section_info> info =
881 llvm::Expected<WasmImports> imports =
ParseImports(import_data);
884 "Failed to parse Wasm import section: {0}");
892 if (std::optional<section_info> info =
895 llvm::Expected<std::vector<WasmGlobal>> globals =
ParseGlobals(global_data);
898 "Failed to parse Wasm global section: {0}");
905 std::optional<section_info> data_info =
909 llvm::Expected<std::vector<WasmSegment>> maybe_segments =
911 if (!maybe_segments) {
913 "Failed to parse Wasm data section: {0}");
915 segments = *maybe_segments;
924 global_section_sp = std::make_shared<Section>(
933 unified_section_list.
AddSection(global_section_sp);
938 llvm::Expected<std::vector<Symbol>> symbols =
ParseNames(
940 global_section_sp, names_data, functions, segments,
m_globals,
944 "Failed to parse Wasm names: {0}");
955 if (
segment.memory_index != 0) {
957 "Skipping segment {}: non-zero memory index is "
958 "currently unsupported",
964 LLDB_LOG(log,
"Skipping segment {}: unsupported init expression",
973 : data_info->offset +
segment.section_offset;
975 data_info->GetFileOffset() +
segment.GetFileOffset();
976 SectionSP segment_sp = std::make_shared<Section>(
988 GetModule()->GetSectionList()->AddSection(segment_sp);
991 static_data_end = std::max(static_data_end, file_vm_addr +
segment.
size);
999 if (std::optional<section_info> mem_info =
1005 "Failed to parse Wasm memory section: {0}");
1006 }
else if (*memory_size > static_data_end) {
1009 this, ++segment_id << 8,
1012 *memory_size - static_data_end,
1017 GetModule()->GetSectionList()->AddSection(bss_sp);
1041 uint8_t bytes[
sizeof(uint64_t)];
1043 std::memcpy(dst, bytes, dst_len);
1048 bool value_is_offset) {
1074 size_t num_loaded_sections = 0;
1079 const size_t num_sections = section_list->
GetSize();
1080 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
1083 switch (section_sp->GetType()) {
1099 section_load_addr = load_address | section_sp->GetFileOffset();
1103 ++num_loaded_sections;
1106 return num_loaded_sections > 0;
1113 size = std::min(
static_cast<uint64_t
>(size),
GetByteSize() - offset);
1120 auto data_up = std::make_unique<DataBufferHeap>(size, 0);
1122 size_t bytes_read = process_sp->ReadMemory(
1123 offset, data_up->GetBytes(), data_up->GetByteSize(), readmem_error);
1124 if (bytes_read > 0) {
1129 size = std::min(
static_cast<uint64_t
>(size),
1140 static ConstString g_sect_name_external_debug_info(
"external_debug_info");
1143 if (g_sect_name_external_debug_info == sect_info.name) {
1144 const uint32_t kBufferSize = 1024;
1148 llvm::DataExtractor data = section_header_data.
GetAsLLVM();
1149 llvm::DataExtractor::Cursor c(0);
1150 llvm::Expected<std::string> symbols_url =
GetWasmString(data, c);
1152 llvm::consumeError(symbols_url.takeError());
1153 return std::nullopt;
1158 return std::nullopt;
1166 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1169 ostream << static_cast<void *>(
this) <<
": ";
1171 ostream <<
"ObjectFileWasm, file = '";
1173 ostream <<
"', arch = ";
1189 << llvm::format_hex(sh.
offset, 10) <<
" "
1190 << llvm::format_hex(sh.
size, 10) <<
" " << llvm::format_hex(sh.
id, 6)
1195 ostream <<
"Section Headers\n";
1196 ostream <<
"IDX name addr size id\n";
1197 ostream <<
"==== ---------------- ---------- ---------- ------\n";
1202 ostream <<
"[" << llvm::format_decimal(idx, 2) <<
"] ";
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
static SectionType GetSectionTypeFromName(llvm::StringRef Name)
static std::optional< uint32_t > GetWasmValueTypeSize(uint8_t type)
Size in bytes of a WebAssembly value type, or nothing for the types whose values cannot be read.
static lldb::offset_t GetWasmOffsetFromInitExpr(DataExtractor &data, lldb::offset_t &offset)
An "init expr" refers to a constant expression used to determine the initial value of certain element...
static llvm::Expected< std::vector< WasmGlobal > > ParseGlobals(DataExtractor &data)
Parse the module's own globals, which start at the number of imported ones.
static llvm::Expected< std::string > GetWasmString(llvm::DataExtractor &data, llvm::DataExtractor::Cursor &c)
Helper to read a Wasm string, whcih is encoded as a vector of UTF-8 codes.
static llvm::Expected< uint32_t > GetULEB32(DataExtractor &data, lldb::offset_t &offset)
Helper to read a 32-bit ULEB using LLDB's DataExtractor.
static llvm::Expected< WasmImports > ParseImports(DataExtractor &import_data)
static llvm::Expected< uint32_t > GetFunctionCodeOffset(DataExtractor &data, lldb::offset_t offset)
Get the offset in the function to the first instruction.
static llvm::Expected< std::vector< WasmFunction > > ParseFunctions(DataExtractor &data)
static llvm::Expected< std::vector< Symbol > > ParseNames(SectionSP code_section_sp, SectionSP global_section_sp, DataExtractor &name_data, const std::vector< WasmFunction > &functions, std::vector< WasmSegment > &segments, const std::vector< WasmGlobal > &globals, uint32_t num_imported_functions, uint32_t num_imported_globals)
static bool ValidateModuleHeader(llvm::ArrayRef< uint8_t > data)
Checks whether the data buffer starts with a valid Wasm module header.
static SectionType GetSegmentTypeFromName(llvm::StringRef Name)
A section attribute on a data variable lands in a named data segment on wasm, not a top-level custom ...
static const uint32_t kWasmHeaderSize
static llvm::Expected< uint64_t > ParseMemoryMinSize(DataExtractor &data)
Parse the minimum size in bytes of the module's first linear memory.
static constexpr lldb::addr_t kWasmGlobalFileAddress
File address the synthetic global section is based at.
static std::optional< uint64_t > ParseGlobalInitValue(DataExtractor &data, lldb::offset_t &offset)
Parse the init expr that gives a global its initial value.
static llvm::Expected< std::vector< WasmSegment > > ParseData(DataExtractor &data)
#define LLDB_PLUGIN_DEFINE(PluginName)
An architecture specification class.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
void Append(const ModuleSpec &spec)
std::unique_ptr< lldb_private::SectionList > m_sections_up
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
static lldb::SectionType GetDWARFSectionTypeFromName(llvm::StringRef name)
Parses the section type from a section name for DWARF sections.
DataExtractorNSP m_data_nsp
The data for this object file so things can be parsed lazily.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
bool IsInMemory() const
Returns true if the object file exists only in memory.
lldb::ProcessWP m_process_wp
virtual size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len)
virtual lldb::addr_t GetByteSize() const
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
size_t AddSection(const lldb::SectionSP §ion_sp)
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
lldb::SectionSP GetSectionAtIndex(size_t idx) const
lldb::SectionType GetType() const
A stream class that can stream formatted output to a file.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
unsigned GetIndentLevel() const
Get the current indentation level.
uint32_t AddSymbol(const Symbol &symbol)
bool SetSectionLoadAddress(const lldb::SectionSP §ion, lldb::addr_t load_addr, bool warn_multiple=false)
Generic Wasm object file reader.
ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
std::optional< FileSpec > GetExternalDebugInfoFileSpec()
A Wasm module that has external DWARF debug information should contain a custom section named "extern...
size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len) override
A global has no bytes in the module to read, so serve its initial value when there is no process to a...
bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override
Sets the load address for an entire module, assuming a rigid slide of sections, if possible in the im...
bool DecodeNextSection(lldb::offset_t *offset_ptr)
Wasm section decoding routines.
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
void CreateSections(SectionList &unified_section_list) override
ObjectFileWasm(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
std::optional< section_info > GetSectionInfo(uint32_t section_id)
void Dump(Stream *s) override
Dump a description of this object to a Stream.
static llvm::StringRef GetPluginNameStatic()
std::vector< section_info > m_sect_infos
void DumpSectionHeader(llvm::raw_ostream &ostream, const section_info &sh)
Wasm section header dump routines.
void DumpSectionHeaders(llvm::raw_ostream &ostream)
static ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
static char ID
LLVM RTTI support.
std::vector< Symbol > m_symbols
void ParseSymtab(lldb_private::Symtab &symtab) override
Parse the symbol table into the provides symbol table object.
static ModuleSpecList GetModuleSpecifications(const FileSpec &file, lldb::DataExtractorSP &extractor_sp, lldb::offset_t file_offset, lldb::offset_t length)
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
uint32_t m_num_imported_globals
static ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
std::vector< WasmGlobal > m_globals
bool ParseHeader() override
ObjectFile Protocol.
uint32_t m_num_imported_functions
static const char * GetPluginDescriptionStatic()
DataExtractor ReadImageData(lldb::offset_t offset, uint32_t size)
Read a range of bytes from the Wasm module.
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_OFFSET
static constexpr uint64_t kWasmAddressTypeMask
WasmAddressType
Each WebAssembly module has separate address spaces for Code and Memory.
static constexpr uint32_t kWasmAddressTypeShift
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.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eSectionTypeLLDBFormatters
@ eSectionTypeLLDBTypeSummaries
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::Module > ModuleSP
lldb::offset_t section_offset
Offset from the section to the start of the function.
uint32_t code_offset
Offset from section_offset to the first instruction in the function, past the local variable declarat...
uint32_t size
Function size, which includes the function header, but not the size ULEB that proceeds it.
The number of imports of each kind.
lldb::offset_t section_offset
lldb::offset_t GetFileOffset() const
lldb::offset_t init_expr_offset
A global declared by the module itself.
std::optional< uint32_t > size
Size of the global's value type, which bounds what a read can produce.
std::optional< uint64_t > init_expr_value
Value the global is initialized with, when the initializer is a constant.