diff options
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
| -rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 1a687d94d7f4..34e4d192e590 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/ScopedPrinter.h" #include <algorithm> #include <cassert> #include <cstdint> @@ -207,8 +208,8 @@ static wasm::WasmTable readTable(WasmObjectFile::ReadContext &Ctx) { return Table; } -static Error readSection(WasmSection &Section, - WasmObjectFile::ReadContext &Ctx) { +static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx, + WasmSectionOrderChecker &Checker) { Section.Offset = Ctx.Ptr - Ctx.Start; Section.Type = readUint8(Ctx); LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n"); @@ -231,6 +232,13 @@ static Error readSection(WasmSection &Section, Ctx.Ptr += SectionNameSize; Size -= SectionNameSize; } + + if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) { + return make_error<StringError>("Out of order section type: " + + llvm::to_string(Section.Type), + object_error::parse_failed); + } + Section.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size); Ctx.Ptr += Size; return Error::success(); @@ -265,8 +273,9 @@ WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err) } WasmSection Sec; + WasmSectionOrderChecker Checker; while (Ctx.Ptr < Ctx.End) { - if ((Err = readSection(Sec, Ctx))) + if ((Err = readSection(Sec, Ctx, Checker))) return; if ((Err = parseSection(Sec))) return; @@ -1433,3 +1442,58 @@ WasmObjectFile::getWasmRelocation(DataRefImpl Ref) const { assert(Ref.d.b < Sec.Relocations.size()); return Sec.Relocations[Ref.d.b]; } + +int WasmSectionOrderChecker::getSectionOrder(unsigned ID, + StringRef CustomSectionName) { + switch (ID) { + case wasm::WASM_SEC_CUSTOM: + return StringSwitch<unsigned>(CustomSectionName) + .Case("dylink", WASM_SEC_ORDER_DYLINK) + .Case("linking", WASM_SEC_ORDER_LINKING) + .StartsWith("reloc.", WASM_SEC_ORDER_RELOC) + .Case("name", WASM_SEC_ORDER_NAME) + .Case("producers", WASM_SEC_ORDER_PRODUCERS) + .Default(-1); + case wasm::WASM_SEC_TYPE: + return WASM_SEC_ORDER_TYPE; + case wasm::WASM_SEC_IMPORT: + return WASM_SEC_ORDER_IMPORT; + case wasm::WASM_SEC_FUNCTION: + return WASM_SEC_ORDER_FUNCTION; + case wasm::WASM_SEC_TABLE: + return WASM_SEC_ORDER_TABLE; + case wasm::WASM_SEC_MEMORY: + return WASM_SEC_ORDER_MEMORY; + case wasm::WASM_SEC_GLOBAL: + return WASM_SEC_ORDER_GLOBAL; + case wasm::WASM_SEC_EXPORT: + return WASM_SEC_ORDER_EXPORT; + case wasm::WASM_SEC_START: + return WASM_SEC_ORDER_START; + case wasm::WASM_SEC_ELEM: + return WASM_SEC_ORDER_ELEM; + case wasm::WASM_SEC_CODE: + return WASM_SEC_ORDER_CODE; + case wasm::WASM_SEC_DATA: + 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; + default: + llvm_unreachable("invalid section"); + } +} + +bool WasmSectionOrderChecker::isValidSectionOrder(unsigned ID, + StringRef CustomSectionName) { + int Order = getSectionOrder(ID, CustomSectionName); + if (Order == -1) // Skip unknown sections + return true; + // There can be multiple "reloc." sections. Otherwise there shouldn't be any + // duplicate section orders. + bool IsValid = (LastOrder == Order && Order == WASM_SEC_ORDER_RELOC) || + LastOrder < Order; + LastOrder = Order; + return IsValid; +} |
