diff options
author | Heejin Ahn <aheejin@gmail.com> | 2018-12-15 00:58:12 +0000 |
---|---|---|
committer | Heejin Ahn <aheejin@gmail.com> | 2018-12-15 00:58:12 +0000 |
commit | feef720bb86001ba3173d5022fd329fb385c7794 (patch) | |
tree | 8ecf5eaf9c3c4a7f05549f44ed6d5881dfb954bb /llvm/lib/Object/WasmObjectFile.cpp | |
parent | c214bc2b8da91f38c4d2c060831229a17b6af816 (diff) | |
download | bcm5719-llvm-feef720bb86001ba3173d5022fd329fb385c7794.tar.gz bcm5719-llvm-feef720bb86001ba3173d5022fd329fb385c7794.zip |
[WebAssembly] Check if the section order is correct
Summary:
This patch checks if the section order is correct when reading a wasm
object file in `WasmObjectFile` and converting YAML to wasm object in
yaml2wasm. (It is not possible to check when reading YAML because it is
handled exclusively by the YAML reader.)
This checks the ordering of all known sections (core sections + known
custom sections). This also adds section ID DataCount section that will
be scheduled to be added in near future.
Reviewers: sbc100
Subscribers: dschuff, mgorny, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D54924
llvm-svn: 349221
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 1a687d94d7f..34e4d192e59 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; +} |