diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-03-20 11:40:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:43:05 +0000 |
commit | 349cc55c9796c4596a5b9904cd3281af295f878f (patch) | |
tree | 410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp | |
parent | cb2ae6163174b90e999326ecec3699ee093a5d43 (diff) | |
parent | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp | 119 |
1 files changed, 99 insertions, 20 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp index a08c648358c0..6a19b159f3d5 100644 --- a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp +++ b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp @@ -286,9 +286,9 @@ WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err) return; } - WasmSection Sec; WasmSectionOrderChecker Checker; while (Ctx.Ptr < Ctx.End) { + WasmSection Sec; if ((Err = readSection(Sec, Ctx, Checker))) return; if ((Err = parseSection(Sec))) @@ -339,7 +339,8 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) { } Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) { - // See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md + // Legacy "dylink" section support. + // See parseDylink0Section for the current "dylink.0" section parsing. HasDylinkSection = true; DylinkInfo.MemorySize = readVaruint32(Ctx); DylinkInfo.MemoryAlignment = readVaruint32(Ctx); @@ -349,17 +350,77 @@ Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) { while (Count--) { DylinkInfo.Needed.push_back(readString(Ctx)); } + if (Ctx.Ptr != Ctx.End) return make_error<GenericBinaryError>("dylink section ended prematurely", object_error::parse_failed); return Error::success(); } +Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) { + // See + // https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md + HasDylinkSection = true; + + const uint8_t *OrigEnd = Ctx.End; + while (Ctx.Ptr < OrigEnd) { + Ctx.End = OrigEnd; + uint8_t Type = readUint8(Ctx); + uint32_t Size = readVaruint32(Ctx); + LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size + << "\n"); + Ctx.End = Ctx.Ptr + Size; + uint32_t Count; + switch (Type) { + case wasm::WASM_DYLINK_MEM_INFO: + DylinkInfo.MemorySize = readVaruint32(Ctx); + DylinkInfo.MemoryAlignment = readVaruint32(Ctx); + DylinkInfo.TableSize = readVaruint32(Ctx); + DylinkInfo.TableAlignment = readVaruint32(Ctx); + break; + case wasm::WASM_DYLINK_NEEDED: + Count = readVaruint32(Ctx); + while (Count--) { + DylinkInfo.Needed.push_back(readString(Ctx)); + } + break; + case wasm::WASM_DYLINK_EXPORT_INFO: { + uint32_t Count = readVaruint32(Ctx); + while (Count--) { + DylinkInfo.ExportInfo.push_back({readString(Ctx), readVaruint32(Ctx)}); + } + break; + } + case wasm::WASM_DYLINK_IMPORT_INFO: { + uint32_t Count = readVaruint32(Ctx); + while (Count--) { + DylinkInfo.ImportInfo.push_back( + {readString(Ctx), readString(Ctx), readVaruint32(Ctx)}); + } + break; + } + default: + LLVM_DEBUG(dbgs() << "unknown dylink.0 sub-section: " << Type << "\n"); + Ctx.Ptr += Size; + break; + } + if (Ctx.Ptr != Ctx.End) { + return make_error<GenericBinaryError>( + "dylink.0 sub-section ended prematurely", object_error::parse_failed); + } + } + + if (Ctx.Ptr != Ctx.End) + return make_error<GenericBinaryError>("dylink.0 section ended prematurely", + object_error::parse_failed); + return Error::success(); +} + Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { llvm::DenseSet<uint64_t> SeenFunctions; llvm::DenseSet<uint64_t> SeenGlobals; llvm::DenseSet<uint64_t> SeenSegments; - if (FunctionTypes.size() && !SeenCodeSection) { + if (Functions.size() && !SeenCodeSection) { return make_error<GenericBinaryError>("names must come after code section", object_error::parse_failed); } @@ -427,7 +488,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) { HasLinkingSection = true; - if (FunctionTypes.size() && !SeenCodeSection) { + if (Functions.size() && !SeenCodeSection) { return make_error<GenericBinaryError>( "linking data must come after code section", object_error::parse_failed); @@ -529,7 +590,6 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { const wasm::WasmSignature *Signature = nullptr; const wasm::WasmGlobalType *GlobalType = nullptr; const wasm::WasmTableType *TableType = nullptr; - const wasm::WasmTagType *TagType = nullptr; Info.Kind = readUint8(Ctx); Info.Flags = readVaruint32(Ctx); @@ -545,8 +605,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { if (IsDefined) { Info.Name = readString(Ctx); unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions; - Signature = &Signatures[FunctionTypes[FuncIndex]]; wasm::WasmFunction &Function = Functions[FuncIndex]; + Signature = &Signatures[Function.SigIndex]; if (Function.SymbolName.empty()) Function.SymbolName = Info.Name; } else { @@ -674,8 +734,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { Info.Name = readString(Ctx); unsigned TagIndex = Info.ElementIndex - NumImportedTags; wasm::WasmTag &Tag = Tags[TagIndex]; - Signature = &Signatures[Tag.Type.SigIndex]; - TagType = &Tag.Type; + Signature = &Signatures[Tag.SigIndex]; if (Tag.SymbolName.empty()) Tag.SymbolName = Info.Name; @@ -687,8 +746,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { } else { Info.Name = Import.Field; } - TagType = &Import.Tag; - Signature = &Signatures[TagType->SigIndex]; + Signature = &Signatures[Import.SigIndex]; if (!Import.Module.empty()) { Info.ImportModule = Import.Module; } @@ -710,7 +768,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { object_error::parse_failed); LinkingData.SymbolTable.emplace_back(Info); Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType, - TagType, Signature); + Signature); LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n"); } @@ -984,6 +1042,9 @@ Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) { if (Sec.Name == "dylink") { if (Error Err = parseDylinkSection(Ctx)) return Err; + } else if (Sec.Name == "dylink.0") { + if (Error Err = parseDylink0Section(Ctx)) + return Err; } else if (Sec.Name == "name") { if (Error Err = parseNameSection(Ctx)) return Err; @@ -1034,6 +1095,7 @@ Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) { Error WasmObjectFile::parseImportSection(ReadContext &Ctx) { uint32_t Count = readVaruint32(Ctx); + uint32_t NumTypes = Signatures.size(); Imports.reserve(Count); for (uint32_t I = 0; I < Count; I++) { wasm::WasmImport Im; @@ -1044,6 +1106,9 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) { case wasm::WASM_EXTERNAL_FUNCTION: NumImportedFunctions++; Im.SigIndex = readVaruint32(Ctx); + if (Im.SigIndex >= NumTypes) + return make_error<GenericBinaryError>("invalid function type", + object_error::parse_failed); break; case wasm::WASM_EXTERNAL_GLOBAL: NumImportedGlobals++; @@ -1067,8 +1132,13 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) { } case wasm::WASM_EXTERNAL_TAG: NumImportedTags++; - Im.Tag.Attribute = readUint8(Ctx); - Im.Tag.SigIndex = readVarint32(Ctx); + if (readUint8(Ctx) != 0) // Reserved 'attribute' field + return make_error<GenericBinaryError>("invalid attribute", + object_error::parse_failed); + Im.SigIndex = readVaruint32(Ctx); + if (Im.SigIndex >= NumTypes) + return make_error<GenericBinaryError>("invalid tag type", + object_error::parse_failed); break; default: return make_error<GenericBinaryError>("unexpected import kind", @@ -1084,15 +1154,16 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) { Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) { uint32_t Count = readVaruint32(Ctx); - FunctionTypes.reserve(Count); - Functions.resize(Count); + Functions.reserve(Count); uint32_t NumTypes = Signatures.size(); while (Count--) { uint32_t Type = readVaruint32(Ctx); if (Type >= NumTypes) return make_error<GenericBinaryError>("invalid function type", object_error::parse_failed); - FunctionTypes.push_back(Type); + wasm::WasmFunction F; + F.SigIndex = Type; + Functions.push_back(F); } if (Ctx.Ptr != Ctx.End) return make_error<GenericBinaryError>("function section ended prematurely", @@ -1141,11 +1212,18 @@ Error WasmObjectFile::parseTagSection(ReadContext &Ctx) { TagSection = Sections.size(); uint32_t Count = readVaruint32(Ctx); Tags.reserve(Count); + uint32_t NumTypes = Signatures.size(); while (Count--) { + if (readUint8(Ctx) != 0) // Reserved 'attribute' field + return make_error<GenericBinaryError>("invalid attribute", + object_error::parse_failed); + uint32_t Type = readVaruint32(Ctx); + if (Type >= NumTypes) + return make_error<GenericBinaryError>("invalid tag type", + object_error::parse_failed); wasm::WasmTag Tag; Tag.Index = NumImportedTags + Tags.size(); - Tag.Type.Attribute = readUint8(Ctx); - Tag.Type.SigIndex = readVaruint32(Ctx); + Tag.SigIndex = Type; Tags.push_back(Tag); } @@ -1216,7 +1294,7 @@ Error WasmObjectFile::parseExportSection(ReadContext &Ctx) { } bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const { - return Index < NumImportedFunctions + FunctionTypes.size(); + return Index < NumImportedFunctions + Functions.size(); } bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const { @@ -1304,7 +1382,7 @@ Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) { SeenCodeSection = true; CodeSection = Sections.size(); uint32_t FunctionCount = readVaruint32(Ctx); - if (FunctionCount != FunctionTypes.size()) { + if (FunctionCount != Functions.size()) { return make_error<GenericBinaryError>("invalid function count", object_error::parse_failed); } @@ -1793,6 +1871,7 @@ int WasmSectionOrderChecker::getSectionOrder(unsigned ID, case wasm::WASM_SEC_CUSTOM: return StringSwitch<unsigned>(CustomSectionName) .Case("dylink", WASM_SEC_ORDER_DYLINK) + .Case("dylink.0", WASM_SEC_ORDER_DYLINK) .Case("linking", WASM_SEC_ORDER_LINKING) .StartsWith("reloc.", WASM_SEC_ORDER_RELOC) .Case("name", WASM_SEC_ORDER_NAME) |