aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/WasmObjectFile.cpp
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2023-12-20 11:13:09 -0800
committerGitHub <noreply@github.com>2023-12-20 11:13:09 -0800
commit4e8cb01b01458860ed3d3f6f54ca5405e50be605 (patch)
treead8251c7f2b42b84d5794c5b174844aca58fbdaa /llvm/lib/Object/WasmObjectFile.cpp
parent2c27013fa918211816d24c9d2530469fd822bc00 (diff)
downloadllvm-4e8cb01b01458860ed3d3f6f54ca5405e50be605.zip
llvm-4e8cb01b01458860ed3d3f6f54ca5405e50be605.tar.gz
llvm-4e8cb01b01458860ed3d3f6f54ca5405e50be605.tar.bz2
[WebAssembly] Add symbol information for shared libraries (#75238)
The current (experimental) spec for WebAssembly shared libraries does not include a full symbol table like the object format. This change extracts symbol information from the normal wasm exports. This is the first step in having the linker report undefined symbols when linking with shared libraries. The current behaviour is to ignore all undefined symbols when linking with `-pie` or `-shared`. See https://github.com/emscripten-core/emscripten/issues/18198
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp50
1 files changed, 47 insertions, 3 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 168fb57..05bd730 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -599,6 +599,10 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
uint32_t Count = readVaruint32(Ctx);
+ // Clear out any symbol information that was derived from the exports
+ // section.
+ LinkingData.SymbolTable.clear();
+ Symbols.clear();
LinkingData.SymbolTable.reserve(Count);
Symbols.reserve(Count);
StringSet<> SymbolNames;
@@ -1290,37 +1294,75 @@ Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
uint32_t Count = readVaruint32(Ctx);
Exports.reserve(Count);
+ LinkingData.SymbolTable.reserve(Count);
+ Symbols.reserve(Count);
for (uint32_t I = 0; I < Count; I++) {
wasm::WasmExport Ex;
Ex.Name = readString(Ctx);
Ex.Kind = readUint8(Ctx);
Ex.Index = readVaruint32(Ctx);
+ const wasm::WasmSignature *Signature = nullptr;
+ const wasm::WasmGlobalType *GlobalType = nullptr;
+ const wasm::WasmTableType *TableType = nullptr;
+ wasm::WasmSymbolInfo Info;
+ Info.Name = Ex.Name;
+ Info.Flags = 0;
switch (Ex.Kind) {
- case wasm::WASM_EXTERNAL_FUNCTION:
-
+ case wasm::WASM_EXTERNAL_FUNCTION: {
if (!isDefinedFunctionIndex(Ex.Index))
return make_error<GenericBinaryError>("invalid function export",
object_error::parse_failed);
getDefinedFunction(Ex.Index).ExportName = Ex.Name;
+ Info.Kind = wasm::WASM_SYMBOL_TYPE_FUNCTION;
+ Info.ElementIndex = Ex.Index;
+ unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
+ wasm::WasmFunction &Function = Functions[FuncIndex];
+ Signature = &Signatures[Function.SigIndex];
break;
- case wasm::WASM_EXTERNAL_GLOBAL:
+ }
+ case wasm::WASM_EXTERNAL_GLOBAL: {
if (!isValidGlobalIndex(Ex.Index))
return make_error<GenericBinaryError>("invalid global export",
object_error::parse_failed);
+ Info.Kind = wasm::WASM_SYMBOL_TYPE_DATA;
+ uint64_t Offset = 0;
+ if (isDefinedGlobalIndex(Ex.Index)) {
+ auto Global = getDefinedGlobal(Ex.Index);
+ if (!Global.InitExpr.Extended) {
+ auto Inst = Global.InitExpr.Inst;
+ if (Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) {
+ Offset = Inst.Value.Int32;
+ } else if (Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) {
+ Offset = Inst.Value.Int64;
+ }
+ }
+ }
+ Info.DataRef = wasm::WasmDataReference{0, Offset, 0};
break;
+ }
case wasm::WASM_EXTERNAL_TAG:
if (!isValidTagIndex(Ex.Index))
return make_error<GenericBinaryError>("invalid tag export",
object_error::parse_failed);
+ Info.Kind = wasm::WASM_SYMBOL_TYPE_TAG;
+ Info.ElementIndex = Ex.Index;
break;
case wasm::WASM_EXTERNAL_MEMORY:
+ break;
case wasm::WASM_EXTERNAL_TABLE:
+ Info.Kind = wasm::WASM_SYMBOL_TYPE_TABLE;
break;
default:
return make_error<GenericBinaryError>("unexpected export kind",
object_error::parse_failed);
}
Exports.push_back(Ex);
+ if (Ex.Kind != wasm::WASM_EXTERNAL_MEMORY) {
+ LinkingData.SymbolTable.emplace_back(Info);
+ Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType,
+ TableType, Signature);
+ LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
+ }
}
if (Ctx.Ptr != Ctx.End)
return make_error<GenericBinaryError>("export section ended prematurely",
@@ -1644,6 +1686,8 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
return Segment.Offset.Inst.Value.Int32 + Sym.Info.DataRef.Offset;
} else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) {
return Segment.Offset.Inst.Value.Int64 + Sym.Info.DataRef.Offset;
+ } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_GLOBAL_GET) {
+ return Sym.Info.DataRef.Offset;
} else {
llvm_unreachable("unknown init expr opcode");
}