summaryrefslogtreecommitdiff
path: root/llvm/lib/MC/WasmObjectWriter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/MC/WasmObjectWriter.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/MC/WasmObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp277
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);