summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/binary-reader-ir.cc19
-rw-r--r--src/binary-reader-logging.cc10
-rw-r--r--src/binary-reader-logging.h4
-rw-r--r--src/binary-reader-nop.h6
-rw-r--r--src/binary-reader-objdump.cc42
-rw-r--r--src/binary-reader-objdump.h1
-rw-r--r--src/binary-reader.cc7
-rw-r--r--src/binary-reader.h4
-rw-r--r--src/binary-writer.cc107
-rw-r--r--src/common.cc1
-rw-r--r--src/common.h6
-rw-r--r--test/dump/relocations-all-features.txt90
-rw-r--r--test/dump/relocations.txt46
-rw-r--r--test/dump/symbol-tables-all-features.txt74
-rw-r--r--test/dump/symbol-tables.txt50
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 ;;)