|
| 1 | +//===- SFrameParser.cpp ---------------------------------------------------===// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | + |
| 9 | +#include "llvm/Object/SFrameParser.h" |
| 10 | +#include "llvm/BinaryFormat/SFrame.h" |
| 11 | +#include "llvm/Object/Error.h" |
| 12 | +#include "llvm/Support/FormatVariadic.h" |
| 13 | + |
| 14 | +using namespace llvm; |
| 15 | +using namespace llvm::object; |
| 16 | + |
| 17 | +template <typename T> |
| 18 | +static Expected<const T &> getDataSliceAs(ArrayRef<uint8_t> Data, |
| 19 | + uint64_t Offset) { |
| 20 | + static_assert(std::is_trivial_v<T>); |
| 21 | + if (Data.size() < Offset + sizeof(T)) { |
| 22 | + return createStringError( |
| 23 | + formatv("unexpected end of data at offset {0:x} while reading [{1:x}, " |
| 24 | + "{2:x})", |
| 25 | + Data.size(), Offset, Offset + sizeof(T)) |
| 26 | + .str(), |
| 27 | + object_error::unexpected_eof); |
| 28 | + } |
| 29 | + return *reinterpret_cast<const T *>(Data.data() + Offset); |
| 30 | +} |
| 31 | + |
| 32 | +template <endianness E> |
| 33 | +Expected<SFrameParser<E>> SFrameParser<E>::create(ArrayRef<uint8_t> Contents) { |
| 34 | + Expected<const sframe::Preamble<E> &> Preamble = |
| 35 | + getDataSliceAs<sframe::Preamble<E>>(Contents, 0); |
| 36 | + if (!Preamble) |
| 37 | + return Preamble.takeError(); |
| 38 | + |
| 39 | + if (Preamble->Magic != sframe::Magic) |
| 40 | + return createError( |
| 41 | + formatv("invalid magic number ({0:x+4})", Preamble->Magic.value())); |
| 42 | + if (Preamble->Version != sframe::Version::V2) |
| 43 | + return createError( |
| 44 | + formatv("invalid/unsupported version number ({0})", |
| 45 | + static_cast<unsigned>(Preamble->Version.value()))); |
| 46 | + |
| 47 | + Expected<const sframe::Header<E> &> Header = |
| 48 | + getDataSliceAs<sframe::Header<E>>(Contents, 0); |
| 49 | + if (!Header) |
| 50 | + return Header.takeError(); |
| 51 | + return SFrameParser(Contents, *Header); |
| 52 | +} |
| 53 | + |
| 54 | +template class llvm::object::SFrameParser<endianness::big>; |
| 55 | +template class llvm::object::SFrameParser<endianness::little>; |
0 commit comments