summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/binary-reader-logging.cc10
-rw-r--r--src/binary-reader-objdump.cc93
-rw-r--r--src/binary-reader-objdump.h7
-rw-r--r--src/binary-writer.cc80
-rw-r--r--src/ir.h6
-rw-r--r--test/dump/relocations.txt18
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(&section);
}
diff --git a/src/ir.h b/src/ir.h
index ac811173..7ca56fa5 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -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 ;;)