diff options
-rw-r--r-- | src/binary-reader-ir.cc | 19 | ||||
-rw-r--r-- | src/binary-reader-logging.cc | 10 | ||||
-rw-r--r-- | src/binary-reader-logging.h | 4 | ||||
-rw-r--r-- | src/binary-reader-nop.h | 6 | ||||
-rw-r--r-- | src/binary-reader-objdump.cc | 42 | ||||
-rw-r--r-- | src/binary-reader-objdump.h | 1 | ||||
-rw-r--r-- | src/binary-reader.cc | 7 | ||||
-rw-r--r-- | src/binary-reader.h | 4 | ||||
-rw-r--r-- | src/binary-writer.cc | 107 | ||||
-rw-r--r-- | src/common.cc | 1 | ||||
-rw-r--r-- | src/common.h | 6 | ||||
-rw-r--r-- | test/dump/relocations-all-features.txt | 90 | ||||
-rw-r--r-- | test/dump/relocations.txt | 46 | ||||
-rw-r--r-- | test/dump/symbol-tables-all-features.txt | 74 | ||||
-rw-r--r-- | test/dump/symbol-tables.txt | 50 |
15 files changed, 418 insertions, 49 deletions
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index 3678438e..58636e88 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -260,6 +260,8 @@ class BinaryReaderIR : public BinaryReaderNop { Index section_index) override; Result OnEventSymbol(Index index, uint32_t flags, string_view name, Index event_index) override; + Result OnTableSymbol(Index index, uint32_t flags, string_view name, + Index table_index) override; private: Location GetLocation() const; @@ -1349,6 +1351,23 @@ Result BinaryReaderIR::OnEventSymbol(Index index, uint32_t flags, return Result::Ok; } +Result BinaryReaderIR::OnTableSymbol(Index index, uint32_t flags, + string_view name, Index table_index) { + if (name.empty()) { + return Result::Ok; + } + if (table_index >= module_->tables.size()) { + PrintError("invalid table index: %" PRIindex, table_index); + return Result::Error; + } + Table* table = module_->tables[table_index]; + std::string dollar_name = + GetUniqueName(&module_->table_bindings, MakeDollarName(name)); + table->name = dollar_name; + module_->table_bindings.emplace(dollar_name, Binding(table_index)); + return Result::Ok; +} + } // end anonymous namespace Result ReadBinaryIr(const char* filename, diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc index b74dcf43..9c83a049 100644 --- a/src/binary-reader-logging.cc +++ b/src/binary-reader-logging.cc @@ -603,6 +603,16 @@ Result BinaryReaderLogging::OnEventSymbol(Index index, return reader_->OnEventSymbol(index, flags, name, event_index); } +Result BinaryReaderLogging::OnTableSymbol(Index index, + uint32_t flags, + string_view name, + Index table_index) { + LOGF("OnTableSymbol(name: " PRIstringview " flags: 0x%x index: %" PRIindex + ")\n", + WABT_PRINTF_STRING_VIEW_ARG(name), flags, table_index); + return reader_->OnTableSymbol(index, flags, name, table_index); +} + Result BinaryReaderLogging::OnSegmentInfo(Index index, string_view name, Address alignment, diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h index a461572b..5936dad6 100644 --- a/src/binary-reader-logging.h +++ b/src/binary-reader-logging.h @@ -327,6 +327,10 @@ class BinaryReaderLogging : public BinaryReaderDelegate { uint32_t flags, string_view name, Index event_index) override; + Result OnTableSymbol(Index index, + uint32_t flags, + string_view name, + Index event_index) override; Result OnSegmentInfoCount(Index count) override; Result OnSegmentInfo(Index index, string_view name, diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h index 492687bd..b49883b9 100644 --- a/src/binary-reader-nop.h +++ b/src/binary-reader-nop.h @@ -472,6 +472,12 @@ class BinaryReaderNop : public BinaryReaderDelegate { Index event_index) override { return Result::Ok; } + Result OnTableSymbol(Index index, + uint32_t flags, + string_view name, + Index table_index) override { + return Result::Ok; + } Result OnSegmentInfoCount(Index count) override { return Result::Ok; } Result OnSegmentInfo(Index index, string_view name, diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index 649358d6..0d3d1188 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -58,6 +58,7 @@ class BinaryReaderObjdumpBase : public BinaryReaderNop { string_view GetEventName(Index index) const; string_view GetSymbolName(Index index) const; string_view GetSegmentName(Index index) const; + string_view GetTableName(Index 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)]; @@ -152,6 +153,10 @@ string_view BinaryReaderObjdumpBase::GetSegmentName(Index index) const { return objdump_state_->segment_names.Get(index); } +string_view BinaryReaderObjdumpBase::GetTableName(Index index) const { + return objdump_state_->table_names.Get(index); +} + string_view BinaryReaderObjdumpBase::GetSymbolName(Index symbol_index) const { if (symbol_index >= objdump_state_->symtab.size()) return "<illegal_symbol_index>"; @@ -167,6 +172,8 @@ string_view BinaryReaderObjdumpBase::GetSymbolName(Index symbol_index) const { return GetSectionName(sym.index); case SymbolType::Event: return GetEventName(sym.index); + case SymbolType::Table: + return GetTableName(sym.index); } WABT_UNREACHABLE; } @@ -283,6 +290,18 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase { return Result::Ok; } + Result OnTableSymbol(Index index, + uint32_t flags, + string_view name, + Index table_index) override { + if (!name.empty()) { + SetTableName(table_index, name); + } + objdump_state_->symtab[index] = {SymbolType::Table, name.to_string(), + table_index}; + return Result::Ok; + } + Result OnImportFunc(Index import_index, string_view module_name, string_view field_name, @@ -351,6 +370,7 @@ class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase { void SetFunctionName(Index index, string_view name); void SetGlobalName(Index index, string_view name); void SetEventName(Index index, string_view name); + void SetTableName(Index index, string_view name); void SetSegmentName(Index index, string_view name); }; @@ -367,6 +387,10 @@ void BinaryReaderObjdumpPrepass::SetEventName(Index index, string_view name) { objdump_state_->event_names.Set(index, name); } +void BinaryReaderObjdumpPrepass::SetTableName(Index index, string_view name) { + objdump_state_->table_names.Set(index, name); +} + void BinaryReaderObjdumpPrepass::SetSegmentName(Index index, string_view name) { objdump_state_->segment_names.Set(index, name); } @@ -891,6 +915,10 @@ class BinaryReaderObjdump : public BinaryReaderObjdumpBase { uint32_t flags, string_view name, Index event_index) override; + Result OnTableSymbol(Index index, + uint32_t flags, + string_view name, + Index table_index) override; Result OnSegmentInfoCount(Index count) override; Result OnSegmentInfo(Index index, string_view name, @@ -1781,11 +1809,23 @@ Result BinaryReaderObjdump::OnEventSymbol(Index index, if (name.empty()) { name = GetEventName(event_index); } - PrintDetails(" - [%d] E <" PRIstringview "> event=%" PRIindex, index, + PrintDetails(" - %d: E <" PRIstringview "> event=%" PRIindex, index, WABT_PRINTF_STRING_VIEW_ARG(name), event_index); return PrintSymbolFlags(flags); } +Result BinaryReaderObjdump::OnTableSymbol(Index index, + uint32_t flags, + string_view name, + Index table_index) { + if (name.empty()) { + name = GetTableName(table_index); + } + PrintDetails(" - %d: T <" PRIstringview "> table=%" PRIindex, index, + WABT_PRINTF_STRING_VIEW_ARG(name), table_index); + return PrintSymbolFlags(flags); +} + Result BinaryReaderObjdump::OnSegmentInfoCount(Index count) { PrintDetails(" - segment info [count=%d]\n", count); return Result::Ok; diff --git a/src/binary-reader-objdump.h b/src/binary-reader-objdump.h index b1e24f81..b2874dac 100644 --- a/src/binary-reader-objdump.h +++ b/src/binary-reader-objdump.h @@ -73,6 +73,7 @@ struct ObjdumpState { ObjdumpNames section_names; ObjdumpNames event_names; ObjdumpNames segment_names; + ObjdumpNames table_names; std::vector<ObjdumpSymbol> symtab; }; diff --git a/src/binary-reader.cc b/src/binary-reader.cc index a28a0ad9..e44b8ca7 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -1784,6 +1784,7 @@ Result BinaryReader::ReadRelocSection(Offset section_size) { case RelocType::GlobalIndexI32: case RelocType::EventIndexLEB: case RelocType::TableIndexRelSLEB: + case RelocType::TableNumberLEB: break; default: @@ -1854,7 +1855,8 @@ Result BinaryReader::ReadLinkingSection(Offset section_size) { switch (sym_type) { case SymbolType::Function: case SymbolType::Global: - case SymbolType::Event: { + case SymbolType::Event: + case SymbolType::Table: { uint32_t index = 0; CHECK_RESULT(ReadU32Leb128(&index, "index")); if ((flags & WABT_SYMBOL_FLAG_UNDEFINED) == 0 || @@ -1870,6 +1872,9 @@ Result BinaryReader::ReadLinkingSection(Offset section_size) { case SymbolType::Event: CALLBACK(OnEventSymbol, i, flags, name, index); break; + case SymbolType::Table: + CALLBACK(OnTableSymbol, i, flags, name, index); + break; default: WABT_UNREACHABLE; } diff --git a/src/binary-reader.h b/src/binary-reader.h index 1c3fcf12..8e5e3dd6 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -401,6 +401,10 @@ class BinaryReaderDelegate { uint32_t flags, string_view name, Index event_index) = 0; + virtual Result OnTableSymbol(Index index, + uint32_t flags, + string_view name, + Index table_index) = 0; virtual Result OnSegmentInfoCount(Index count) = 0; virtual Result OnSegmentInfo(Index index, string_view name, diff --git a/src/binary-writer.cc b/src/binary-writer.cc index c628b108..b5732533 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -122,6 +122,10 @@ class Symbol { static const SymbolType type = SymbolType::Event; Index index; }; + struct Table { + static const SymbolType type = SymbolType::Table; + Index index; + }; private: SymbolType type_; @@ -133,6 +137,7 @@ class Symbol { Global global_; Section section_; Event event_; + Table table_; }; public: @@ -146,6 +151,8 @@ class Symbol { : type_(Section::type), name_(name), flags_(flags), section_(s) {} Symbol(const string_view& name, uint8_t flags, const Event& e) : type_(Event::type), name_(name), flags_(flags), event_(e) {} + Symbol(const string_view& name, uint8_t flags, const Table& t) + : type_(Table::type), name_(name), flags_(flags), table_(t) {} SymbolType type() const { return type_; } const string_view& name() const { return name_; } @@ -168,6 +175,7 @@ class Symbol { bool IsGlobal() const { return type() == Global::type; } bool IsSection() const { return type() == Section::type; } bool IsEvent() const { return type() == Event::type; } + bool IsTable() const { return type() == Table::type; } const Function& AsFunction() const { assert(IsFunction()); @@ -189,6 +197,10 @@ class Symbol { assert(IsEvent()); return event_; } + const Table& AsTable() const { + assert(IsTable()); + return table_; + } }; class SymbolTable { @@ -197,6 +209,7 @@ class SymbolTable { std::vector<Symbol> symbols_; std::vector<Index> functions_; + std::vector<Index> tables_; std::vector<Index> globals_; std::set<string_view> seen_names_; @@ -222,17 +235,17 @@ class SymbolTable { // name fabricated by wabt. name = string_view(); } else { - // Functions defined in this module without a name don't go in the symbol - // table. if (name.empty()) { - return Result::Ok; + // Definitions without a name are local. + flags |= uint8_t(SymbolBinding::Local); + flags |= uint8_t(SymbolVisibility::Hidden); + } else { + // Otherwise, strip the dollar off the name; a definition $foo is + // available for linking as "foo". + assert(name[0] == '$'); + name.remove_prefix(1); } - // Otherwise, strip the dollar off the name; a function $foo is available - // for linking as "foo". - assert(name[0] == '$'); - name.remove_prefix(1); - if (exported) { CHECK_RESULT(EnsureUnique(name)); flags |= uint8_t(SymbolVisibility::Hidden); @@ -248,6 +261,13 @@ class SymbolTable { return Result::Ok; }; + Index SymbolIndex(const std::vector<Index>& table, Index index) const { + // For well-formed modules, an index into (e.g.) functions_ will always be + // within bounds; the out-of-bounds case here is just to allow --relocatable + // to write known-invalid modules. + return index < table.size() ? table[index] : kInvalidIndex; + } + public: SymbolTable() {} @@ -276,8 +296,8 @@ class SymbolTable { } } - // We currently only create symbol table entries for function and global - // symbols. + // We currently only create symbol table entries for function, table, and + // global symbols. for (size_t i = 0; i < module->funcs.size(); ++i) { const Func* func = module->funcs[i]; bool imported = i < module->num_func_imports; @@ -286,6 +306,14 @@ class SymbolTable { Symbol::Function{Index(i)})); } + for (size_t i = 0; i < module->tables.size(); ++i) { + const Table* table = module->tables[i]; + bool imported = i < module->num_table_imports; + bool exported = exported_tables.count(i); + CHECK_RESULT(AddSymbol(&tables_, table->name, imported, exported, + Symbol::Table{Index(i)})); + } + for (size_t i = 0; i < module->globals.size(); ++i) { const Global* global = module->globals[i]; bool imported = i < module->num_global_imports; @@ -298,8 +326,15 @@ class SymbolTable { } const std::vector<Symbol>& symbols() const { return symbols_; } - Index FunctionSymbolIndex(Index index) const { return functions_[index]; } - Index GlobalSymbolIndex(Index index) const { return globals_[index]; } + Index FunctionSymbolIndex(Index index) const { + return SymbolIndex(functions_, index); + } + Index TableSymbolIndex(Index index) const { + return SymbolIndex(tables_, index); + } + Index GlobalSymbolIndex(Index index) const { + return SymbolIndex(globals_, index); + } }; class BinaryWriter { @@ -336,6 +371,7 @@ class BinaryWriter { void WriteS32Leb128WithReloc(int32_t value, const char* desc, RelocType reloc_type); + void WriteTableNumberWithReloc(Index table_number, const char* desc); template <typename T> void WriteLoadStoreExpr(const Func* func, const Expr* expr, const char* desc); void WriteExpr(const Func* func, const Expr* expr); @@ -513,6 +549,8 @@ Index BinaryWriter::GetSymbolIndex(RelocType reloc_type, Index index) { switch (reloc_type) { case RelocType::FuncIndexLEB: return symtab_.FunctionSymbolIndex(index); + case RelocType::TableNumberLEB: + return symtab_.TableSymbolIndex(index); case RelocType::GlobalIndexLEB: return symtab_.GlobalSymbolIndex(index); case RelocType::TypeIndexLEB: @@ -537,6 +575,12 @@ 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_; Index symbol_index = GetSymbolIndex(reloc_type, index); + if (symbol_index == kInvalidIndex) { + // The file is invalid, for example a reference to function 42 where only 10 + // functions are defined. The user must have already passed --no-check, so + // no extra warning here is needed. + return; + } current_reloc_section_->relocations.emplace_back(reloc_type, offset, symbol_index); } @@ -563,6 +607,18 @@ void BinaryWriter::WriteS32Leb128WithReloc(int32_t value, } } +void BinaryWriter::WriteTableNumberWithReloc(Index value, + const char* desc) { + // Unless reference types are enabled, all references to tables refer to table + // 0, so no relocs need be emitted when making relocatable binaries. + if (options_.relocatable && options_.features.reference_types_enabled()) { + AddReloc(RelocType::TableNumberLEB, value); + WriteFixedS32Leb128(stream_, value, desc); + } else { + WriteS32Leb128(stream_, value, desc); + } +} + Index BinaryWriter::GetLocalIndex(const Func* func, const Var& var) { // func can be nullptr when using local.get/local.set/local.tee in an // init_expr. @@ -674,7 +730,7 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { module_->GetTableIndex(cast<CallIndirectExpr>(expr)->table); WriteOpcode(stream_, Opcode::CallIndirect); WriteU32Leb128WithReloc(sig_index, "signature index", RelocType::TypeIndexLEB); - WriteU32Leb128(stream_, table_index, "table index"); + WriteTableNumberWithReloc(table_index, "table index"); break; } case ExprType::ReturnCallIndirect: { @@ -684,7 +740,7 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { module_->GetTableIndex(cast<ReturnCallIndirectExpr>(expr)->table); WriteOpcode(stream_, Opcode::ReturnCallIndirect); WriteU32Leb128WithReloc(sig_index, "signature index", RelocType::TypeIndexLEB); - WriteU32Leb128(stream_, table_index, "table index"); + WriteTableNumberWithReloc(table_index, "table index"); break; } case ExprType::Compare: @@ -815,8 +871,8 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { Index dst = module_->GetTableIndex(copy_expr->dst_table); Index src = module_->GetTableIndex(copy_expr->src_table); WriteOpcode(stream_, Opcode::TableCopy); - WriteU32Leb128(stream_, dst, "table.copy dst_table"); - WriteU32Leb128(stream_, src, "table.copy src_table"); + WriteTableNumberWithReloc(dst, "table.copy dst_table"); + WriteTableNumberWithReloc(src, "table.copy src_table"); break; } case ExprType::ElemDrop: { @@ -833,42 +889,42 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { module_->GetElemSegmentIndex(init_expr->segment_index); WriteOpcode(stream_, Opcode::TableInit); WriteU32Leb128(stream_, segment_index, "table.init segment"); - WriteU32Leb128(stream_, table_index, "table.init table"); + WriteTableNumberWithReloc(table_index, "table.init table"); break; } case ExprType::TableGet: { Index index = module_->GetTableIndex(cast<TableGetExpr>(expr)->var); WriteOpcode(stream_, Opcode::TableGet); - WriteU32Leb128(stream_, index, "table.get table index"); + WriteTableNumberWithReloc(index, "table.get table index"); break; } case ExprType::TableSet: { Index index = module_->GetTableIndex(cast<TableSetExpr>(expr)->var); WriteOpcode(stream_, Opcode::TableSet); - WriteU32Leb128(stream_, index, "table.set table index"); + WriteTableNumberWithReloc(index, "table.set table index"); break; } case ExprType::TableGrow: { Index index = module_->GetTableIndex(cast<TableGrowExpr>(expr)->var); WriteOpcode(stream_, Opcode::TableGrow); - WriteU32Leb128(stream_, index, "table.grow table index"); + WriteTableNumberWithReloc(index, "table.grow table index"); break; } case ExprType::TableSize: { Index index = module_->GetTableIndex(cast<TableSizeExpr>(expr)->var); WriteOpcode(stream_, Opcode::TableSize); - WriteU32Leb128(stream_, index, "table.size table index"); + WriteTableNumberWithReloc(index, "table.size table index"); break; } case ExprType::TableFill: { Index index = module_->GetTableIndex(cast<TableFillExpr>(expr)->var); WriteOpcode(stream_, Opcode::TableFill); - WriteU32Leb128(stream_, index, "table.fill table index"); + WriteTableNumberWithReloc(index, "table.fill table index"); break; } case ExprType::RefFunc: { @@ -1042,6 +1098,7 @@ void BinaryWriter::WriteRelocSection(const RelocSection* reloc_section) { case RelocType::GlobalIndexLEB: case RelocType::EventIndexLEB: case RelocType::TableIndexRelSLEB: + case RelocType::TableNumberLEB: break; default: fprintf(stderr, "warning: unsupported relocation type: %s\n", @@ -1094,6 +1151,12 @@ void BinaryWriter::WriteLinkingSection() { WriteStr(stream_, sym.name(), "event name", PrintChars::Yes); } break; + case SymbolType::Table: + WriteU32Leb128(stream_, sym.AsTable().index, "table index"); + if (sym.defined() || sym.explicit_name()) { + WriteStr(stream_, sym.name(), "table name", PrintChars::Yes); + } + break; } } EndSubsection(); diff --git a/src/common.cc b/src/common.cc index 875f71ae..0de9cf93 100644 --- a/src/common.cc +++ b/src/common.cc @@ -53,6 +53,7 @@ const char* g_reloc_type_name[] = { "R_WASM_MEMORY_ADDR_LEB64", "R_WASM_MEMORY_ADDR_SLEB64", "R_WASM_MEMORY_ADDR_I64", "R_WASM_MEMORY_ADDR_REL_SLEB64", "R_WASM_TABLE_INDEX_SLEB64", "R_WASM_TABLE_INDEX_I64", + "R_WASM_TABLE_NUMBER_LEB", }; WABT_STATIC_ASSERT(WABT_ARRAY_SIZE(g_reloc_type_name) == kRelocTypeCount); diff --git a/src/common.h b/src/common.h index 40f79f49..d900619d 100644 --- a/src/common.h +++ b/src/common.h @@ -294,9 +294,10 @@ enum class RelocType { MemoryAddressRelSLEB64 = 17, // Memory64: Like MemoryAddressRelSLEB TableIndexSLEB64 = 18, // Memory64: Like TableIndexSLEB TableIndexI64 = 19, // Memory64: Like TableIndexI32 + TableNumberLEB = 20, // e.g. Immediate of table.get First = FuncIndexLEB, - Last = TableIndexI64, + Last = TableNumberLEB, }; static const int kRelocTypeCount = WABT_ENUM_COUNT(RelocType); @@ -322,6 +323,7 @@ enum class SymbolType { Global = 2, Section = 3, Event = 4, + Table = 5, }; enum class ComdatType { @@ -422,6 +424,8 @@ static WABT_INLINE const char* GetSymbolTypeName(SymbolType type) { return "section"; case SymbolType::Event: return "event"; + case SymbolType::Table: + return "table"; default: return "<error_symbol_type>"; } diff --git a/test/dump/relocations-all-features.txt b/test/dump/relocations-all-features.txt new file mode 100644 index 00000000..19f940a4 --- /dev/null +++ b/test/dump/relocations-all-features.txt @@ -0,0 +1,90 @@ +;;; TOOL: run-objdump +;;; ARGS0: -r --enable-all +;;; ARGS1: --headers --details +(module + (type $t (func (param i32))) + (import "__extern" "foo" (func (param i32) (result i32))) + (import "__extern" "bar" (func (param i32) (param i32) (result i32))) + (global $g i32 (i32.const 0)) + (func $f (param i32) (result i32) + get_global 0 + call 2 + call 0 + i32.const 1234 + i32.const 0 + call_indirect (param i32) (param i32) (result i32)) + (export "f" (func $f)) + (table anyfunc (elem 1))) +(;; STDOUT ;;; + +relocations-all-features.wasm: file format wasm 0x1 + +Sections: + + Type start=0x0000000a end=0x0000001a (size=0x00000010) count: 3 + Import start=0x0000001c end=0x0000003b (size=0x0000001f) count: 2 + Function start=0x0000003d end=0x0000003f (size=0x00000002) count: 1 + Table start=0x00000041 end=0x00000046 (size=0x00000005) count: 1 + Global start=0x00000048 end=0x0000004e (size=0x00000006) count: 1 + Export start=0x00000050 end=0x00000055 (size=0x00000005) count: 1 + Elem start=0x00000057 end=0x0000005e (size=0x00000007) count: 1 + Code start=0x00000060 end=0x00000086 (size=0x00000026) count: 1 + Custom start=0x00000088 end=0x000000a9 (size=0x00000021) "linking" + Custom start=0x000000ab end=0x000000c7 (size=0x0000001c) "reloc.Code" + +Section Details: + +Type[3]: + - type[0] (i32) -> nil + - type[1] (i32) -> i32 + - type[2] (i32, i32) -> i32 +Import[2]: + - func[0] sig=1 <__extern.foo> <- __extern.foo + - func[1] sig=2 <__extern.bar> <- __extern.bar +Function[1]: + - func[2] sig=1 <f> +Table[1]: + - table[0] type=funcref initial=1 max=1 +Global[1]: + - global[0] i32 mutable=0 <g> - init i32=0 +Export[1]: + - func[2] <f> -> "f" +Elem[1]: + - segment[0] flags=0 table=0 count=1 - init i32=0 + - elem[0] = func[1] <__extern.bar> +Code[1]: + - func[2] size=36 <f> +Custom: + - name: "linking" + - symbol table [count=5] + - 0: F <__extern.foo> func=0 undefined binding=global vis=default + - 1: F <__extern.bar> func=1 undefined binding=global vis=default + - 2: F <f> func=2 exported no_strip binding=global vis=hidden + - 3: T <> table=0 binding=local vis=hidden + - 4: G <g> global=0 binding=global vis=default +Custom: + - name: "reloc.Code" + - relocations for section: 7 (Code) [5] + - R_WASM_GLOBAL_INDEX_LEB offset=0x000004(file=0x000064) symbol=4 <g> + - R_WASM_FUNCTION_INDEX_LEB offset=0x00000a(file=0x00006a) symbol=2 <f> + - R_WASM_FUNCTION_INDEX_LEB offset=0x000010(file=0x000070) symbol=0 <__extern.foo> + - R_WASM_TYPE_INDEX_LEB offset=0x00001b(file=0x00007b) type=2 + - R_WASM_TABLE_NUMBER_LEB offset=0x000020(file=0x000080) symbol=3 <> + +Code Disassembly: + +000062 func[2] <f>: + 000063: 23 80 80 80 80 00 | global.get 0 <g> + 000064: R_WASM_GLOBAL_INDEX_LEB 4 <g> + 000069: 10 82 80 80 80 00 | call 2 <f> + 00006a: R_WASM_FUNCTION_INDEX_LEB 2 <f> + 00006f: 10 80 80 80 80 00 | call 0 <__extern.foo> + 000070: R_WASM_FUNCTION_INDEX_LEB 0 <__extern.foo> + 000075: 41 d2 09 | i32.const 1234 + 000078: 41 00 | i32.const 0 + 00007a: 11 82 80 80 80 00 80 80 80 | call_indirect 2 0 + 000083: 80 00 | + 00007b: R_WASM_TYPE_INDEX_LEB 2 + 000085: 0b | end + 000080: R_WASM_TABLE_NUMBER_LEB 3 <> +;;; STDOUT ;;) diff --git a/test/dump/relocations.txt b/test/dump/relocations.txt index d856413a..1fb5e708 100644 --- a/test/dump/relocations.txt +++ b/test/dump/relocations.txt @@ -1,6 +1,6 @@ ;;; TOOL: run-objdump ;;; ARGS0: -r -;;; ARGS1: --headers +;;; ARGS1: --headers --details (module (type $t (func (param i32))) (import "__extern" "foo" (func (param i32) (result i32))) @@ -29,14 +29,52 @@ Sections: Export start=0x00000050 end=0x00000055 (size=0x00000005) count: 1 Elem start=0x00000057 end=0x0000005e (size=0x00000007) count: 1 Code start=0x00000060 end=0x00000082 (size=0x00000022) count: 1 - Custom start=0x00000084 end=0x000000a1 (size=0x0000001d) "linking" - Custom start=0x000000a3 end=0x000000bc (size=0x00000019) "reloc.Code" + Custom start=0x00000084 end=0x000000a5 (size=0x00000021) "linking" + Custom start=0x000000a7 end=0x000000c0 (size=0x00000019) "reloc.Code" + +Section Details: + +Type[3]: + - type[0] (i32) -> nil + - type[1] (i32) -> i32 + - type[2] (i32, i32) -> i32 +Import[2]: + - func[0] sig=1 <__extern.foo> <- __extern.foo + - func[1] sig=2 <__extern.bar> <- __extern.bar +Function[1]: + - func[2] sig=1 <f> +Table[1]: + - table[0] type=funcref initial=1 max=1 +Global[1]: + - global[0] i32 mutable=0 <g> - init i32=0 +Export[1]: + - func[2] <f> -> "f" +Elem[1]: + - segment[0] flags=0 table=0 count=1 - init i32=0 + - elem[0] = func[1] <__extern.bar> +Code[1]: + - func[2] size=32 <f> +Custom: + - name: "linking" + - symbol table [count=5] + - 0: F <__extern.foo> func=0 undefined binding=global vis=default + - 1: F <__extern.bar> func=1 undefined binding=global vis=default + - 2: F <f> func=2 exported no_strip binding=global vis=hidden + - 3: T <> table=0 binding=local vis=hidden + - 4: G <g> global=0 binding=global vis=default +Custom: + - name: "reloc.Code" + - relocations for section: 7 (Code) [4] + - R_WASM_GLOBAL_INDEX_LEB offset=0x000004(file=0x000064) symbol=4 <g> + - R_WASM_FUNCTION_INDEX_LEB offset=0x00000a(file=0x00006a) symbol=2 <f> + - R_WASM_FUNCTION_INDEX_LEB offset=0x000010(file=0x000070) symbol=0 <__extern.foo> + - R_WASM_TYPE_INDEX_LEB offset=0x00001b(file=0x00007b) type=2 Code Disassembly: 000062 func[2] <f>: 000063: 23 80 80 80 80 00 | global.get 0 <g> - 000064: R_WASM_GLOBAL_INDEX_LEB 3 <g> + 000064: R_WASM_GLOBAL_INDEX_LEB 4 <g> 000069: 10 82 80 80 80 00 | call 2 <f> 00006a: R_WASM_FUNCTION_INDEX_LEB 2 <f> 00006f: 10 80 80 80 80 00 | call 0 <__extern.foo> diff --git a/test/dump/symbol-tables-all-features.txt b/test/dump/symbol-tables-all-features.txt new file mode 100644 index 00000000..562c62a2 --- /dev/null +++ b/test/dump/symbol-tables-all-features.txt @@ -0,0 +1,74 @@ +;;; TOOL: run-objdump +;;; ARGS0: -r --enable-all +;;; ARGS1: -x +(module + (type (;0;) (func)) + (import "env" "b" (func (;0;) (type 0))) + (func $a (type 0) + call 0) + (func (type 0) + call 0) + (func $b (type 0) + (call_indirect (type 0) (i32.const 0)) + call 0) + (export "a" (func $a)) + (table $t 0 funcref)) +(;; STDOUT ;;; + +symbol-tables-all-features.wasm: file format wasm 0x1 + +Section Details: + +Type[1]: + - type[0] () -> nil +Import[1]: + - func[0] sig=0 <env.b> <- env.b +Function[3]: + - func[1] sig=0 <a> + - func[2] sig=0 + - func[3] sig=0 <b> +Table[1]: + - table[0] type=funcref initial=0 +Export[1]: + - func[1] <a> -> "a" +Code[3]: + - func[1] size=8 <a> + - func[2] size=8 + - func[3] size=21 <b> +Custom: + - name: "linking" + - symbol table [count=5] + - 0: F <env.b> func=0 undefined binding=global vis=default + - 1: F <a> func=1 exported no_strip binding=global vis=hidden + - 2: F <> func=2 binding=local vis=hidden + - 3: F <b> func=3 binding=global vis=default + - 4: T <t> table=0 binding=global vis=default +Custom: + - name: "reloc.Code" + - relocations for section: 5 (Code) [5] + - R_WASM_FUNCTION_INDEX_LEB offset=0x000004(file=0x000032) symbol=0 <env.b> + - R_WASM_FUNCTION_INDEX_LEB offset=0x00000d(file=0x00003b) symbol=0 <env.b> + - R_WASM_TYPE_INDEX_LEB offset=0x000018(file=0x000046) type=0 + - R_WASM_TABLE_NUMBER_LEB offset=0x00001d(file=0x00004b) symbol=4 <t> + - R_WASM_FUNCTION_INDEX_LEB offset=0x000023(file=0x000051) symbol=0 <env.b> + +Code Disassembly: + +000030 func[1] <a>: + 000031: 10 80 80 80 80 00 | call 0 <env.b> + 000032: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> + 000037: 0b | end +000039 func[2]: + 00003a: 10 80 80 80 80 00 | call 0 <env.b> + 00003b: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> + 000040: 0b | end +000042 func[3] <b>: + 000043: 41 00 | i32.const 0 + 000045: 11 80 80 80 80 00 80 80 80 | call_indirect 0 0 + 00004e: 80 00 | + 000046: R_WASM_TYPE_INDEX_LEB 0 + 000050: 10 80 80 80 80 00 | call 0 <env.b> + 00004b: R_WASM_TABLE_NUMBER_LEB 4 <t> + 000056: 0b | end + 000051: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> +;;; STDOUT ;;) diff --git a/test/dump/symbol-tables.txt b/test/dump/symbol-tables.txt index 26385d4f..7d6555e2 100644 --- a/test/dump/symbol-tables.txt +++ b/test/dump/symbol-tables.txt @@ -9,8 +9,10 @@ (func (type 0) call 0) (func $b (type 0) + (call_indirect (type 0) (i32.const 0)) call 0) - (export "a" (func $a))) + (export "a" (func $a)) + (table $t 0 funcref)) (;; STDOUT ;;; symbol-tables.wasm: file format wasm 0x1 @@ -25,37 +27,45 @@ Function[3]: - func[1] sig=0 <a> - func[2] sig=0 - func[3] sig=0 <b> +Table[1]: + - table[0] type=funcref initial=0 Export[1]: - func[1] <a> -> "a" Code[3]: - func[1] size=8 <a> - func[2] size=8 - - func[3] size=8 <b> + - func[3] size=17 <b> Custom: - name: "linking" - - symbol table [count=3] + - symbol table [count=5] - 0: F <env.b> func=0 undefined binding=global vis=default - 1: F <a> func=1 exported no_strip binding=global vis=hidden - - 2: F <b> func=3 binding=global vis=default + - 2: F <> func=2 binding=local vis=hidden + - 3: F <b> func=3 binding=global vis=default + - 4: T <t> table=0 binding=global vis=default Custom: - name: "reloc.Code" - - relocations for section: 4 (Code) [3] - - R_WASM_FUNCTION_INDEX_LEB offset=0x000004(file=0x00002c) symbol=0 <env.b> - - R_WASM_FUNCTION_INDEX_LEB offset=0x00000d(file=0x000035) symbol=0 <env.b> - - R_WASM_FUNCTION_INDEX_LEB offset=0x000016(file=0x00003e) symbol=0 <env.b> + - relocations for section: 5 (Code) [4] + - R_WASM_FUNCTION_INDEX_LEB offset=0x000004(file=0x000032) symbol=0 <env.b> + - R_WASM_FUNCTION_INDEX_LEB offset=0x00000d(file=0x00003b) symbol=0 <env.b> + - R_WASM_TYPE_INDEX_LEB offset=0x000018(file=0x000046) type=0 + - R_WASM_FUNCTION_INDEX_LEB offset=0x00001f(file=0x00004d) symbol=0 <env.b> Code Disassembly: -00002a func[1] <a>: - 00002b: 10 80 80 80 80 00 | call 0 <env.b> - 00002c: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> - 000031: 0b | end -000033 func[2]: - 000034: 10 80 80 80 80 00 | call 0 <env.b> - 000035: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> - 00003a: 0b | end -00003c func[3] <b>: - 00003d: 10 80 80 80 80 00 | call 0 <env.b> - 00003e: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> - 000043: 0b | end +000030 func[1] <a>: + 000031: 10 80 80 80 80 00 | call 0 <env.b> + 000032: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> + 000037: 0b | end +000039 func[2]: + 00003a: 10 80 80 80 80 00 | call 0 <env.b> + 00003b: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> + 000040: 0b | end +000042 func[3] <b>: + 000043: 41 00 | i32.const 0 + 000045: 11 80 80 80 80 00 00 | call_indirect 0 0 + 000046: R_WASM_TYPE_INDEX_LEB 0 + 00004c: 10 80 80 80 80 00 | call 0 <env.b> + 00004d: R_WASM_FUNCTION_INDEX_LEB 0 <env.b> + 000052: 0b | end ;;; STDOUT ;;) |