[llvm] [Object][WebAssembly] Make Wasm read failures recoverable (PR #215102)
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 10 01:43:17 PDT 2026
================
@@ -86,103 +85,121 @@ ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) {
#define VARUINT7_MAX (1 << 7)
#define VARUINT1_MAX (1)
-static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx) {
+static Error parseFailed(const Twine &Msg) {
+ return make_error<GenericBinaryError>(Msg, object_error::parse_failed);
+}
+
+static Error readUint8(WasmObjectFile::ReadContext &Ctx, uint8_t &Result) {
if (Ctx.Ptr == Ctx.End)
- report_fatal_error("EOF while reading uint8");
- return *Ctx.Ptr++;
+ return parseFailed("EOF while reading uint8");
+ Result = *Ctx.Ptr++;
+ return Error::success();
}
-static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx) {
+static Error readUint32(WasmObjectFile::ReadContext &Ctx, uint32_t &Result) {
if (Ctx.Ptr + 4 > Ctx.End)
- report_fatal_error("EOF while reading uint32");
- uint32_t Result = support::endian::read32le(Ctx.Ptr);
+ return parseFailed("EOF while reading uint32");
+ Result = support::endian::read32le(Ctx.Ptr);
Ctx.Ptr += 4;
- return Result;
+ return Error::success();
}
-static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx) {
+static Error readFloat32(WasmObjectFile::ReadContext &Ctx, int32_t &Result) {
if (Ctx.Ptr + 4 > Ctx.End)
- report_fatal_error("EOF while reading float64");
- int32_t Result = 0;
+ return parseFailed("EOF while reading float64");
+ Result = 0;
memcpy(&Result, Ctx.Ptr, sizeof(Result));
Ctx.Ptr += sizeof(Result);
- return Result;
+ return Error::success();
}
-static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
+static Error readFloat64(WasmObjectFile::ReadContext &Ctx, int64_t &Result) {
if (Ctx.Ptr + 8 > Ctx.End)
- report_fatal_error("EOF while reading float64");
- int64_t Result = 0;
+ return parseFailed("EOF while reading float64");
+ Result = 0;
memcpy(&Result, Ctx.Ptr, sizeof(Result));
Ctx.Ptr += sizeof(Result);
- return Result;
+ return Error::success();
}
-static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
+static Error readULEB128(WasmObjectFile::ReadContext &Ctx, uint64_t &Result) {
unsigned Count;
- const char *Error = nullptr;
- uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
- if (Error)
- report_fatal_error(Error);
+ const char *ErrorStr = nullptr;
+ Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &ErrorStr);
+ if (ErrorStr)
+ return parseFailed(ErrorStr);
Ctx.Ptr += Count;
- return Result;
+ return Error::success();
}
-static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
- uint32_t StringLen = readULEB128(Ctx);
- if (Ctx.Ptr + StringLen > Ctx.End)
- report_fatal_error("EOF while reading string");
- StringRef Return =
- StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
+static Error readString(WasmObjectFile::ReadContext &Ctx, StringRef &Result) {
+ uint64_t StringLen;
+ if (Error E = readULEB128(Ctx, StringLen))
+ return E;
+
+ if (StringLen > static_cast<uint64_t>(Ctx.End - Ctx.Ptr))
+ return parseFailed("EOF while reading string");
+
+ Result = StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
Ctx.Ptr += StringLen;
- return Return;
+ return Error::success();
}
-static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
+static Error readLEB128(WasmObjectFile::ReadContext &Ctx, int64_t &Result) {
unsigned Count;
- const char *Error = nullptr;
- uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
- if (Error)
- report_fatal_error(Error);
+ const char *ErrorStr = nullptr;
+ uint64_t Decoded = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &ErrorStr);
+ if (ErrorStr)
+ return parseFailed(ErrorStr);
+ Result = static_cast<int64_t>(Decoded);
Ctx.Ptr += Count;
- return Result;
+ return Error::success();
}
-static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx) {
- int64_t Result = readLEB128(Ctx);
- if (Result > VARUINT1_MAX || Result < 0)
- report_fatal_error("LEB is outside Varuint1 range");
- return Result;
+static Error readVaruint1(WasmObjectFile::ReadContext &Ctx, uint8_t &Result) {
+ int64_t Value;
+ if (Error E = readLEB128(Ctx, Value))
+ return E;
+ if (Value > VARUINT1_MAX || Value < 0)
+ return parseFailed("LEB is outside Varuint1 range");
+ Result = Value;
+ return Error::success();
}
-static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx) {
- int64_t Result = readLEB128(Ctx);
- if (Result > INT32_MAX || Result < INT32_MIN)
- report_fatal_error("LEB is outside Varint32 range");
- return Result;
+static Error readVarint32(WasmObjectFile::ReadContext &Ctx, int32_t &Result) {
+ int64_t Value;
+ if (Error E = readLEB128(Ctx, Value))
+ return E;
+ if (Value > INT32_MAX || Value < INT32_MIN)
+ return parseFailed("LEB is outside Varint32 range");
+ Result = Value;
+ return Error::success();
}
-static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx) {
- uint64_t Result = readULEB128(Ctx);
- if (Result > UINT32_MAX)
- report_fatal_error("LEB is outside Varuint32 range");
- return Result;
+static Error readVaruint32(WasmObjectFile::ReadContext &Ctx, uint32_t &Result) {
+ uint64_t Value;
+ if (Error E = readULEB128(Ctx, Value))
+ return E;
+ if (Value > UINT32_MAX)
+ return parseFailed("LEB is outside Varuint32 range");
+ Result = Value;
+ return Error::success();
}
-static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
- return readLEB128(Ctx);
+static Error readVarint64(WasmObjectFile::ReadContext &Ctx, int64_t &Result) {
+ return readLEB128(Ctx, Result);
}
-static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) {
- return readULEB128(Ctx);
+static Error readVaruint64(WasmObjectFile::ReadContext &Ctx, uint64_t &Result) {
+ return readULEB128(Ctx, Result);
}
-static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
- return readUint8(Ctx);
+static Error readOpcode(WasmObjectFile::ReadContext &Ctx, uint8_t &Result) {
+ return readUint8(Ctx, Result);
}
-static wasm::ValType parseValType(WasmObjectFile::ReadContext &Ctx,
- uint32_t Code) {
+static Error parseValType(WasmObjectFile::ReadContext &Ctx, uint32_t Code,
----------------
jh7370 wrote:
This sort of function should return `Expected<T>` (where `T` is the intended return type) and not add a new output parameter instead.
Same applies in multiple places.
https://github.com/llvm/llvm-project/pull/215102
More information about the llvm-commits
mailing list