summaryrefslogtreecommitdiff
path: root/lib/MC/WasmObjectWriter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
commitd8e91e46262bc44006913e6796843909f1ac7bcd (patch)
tree7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/MC/WasmObjectWriter.cpp
parentb7eb8e35e481a74962664b63dfb09483b200209a (diff)
Notes
Diffstat (limited to 'lib/MC/WasmObjectWriter.cpp')
-rw-r--r--lib/MC/WasmObjectWriter.cpp292
1 files changed, 198 insertions, 94 deletions
diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp
index 5a979d36e81b..0cca3757be90 100644
--- a/lib/MC/WasmObjectWriter.cpp
+++ b/lib/MC/WasmObjectWriter.cpp
@@ -56,9 +56,10 @@ struct SectionBookkeeping {
uint32_t Index;
};
-// The signature of a wasm function, in a struct capable of being used as a
-// DenseMap key.
-struct WasmFunctionType {
+// The signature of a wasm function or event, in a struct capable of being used
+// as a DenseMap key.
+// TODO: Consider using wasm::WasmSignature directly instead.
+struct WasmSignature {
// Support empty and tombstone instances, needed by DenseMap.
enum { Plain, Empty, Tombstone } State;
@@ -68,36 +69,35 @@ struct WasmFunctionType {
// The parameter types of the function.
SmallVector<wasm::ValType, 4> Params;
- WasmFunctionType() : State(Plain) {}
+ WasmSignature() : State(Plain) {}
- bool operator==(const WasmFunctionType &Other) const {
+ bool operator==(const WasmSignature &Other) const {
return State == Other.State && Returns == Other.Returns &&
Params == Other.Params;
}
};
-// Traits for using WasmFunctionType in a DenseMap.
-struct WasmFunctionTypeDenseMapInfo {
- static WasmFunctionType getEmptyKey() {
- WasmFunctionType FuncTy;
- FuncTy.State = WasmFunctionType::Empty;
- return FuncTy;
+// Traits for using WasmSignature in a DenseMap.
+struct WasmSignatureDenseMapInfo {
+ static WasmSignature getEmptyKey() {
+ WasmSignature Sig;
+ Sig.State = WasmSignature::Empty;
+ return Sig;
}
- static WasmFunctionType getTombstoneKey() {
- WasmFunctionType FuncTy;
- FuncTy.State = WasmFunctionType::Tombstone;
- return FuncTy;
+ static WasmSignature getTombstoneKey() {
+ WasmSignature Sig;
+ Sig.State = WasmSignature::Tombstone;
+ return Sig;
}
- static unsigned getHashValue(const WasmFunctionType &FuncTy) {
- uintptr_t Value = FuncTy.State;
- for (wasm::ValType Ret : FuncTy.Returns)
- Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Ret));
- for (wasm::ValType Param : FuncTy.Params)
- Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Param));
+ static unsigned getHashValue(const WasmSignature &Sig) {
+ uintptr_t Value = Sig.State;
+ for (wasm::ValType Ret : Sig.Returns)
+ Value += DenseMapInfo<uint32_t>::getHashValue(uint32_t(Ret));
+ for (wasm::ValType Param : Sig.Params)
+ Value += DenseMapInfo<uint32_t>::getHashValue(uint32_t(Param));
return Value;
}
- static bool isEqual(const WasmFunctionType &LHS,
- const WasmFunctionType &RHS) {
+ static bool isEqual(const WasmSignature &LHS, const WasmSignature &RHS) {
return LHS == RHS;
}
};
@@ -117,7 +117,7 @@ struct WasmDataSegment {
// A wasm function to be written into the function section.
struct WasmFunction {
- int32_t Type;
+ uint32_t SigIndex;
const MCSymbolWasm *Sym;
};
@@ -137,11 +137,11 @@ struct WasmComdatEntry {
// Information about a single relocation.
struct WasmRelocationEntry {
- uint64_t Offset; // Where is the relocation.
- const MCSymbolWasm *Symbol; // The symbol to relocate with.
- int64_t Addend; // A value to add to the symbol.
- unsigned Type; // The type of the relocation.
- const MCSectionWasm *FixupSection;// The section the relocation is targeting.
+ uint64_t Offset; // Where is the relocation.
+ const MCSymbolWasm *Symbol; // The symbol to relocate with.
+ int64_t Addend; // A value to add to the symbol.
+ unsigned Type; // The type of the relocation.
+ const MCSectionWasm *FixupSection; // The section the relocation is targeting.
WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol,
int64_t Addend, unsigned Type,
@@ -163,8 +163,8 @@ struct WasmRelocationEntry {
}
void print(raw_ostream &Out) const {
- Out << wasm::relocTypetoString(Type)
- << " Off=" << Offset << ", Sym=" << *Symbol << ", Addend=" << Addend
+ Out << wasm::relocTypetoString(Type) << " Off=" << Offset
+ << ", Sym=" << *Symbol << ", Addend=" << Addend
<< ", FixupSection=" << FixupSection->getSectionName();
}
@@ -215,7 +215,8 @@ class WasmObjectWriter : public MCObjectWriter {
// Maps function symbols to the table element index space. Used
// for TABLE_INDEX relocation types (i.e. address taken functions).
DenseMap<const MCSymbolWasm *, uint32_t> TableIndices;
- // Maps function/global symbols to the function/global/section index space.
+ // Maps function/global symbols to the function/global/event/section index
+ // space.
DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
// Maps data symbols to the Wasm segment and offset/size with the segment.
DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations;
@@ -230,13 +231,13 @@ class WasmObjectWriter : public MCObjectWriter {
// Map from section to defining function symbol.
DenseMap<const MCSection *, const MCSymbol *> SectionFunctions;
- DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
- FunctionTypeIndices;
- SmallVector<WasmFunctionType, 4> FunctionTypes;
+ DenseMap<WasmSignature, uint32_t, WasmSignatureDenseMapInfo> SignatureIndices;
+ SmallVector<WasmSignature, 4> Signatures;
SmallVector<WasmGlobal, 4> Globals;
SmallVector<WasmDataSegment, 4> DataSegments;
unsigned NumFunctionImports = 0;
unsigned NumGlobalImports = 0;
+ unsigned NumEventImports = 0;
uint32_t SectionCount = 0;
// TargetObjectWriter wrappers.
@@ -265,8 +266,8 @@ private:
TableIndices.clear();
DataLocations.clear();
CustomSectionsRelocations.clear();
- FunctionTypeIndices.clear();
- FunctionTypes.clear();
+ SignatureIndices.clear();
+ Signatures.clear();
Globals.clear();
DataSegments.clear();
SectionFunctions.clear();
@@ -291,11 +292,9 @@ private:
W.OS << Str;
}
- void writeValueType(wasm::ValType Ty) {
- W.OS << static_cast<char>(Ty);
- }
+ void writeValueType(wasm::ValType Ty) { W.OS << static_cast<char>(Ty); }
- void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes);
+ void writeTypeSection(ArrayRef<WasmSignature> Signatures);
void writeImportSection(ArrayRef<wasm::WasmImport> Imports, uint32_t DataSize,
uint32_t NumElements);
void writeFunctionSection(ArrayRef<WasmFunction> Functions);
@@ -305,8 +304,9 @@ private:
void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
ArrayRef<WasmFunction> Functions);
void writeDataSection();
+ void writeEventSection(ArrayRef<wasm::WasmEventType> Events);
void writeRelocSection(uint32_t SectionIndex, StringRef Name,
- ArrayRef<WasmRelocationEntry> Relocations);
+ std::vector<WasmRelocationEntry> &Relocations);
void writeLinkingMetaDataSection(
ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
@@ -323,7 +323,9 @@ private:
uint32_t getRelocationIndexValue(const WasmRelocationEntry &RelEntry);
uint32_t getFunctionType(const MCSymbolWasm &Symbol);
- uint32_t registerFunctionType(const MCSymbolWasm &Symbol);
+ uint32_t getEventType(const MCSymbolWasm &Symbol);
+ void registerFunctionType(const MCSymbolWasm &Symbol);
+ void registerEventType(const MCSymbolWasm &Symbol);
};
} // end anonymous namespace
@@ -529,8 +531,8 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
// Write X as an (unsigned) LEB value at offset Offset in Stream, padded
// to allow patching.
-static void
-WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
+static void WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X,
+ uint64_t Offset) {
uint8_t Buffer[5];
unsigned SizeLen = encodeULEB128(X, Buffer, 5);
assert(SizeLen == 5);
@@ -539,8 +541,8 @@ WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
// Write X as an signed LEB value at offset Offset in Stream, padded
// to allow patching.
-static void
-WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X, uint64_t Offset) {
+static void WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X,
+ uint64_t Offset) {
uint8_t Buffer[5];
unsigned SizeLen = encodeSLEB128(X, Buffer, 5);
assert(SizeLen == 5);
@@ -554,7 +556,7 @@ static void WriteI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
}
-static const MCSymbolWasm* ResolveSymbol(const MCSymbolWasm& Symbol) {
+static const MCSymbolWasm *ResolveSymbol(const MCSymbolWasm &Symbol) {
if (Symbol.isVariable()) {
const MCExpr *Expr = Symbol.getVariableValue();
auto *Inner = cast<MCSymbolRefExpr>(Expr);
@@ -582,7 +584,8 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
return getRelocationIndexValue(RelEntry);
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- // Provisional value is function/global Wasm index
+ case wasm::R_WEBASSEMBLY_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());
@@ -626,10 +629,9 @@ static void addData(SmallVectorImpl<char> &DataBytes,
report_fatal_error("only byte values supported for alignment");
// If nops are requested, use zeros, as this is the data section.
uint8_t Value = Align->hasEmitNops() ? 0 : Align->getValue();
- uint64_t Size = std::min<uint64_t>(alignTo(DataBytes.size(),
- Align->getAlignment()),
- DataBytes.size() +
- Align->getMaxBytesToEmit());
+ uint64_t Size =
+ std::min<uint64_t>(alignTo(DataBytes.size(), Align->getAlignment()),
+ DataBytes.size() + Align->getMaxBytesToEmit());
DataBytes.resize(Size, Value);
} else if (auto *Fill = dyn_cast<MCFillFragment>(&Frag)) {
int64_t NumValues;
@@ -637,10 +639,12 @@ static void addData(SmallVectorImpl<char> &DataBytes,
llvm_unreachable("The fill should be an assembler constant");
DataBytes.insert(DataBytes.end(), Fill->getValueSize() * NumValues,
Fill->getValue());
+ } else if (auto *LEB = dyn_cast<MCLEBFragment>(&Frag)) {
+ const SmallVectorImpl<char> &Contents = LEB->getContents();
+ DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
} else {
const auto &DataFrag = cast<MCDataFragment>(Frag);
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
-
DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
}
}
@@ -678,6 +682,7 @@ void WasmObjectWriter::applyRelocations(
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+ case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB:
WritePatchableLEB(Stream, Value, Offset);
break;
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
@@ -696,23 +701,22 @@ void WasmObjectWriter::applyRelocations(
}
}
-void WasmObjectWriter::writeTypeSection(
- ArrayRef<WasmFunctionType> FunctionTypes) {
- if (FunctionTypes.empty())
+void WasmObjectWriter::writeTypeSection(ArrayRef<WasmSignature> Signatures) {
+ if (Signatures.empty())
return;
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_TYPE);
- encodeULEB128(FunctionTypes.size(), W.OS);
+ encodeULEB128(Signatures.size(), W.OS);
- for (const WasmFunctionType &FuncTy : FunctionTypes) {
+ for (const WasmSignature &Sig : Signatures) {
W.OS << char(wasm::WASM_TYPE_FUNC);
- encodeULEB128(FuncTy.Params.size(), W.OS);
- for (wasm::ValType Ty : FuncTy.Params)
+ encodeULEB128(Sig.Params.size(), W.OS);
+ for (wasm::ValType Ty : Sig.Params)
writeValueType(Ty);
- encodeULEB128(FuncTy.Returns.size(), W.OS);
- for (wasm::ValType Ty : FuncTy.Returns)
+ encodeULEB128(Sig.Returns.size(), W.OS);
+ for (wasm::ValType Ty : Sig.Returns)
writeValueType(Ty);
}
@@ -745,14 +749,18 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports,
W.OS << char(Import.Global.Mutable ? 1 : 0);
break;
case wasm::WASM_EXTERNAL_MEMORY:
- encodeULEB128(0, W.OS); // flags
+ encodeULEB128(0, W.OS); // flags
encodeULEB128(NumPages, W.OS); // initial
break;
case wasm::WASM_EXTERNAL_TABLE:
W.OS << char(Import.Table.ElemType);
- encodeULEB128(0, W.OS); // flags
+ 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);
+ break;
default:
llvm_unreachable("unsupported import kind");
}
@@ -770,7 +778,7 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) {
encodeULEB128(Functions.size(), W.OS);
for (const WasmFunction &Func : Functions)
- encodeULEB128(Func.Type, W.OS);
+ encodeULEB128(Func.SigIndex, W.OS);
endSection(Section);
}
@@ -795,6 +803,22 @@ void WasmObjectWriter::writeGlobalSection() {
endSection(Section);
}
+void WasmObjectWriter::writeEventSection(ArrayRef<wasm::WasmEventType> Events) {
+ if (Events.empty())
+ return;
+
+ SectionBookkeeping Section;
+ startSection(Section, wasm::WASM_SEC_EVENT);
+
+ encodeULEB128(Events.size(), W.OS);
+ for (const wasm::WasmEventType &Event : Events) {
+ encodeULEB128(Event.Attribute, W.OS);
+ encodeULEB128(Event.SigIndex, W.OS);
+ }
+
+ endSection(Section);
+}
+
void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) {
if (Exports.empty())
return;
@@ -892,21 +916,33 @@ void WasmObjectWriter::writeDataSection() {
void WasmObjectWriter::writeRelocSection(
uint32_t SectionIndex, StringRef Name,
- ArrayRef<WasmRelocationEntry> Relocations) {
+ std::vector<WasmRelocationEntry> &Relocs) {
// See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
// for descriptions of the reloc sections.
- if (Relocations.empty())
+ if (Relocs.empty())
return;
+ // First, ensure the relocations are sorted in offset order. In general they
+ // should already be sorted since `recordRelocation` is called in offset
+ // order, but for the code section we combine many MC sections into single
+ // wasm section, and this order is determined by the order of Asm.Symbols()
+ // not the sections order.
+ std::stable_sort(
+ Relocs.begin(), Relocs.end(),
+ [](const WasmRelocationEntry &A, const WasmRelocationEntry &B) {
+ return (A.Offset + A.FixupSection->getSectionOffset()) <
+ (B.Offset + B.FixupSection->getSectionOffset());
+ });
+
SectionBookkeeping Section;
startCustomSection(Section, std::string("reloc.") + Name.str());
encodeULEB128(SectionIndex, W.OS);
- encodeULEB128(Relocations.size(), W.OS);
- for (const WasmRelocationEntry& RelEntry : Relocations) {
- uint64_t Offset = RelEntry.Offset +
- RelEntry.FixupSection->getSectionOffset();
+ encodeULEB128(Relocs.size(), W.OS);
+ for (const WasmRelocationEntry &RelEntry : Relocs) {
+ uint64_t Offset =
+ RelEntry.Offset + RelEntry.FixupSection->getSectionOffset();
uint32_t Index = getRelocationIndexValue(RelEntry);
W.OS << char(RelEntry.Type);
@@ -944,6 +980,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:
encodeULEB128(Sym.ElementIndex, W.OS);
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
writeString(Sym.Name);
@@ -984,7 +1021,7 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
startSection(SubSection, wasm::WASM_INIT_FUNCS);
encodeULEB128(InitFuncs.size(), W.OS);
for (auto &StartFunc : InitFuncs) {
- encodeULEB128(StartFunc.first, W.OS); // priority
+ encodeULEB128(StartFunc.first, W.OS); // priority
encodeULEB128(StartFunc.second, W.OS); // function index
}
endSection(SubSection);
@@ -1029,30 +1066,57 @@ void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
}
}
-uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm& Symbol) {
+uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) {
assert(Symbol.isFunction());
assert(TypeIndices.count(&Symbol));
return TypeIndices[&Symbol];
}
-uint32_t WasmObjectWriter::registerFunctionType(const MCSymbolWasm& Symbol) {
+uint32_t WasmObjectWriter::getEventType(const MCSymbolWasm &Symbol) {
+ assert(Symbol.isEvent());
+ assert(TypeIndices.count(&Symbol));
+ return TypeIndices[&Symbol];
+}
+
+void WasmObjectWriter::registerFunctionType(const MCSymbolWasm &Symbol) {
assert(Symbol.isFunction());
- WasmFunctionType F;
- const MCSymbolWasm* ResolvedSym = ResolveSymbol(Symbol);
- F.Returns = ResolvedSym->getReturns();
- F.Params = ResolvedSym->getParams();
+ WasmSignature S;
+ const MCSymbolWasm *ResolvedSym = ResolveSymbol(Symbol);
+ if (auto *Sig = ResolvedSym->getSignature()) {
+ S.Returns = Sig->Returns;
+ S.Params = Sig->Params;
+ }
- auto Pair =
- FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
+ auto Pair = SignatureIndices.insert(std::make_pair(S, Signatures.size()));
if (Pair.second)
- FunctionTypes.push_back(F);
+ Signatures.push_back(S);
TypeIndices[&Symbol] = Pair.first->second;
LLVM_DEBUG(dbgs() << "registerFunctionType: " << Symbol
<< " new:" << Pair.second << "\n");
LLVM_DEBUG(dbgs() << " -> type index: " << Pair.first->second << "\n");
- return Pair.first->second;
+}
+
+void WasmObjectWriter::registerEventType(const MCSymbolWasm &Symbol) {
+ assert(Symbol.isEvent());
+
+ // TODO Currently we don't generate imported exceptions, but if we do, we
+ // should have a way of infering types of imported exceptions.
+ WasmSignature S;
+ if (auto *Sig = Symbol.getSignature()) {
+ S.Returns = Sig->Returns;
+ S.Params = Sig->Params;
+ }
+
+ auto Pair = SignatureIndices.insert(std::make_pair(S, Signatures.size()));
+ if (Pair.second)
+ Signatures.push_back(S);
+ TypeIndices[&Symbol] = Pair.first->second;
+
+ LLVM_DEBUG(dbgs() << "registerEventType: " << Symbol << " new:" << Pair.second
+ << "\n");
+ LLVM_DEBUG(dbgs() << " -> type index: " << Pair.first->second << "\n");
}
static bool isInSymtab(const MCSymbolWasm &Sym) {
@@ -1086,6 +1150,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
SmallVector<uint32_t, 4> TableElems;
SmallVector<wasm::WasmImport, 4> Imports;
SmallVector<wasm::WasmExport, 4> Exports;
+ SmallVector<wasm::WasmEventType, 1> Events;
SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
std::map<StringRef, std::vector<WasmComdatEntry>> Comdats;
@@ -1111,10 +1176,10 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
TableImport.Module = TableSym->getModuleName();
TableImport.Field = TableSym->getName();
TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
- TableImport.Table.ElemType = wasm::WASM_TYPE_ANYFUNC;
+ TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
Imports.push_back(TableImport);
- // Populate FunctionTypeIndices, and Imports and WasmIndices for undefined
+ // Populate SignatureIndices, and Imports and WasmIndices for undefined
// symbols. This must be done before populating WasmIndices for defined
// symbols.
for (const MCSymbol &S : Asm.symbols()) {
@@ -1125,6 +1190,9 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
if (WS.isFunction())
registerFunctionType(WS);
+ if (WS.isEvent())
+ registerEventType(WS);
+
if (WS.isTemporary())
continue;
@@ -1149,6 +1217,18 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
Import.Global = WS.getGlobalType();
Imports.push_back(Import);
WasmIndices[&WS] = NumGlobalImports++;
+ } else if (WS.isEvent()) {
+ if (WS.isWeak())
+ report_fatal_error("undefined event symbol cannot be weak");
+
+ wasm::WasmImport Import;
+ Import.Module = WS.getModuleName();
+ Import.Field = WS.getName();
+ Import.Kind = wasm::WASM_EXTERNAL_EVENT;
+ Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
+ Import.Event.SigIndex = getEventType(WS);
+ Imports.push_back(Import);
+ WasmIndices[&WS] = NumEventImports++;
}
}
}
@@ -1176,7 +1256,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
Segment.Offset = DataSize;
Segment.Section = &Section;
addData(Segment.Data, Section);
- Segment.Alignment = Section.getAlignment();
+ Segment.Alignment = Log2_32(Section.getAlignment());
Segment.Flags = 0;
DataSize += Segment.Data.size();
Section.setSegmentIndex(SegmentIndex);
@@ -1195,7 +1275,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
if (Name.startswith(".custom_section."))
Name = Name.substr(strlen(".custom_section."));
- MCSymbol* Begin = Sec.getBeginSymbol();
+ MCSymbol *Begin = Sec.getBeginSymbol();
if (Begin) {
WasmIndices[cast<MCSymbolWasm>(Begin)] = CustomSections.size();
if (SectionName != Begin->getName())
@@ -1240,7 +1320,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
// A definition. Write out the function body.
Index = NumFunctionImports + Functions.size();
WasmFunction Func;
- Func.Type = getFunctionType(WS);
+ Func.SigIndex = getFunctionType(WS);
Func.Sym = &WS;
WasmIndices[&WS] = Index;
Functions.push_back(Func);
@@ -1256,6 +1336,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
}
LLVM_DEBUG(dbgs() << " -> function index: " << Index << "\n");
+
} else if (WS.isData()) {
if (WS.isTemporary() && !WS.getSize())
continue;
@@ -1285,6 +1366,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
static_cast<uint32_t>(Size)};
DataLocations[&WS] = Ref;
LLVM_DEBUG(dbgs() << " -> segment index: " << Ref.Segment << "\n");
+
} else if (WS.isGlobal()) {
// A "true" Wasm global (currently just __stack_pointer)
if (WS.isDefined())
@@ -1293,6 +1375,24 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
// An import; the index was assigned above
LLVM_DEBUG(dbgs() << " -> global index: "
<< WasmIndices.find(&WS)->second << "\n");
+
+ } else if (WS.isEvent()) {
+ // 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;
+ WasmIndices[&WS] = Index;
+ Events.push_back(Event);
+ } else {
+ // An import; the index was assigned above.
+ Index = WasmIndices.find(&WS)->second;
+ }
+ LLVM_DEBUG(dbgs() << " -> event index: " << WasmIndices.find(&WS)->second
+ << "\n");
+
} else {
assert(WS.isSection());
}
@@ -1326,7 +1426,7 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
DataLocations[&WS] = Ref;
LLVM_DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n");
} else {
- report_fatal_error("don't yet support global aliases");
+ report_fatal_error("don't yet support global/event aliases");
}
}
@@ -1424,7 +1524,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
unsigned PrefixLength = strlen(".init_array");
if (WS.getSectionName().size() > PrefixLength) {
if (WS.getSectionName()[PrefixLength] != '.')
- report_fatal_error(".init_array section priority should start with '.'");
+ report_fatal_error(
+ ".init_array section priority should start with '.'");
if (WS.getSectionName()
.substr(PrefixLength + 1)
.getAsInteger(10, Priority))
@@ -1432,14 +1533,16 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
}
const auto &DataFrag = cast<MCDataFragment>(Frag);
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
- for (const uint8_t *p = (const uint8_t *)Contents.data(),
- *end = (const uint8_t *)Contents.data() + Contents.size();
+ for (const uint8_t *
+ p = (const uint8_t *)Contents.data(),
+ *end = (const uint8_t *)Contents.data() + Contents.size();
p != end; ++p) {
if (*p != 0)
report_fatal_error("non-symbolic data in .init_array section");
}
for (const MCFixup &Fixup : DataFrag.getFixups()) {
- assert(Fixup.getKind() == MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
+ assert(Fixup.getKind() ==
+ MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));
const MCExpr *Expr = Fixup.getValue();
auto *Sym = dyn_cast<MCSymbolRefExpr>(Expr);
if (!Sym)
@@ -1456,12 +1559,13 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
// Write out the Wasm header.
writeHeader(Asm);
- writeTypeSection(FunctionTypes);
+ writeTypeSection(Signatures);
writeImportSection(Imports, DataSize, TableElems.size());
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);
writeCodeSection(Asm, Layout, Functions);