diff options
Diffstat (limited to 'llvm/lib/MC/WasmObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 0014b695b90..adf0aef1202 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -243,6 +243,7 @@ class WasmObjectWriter : public MCObjectWriter { // Maps function/global symbols to the function/global/event/section index // space. DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices; + DenseMap<const MCSymbolWasm *, uint32_t> GOTIndices; // Maps data symbols to the Wasm segment and offset/size with the segment. DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations; @@ -260,7 +261,6 @@ class WasmObjectWriter : public MCObjectWriter { DenseMap<WasmSignature, uint32_t, WasmSignatureDenseMapInfo> SignatureIndices; SmallVector<WasmSignature, 4> Signatures; - SmallVector<WasmGlobal, 4> Globals; SmallVector<WasmDataSegment, 4> DataSegments; unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; @@ -288,6 +288,7 @@ private: DataRelocations.clear(); TypeIndices.clear(); WasmIndices.clear(); + GOTIndices.clear(); TableIndices.clear(); DataLocations.clear(); CustomSections.clear(); @@ -296,7 +297,6 @@ private: CustomSectionsRelocations.clear(); SignatureIndices.clear(); Signatures.clear(); - Globals.clear(); DataSegments.clear(); SectionFunctions.clear(); NumFunctionImports = 0; @@ -326,7 +326,6 @@ private: void writeImportSection(ArrayRef<wasm::WasmImport> Imports, uint32_t DataSize, uint32_t NumElements); void writeFunctionSection(ArrayRef<WasmFunction> Functions); - void writeGlobalSection(); void writeExportSection(ArrayRef<wasm::WasmExport> Exports); void writeElemSection(ArrayRef<uint32_t> TableElems); void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, @@ -545,6 +544,9 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, SymA->setUsedInReloc(); } + if (RefA->getKind() == MCSymbolRefExpr::VK_GOT) + SymA->setUsedInGOT(); + WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection); LLVM_DEBUG(dbgs() << "WasmReloc: " << Rec << "\n"); @@ -575,6 +577,11 @@ static const MCSymbolWasm *resolveSymbol(const MCSymbolWasm &Symbol) { // useable. uint32_t WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { + if (RelEntry.Type == wasm::R_WASM_GLOBAL_INDEX_LEB && !RelEntry.Symbol->isGlobal()) { + assert(GOTIndices.count(RelEntry.Symbol) > 0 && "symbol not found in GOT index space"); + return GOTIndices[RelEntry.Symbol]; + } + switch (RelEntry.Type) { case wasm::R_WASM_TABLE_INDEX_SLEB: case wasm::R_WASM_TABLE_INDEX_I32: { @@ -590,9 +597,7 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { case wasm::R_WASM_GLOBAL_INDEX_LEB: case wasm::R_WASM_EVENT_INDEX_LEB: // Provisional value is function/global/event Wasm index - if (!WasmIndices.count(RelEntry.Symbol)) - report_fatal_error("symbol not found in wasm index space: " + - RelEntry.Symbol->getName()); + assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space"); return WasmIndices[RelEntry.Symbol]; case wasm::R_WASM_FUNCTION_OFFSET_I32: case wasm::R_WASM_SECTION_OFFSET_I32: { @@ -787,26 +792,6 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) { endSection(Section); } -void WasmObjectWriter::writeGlobalSection() { - if (Globals.empty()) - return; - - SectionBookkeeping Section; - startSection(Section, wasm::WASM_SEC_GLOBAL); - - encodeULEB128(Globals.size(), W.OS); - for (const WasmGlobal &Global : Globals) { - writeValueType(static_cast<wasm::ValType>(Global.Type.Type)); - W.OS << char(Global.Type.Mutable); - - W.OS << char(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(Global.InitialValue, W.OS); - W.OS << char(wasm::WASM_OPCODE_END); - } - - endSection(Section); -} - void WasmObjectWriter::writeEventSection(ArrayRef<wasm::WasmEventType> Events) { if (Events.empty()) return; @@ -1208,17 +1193,19 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, Import.Kind = wasm::WASM_EXTERNAL_FUNCTION; Import.SigIndex = getFunctionType(WS); Imports.push_back(Import); + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumFunctionImports++; } else if (WS.isGlobal()) { if (WS.isWeak()) report_fatal_error("undefined global symbol cannot be weak"); wasm::WasmImport Import; - Import.Module = WS.getImportModule(); Import.Field = WS.getImportName(); Import.Kind = wasm::WASM_EXTERNAL_GLOBAL; + Import.Module = WS.getImportModule(); Import.Global = WS.getGlobalType(); Imports.push_back(Import); + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumGlobalImports++; } else if (WS.isEvent()) { if (WS.isWeak()) @@ -1231,11 +1218,30 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION; Import.Event.SigIndex = getEventType(WS); Imports.push_back(Import); + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumEventImports++; } } } + // Add imports for GOT globals + for (const MCSymbol &S : Asm.symbols()) { + const auto &WS = static_cast<const MCSymbolWasm &>(S); + if (WS.isUsedInGOT()) { + wasm::WasmImport Import; + if (WS.isFunction()) + Import.Module = "GOT.func"; + else + Import.Module = "GOT.mem"; + Import.Field = WS.getName(); + Import.Kind = wasm::WASM_EXTERNAL_GLOBAL; + Import.Global = {wasm::WASM_TYPE_I32, true}; + Imports.push_back(Import); + assert(GOTIndices.count(&WS) == 0); + GOTIndices[&WS] = NumGlobalImports++; + } + } + // Populate DataSegments and CustomSections, which must be done before // populating DataLocations. for (MCSection &Sec : Asm) { @@ -1401,10 +1407,12 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, wasm::WasmEventType Event; Event.SigIndex = getEventType(WS); Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION; + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = Index; Events.push_back(Event); } else { // An import; the index was assigned above. + assert(WasmIndices.count(&WS) > 0); Index = WasmIndices.find(&WS)->second; } LLVM_DEBUG(dbgs() << " -> event index: " << WasmIndices.find(&WS)->second @@ -1434,6 +1442,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, if (ResolvedSym->isFunction()) { assert(WasmIndices.count(ResolvedSym) > 0); uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second; + assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = WasmIndex; LLVM_DEBUG(dbgs() << " -> index:" << WasmIndex << "\n"); } else if (ResolvedSym->isData()) { @@ -1586,7 +1595,6 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, writeFunctionSection(Functions); // Skip the "table" section; we import the table instead. // Skip the "memory" section; we import the memory instead. - writeGlobalSection(); writeEventSection(Events); writeExportSection(Exports); writeElemSection(TableElems); |