aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/WasmObjectFile.cpp123
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; }