diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp | 123 |
1 files changed, 65 insertions, 58 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp index 6a19b159f3d5..ce816b097691 100644 --- a/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp +++ b/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp @@ -8,7 +8,6 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" @@ -30,7 +29,6 @@ #include <cassert> #include <cstdint> #include <cstring> -#include <system_error> #define DEBUG_TYPE "wasm-object" @@ -166,23 +164,25 @@ static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) { static Error readInitExpr(wasm::WasmInitExpr &Expr, WasmObjectFile::ReadContext &Ctx) { - Expr.Opcode = readOpcode(Ctx); + auto Start = Ctx.Ptr; - switch (Expr.Opcode) { + Expr.Extended = false; + Expr.Inst.Opcode = readOpcode(Ctx); + switch (Expr.Inst.Opcode) { case wasm::WASM_OPCODE_I32_CONST: - Expr.Value.Int32 = readVarint32(Ctx); + Expr.Inst.Value.Int32 = readVarint32(Ctx); break; case wasm::WASM_OPCODE_I64_CONST: - Expr.Value.Int64 = readVarint64(Ctx); + Expr.Inst.Value.Int64 = readVarint64(Ctx); break; case wasm::WASM_OPCODE_F32_CONST: - Expr.Value.Float32 = readFloat32(Ctx); + Expr.Inst.Value.Float32 = readFloat32(Ctx); break; case wasm::WASM_OPCODE_F64_CONST: - Expr.Value.Float64 = readFloat64(Ctx); + Expr.Inst.Value.Float64 = readFloat64(Ctx); break; case wasm::WASM_OPCODE_GLOBAL_GET: - Expr.Value.Global = readULEB128(Ctx); + Expr.Inst.Value.Global = readULEB128(Ctx); break; case wasm::WASM_OPCODE_REF_NULL: { wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx)); @@ -193,15 +193,46 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr, break; } default: - return make_error<GenericBinaryError>("invalid opcode in init_expr", - object_error::parse_failed); + Expr.Extended = true; } - uint8_t EndOpcode = readOpcode(Ctx); - if (EndOpcode != wasm::WASM_OPCODE_END) { - return make_error<GenericBinaryError>("invalid init_expr", - object_error::parse_failed); + if (!Expr.Extended) { + uint8_t EndOpcode = readOpcode(Ctx); + if (EndOpcode != wasm::WASM_OPCODE_END) + Expr.Extended = true; + } + + if (Expr.Extended) { + Ctx.Ptr = Start; + while (1) { + uint8_t Opcode = readOpcode(Ctx); + switch (Opcode) { + case wasm::WASM_OPCODE_I32_CONST: + case wasm::WASM_OPCODE_GLOBAL_GET: + case wasm::WASM_OPCODE_REF_NULL: + case wasm::WASM_OPCODE_I64_CONST: + case wasm::WASM_OPCODE_F32_CONST: + case wasm::WASM_OPCODE_F64_CONST: + readULEB128(Ctx); + break; + case wasm::WASM_OPCODE_I32_ADD: + case wasm::WASM_OPCODE_I32_SUB: + case wasm::WASM_OPCODE_I32_MUL: + case wasm::WASM_OPCODE_I64_ADD: + case wasm::WASM_OPCODE_I64_SUB: + case wasm::WASM_OPCODE_I64_MUL: + break; + case wasm::WASM_OPCODE_END: + Expr.Body = ArrayRef<uint8_t>(Start, Ctx.Ptr - Start); + return Error::success(); + default: + return make_error<GenericBinaryError>( + Twine("invalid opcode in init_expr: ") + Twine(unsigned(Opcode)), + object_error::parse_failed); + } + } } + return Error::success(); } @@ -420,10 +451,6 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { llvm::DenseSet<uint64_t> SeenFunctions; llvm::DenseSet<uint64_t> SeenGlobals; llvm::DenseSet<uint64_t> SeenSegments; - if (Functions.size() && !SeenCodeSection) { - return make_error<GenericBinaryError>("names must come after code section", - object_error::parse_failed); - } while (Ctx.Ptr < Ctx.End) { uint8_t Type = readUint8(Ctx); @@ -443,7 +470,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { return make_error<GenericBinaryError>( "function named more than once", object_error::parse_failed); if (!isValidFunctionIndex(Index) || Name.empty()) - return make_error<GenericBinaryError>("invalid name entry", + return make_error<GenericBinaryError>("invalid function name entry", object_error::parse_failed); if (isDefinedFunctionIndex(Index)) @@ -454,7 +481,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { return make_error<GenericBinaryError>("global named more than once", object_error::parse_failed); if (!isValidGlobalIndex(Index) || Name.empty()) - return make_error<GenericBinaryError>("invalid name entry", + return make_error<GenericBinaryError>("invalid global name entry", object_error::parse_failed); } else { nameType = wasm::NameType::DATA_SEGMENT; @@ -462,7 +489,7 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { return make_error<GenericBinaryError>( "segment named more than once", object_error::parse_failed); if (Index > DataSegments.size()) - return make_error<GenericBinaryError>("invalid named data segment", + return make_error<GenericBinaryError>("invalid data segment name entry", object_error::parse_failed); } DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name}); @@ -488,11 +515,6 @@ Error WasmObjectFile::parseNameSection(ReadContext &Ctx) { Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) { HasLinkingSection = true; - if (Functions.size() && !SeenCodeSection) { - return make_error<GenericBinaryError>( - "linking data must come after code section", - object_error::parse_failed); - } LinkingData.Version = readVaruint32(Ctx); if (LinkingData.Version != wasm::WasmMetadataVersion) { @@ -1379,7 +1401,6 @@ Error WasmObjectFile::parseStartSection(ReadContext &Ctx) { } Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) { - SeenCodeSection = true; CodeSection = Sections.size(); uint32_t FunctionCount = readVaruint32(Ctx); if (FunctionCount != Functions.size()) { @@ -1443,8 +1464,9 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) { 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; + Segment.Offset.Extended = false; + Segment.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Offset.Inst.Value.Int32 = 0; } else { if (Error Err = readInitExpr(Segment.Offset, Ctx)) return Err; @@ -1488,7 +1510,7 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) { Error WasmObjectFile::parseDataSection(ReadContext &Ctx) { DataSection = Sections.size(); uint32_t Count = readVaruint32(Ctx); - if (DataCount && Count != DataCount.getValue()) + if (DataCount && Count != *DataCount) return make_error<GenericBinaryError>( "number of data segments does not match DataCount section"); DataSegments.reserve(Count); @@ -1503,8 +1525,9 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) { if (Error Err = readInitExpr(Segment.Data.Offset, Ctx)) return Err; } else { - Segment.Data.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; - Segment.Data.Offset.Value.Int32 = 0; + Segment.Data.Offset.Extended = false; + Segment.Data.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Data.Offset.Inst.Value.Int32 = 0; } uint32_t Size = readVaruint32(Ctx); if (Size > (size_t)(Ctx.End - Ctx.Ptr)) @@ -1602,10 +1625,12 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const { // offset within the segment. uint32_t SegmentIndex = Sym.Info.DataRef.Segment; const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data; - if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) { - return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset; - } else if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) { - return Segment.Offset.Value.Int64 + Sym.Info.DataRef.Offset; + if (Segment.Offset.Extended) { + llvm_unreachable("extended init exprs not supported"); + } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) { + return Segment.Offset.Inst.Value.Int32 + Sym.Info.DataRef.Offset; + } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) { + return Segment.Offset.Inst.Value.Int64 + Sym.Info.DataRef.Offset; } else { llvm_unreachable("unknown init expr opcode"); } @@ -1692,29 +1717,11 @@ void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; } Expected<StringRef> WasmObjectFile::getSectionName(DataRefImpl Sec) const { const WasmSection &S = Sections[Sec.d.a]; -#define ECase(X) \ - case wasm::WASM_SEC_##X: \ - return #X; - switch (S.Type) { - ECase(TYPE); - ECase(IMPORT); - ECase(FUNCTION); - ECase(TABLE); - ECase(MEMORY); - ECase(GLOBAL); - ECase(TAG); - ECase(EXPORT); - ECase(START); - ECase(ELEM); - ECase(CODE); - ECase(DATA); - ECase(DATACOUNT); - case wasm::WASM_SEC_CUSTOM: + if (S.Type == wasm::WASM_SEC_CUSTOM) return S.Name; - default: + if (S.Type > wasm::WASM_SEC_LAST_KNOWN) return createStringError(object_error::invalid_section_index, ""); - } -#undef ECase + return wasm::sectionTypeToString(S.Type); } uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; } |