aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/WasmObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp100
1 files changed, 67 insertions, 33 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 9309751..bd51fbd 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -300,9 +300,69 @@ Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) {
return Error::success();
}
+void WasmObjectFile::populateSymbolTable() {
+ // Add imports to symbol table
+ size_t ImportIndex = 0;
+ for (const wasm::WasmImport& Import : Imports) {
+ switch (Import.Kind) {
+ case wasm::WASM_EXTERNAL_GLOBAL:
+ assert(Import.Global.Type == wasm::WASM_TYPE_I32);
+ SymbolMap.try_emplace(Import.Field, Symbols.size());
+ Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
+ ImportSection, ImportIndex);
+ DEBUG(dbgs() << "Adding import: " << Symbols.back()
+ << " sym index:" << Symbols.size() << "\n");
+ break;
+ case wasm::WASM_EXTERNAL_FUNCTION:
+ SymbolMap.try_emplace(Import.Field, Symbols.size());
+ Symbols.emplace_back(Import.Field,
+ WasmSymbol::SymbolType::FUNCTION_IMPORT,
+ ImportSection, ImportIndex);
+ DEBUG(dbgs() << "Adding import: " << Symbols.back()
+ << " sym index:" << Symbols.size() << "\n");
+ break;
+ default:
+ break;
+ }
+ ImportIndex++;
+ }
+
+ // Add exports to symbol table
+ size_t ExportIndex = 0;
+ for (const wasm::WasmExport& Export : Exports) {
+ if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION ||
+ Export.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
+ WasmSymbol::SymbolType ExportType =
+ Export.Kind == wasm::WASM_EXTERNAL_FUNCTION
+ ? WasmSymbol::SymbolType::FUNCTION_EXPORT
+ : WasmSymbol::SymbolType::GLOBAL_EXPORT;
+ auto Pair = SymbolMap.try_emplace(Export.Name, Symbols.size());
+ if (Pair.second) {
+ Symbols.emplace_back(Export.Name, ExportType,
+ ExportSection, ExportIndex);
+ DEBUG(dbgs() << "Adding export: " << Symbols.back()
+ << " sym index:" << Symbols.size() << "\n");
+ } else {
+ uint32_t SymIndex = Pair.first->second;
+ Symbols[SymIndex] =
+ WasmSymbol(Export.Name, ExportType, ExportSection, ExportIndex);
+ DEBUG(dbgs() << "Replacing existing symbol: " << Symbols[SymIndex]
+ << " sym index:" << SymIndex << "\n");
+ }
+ }
+ ExportIndex++;
+ }
+}
+
Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
const uint8_t *End) {
HasLinkingSection = true;
+
+ // Only populate the symbol table with imports and exports if the object
+ // has a linking section (i.e. its a relocatable object file). Otherwise
+ // the global might not represent symbols at all.
+ populateSymbolTable();
+
while (Ptr < End) {
uint8_t Type = readVarint7(Ptr);
uint32_t Size = readVaruint32(Ptr);
@@ -463,6 +523,7 @@ Error WasmObjectFile::parseTypeSection(const uint8_t *Ptr, const uint8_t *End) {
}
Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End) {
+ ImportSection = Sections.size();
uint32_t Count = readVaruint32(Ptr);
Imports.reserve(Count);
for (uint32_t i = 0; i < Count; i++) {
@@ -474,31 +535,20 @@ Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End)
case wasm::WASM_EXTERNAL_FUNCTION:
NumImportedFunctions++;
Im.SigIndex = readVaruint32(Ptr);
- SymbolMap.try_emplace(Im.Field, Symbols.size());
- Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::FUNCTION_IMPORT,
- Sections.size(), i);
- DEBUG(dbgs() << "Adding import: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
break;
case wasm::WASM_EXTERNAL_GLOBAL:
NumImportedGlobals++;
Im.Global.Type = readVarint7(Ptr);
Im.Global.Mutable = readVaruint1(Ptr);
- SymbolMap.try_emplace(Im.Field, Symbols.size());
- Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
- Sections.size(), i);
- DEBUG(dbgs() << "Adding import: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
break;
case wasm::WASM_EXTERNAL_MEMORY:
Im.Memory = readLimits(Ptr);
break;
case wasm::WASM_EXTERNAL_TABLE:
Im.Table = readTable(Ptr);
- if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC) {
+ if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC)
return make_error<GenericBinaryError>("Invalid table element type",
object_error::parse_failed);
- }
break;
default:
return make_error<GenericBinaryError>(
@@ -570,6 +620,7 @@ Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End)
}
Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End) {
+ ExportSection = Sections.size();
uint32_t Count = readVaruint32(Ptr);
Exports.reserve(Count);
for (uint32_t i = 0; i < Count; i++) {
@@ -577,23 +628,18 @@ Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End)
Ex.Name = readString(Ptr);
Ex.Kind = readUint8(Ptr);
Ex.Index = readVaruint32(Ptr);
- WasmSymbol::SymbolType ExportType;
- bool MakeSymbol = false;
switch (Ex.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
- ExportType = WasmSymbol::SymbolType::FUNCTION_EXPORT;
if (Ex.Index >= FunctionTypes.size() + NumImportedFunctions)
return make_error<GenericBinaryError>("Invalid function export",
object_error::parse_failed);
- MakeSymbol = true;
break;
- case wasm::WASM_EXTERNAL_GLOBAL:
- ExportType = WasmSymbol::SymbolType::GLOBAL_EXPORT;
+ case wasm::WASM_EXTERNAL_GLOBAL: {
if (Ex.Index >= Globals.size() + NumImportedGlobals)
return make_error<GenericBinaryError>("Invalid global export",
object_error::parse_failed);
- MakeSymbol = true;
break;
+ }
case wasm::WASM_EXTERNAL_MEMORY:
case wasm::WASM_EXTERNAL_TABLE:
break;
@@ -601,20 +647,6 @@ Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End)
return make_error<GenericBinaryError>(
"Unexpected export kind", object_error::parse_failed);
}
- if (MakeSymbol) {
- auto Pair = SymbolMap.try_emplace(Ex.Name, Symbols.size());
- if (Pair.second) {
- Symbols.emplace_back(Ex.Name, ExportType,
- Sections.size(), i);
- DEBUG(dbgs() << "Adding export: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
- } else {
- uint32_t SymIndex = Pair.first->second;
- Symbols[SymIndex] = WasmSymbol(Ex.Name, ExportType, Sections.size(), i);
- DEBUG(dbgs() << "Replacing existing symbol: " << Symbols[SymIndex]
- << " sym index:" << SymIndex << "\n");
- }
- }
Exports.push_back(Ex);
}
if (Ptr != End)
@@ -791,6 +823,8 @@ uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
uint32_t GlobalIndex = Exports[Sym.ElementIndex].Index - NumImportedGlobals;
assert(GlobalIndex < Globals.size());
const wasm::WasmGlobal& Global = Globals[GlobalIndex];
+ // WasmSymbols correspond only to I32_CONST globals
+ assert(Global.InitExpr.Opcode == wasm::WASM_OPCODE_I32_CONST);
return Global.InitExpr.Value.Int32;
}
case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME: