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);
259 section_id, std::move(*sect_name)});
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),
266 *offset_ptr += (c.tell() + payload_len);
301 :
ObjectFile(module_sp, file, offset, length, extractor_sp, data_offset),
310 :
ObjectFile(module_sp, process_sp, header_addr,
341 llvm::DataExtractor data = import_data.
GetAsLLVM();
342 llvm::DataExtractor::Cursor c(0);
344 llvm::Expected<uint32_t> count =
GetULEB32(data, c);
346 return count.takeError();
349 for (uint32_t i = 0; c && i < *count; ++i) {
352 llvm::Expected<std::string> module_name =
GetWasmString(data, c);
354 return llvm::joinErrors(
355 llvm::createStringError(
"failed to parse module name"),
356 module_name.takeError());
357 llvm::Expected<std::string> field_name =
GetWasmString(data, c);
359 return llvm::joinErrors(
360 llvm::createStringError(
"failed to parse field name"),
361 field_name.takeError());
365 const uint8_t kind = data.getU8(c);
367 case llvm::wasm::WASM_EXTERNAL_FUNCTION:
371 case llvm::wasm::WASM_EXTERNAL_GLOBAL:
376 case llvm::wasm::WASM_EXTERNAL_TAG:
380 case llvm::wasm::WASM_EXTERNAL_TABLE:
383 case llvm::wasm::WASM_EXTERNAL_MEMORY: {
385 const uint8_t flags = data.getU8(c);
387 if (flags & llvm::wasm::WASM_LIMITS_FLAG_HAS_MAX)
393 return llvm::joinErrors(
395 llvm::createStringError(
"unknown import kind %u", kind));
400 return c.takeError();
413 const uint32_t local_count = data.
GetULEB128(&offset);
414 for (uint32_t i = 0; i < local_count; ++i) {
418 return offset - locals_start;
421static llvm::Expected<std::vector<WasmFunction>>
425 llvm::Expected<uint32_t> function_count =
GetULEB32(data, offset);
427 return function_count.takeError();
429 std::vector<WasmFunction> functions;
430 functions.reserve(*function_count);
432 for (uint32_t i = 0; i < *function_count; ++i) {
437 llvm::Expected<uint32_t> function_size =
GetULEB32(data, offset);
439 return function_size.takeError();
445 return code_offset.takeError();
447 functions.push_back({offset, *function_size, *code_offset});
449 std::optional<lldb::offset_t> next_offset =
450 llvm::checkedAddUnsigned<lldb::offset_t>(offset, *function_size);
452 return llvm::createStringError(
"function offset overflows 64 bits");
453 offset = *next_offset;
478 llvm::Expected<uint32_t> segment_count =
GetULEB32(data, offset);
480 return segment_count.takeError();
482 std::vector<WasmSegment> segments;
483 segments.reserve(*segment_count);
485 for (uint32_t i = 0; i < *segment_count; ++i) {
486 llvm::Expected<uint32_t> flags =
GetULEB32(data, offset);
488 return flags.takeError();
496 segment.type = (*flags & llvm::wasm::WASM_DATA_SEGMENT_IS_PASSIVE)
500 if (*flags & llvm::wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) {
502 llvm::Expected<uint32_t> memidx =
GetULEB32(data, offset);
504 return memidx.takeError();
505 segment.memory_index = *memidx;
511 llvm::Expected<uint32_t> segment_size =
GetULEB32(data, offset);
513 return segment_size.takeError();
515 segment.section_offset = offset;
519 std::optional<lldb::offset_t> next_offset =
520 llvm::checkedAddUnsigned<lldb::offset_t>(offset, *segment_size);
522 return llvm::createStringError(
"segment offset overflows 64 bits");
523 offset = *next_offset;
535 llvm::Expected<uint32_t> memory_count =
GetULEB32(data, offset);
537 return memory_count.takeError();
538 if (*memory_count == 0)
539 return llvm::createStringError(
"module declares no linear memory");
544 llvm::Expected<uint32_t> min_pages =
GetULEB32(data, offset);
546 return min_pages.takeError();
548 return static_cast<uint64_t
>(*min_pages) * llvm::wasm::WasmDefaultPageSize;
555 case llvm::wasm::WASM_TYPE_I32:
556 case llvm::wasm::WASM_TYPE_F32:
558 case llvm::wasm::WASM_TYPE_I64:
559 case llvm::wasm::WASM_TYPE_F64:
571 std::optional<uint64_t> value;
573 switch (data.
GetU8(&offset)) {
574 case llvm::wasm::WASM_OPCODE_I32_CONST:
575 value =
static_cast<uint32_t
>(data.
GetSLEB128(&offset));
577 case llvm::wasm::WASM_OPCODE_I64_CONST:
578 value =
static_cast<uint64_t
>(data.
GetSLEB128(&offset));
580 case llvm::wasm::WASM_OPCODE_F32_CONST:
581 value = data.
GetU32(&offset);
583 case llvm::wasm::WASM_OPCODE_F64_CONST:
584 value = data.
GetU64(&offset);
586 case llvm::wasm::WASM_OPCODE_GLOBAL_GET:
587 case llvm::wasm::WASM_OPCODE_REF_NULL:
596 uint8_t opcode = data.
GetU8(&offset);
597 while (opcode != llvm::wasm::WASM_OPCODE_END && data.
ValidOffset(offset))
598 opcode = data.
GetU8(&offset);
599 if (opcode != llvm::wasm::WASM_OPCODE_END)
606static llvm::Expected<std::vector<WasmGlobal>>
610 llvm::Expected<uint32_t> count =
GetULEB32(data, offset);
612 return count.takeError();
615 std::vector<WasmGlobal> globals;
617 for (uint32_t i = 0; i < *count; ++i) {
619 return llvm::createStringError(
620 "global section holds %zu of its %u globals", globals.size(), *count);
626 globals.push_back(global);
632static llvm::Expected<std::vector<Symbol>>
634 DataExtractor &name_data,
const std::vector<WasmFunction> &functions,
635 std::vector<WasmSegment> &segments,
636 const std::vector<WasmGlobal> &globals,
637 uint32_t num_imported_functions, uint32_t num_imported_globals) {
639 llvm::DataExtractor data = name_data.
GetAsLLVM();
640 llvm::DataExtractor::Cursor c(0);
641 std::vector<Symbol> symbols;
642 while (c && c.tell() < data.size()) {
643 const uint8_t type = data.getU8(c);
644 llvm::Expected<uint32_t> size =
GetULEB32(data, c);
646 return size.takeError();
649 case llvm::wasm::WASM_NAMES_FUNCTION: {
650 const uint64_t count = data.getULEB128(c);
651 if (count > std::numeric_limits<uint32_t>::max())
652 return llvm::joinErrors(
654 llvm::createStringError(
"function count overflows uint32_t"));
656 for (uint64_t i = 0; c && i < count; ++i) {
657 llvm::Expected<uint32_t> idx =
GetULEB32(data, c);
659 return idx.takeError();
662 return name.takeError();
663 if (*idx >= num_imported_functions + functions.size())
666 if (*idx < num_imported_functions) {
677 const WasmFunction &func = functions[*idx - num_imported_functions];
686 symbols.back().SetPrologueByteSize(func.
code_offset);
690 case llvm::wasm::WASM_NAMES_DATA_SEGMENT: {
691 llvm::Expected<uint32_t> count =
GetULEB32(data, c);
693 return count.takeError();
694 for (uint32_t i = 0; c && i < *count; ++i) {
695 llvm::Expected<uint32_t> idx =
GetULEB32(data, c);
697 return idx.takeError();
700 return name.takeError();
701 if (*idx >= segments.size())
704 segments[i].name = *name;
708 case llvm::wasm::WASM_NAMES_GLOBAL: {
709 llvm::Expected<uint32_t> count =
GetULEB32(data, c);
711 return count.takeError();
712 for (uint32_t i = 0; c && i < *count; ++i) {
713 llvm::Expected<uint32_t> idx =
GetULEB32(data, c);
715 return idx.takeError();
718 return name.takeError();
722 if (*idx < num_imported_globals)
724 const uint32_t global_idx = *idx - num_imported_globals;
725 if (global_idx >= globals.size())
734 global_section_sp, *idx,
741 case llvm::wasm::WASM_NAMES_LOCAL:
743 std::optional<lldb::offset_t> offset =
744 llvm::checkedAddUnsigned<lldb::offset_t>(c.tell(), *size);
746 return llvm::joinErrors(
747 c.takeError(), llvm::createStringError(
"offset overflows 64 bits"));
753 return c.takeError();
769 if (Name.consume_front(
".debug_") || Name.consume_front(
".zdebug_"))
778 return llvm::StringSwitch<SectionType>(Name)
784std::optional<ObjectFileWasm::section_info>
787 if (sect_info.id == section_id)
793std::optional<ObjectFileWasm::section_info>
796 if (sect_info.name == section_name)
816 std::string section_name;
817 offset_t file_offset = sect_info.offset & 0xffffffff;
818 addr_t vm_addr = sect_info.offset;
819 size_t vm_size = sect_info.size;
821 if (llvm::wasm::WASM_SEC_CODE == sect_info.id) {
823 section_name =
"code";
834 section_name = sect_info.name;
841 SectionSP section_sp = std::make_shared<Section>(
860 std::vector<WasmFunction> functions;
861 std::vector<WasmSegment> segments;
864 if (std::optional<section_info> info =
867 llvm::Expected<std::vector<WasmFunction>> maybe_functions =
869 if (!maybe_functions) {
871 "Failed to parse Wasm code section: {0}");
873 functions = *maybe_functions;
879 if (std::optional<section_info> info =
882 llvm::Expected<WasmImports> imports =
ParseImports(import_data);
885 "Failed to parse Wasm import section: {0}");
893 if (std::optional<section_info> info =
896 llvm::Expected<std::vector<WasmGlobal>> globals =
ParseGlobals(global_data);
899 "Failed to parse Wasm global section: {0}");
906 std::optional<section_info> data_info =
910 llvm::Expected<std::vector<WasmSegment>> maybe_segments =
912 if (!maybe_segments) {
914 "Failed to parse Wasm data section: {0}");
916 segments = *maybe_segments;
925 global_section_sp = std::make_shared<Section>(
934 unified_section_list.
AddSection(global_section_sp);
939 llvm::Expected<std::vector<Symbol>> symbols =
ParseNames(
941 global_section_sp, names_data, functions, segments,
m_globals,
945 "Failed to parse Wasm names: {0}");
956 if (
segment.memory_index != 0) {
958 "Skipping segment {}: non-zero memory index is "
959 "currently unsupported",
965 LLDB_LOG(log,
"Skipping segment {}: unsupported init expression",
974 : data_info->offset +
segment.section_offset;
976 data_info->GetFileOffset() +
segment.GetFileOffset();
977 SectionSP segment_sp = std::make_shared<Section>(
989 GetModule()->GetSectionList()->AddSection(segment_sp);
992 static_data_end = std::max(static_data_end, file_vm_addr +
segment.
size);
1000 if (std::optional<section_info> mem_info =
1006 "Failed to parse Wasm memory section: {0}");
1007 }
else if (*memory_size > static_data_end) {
1010 this, ++segment_id << 8,
1013 *memory_size - static_data_end,
1018 GetModule()->GetSectionList()->AddSection(bss_sp);
1042 uint8_t bytes[
sizeof(uint64_t)];
1044 std::memcpy(dst, bytes, dst_len);
1049 bool value_is_offset) {
1075 size_t num_loaded_sections = 0;
1080 const size_t num_sections = section_list->
GetSize();
1081 for (
size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
1084 switch (section_sp->GetType()) {
1100 section_load_addr = load_address | section_sp->GetFileOffset();
1104 ++num_loaded_sections;
1107 return num_loaded_sections > 0;
1114 size = std::min(
static_cast<uint64_t
>(size),
GetByteSize() - offset);
1121 auto data_up = std::make_unique<DataBufferHeap>(size, 0);
1123 size_t bytes_read = process_sp->ReadMemory(
1124 offset, data_up->GetBytes(), data_up->GetByteSize(), readmem_error);
1125 if (bytes_read > 0) {
1130 size = std::min(
static_cast<uint64_t
>(size),
1147 static constexpr llvm::StringLiteral g_sect_name_build_id(
"build_id");
1149 if (g_sect_name_build_id != sect_info.name)
1154 llvm::DataExtractor data = section_data.
GetAsLLVM();
1155 llvm::DataExtractor::Cursor c(0);
1156 llvm::Expected<uint32_t> length =
GetULEB32(data, c);
1159 "failed to parse the build id length: {0}");
1162 llvm::SmallVector<uint8_t, 32>
id(*length, 0);
1163 data.getU8(c,
id.data(),
id.size());
1166 "failed to parse the build id: {0}");
1177 static constexpr llvm::StringLiteral g_sect_name_external_debug_info(
1178 "external_debug_info");
1181 if (g_sect_name_external_debug_info == sect_info.name) {
1182 const uint32_t kBufferSize = 1024;
1186 llvm::DataExtractor data = section_header_data.
GetAsLLVM();
1187 llvm::DataExtractor::Cursor c(0);
1188 llvm::Expected<std::string> symbols_url =
GetWasmString(data, c);
1190 llvm::consumeError(symbols_url.takeError());
1191 return std::nullopt;
1196 return std::nullopt;
1204 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
1207 ostream << static_cast<void *>(
this) <<
": ";
1209 ostream <<
"ObjectFileWasm, file = '";
1211 ostream <<
"', arch = ";
1226 ostream << llvm::left_justify(sh.
name, 16) <<
" "
1227 << llvm::format_hex(sh.
offset, 10) <<
" "
1228 << llvm::format_hex(sh.
size, 10) <<
" " << llvm::format_hex(sh.
id, 6)
1233 ostream <<
"Section Headers\n";
1234 ostream <<
"IDX name addr size id\n";
1235 ostream <<
"==== ---------------- ---------- ---------- ------\n";
1240 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.
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)
Represents UUID's of various sizes.
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
UUID GetUUID() override
Gets the UUID for this object file.
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.