diff options
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 208 |
1 files changed, 128 insertions, 80 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 40f468881edd..a08c648358c0 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -39,8 +39,8 @@ using namespace object; void WasmSymbol::print(raw_ostream &Out) const { Out << "Name=" << Info.Name - << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) - << ", Flags=" << Info.Flags; + << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x" + << Twine::utohexstr(Info.Flags); if (!isTypeData()) { Out << ", ElemIndex=" << Info.ElementIndex; } else if (isDefined()) { @@ -208,7 +208,7 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr, static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) { wasm::WasmLimits Result; Result.Flags = readVaruint32(Ctx); - Result.Initial = readVaruint64(Ctx); + Result.Minimum = readVaruint64(Ctx); if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) Result.Maximum = readVaruint64(Ctx); return Result; @@ -316,8 +316,8 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) { return parseTableSection(Ctx); case wasm::WASM_SEC_MEMORY: return parseMemorySection(Ctx); - case wasm::WASM_SEC_EVENT: - return parseEventSection(Ctx); + case wasm::WASM_SEC_TAG: + return parseTagSection(Ctx); case wasm::WASM_SEC_GLOBAL: return parseGlobalSection(Ctx); case wasm::WASM_SEC_EXPORT: @@ -462,7 +462,7 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) { for (uint32_t I = 0; I < Count; I++) { DataSegments[I].Data.Name = readString(Ctx); DataSegments[I].Data.Alignment = readVaruint32(Ctx); - DataSegments[I].Data.LinkerFlags = readVaruint32(Ctx); + DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx); } break; } @@ -507,19 +507,19 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { std::vector<wasm::WasmImport *> ImportedGlobals; std::vector<wasm::WasmImport *> ImportedFunctions; - std::vector<wasm::WasmImport *> ImportedEvents; + std::vector<wasm::WasmImport *> ImportedTags; std::vector<wasm::WasmImport *> ImportedTables; ImportedGlobals.reserve(Imports.size()); ImportedFunctions.reserve(Imports.size()); - ImportedEvents.reserve(Imports.size()); + ImportedTags.reserve(Imports.size()); ImportedTables.reserve(Imports.size()); for (auto &I : Imports) { if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION) ImportedFunctions.emplace_back(&I); else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL) ImportedGlobals.emplace_back(&I); - else if (I.Kind == wasm::WASM_EXTERNAL_EVENT) - ImportedEvents.emplace_back(&I); + else if (I.Kind == wasm::WASM_EXTERNAL_TAG) + ImportedTags.emplace_back(&I); else if (I.Kind == wasm::WASM_EXTERNAL_TABLE) ImportedTables.emplace_back(&I); } @@ -529,7 +529,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { const wasm::WasmSignature *Signature = nullptr; const wasm::WasmGlobalType *GlobalType = nullptr; const wasm::WasmTableType *TableType = nullptr; - const wasm::WasmEventType *EventType = nullptr; + const wasm::WasmTagType *TagType = nullptr; Info.Kind = readUint8(Ctx); Info.Flags = readVaruint32(Ctx); @@ -598,8 +598,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { case wasm::WASM_SYMBOL_TYPE_TABLE: Info.ElementIndex = readVaruint32(Ctx); - if (!isValidTableIndex(Info.ElementIndex) || - IsDefined != isDefinedTableIndex(Info.ElementIndex)) + if (!isValidTableNumber(Info.ElementIndex) || + IsDefined != isDefinedTableNumber(Info.ElementIndex)) return make_error<GenericBinaryError>("invalid table symbol index", object_error::parse_failed); if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) == @@ -608,8 +608,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { object_error::parse_failed); if (IsDefined) { Info.Name = readString(Ctx); - unsigned TableIndex = Info.ElementIndex - NumImportedTables; - wasm::WasmTable &Table = Tables[TableIndex]; + unsigned TableNumber = Info.ElementIndex - NumImportedTables; + wasm::WasmTable &Table = Tables[TableNumber]; TableType = &Table.Type; if (Table.SymbolName.empty()) Table.SymbolName = Info.Name; @@ -637,9 +637,12 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { object_error::parse_failed); auto Offset = readVaruint64(Ctx); auto Size = readVaruint64(Ctx); - if (Offset + Size > DataSegments[Index].Data.Content.size()) - return make_error<GenericBinaryError>("invalid data symbol offset", - object_error::parse_failed); + size_t SegmentSize = DataSegments[Index].Data.Content.size(); + if (Offset > SegmentSize) + return make_error<GenericBinaryError>( + "invalid data symbol offset: `" + Info.Name + "` (offset: " + + Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")", + object_error::parse_failed); Info.DataRef = wasm::WasmDataReference{Index, Offset, Size}; } break; @@ -657,11 +660,11 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { break; } - case wasm::WASM_SYMBOL_TYPE_EVENT: { + case wasm::WASM_SYMBOL_TYPE_TAG: { Info.ElementIndex = readVaruint32(Ctx); - if (!isValidEventIndex(Info.ElementIndex) || - IsDefined != isDefinedEventIndex(Info.ElementIndex)) - return make_error<GenericBinaryError>("invalid event symbol index", + if (!isValidTagIndex(Info.ElementIndex) || + IsDefined != isDefinedTagIndex(Info.ElementIndex)) + return make_error<GenericBinaryError>("invalid tag symbol index", object_error::parse_failed); if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) == wasm::WASM_SYMBOL_BINDING_WEAK) @@ -669,23 +672,23 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { object_error::parse_failed); if (IsDefined) { Info.Name = readString(Ctx); - unsigned EventIndex = Info.ElementIndex - NumImportedEvents; - wasm::WasmEvent &Event = Events[EventIndex]; - Signature = &Signatures[Event.Type.SigIndex]; - EventType = &Event.Type; - if (Event.SymbolName.empty()) - Event.SymbolName = Info.Name; + unsigned TagIndex = Info.ElementIndex - NumImportedTags; + wasm::WasmTag &Tag = Tags[TagIndex]; + Signature = &Signatures[Tag.Type.SigIndex]; + TagType = &Tag.Type; + if (Tag.SymbolName.empty()) + Tag.SymbolName = Info.Name; } else { - wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex]; + wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex]; if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) { Info.Name = readString(Ctx); Info.ImportName = Import.Field; } else { Info.Name = Import.Field; } - EventType = &Import.Event; - Signature = &Signatures[EventType->SigIndex]; + TagType = &Import.Tag; + Signature = &Signatures[TagType->SigIndex]; if (!Import.Module.empty()) { Info.ImportModule = Import.Module; } @@ -707,7 +710,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { object_error::parse_failed); LinkingData.SymbolTable.emplace_back(Info); Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType, - EventType, Signature); + TagType, Signature); LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n"); } @@ -867,6 +870,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { case wasm::R_WASM_TABLE_INDEX_I32: case wasm::R_WASM_TABLE_INDEX_I64: case wasm::R_WASM_TABLE_INDEX_REL_SLEB: + case wasm::R_WASM_TABLE_INDEX_REL_SLEB64: if (!isValidFunctionSymbol(Reloc.Index)) return make_error<GenericBinaryError>( "invalid relocation function index", object_error::parse_failed); @@ -895,9 +899,9 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { return make_error<GenericBinaryError>("invalid relocation global index", object_error::parse_failed); break; - case wasm::R_WASM_EVENT_INDEX_LEB: - if (!isValidEventSymbol(Reloc.Index)) - return make_error<GenericBinaryError>("invalid relocation event index", + case wasm::R_WASM_TAG_INDEX_LEB: + if (!isValidTagSymbol(Reloc.Index)) + return make_error<GenericBinaryError>("invalid relocation tag index", object_error::parse_failed); break; case wasm::R_WASM_MEMORY_ADDR_LEB: @@ -905,6 +909,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { case wasm::R_WASM_MEMORY_ADDR_I32: case wasm::R_WASM_MEMORY_ADDR_REL_SLEB: case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: + case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: if (!isValidDataSymbol(Reloc.Index)) return make_error<GenericBinaryError>("invalid relocation data index", object_error::parse_failed); @@ -914,6 +919,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { case wasm::R_WASM_MEMORY_ADDR_SLEB64: case wasm::R_WASM_MEMORY_ADDR_I64: case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64: + case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64: if (!isValidDataSymbol(Reloc.Index)) return make_error<GenericBinaryError>("invalid relocation data index", object_error::parse_failed); @@ -953,6 +959,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { Size = 10; if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 || Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 || + Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 || Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 || Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 || Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32) @@ -1058,10 +1065,10 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) { object_error::parse_failed); break; } - case wasm::WASM_EXTERNAL_EVENT: - NumImportedEvents++; - Im.Event.Attribute = readVarint32(Ctx); - Im.Event.SigIndex = readVarint32(Ctx); + case wasm::WASM_EXTERNAL_TAG: + NumImportedTags++; + Im.Tag.Attribute = readUint8(Ctx); + Im.Tag.SigIndex = readVarint32(Ctx); break; default: return make_error<GenericBinaryError>("unexpected import kind", @@ -1130,20 +1137,20 @@ Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) { return Error::success(); } -Error WasmObjectFile::parseEventSection(ReadContext &Ctx) { - EventSection = Sections.size(); - uint32_t Count = readVarint32(Ctx); - Events.reserve(Count); +Error WasmObjectFile::parseTagSection(ReadContext &Ctx) { + TagSection = Sections.size(); + uint32_t Count = readVaruint32(Ctx); + Tags.reserve(Count); while (Count--) { - wasm::WasmEvent Event; - Event.Index = NumImportedEvents + Events.size(); - Event.Type.Attribute = readVaruint32(Ctx); - Event.Type.SigIndex = readVarint32(Ctx); - Events.push_back(Event); + wasm::WasmTag Tag; + Tag.Index = NumImportedTags + Tags.size(); + Tag.Type.Attribute = readUint8(Ctx); + Tag.Type.SigIndex = readVaruint32(Ctx); + Tags.push_back(Tag); } if (Ctx.Ptr != Ctx.End) - return make_error<GenericBinaryError>("event section ended prematurely", + return make_error<GenericBinaryError>("tag section ended prematurely", object_error::parse_failed); return Error::success(); } @@ -1188,9 +1195,9 @@ Error WasmObjectFile::parseExportSection(ReadContext &Ctx) { return make_error<GenericBinaryError>("invalid global export", object_error::parse_failed); break; - case wasm::WASM_EXTERNAL_EVENT: - if (!isValidEventIndex(Ex.Index)) - return make_error<GenericBinaryError>("invalid event export", + case wasm::WASM_EXTERNAL_TAG: + if (!isValidTagIndex(Ex.Index)) + return make_error<GenericBinaryError>("invalid tag export", object_error::parse_failed); break; case wasm::WASM_EXTERNAL_MEMORY: @@ -1220,7 +1227,7 @@ bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const { return Index < NumImportedGlobals + Globals.size(); } -bool WasmObjectFile::isValidTableIndex(uint32_t Index) const { +bool WasmObjectFile::isValidTableNumber(uint32_t Index) const { return Index < NumImportedTables + Tables.size(); } @@ -1228,16 +1235,16 @@ bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const { return Index >= NumImportedGlobals && isValidGlobalIndex(Index); } -bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const { - return Index >= NumImportedTables && isValidTableIndex(Index); +bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const { + return Index >= NumImportedTables && isValidTableNumber(Index); } -bool WasmObjectFile::isValidEventIndex(uint32_t Index) const { - return Index < NumImportedEvents + Events.size(); +bool WasmObjectFile::isValidTagIndex(uint32_t Index) const { + return Index < NumImportedTags + Tags.size(); } -bool WasmObjectFile::isDefinedEventIndex(uint32_t Index) const { - return Index >= NumImportedEvents && isValidEventIndex(Index); +bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const { + return Index >= NumImportedTags && isValidTagIndex(Index); } bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const { @@ -1252,8 +1259,8 @@ bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const { return Index < Symbols.size() && Symbols[Index].isTypeGlobal(); } -bool WasmObjectFile::isValidEventSymbol(uint32_t Index) const { - return Index < Symbols.size() && Symbols[Index].isTypeEvent(); +bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const { + return Index < Symbols.size() && Symbols[Index].isTypeTag(); } bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const { @@ -1280,9 +1287,9 @@ wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) { return Globals[Index - NumImportedGlobals]; } -wasm::WasmEvent &WasmObjectFile::getDefinedEvent(uint32_t Index) { - assert(isDefinedEventIndex(Index)); - return Events[Index - NumImportedEvents]; +wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) { + assert(isDefinedTagIndex(Index)); + return Tags[Index - NumImportedTags]; } Error WasmObjectFile::parseStartSection(ReadContext &Ctx) { @@ -1340,13 +1347,54 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) { ElemSegments.reserve(Count); while (Count--) { wasm::WasmElemSegment Segment; - Segment.TableIndex = readVaruint32(Ctx); - if (Segment.TableIndex != 0) { - return make_error<GenericBinaryError>("invalid TableIndex", + Segment.Flags = readVaruint32(Ctx); + + uint32_t SupportedFlags = wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER | + wasm::WASM_ELEM_SEGMENT_IS_PASSIVE | + wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS; + if (Segment.Flags & ~SupportedFlags) + return make_error<GenericBinaryError>( + "Unsupported flags for element segment", object_error::parse_failed); + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER) + Segment.TableNumber = readVaruint32(Ctx); + else + Segment.TableNumber = 0; + if (!isValidTableNumber(Segment.TableNumber)) + return make_error<GenericBinaryError>("invalid TableNumber", object_error::parse_failed); + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) { + Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Offset.Value.Int32 = 0; + } else { + if (Error Err = readInitExpr(Segment.Offset, Ctx)) + return Err; } - if (Error Err = readInitExpr(Segment.Offset, Ctx)) - return Err; + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) { + Segment.ElemKind = readUint8(Ctx); + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS) { + if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) && + Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) { + return make_error<GenericBinaryError>("invalid reference type", + object_error::parse_failed); + } + } else { + if (Segment.ElemKind != 0) + return make_error<GenericBinaryError>("invalid elemtype", + object_error::parse_failed); + Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF); + } + } else { + Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF); + } + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS) + return make_error<GenericBinaryError>( + "elem segment init expressions not yet implemented", + object_error::parse_failed); + uint32_t NumElems = readVaruint32(Ctx); while (NumElems--) { Segment.Functions.push_back(readVaruint32(Ctx)); @@ -1388,7 +1436,7 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) { // The rest of these Data fields are set later, when reading in the linking // metadata section. Segment.Data.Alignment = 0; - Segment.Data.LinkerFlags = 0; + Segment.Data.LinkingFlags = 0; Segment.Data.Comdat = UINT32_MAX; Segment.SectionOffset = Ctx.Ptr - Ctx.Start; Ctx.Ptr += Size; @@ -1468,7 +1516,7 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const { switch (Sym.Info.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: return Sym.Info.ElementIndex; case wasm::WASM_SYMBOL_TYPE_DATA: { @@ -1517,7 +1565,7 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const { return SymbolRef::ST_Data; case wasm::WASM_SYMBOL_TYPE_SECTION: return SymbolRef::ST_Debug; - case wasm::WASM_SYMBOL_TYPE_EVENT: + case wasm::WASM_SYMBOL_TYPE_TAG: return SymbolRef::ST_Other; case wasm::WASM_SYMBOL_TYPE_TABLE: return SymbolRef::ST_Other; @@ -1553,8 +1601,8 @@ uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const { return DataSection; case wasm::WASM_SYMBOL_TYPE_SECTION: return Sym.Info.ElementIndex; - case wasm::WASM_SYMBOL_TYPE_EVENT: - return EventSection; + case wasm::WASM_SYMBOL_TYPE_TAG: + return TagSection; case wasm::WASM_SYMBOL_TYPE_TABLE: return TableSection; default: @@ -1576,7 +1624,7 @@ Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const { ECase(TABLE); ECase(MEMORY); ECase(GLOBAL); - ECase(EVENT); + ECase(TAG); ECase(EXPORT); ECase(START); ECase(ELEM); @@ -1775,8 +1823,8 @@ int WasmSectionOrderChecker::getSectionOrder(unsigned ID, return WASM_SEC_ORDER_DATA; case wasm::WASM_SEC_DATACOUNT: return WASM_SEC_ORDER_DATACOUNT; - case wasm::WASM_SEC_EVENT: - return WASM_SEC_ORDER_EVENT; + case wasm::WASM_SEC_TAG: + return WASM_SEC_ORDER_TAG; default: return WASM_SEC_ORDER_NONE; } @@ -1798,9 +1846,9 @@ int WasmSectionOrderChecker::DisallowedPredecessors // WASM_SEC_ORDER_TABLE {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY}, // WASM_SEC_ORDER_MEMORY - {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_EVENT}, - // WASM_SEC_ORDER_EVENT - {WASM_SEC_ORDER_EVENT, WASM_SEC_ORDER_GLOBAL}, + {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG}, + // WASM_SEC_ORDER_TAG + {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL}, // WASM_SEC_ORDER_GLOBAL {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT}, // WASM_SEC_ORDER_EXPORT |