diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
| commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
| tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/MC/WasmObjectWriter.cpp | |
| parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'llvm/lib/MC/WasmObjectWriter.cpp')
| -rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 277 |
1 files changed, 166 insertions, 111 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 930413e83438..0dc5c9111db2 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -67,7 +67,7 @@ struct WasmDataSegment { uint32_t InitFlags; uint64_t Offset; uint32_t Alignment; - uint32_t LinkerFlags; + uint32_t LinkingFlags; SmallVector<char, 4> Data; }; @@ -195,7 +195,7 @@ class WasmObjectWriter : public MCObjectWriter { // for TABLE_INDEX relocation types (i.e. address taken functions). DenseMap<const MCSymbolWasm *, uint32_t> TableIndices; // Maps function/global/table symbols to the - // function/global/table/event/section index space. + // function/global/table/tag/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. @@ -219,7 +219,7 @@ class WasmObjectWriter : public MCObjectWriter { unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; unsigned NumTableImports = 0; - unsigned NumEventImports = 0; + unsigned NumTagImports = 0; uint32_t SectionCount = 0; enum class DwoMode { @@ -311,12 +311,13 @@ private: uint32_t NumElements); void writeFunctionSection(ArrayRef<WasmFunction> Functions); void writeExportSection(ArrayRef<wasm::WasmExport> Exports); - void writeElemSection(ArrayRef<uint32_t> TableElems); + void writeElemSection(const MCSymbolWasm *IndirectFunctionTable, + ArrayRef<uint32_t> TableElems); void writeDataCountSection(); uint32_t writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, ArrayRef<WasmFunction> Functions); uint32_t writeDataSection(const MCAsmLayout &Layout); - void writeEventSection(ArrayRef<wasm::WasmEventType> Events); + void writeTagSection(ArrayRef<wasm::WasmTagType> Tags); void writeGlobalSection(ArrayRef<wasm::WasmGlobal> Globals); void writeTableSection(ArrayRef<wasm::WasmTable> Tables); void writeRelocSection(uint32_t SectionIndex, StringRef Name, @@ -336,9 +337,9 @@ private: uint32_t getRelocationIndexValue(const WasmRelocationEntry &RelEntry); uint32_t getFunctionType(const MCSymbolWasm &Symbol); - uint32_t getEventType(const MCSymbolWasm &Symbol); + uint32_t getTagType(const MCSymbolWasm &Symbol); void registerFunctionType(const MCSymbolWasm &Symbol); - void registerEventType(const MCSymbolWasm &Symbol); + void registerTagType(const MCSymbolWasm &Symbol); }; } // end anonymous namespace @@ -405,12 +406,17 @@ void WasmObjectWriter::writeHeader(const MCAssembler &Asm) { void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { - // As a stopgap measure until call_indirect instructions start explicitly - // referencing the indirect function table via TABLE_NUMBER relocs, ensure - // that the indirect function table import makes it to the output if anything - // in the compilation unit has caused it to be present. - if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table")) - Asm.registerSymbol(*Sym); + // Some compilation units require the indirect function table to be present + // but don't explicitly reference it. This is the case for call_indirect + // without the reference-types feature, and also function bitcasts in all + // cases. In those cases the __indirect_function_table has the + // WASM_SYMBOL_NO_STRIP attribute. Here we make sure this symbol makes it to + // the assembler, if needed. + if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table")) { + const auto *WasmSym = static_cast<const MCSymbolWasm *>(Sym); + if (WasmSym->isNoStrip()) + Asm.registerSymbol(*Sym); + } // Build a map of sections to the function that defines them, for use // in recordRelocation. @@ -439,17 +445,35 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); MCContext &Ctx = Asm.getContext(); + bool IsLocRel = false; if (const MCSymbolRefExpr *RefB = Target.getSymB()) { - // To get here the A - B expression must have failed evaluateAsRelocatable. - // This means either A or B must be undefined and in WebAssembly we can't - // support either of those cases. + const auto &SymB = cast<MCSymbolWasm>(RefB->getSymbol()); - Ctx.reportError( - Fixup.getLoc(), - Twine("symbol '") + SymB.getName() + - "': unsupported subtraction expression used in relocation."); - return; + + if (FixupSection.getKind().isText()) { + Ctx.reportError(Fixup.getLoc(), + Twine("symbol '") + SymB.getName() + + "' unsupported subtraction expression used in " + "relocation in code section."); + return; + } + + if (SymB.isUndefined()) { + Ctx.reportError(Fixup.getLoc(), + Twine("symbol '") + SymB.getName() + + "' can not be undefined in a subtraction expression"); + return; + } + const MCSection &SecB = SymB.getSection(); + if (&SecB != &FixupSection) { + Ctx.reportError(Fixup.getLoc(), + Twine("symbol '") + SymB.getName() + + "' can not be placed in a different section"); + return; + } + IsLocRel = true; + C += FixupOffset - Layout.getSymbolOffset(SymB); } // We either rejected the fixup or folded B into C at this point. @@ -474,24 +498,35 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, // be negative and don't wrap. FixedValue = 0; - unsigned Type = TargetObjectWriter->getRelocType(Target, Fixup); + unsigned Type = + TargetObjectWriter->getRelocType(Target, Fixup, FixupSection, IsLocRel); // Absolute offset within a section or a function. // Currently only supported for for metadata sections. // See: test/MC/WebAssembly/blockaddress.ll - if (Type == wasm::R_WASM_FUNCTION_OFFSET_I32 || - Type == wasm::R_WASM_FUNCTION_OFFSET_I64 || - Type == wasm::R_WASM_SECTION_OFFSET_I32) { + if ((Type == wasm::R_WASM_FUNCTION_OFFSET_I32 || + Type == wasm::R_WASM_FUNCTION_OFFSET_I64 || + Type == wasm::R_WASM_SECTION_OFFSET_I32) && + SymA->isDefined()) { + // SymA can be a temp data symbol that represents a function (in which case + // it needs to be replaced by the section symbol), [XXX and it apparently + // later gets changed again to a func symbol?] or it can be a real + // function symbol, in which case it can be left as-is. + if (!FixupSection.getKind().isMetadata()) report_fatal_error("relocations for function or section offsets are " "only supported in metadata sections"); const MCSymbol *SectionSymbol = nullptr; const MCSection &SecA = SymA->getSection(); - if (SecA.getKind().isText()) - SectionSymbol = SectionFunctions.find(&SecA)->second; - else + if (SecA.getKind().isText()) { + auto SecSymIt = SectionFunctions.find(&SecA); + if (SecSymIt == SectionFunctions.end()) + report_fatal_error("section doesn\'t have defining symbol"); + SectionSymbol = SecSymIt->second; + } else { SectionSymbol = SecA.getBeginSymbol(); + } if (!SectionSymbol) report_fatal_error("section symbol is required for relocation"); @@ -500,26 +535,24 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, } if (Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB || + Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB64 || Type == wasm::R_WASM_TABLE_INDEX_SLEB || Type == wasm::R_WASM_TABLE_INDEX_SLEB64 || Type == wasm::R_WASM_TABLE_INDEX_I32 || Type == wasm::R_WASM_TABLE_INDEX_I64) { // TABLE_INDEX relocs implicitly use the default indirect function table. + // We require the function table to have already been defined. auto TableName = "__indirect_function_table"; MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(TableName)); - if (Sym) { - if (!Sym->isFunctionTable()) - Ctx.reportError( - Fixup.getLoc(), - "symbol '__indirect_function_table' is not a function table"); + if (!Sym) { + report_fatal_error("missing indirect function table symbol"); } else { - Sym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(TableName)); - Sym->setFunctionTable(); - // The default function table is synthesized by the linker. - Sym->setUndefined(); + if (!Sym->isFunctionTable()) + report_fatal_error("__indirect_function_table symbol has wrong type"); + // Ensure that __indirect_function_table reaches the output. + Sym->setNoStrip(); + Asm.registerSymbol(*Sym); } - Sym->setUsedInReloc(); - Asm.registerSymbol(*Sym); } // Relocation other than R_WASM_TYPE_INDEX_LEB are required to be @@ -565,6 +598,7 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry, switch (RelEntry.Type) { case wasm::R_WASM_TABLE_INDEX_REL_SLEB: + case wasm::R_WASM_TABLE_INDEX_REL_SLEB64: case wasm::R_WASM_TABLE_INDEX_SLEB: case wasm::R_WASM_TABLE_INDEX_SLEB64: case wasm::R_WASM_TABLE_INDEX_I32: @@ -573,7 +607,8 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry, const MCSymbolWasm *Base = cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol)); assert(Base->isFunction()); - if (RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB) + if (RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB || + RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB64) return TableIndices[Base] - InitialTableOffset; else return TableIndices[Base]; @@ -584,14 +619,16 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry, case wasm::R_WASM_FUNCTION_INDEX_LEB: case wasm::R_WASM_GLOBAL_INDEX_LEB: case wasm::R_WASM_GLOBAL_INDEX_I32: - case wasm::R_WASM_EVENT_INDEX_LEB: + case wasm::R_WASM_TAG_INDEX_LEB: case wasm::R_WASM_TABLE_NUMBER_LEB: - // Provisional value is function/global/event Wasm index + // Provisional value is function/global/tag Wasm index 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_FUNCTION_OFFSET_I64: case wasm::R_WASM_SECTION_OFFSET_I32: { + if (!RelEntry.Symbol->isDefined()) + return 0; const auto &Section = static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection()); return Section.getSectionOffset() + RelEntry.Addend; @@ -604,18 +641,17 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry, case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64: case wasm::R_WASM_MEMORY_ADDR_I32: case wasm::R_WASM_MEMORY_ADDR_I64: - case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: { + case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: + case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64: + case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: { // Provisional value is address of the global plus the offset - const MCSymbolWasm *Base = - cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol)); // For undefined symbols, use zero - if (!Base->isDefined()) + if (!RelEntry.Symbol->isDefined()) return 0; - const wasm::WasmDataReference &BaseRef = DataLocations[Base], - &SymRef = DataLocations[RelEntry.Symbol]; - const WasmDataSegment &Segment = DataSegments[BaseRef.Segment]; + const wasm::WasmDataReference &SymRef = DataLocations[RelEntry.Symbol]; + const WasmDataSegment &Segment = DataSegments[SymRef.Segment]; // Ignore overflow. LLVM allows address arithmetic to silently wrap. - return Segment.Offset + BaseRef.Offset + SymRef.Offset + RelEntry.Addend; + return Segment.Offset + SymRef.Offset + RelEntry.Addend; } default: llvm_unreachable("invalid relocation type"); @@ -691,7 +727,7 @@ void WasmObjectWriter::applyRelocations( case wasm::R_WASM_TYPE_INDEX_LEB: case wasm::R_WASM_GLOBAL_INDEX_LEB: case wasm::R_WASM_MEMORY_ADDR_LEB: - case wasm::R_WASM_EVENT_INDEX_LEB: + case wasm::R_WASM_TAG_INDEX_LEB: case wasm::R_WASM_TABLE_NUMBER_LEB: writePatchableLEB<5>(Stream, Value, Offset); break; @@ -703,6 +739,7 @@ void WasmObjectWriter::applyRelocations( case wasm::R_WASM_FUNCTION_OFFSET_I32: case wasm::R_WASM_SECTION_OFFSET_I32: case wasm::R_WASM_GLOBAL_INDEX_I32: + case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: patchI32(Stream, Value, Offset); break; case wasm::R_WASM_TABLE_INDEX_I64: @@ -718,8 +755,10 @@ void WasmObjectWriter::applyRelocations( writePatchableSLEB<5>(Stream, Value, Offset); break; case wasm::R_WASM_TABLE_INDEX_SLEB64: + case wasm::R_WASM_TABLE_INDEX_REL_SLEB64: case wasm::R_WASM_MEMORY_ADDR_SLEB64: case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64: + case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64: writePatchableSLEB<10>(Stream, Value, Offset); break; default: @@ -785,9 +824,9 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports, encodeULEB128(0, W->OS); // flags encodeULEB128(NumElements, W->OS); // initial break; - case wasm::WASM_EXTERNAL_EVENT: - encodeULEB128(Import.Event.Attribute, W->OS); - encodeULEB128(Import.Event.SigIndex, W->OS); + case wasm::WASM_EXTERNAL_TAG: + W->OS << char(Import.Tag.Attribute); + encodeULEB128(Import.Tag.SigIndex, W->OS); break; default: llvm_unreachable("unsupported import kind"); @@ -811,17 +850,17 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) { endSection(Section); } -void WasmObjectWriter::writeEventSection(ArrayRef<wasm::WasmEventType> Events) { - if (Events.empty()) +void WasmObjectWriter::writeTagSection(ArrayRef<wasm::WasmTagType> Tags) { + if (Tags.empty()) return; SectionBookkeeping Section; - startSection(Section, wasm::WASM_SEC_EVENT); + startSection(Section, wasm::WASM_SEC_TAG); - encodeULEB128(Events.size(), W->OS); - for (const wasm::WasmEventType &Event : Events) { - encodeULEB128(Event.Attribute, W->OS); - encodeULEB128(Event.SigIndex, W->OS); + encodeULEB128(Tags.size(), W->OS); + for (const wasm::WasmTagType &Tag : Tags) { + W->OS << char(Tag.Attribute); + encodeULEB128(Tag.SigIndex, W->OS); } endSection(Section); @@ -875,7 +914,7 @@ void WasmObjectWriter::writeTableSection(ArrayRef<wasm::WasmTable> Tables) { for (const wasm::WasmTable &Table : Tables) { encodeULEB128(Table.Type.ElemType, W->OS); encodeULEB128(Table.Type.Limits.Flags, W->OS); - encodeULEB128(Table.Type.Limits.Initial, W->OS); + encodeULEB128(Table.Type.Limits.Minimum, W->OS); if (Table.Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) encodeULEB128(Table.Type.Limits.Maximum, W->OS); } @@ -899,21 +938,39 @@ void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) { endSection(Section); } -void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) { +void WasmObjectWriter::writeElemSection( + const MCSymbolWasm *IndirectFunctionTable, ArrayRef<uint32_t> TableElems) { if (TableElems.empty()) return; + assert(IndirectFunctionTable); + SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_ELEM); encodeULEB128(1, W->OS); // number of "segments" - encodeULEB128(0, W->OS); // the table index + + assert(WasmIndices.count(IndirectFunctionTable)); + uint32_t TableNumber = WasmIndices.find(IndirectFunctionTable)->second; + uint32_t Flags = 0; + if (TableNumber) + Flags |= wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER; + encodeULEB128(Flags, W->OS); + if (Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER) + encodeULEB128(TableNumber, W->OS); // the table number // init expr for starting offset W->OS << char(wasm::WASM_OPCODE_I32_CONST); encodeSLEB128(InitialTableOffset, W->OS); W->OS << char(wasm::WASM_OPCODE_END); + if (Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) { + // We only write active function table initializers, for which the elem kind + // is specified to be written as 0x00 and interpreted to mean "funcref". + const uint8_t ElemKind = 0; + W->OS << ElemKind; + } + encodeULEB128(TableElems.size(), W->OS); for (uint32_t Elem : TableElems) encodeULEB128(Elem, W->OS); @@ -975,8 +1032,8 @@ uint32_t WasmObjectWriter::writeDataSection(const MCAsmLayout &Layout) { if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) encodeULEB128(0, W->OS); // memory index if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) { - W->OS << char(Segment.Offset > INT32_MAX ? wasm::WASM_OPCODE_I64_CONST - : wasm::WASM_OPCODE_I32_CONST); + W->OS << char(is64Bit() ? wasm::WASM_OPCODE_I64_CONST + : wasm::WASM_OPCODE_I32_CONST); encodeSLEB128(Segment.Offset, W->OS); // offset W->OS << char(wasm::WASM_OPCODE_END); } @@ -1057,7 +1114,7 @@ void WasmObjectWriter::writeLinkingMetaDataSection( switch (Sym.Kind) { case wasm::WASM_SYMBOL_TYPE_FUNCTION: case wasm::WASM_SYMBOL_TYPE_GLOBAL: - case wasm::WASM_SYMBOL_TYPE_EVENT: + case wasm::WASM_SYMBOL_TYPE_TAG: case wasm::WASM_SYMBOL_TYPE_TABLE: encodeULEB128(Sym.ElementIndex, W->OS); if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 || @@ -1091,7 +1148,7 @@ void WasmObjectWriter::writeLinkingMetaDataSection( for (const WasmDataSegment &Segment : DataSegments) { writeString(Segment.Name); encodeULEB128(Segment.Alignment, W->OS); - encodeULEB128(Segment.LinkerFlags, W->OS); + encodeULEB128(Segment.LinkingFlags, W->OS); } endSection(SubSection); } @@ -1150,8 +1207,8 @@ uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) { return TypeIndices[&Symbol]; } -uint32_t WasmObjectWriter::getEventType(const MCSymbolWasm &Symbol) { - assert(Symbol.isEvent()); +uint32_t WasmObjectWriter::getTagType(const MCSymbolWasm &Symbol) { + assert(Symbol.isTag()); assert(TypeIndices.count(&Symbol)); return TypeIndices[&Symbol]; } @@ -1176,8 +1233,8 @@ void WasmObjectWriter::registerFunctionType(const MCSymbolWasm &Symbol) { LLVM_DEBUG(dbgs() << " -> type index: " << Pair.first->second << "\n"); } -void WasmObjectWriter::registerEventType(const MCSymbolWasm &Symbol) { - assert(Symbol.isEvent()); +void WasmObjectWriter::registerTagType(const MCSymbolWasm &Symbol) { + assert(Symbol.isTag()); // TODO Currently we don't generate imported exceptions, but if we do, we // should have a way of infering types of imported exceptions. @@ -1192,7 +1249,7 @@ void WasmObjectWriter::registerEventType(const MCSymbolWasm &Symbol) { Signatures.push_back(S); TypeIndices[&Symbol] = Pair.first->second; - LLVM_DEBUG(dbgs() << "registerEventType: " << Symbol << " new:" << Pair.second + LLVM_DEBUG(dbgs() << "registerTagType: " << Symbol << " new:" << Pair.second << "\n"); LLVM_DEBUG(dbgs() << " -> type index: " << Pair.first->second << "\n"); } @@ -1210,6 +1267,9 @@ static bool isInSymtab(const MCSymbolWasm &Sym) { if (Sym.isSection()) return false; + if (Sym.omitFromLinkingSection()) + return false; + return true; } @@ -1243,8 +1303,8 @@ void WasmObjectWriter::prepareImports( registerFunctionType(*cast<MCSymbolWasm>(BS)); } - if (WS.isEvent()) - registerEventType(WS); + if (WS.isTag()) + registerTagType(WS); if (WS.isTemporary()) continue; @@ -1272,19 +1332,19 @@ void WasmObjectWriter::prepareImports( Imports.push_back(Import); assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumGlobalImports++; - } else if (WS.isEvent()) { + } else if (WS.isTag()) { if (WS.isWeak()) - report_fatal_error("undefined event symbol cannot be weak"); + report_fatal_error("undefined tag symbol cannot be weak"); wasm::WasmImport Import; Import.Module = WS.getImportModule(); Import.Field = WS.getImportName(); - Import.Kind = wasm::WASM_EXTERNAL_EVENT; - Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION; - Import.Event.SigIndex = getEventType(WS); + Import.Kind = wasm::WASM_EXTERNAL_TAG; + Import.Tag.Attribute = wasm::WASM_TAG_ATTRIBUTE_EXCEPTION; + Import.Tag.SigIndex = getTagType(WS); Imports.push_back(Import); assert(WasmIndices.count(&WS) == 0); - WasmIndices[&WS] = NumEventImports++; + WasmIndices[&WS] = NumTagImports++; } else if (WS.isTable()) { if (WS.isWeak()) report_fatal_error("undefined table symbol cannot be weak"); @@ -1293,12 +1353,7 @@ void WasmObjectWriter::prepareImports( Import.Module = WS.getImportModule(); Import.Field = WS.getImportName(); Import.Kind = wasm::WASM_EXTERNAL_TABLE; - wasm::ValType ElemType = WS.getTableType(); - Import.Table.ElemType = uint8_t(ElemType); - // FIXME: Extend table type to include limits? For now we don't specify - // a min or max which does not place any restrictions on the size of the - // imported table. - Import.Table.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0}; + Import.Table = WS.getTableType(); Imports.push_back(Import); assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = NumTableImports++; @@ -1354,7 +1409,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, SmallVector<uint32_t, 4> TableElems; SmallVector<wasm::WasmImport, 4> Imports; SmallVector<wasm::WasmExport, 4> Exports; - SmallVector<wasm::WasmEventType, 1> Events; + SmallVector<wasm::WasmTagType, 1> Tags; SmallVector<wasm::WasmGlobal, 1> Globals; SmallVector<wasm::WasmTable, 1> Tables; SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos; @@ -1400,7 +1455,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, Segment.Section = &Section; addData(Segment.Data, Section); Segment.Alignment = Log2_32(Section.getAlignment()); - Segment.LinkerFlags = 0; + Segment.LinkingFlags = Section.getSegmentFlags(); DataSize += Segment.Data.size(); Section.setSegmentIndex(SegmentIndex); @@ -1458,8 +1513,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, continue; const auto &WS = static_cast<const MCSymbolWasm &>(S); - LLVM_DEBUG( - dbgs() << "MCSymbol: " << toString(WS.getType()) << " '" << S << "'" + LLVM_DEBUG(dbgs() + << "MCSymbol: " + << toString(WS.getType().getValueOr(wasm::WASM_SYMBOL_TYPE_DATA)) + << " '" << S << "'" << " isDefined=" << S.isDefined() << " isExternal=" << S.isExternal() << " isTemporary=" << S.isTemporary() << " isWeak=" << WS.isWeak() << " isHidden=" << WS.isHidden() @@ -1579,32 +1636,30 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, if (WS.isDefined()) { wasm::WasmTable Table; Table.Index = NumTableImports + Tables.size(); - Table.Type.ElemType = static_cast<uint8_t>(WS.getTableType()); - // FIXME: Work on custom limits is ongoing - Table.Type.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0}; + Table.Type = WS.getTableType(); assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = Table.Index; Tables.push_back(Table); } LLVM_DEBUG(dbgs() << " -> table index: " << WasmIndices.find(&WS)->second << "\n"); - } else if (WS.isEvent()) { + } else if (WS.isTag()) { // C++ exception symbol (__cpp_exception) unsigned Index; if (WS.isDefined()) { - Index = NumEventImports + Events.size(); - wasm::WasmEventType Event; - Event.SigIndex = getEventType(WS); - Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION; + Index = NumTagImports + Tags.size(); + wasm::WasmTagType Tag; + Tag.SigIndex = getTagType(WS); + Tag.Attribute = wasm::WASM_TAG_ATTRIBUTE_EXCEPTION; assert(WasmIndices.count(&WS) == 0); WasmIndices[&WS] = Index; - Events.push_back(Event); + Tags.push_back(Tag); } else { // An import; the index was assigned above. assert(WasmIndices.count(&WS) > 0); } - LLVM_DEBUG(dbgs() << " -> event index: " - << WasmIndices.find(&WS)->second << "\n"); + LLVM_DEBUG(dbgs() << " -> tag index: " << WasmIndices.find(&WS)->second + << "\n"); } else { assert(WS.isSection()); @@ -1659,7 +1714,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, DataLocations[&WS] = Ref; LLVM_DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n"); } else { - report_fatal_error("don't yet support global/event aliases"); + report_fatal_error("don't yet support global/tag aliases"); } } } @@ -1671,10 +1726,6 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, WS.setIndex(InvalidIndex); continue; } - if (WS.isTable() && WS.getName() == "__indirect_function_table") { - // For the moment, don't emit table symbols -- wasm-ld can't handle them. - continue; - } LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n"); uint32_t Flags = 0; @@ -1699,7 +1750,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, wasm::WasmSymbolInfo Info; Info.Name = WS.getName(); - Info.Kind = WS.getType(); + Info.Kind = WS.getType().getValueOr(wasm::WASM_SYMBOL_TYPE_DATA); Info.Flags = Flags; if (!WS.isData()) { assert(WasmIndices.count(&WS) > 0); @@ -1721,7 +1772,8 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, Rel.Type != wasm::R_WASM_TABLE_INDEX_I64 && Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB && Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB64 && - Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB) + Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB && + Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB64) return; assert(Rel.Symbol->isFunction()); const MCSymbolWasm *Base = @@ -1817,10 +1869,13 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, writeFunctionSection(Functions); writeTableSection(Tables); // Skip the "memory" section; we import the memory instead. - writeEventSection(Events); + writeTagSection(Tags); writeGlobalSection(Globals); writeExportSection(Exports); - writeElemSection(TableElems); + const MCSymbol *IndirectFunctionTable = + Asm.getContext().lookupSymbol("__indirect_function_table"); + writeElemSection(cast_or_null<const MCSymbolWasm>(IndirectFunctionTable), + TableElems); writeDataCountSection(); CodeSectionIndex = writeCodeSection(Asm, Layout, Functions); |
