diff options
-rw-r--r-- | src/binary-reader-logging.cc | 10 | ||||
-rw-r--r-- | src/binary-reader-objdump.cc | 93 | ||||
-rw-r--r-- | src/binary-reader-objdump.h | 7 | ||||
-rw-r--r-- | src/binary-writer.cc | 80 | ||||
-rw-r--r-- | src/ir.h | 6 | ||||
-rw-r--r-- | test/dump/relocations.txt | 18 |
6 files changed, 170 insertions, 44 deletions
diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc index 98c87628..c952bf57 100644 --- a/src/binary-reader-logging.cc +++ b/src/binary-reader-logging.cc @@ -478,8 +478,9 @@ Result BinaryReaderLogging::OnFunctionSymbol(Index index, uint32_t flags, string_view name, Index func_index) { - LOGF("OnFunctionSymbol(name: " PRIstringview " flags: 0x%x)\n", - WABT_PRINTF_STRING_VIEW_ARG(name), flags); + LOGF("OnFunctionSymbol(name: " PRIstringview " flags: 0x%x index: %" PRIindex + ")\n", + WABT_PRINTF_STRING_VIEW_ARG(name), flags, func_index); return reader_->OnGlobalSymbol(index, flags, name, func_index); } @@ -487,8 +488,9 @@ Result BinaryReaderLogging::OnGlobalSymbol(Index index, uint32_t flags, string_view name, Index global_index) { - LOGF("OnGlobalSymbol(name: " PRIstringview " flags: 0x%x)\n", - WABT_PRINTF_STRING_VIEW_ARG(name), flags); + LOGF("OnGlobalSymbol(name: " PRIstringview " flags: 0x%x index: %" PRIindex + ")\n", + WABT_PRINTF_STRING_VIEW_ARG(name), flags, global_index); return reader_->OnGlobalSymbol(index, flags, name, global_index); } diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index 724c4a9f..06b9fb98 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -50,6 +50,7 @@ class BinaryReaderObjdumpBase : public BinaryReaderNop { protected: const char* GetFunctionName(Index index) const; const char* GetGlobalName(Index index) const; + string_view GetSymbolName(Index symbol_index) const; void PrintRelocation(const Reloc& reloc, Offset offset) const; Offset GetSectionStart(BinarySection section_code) const { return section_starts_[static_cast<size_t>(section_code)]; @@ -134,24 +135,30 @@ const char* BinaryReaderObjdumpBase::GetGlobalName(Index index) const { return objdump_state_->global_names[index].c_str(); } +string_view BinaryReaderObjdumpBase::GetSymbolName(Index symbol_index) const { + assert(symbol_index < objdump_state_->symtab.size()); + ObjdumpSymbol& sym = objdump_state_->symtab[symbol_index]; + switch (sym.kind) { + case SymbolType::Function: + return GetFunctionName(sym.index); + case SymbolType::Data: + return sym.name; + case SymbolType::Global: + return GetGlobalName(sym.index); + } + WABT_UNREACHABLE; +} + void BinaryReaderObjdumpBase::PrintRelocation(const Reloc& reloc, Offset offset) const { printf(" %06" PRIzx ": %-18s %" PRIindex "", offset, GetRelocTypeName(reloc.type), reloc.index); - switch (reloc.type) { - case RelocType::MemoryAddressLEB: - case RelocType::MemoryAddressSLEB: - case RelocType::MemoryAddressI32: - printf(" + %d", reloc.addend); - break; - case RelocType::FuncIndexLEB: - case RelocType::TableIndexSLEB: - case RelocType::TableIndexI32: - if (const char* name = GetFunctionName(reloc.index)) { - printf(" <%s>", name); - } - default: - break; + if (reloc.addend) { + printf(" + %d", reloc.addend); + } + if (reloc.type != RelocType::TypeIndexLEB) { + printf(" <" PRIstringview ">", + WABT_PRINTF_STRING_VIEW_ARG(GetSymbolName(reloc.index))); } printf("\n"); } @@ -172,6 +179,21 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase { return Result::Ok; } + Result OnSymbolCount(Index count) override { + objdump_state_->symtab.resize(count); + return Result::Ok; + } + + Result OnDataSymbol(Index index, + uint32_t flags, + string_view name, + Index segment, + uint32_t offset, + uint32_t size) override { + objdump_state_->symtab[index] = {SymbolType::Data, name.to_string(), 0}; + return Result::Ok; + } + Result OnFunctionSymbol(Index index, uint32_t flags, string_view name, @@ -179,6 +201,20 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase { if (!name.empty()) { SetFunctionName(func_index, name); } + objdump_state_->symtab[index] = {SymbolType::Function, name.to_string(), + func_index}; + return Result::Ok; + } + + Result OnGlobalSymbol(Index index, + uint32_t flags, + string_view name, + Index global_index) override { + if (!name.empty()) { + SetGlobalName(global_index, name); + } + objdump_state_->symtab[index] = {SymbolType::Global, name.to_string(), + global_index}; return Result::Ok; } @@ -191,6 +227,16 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase { return Result::Ok; } + Result OnImportGlobal(Index import_index, + string_view module_name, + string_view field_name, + Index global_index, + Type type, + bool mutable_) override { + SetGlobalName(global_index, field_name); + return Result::Ok; + } + Result OnExport(Index index, ExternalKind kind, Index item_index, @@ -207,6 +253,7 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase { protected: void SetFunctionName(Index index, string_view name); + void SetGlobalName(Index index, string_view name); }; void BinaryReaderObjdumpPrepass::SetFunctionName(Index index, @@ -216,6 +263,12 @@ void BinaryReaderObjdumpPrepass::SetFunctionName(Index index, objdump_state_->function_names[index] = name.to_string(); } +void BinaryReaderObjdumpPrepass::SetGlobalName(Index index, string_view name) { + if (objdump_state_->global_names.size() <= index) + objdump_state_->global_names.resize(index + 1); + objdump_state_->global_names[index] = name.to_string(); +} + Result BinaryReaderObjdumpPrepass::OnReloc(RelocType type, Offset offset, Index index, @@ -1158,10 +1211,12 @@ Result BinaryReaderObjdump::OnReloc(RelocType type, Offset total_offset = GetSectionStart(reloc_section_) + offset; PrintDetails(" - %-18s offset=%#08" PRIoffset "(file=%#08" PRIoffset ") ", GetRelocTypeName(type), offset, total_offset); - if (type == RelocType::TypeIndexLEB) + if (type == RelocType::TypeIndexLEB) { PrintDetails("type=%" PRIindex, index); - else - PrintDetails("symbol=%" PRIindex, index); + } else { + PrintDetails("symbol=%" PRIindex " <" PRIstringview ">", index, + WABT_PRINTF_STRING_VIEW_ARG(GetSymbolName(index))); + } if (addend) { int32_t signed_addend = static_cast<int32_t>(addend); @@ -1251,7 +1306,9 @@ Result BinaryReaderObjdump::OnGlobalSymbol(Index index, Index global_index) { std::string sym_name = name.to_string(); if (sym_name.empty()) { - sym_name = GetGlobalName(global_index); + if (const char* Name = GetGlobalName(global_index)) { + sym_name = Name; + } } assert(!sym_name.empty()); PrintDetails(" - sym[%d] <" PRIstringview "> global=%" PRIindex, index, diff --git a/src/binary-reader-objdump.h b/src/binary-reader-objdump.h index 6a485680..aeebd0b9 100644 --- a/src/binary-reader-objdump.h +++ b/src/binary-reader-objdump.h @@ -50,6 +50,12 @@ struct ObjdumpOptions { const char* section_name; }; +struct ObjdumpSymbol { + wabt::SymbolType kind; + std::string name; + Index index; +}; + // read_binary_objdump uses this state to store information from previous runs // and use it to display more useful information. struct ObjdumpState { @@ -57,6 +63,7 @@ struct ObjdumpState { std::vector<Reloc> data_relocations; std::vector<std::string> function_names; std::vector<std::string> global_names; + std::vector<ObjdumpSymbol> symtab; }; Result ReadBinaryObjdump(const uint8_t* data, diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 9a4ea41c..b33c15b3 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -95,6 +95,12 @@ struct RelocSection { std::vector<Reloc> relocations; }; +struct Symbol { + Index symbol_index; + SymbolType type; + Index element_index; +}; + RelocSection::RelocSection(const char* name, BinarySection code) : name(name), section_code(code) {} @@ -123,6 +129,7 @@ class BinaryWriter { Index GetLabelVarDepth(const Var* var); Index GetExceptVarDepth(const Var* var); Index GetLocalIndex(const Func* func, const Var& var); + Index GetSymbolIndex(RelocType reloc_type, Index index); void AddReloc(RelocType reloc_type, Index index); void WriteU32Leb128WithReloc(Index index, const char* desc, @@ -139,12 +146,14 @@ class BinaryWriter { void WriteGlobalHeader(const Global* global); void WriteExceptType(const TypeVector* except_types); void WriteRelocSection(const RelocSection* reloc_section); - void WriteEmptyLinkingSection(); + void WriteLinkingSection(); Stream* stream_; const WriteBinaryOptions* options_; const Module* module_; + std::unordered_map<std::string, Index> symtab_; + std::vector<Symbol> symbols_; std::vector<RelocSection> reloc_sections_; RelocSection* current_reloc_section_ = nullptr; @@ -289,6 +298,31 @@ Index BinaryWriter::GetExceptVarDepth(const Var* var) { return var->index(); } +Index BinaryWriter::GetSymbolIndex(RelocType reloc_type, Index index) { + std::string name; + SymbolType type = SymbolType::Function; + switch (reloc_type) { + case RelocType::FuncIndexLEB: + name = module_->funcs[index]->name; + break; + case RelocType::GlobalIndexLEB: + type = SymbolType::Global; + name = module_->globals[index]->name; + break; + default: + WABT_UNREACHABLE; + } + auto iter = symtab_.find(name); + if (iter != symtab_.end()) { + return iter->second; + } + + Index sym_index = Index(symbols_.size()); + symtab_[name] = sym_index; + symbols_.push_back(Symbol{sym_index, type, index}); + return sym_index; +} + void BinaryWriter::AddReloc(RelocType reloc_type, Index index) { // Add a new reloc section if needed if (!current_reloc_section_ || @@ -300,7 +334,9 @@ void BinaryWriter::AddReloc(RelocType reloc_type, Index index) { // Add a new relocation to the curent reloc section size_t offset = stream_->offset() - last_section_payload_offset_; - current_reloc_section_->relocations.emplace_back(reloc_type, offset, index); + Index symbol_index = GetSymbolIndex(reloc_type, index); + current_reloc_section_->relocations.emplace_back(reloc_type, offset, + symbol_index); } void BinaryWriter::WriteU32Leb128WithReloc(Index index, @@ -663,11 +699,41 @@ void BinaryWriter::WriteRelocSection(const RelocSection* reloc_section) { EndSection(); } -void BinaryWriter::WriteEmptyLinkingSection() { - // Write an empty linking section. This is signal that the resulting - // file is relocatable: - // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md +void BinaryWriter::WriteLinkingSection() { BeginCustomSection(WABT_BINARY_SECTION_LINKING); + if (symbols_.size()) { + stream_->WriteU8Enum(LinkingEntryType::SymbolTable, "symbol table"); + BeginSubsection("symbol table"); + WriteU32Leb128(stream_, symbols_.size(), "num symbols"); + + for (const Symbol& sym : symbols_) { + bool is_defined = true; + if (sym.type == SymbolType::Function) { + if (sym.element_index < module_->num_func_imports) { + is_defined = false; + } + } + if (sym.type == SymbolType::Global) { + if (sym.element_index < module_->num_global_imports) { + is_defined = false; + } + } + stream_->WriteU8Enum(sym.type, "symbol type"); + WriteU32Leb128(stream_, is_defined ? 0 : WABT_SYMBOL_FLAG_UNDEFINED, + "symbol flags"); + WriteU32Leb128(stream_, sym.element_index, "element index"); + if (is_defined) { + if (sym.type == SymbolType::Function) { + WriteStr(stream_, module_->funcs[sym.element_index]->name, + "function name", PrintChars::Yes); + } else if (sym.type == SymbolType::Global) { + WriteStr(stream_, module_->globals[sym.element_index]->name, + "global name", PrintChars::Yes); + } + } + } + EndSubsection(); + } EndSection(); } @@ -971,7 +1037,7 @@ Result BinaryWriter::WriteModule() { } if (options_->relocatable) { - WriteEmptyLinkingSection(); + WriteLinkingSection(); for (RelocSection& section : reloc_sections_) { WriteRelocSection(§ion); } @@ -133,7 +133,6 @@ struct FuncSignature { }; struct FuncType { - FuncType() = default; explicit FuncType(string_view name) : name(name.to_string()) {} Index GetNumParams() const { return sig.GetNumParams(); } @@ -379,7 +378,6 @@ typedef LoadStoreExpr<ExprType::AtomicWait> AtomicWaitExpr; typedef LoadStoreExpr<ExprType::AtomicWake> AtomicWakeExpr; struct Exception { - Exception() = default; explicit Exception(string_view name) : name(name.to_string()) {} std::string name; @@ -387,7 +385,6 @@ struct Exception { }; struct Func { - Func() = default; explicit Func(string_view name) : name(name.to_string()) {} Type GetParamType(Index index) const { return decl.GetParamType(index); } @@ -411,7 +408,6 @@ struct Func { }; struct Global { - Global() = default; explicit Global(string_view name) : name(name.to_string()) {} std::string name; @@ -421,7 +417,6 @@ struct Global { }; struct Table { - Table() = default; explicit Table(string_view name) : name(name.to_string()) {} std::string name; @@ -435,7 +430,6 @@ struct ElemSegment { }; struct Memory { - Memory() = default; explicit Memory(string_view name) : name(name.to_string()) {} std::string name; diff --git a/test/dump/relocations.txt b/test/dump/relocations.txt index af3183b7..a14dd89a 100644 --- a/test/dump/relocations.txt +++ b/test/dump/relocations.txt @@ -4,7 +4,7 @@ (module (type $t (func (param i32))) (import "__extern" "foo" (func (param i32) (result i32))) - (global i32 (i32.const 0)) + (global $g i32 (i32.const 0)) (func $f (param i32) (result i32) get_global 0 call 1 @@ -25,18 +25,18 @@ Sections: Export start=0x0000003b end=0x00000040 (size=0x00000005) count: 1 Elem start=0x00000042 end=0x0000004d (size=0x0000000b) count: 1 Code start=0x0000004f end=0x00000065 (size=0x00000016) count: 1 - Custom start=0x00000067 end=0x0000006f (size=0x00000008) "linking" - Custom start=0x00000071 end=0x00000081 (size=0x00000010) "reloc.Elem" - Custom start=0x00000083 end=0x00000099 (size=0x00000016) "reloc.Code" + Custom start=0x00000067 end=0x00000081 (size=0x0000001a) "linking" + Custom start=0x00000083 end=0x00000093 (size=0x00000010) "reloc.Elem" + Custom start=0x00000095 end=0x000000ab (size=0x00000016) "reloc.Code" Code Disassembly: -000050 <f>: +000050 <$f>: 000052: 23 80 80 80 80 00 | get_global 0 - 000053: R_WEBASSEMBLY_GLOBAL_INDEX_LEB 0 - 000058: 10 81 80 80 80 00 | call 1 <f> - 000059: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 1 <f> + 000053: R_WEBASSEMBLY_GLOBAL_INDEX_LEB 1 <$g> + 000058: 10 81 80 80 80 00 | call 1 <$f> + 000059: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 0 <$f> 00005e: 10 80 80 80 80 00 | call 0 <foo> - 00005f: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 0 <foo> + 00005f: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 2 <foo> 000064: 0b | end ;;; STDOUT ;;) |