aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/SFrameParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object/SFrameParser.cpp')
-rw-r--r--llvm/lib/Object/SFrameParser.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/Object/SFrameParser.cpp b/llvm/lib/Object/SFrameParser.cpp
new file mode 100644
index 0000000..2d74d1d
--- /dev/null
+++ b/llvm/lib/Object/SFrameParser.cpp
@@ -0,0 +1,55 @@
+//===- SFrameParser.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/SFrameParser.h"
+#include "llvm/BinaryFormat/SFrame.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+template <typename T>
+static Expected<const T &> getDataSliceAs(ArrayRef<uint8_t> Data,
+ uint64_t Offset) {
+ static_assert(std::is_trivial_v<T>);
+ if (Data.size() < Offset + sizeof(T)) {
+ return createStringError(
+ formatv("unexpected end of data at offset {0:x} while reading [{1:x}, "
+ "{2:x})",
+ Data.size(), Offset, Offset + sizeof(T))
+ .str(),
+ object_error::unexpected_eof);
+ }
+ return *reinterpret_cast<const T *>(Data.data() + Offset);
+}
+
+template <endianness E>
+Expected<SFrameParser<E>> SFrameParser<E>::create(ArrayRef<uint8_t> Contents) {
+ Expected<const sframe::Preamble<E> &> Preamble =
+ getDataSliceAs<sframe::Preamble<E>>(Contents, 0);
+ if (!Preamble)
+ return Preamble.takeError();
+
+ if (Preamble->Magic != sframe::Magic)
+ return createError(
+ formatv("invalid magic number ({0:x+4})", Preamble->Magic.value()));
+ if (Preamble->Version != sframe::Version::V2)
+ return createError(
+ formatv("invalid/unsupported version number ({0})",
+ static_cast<unsigned>(Preamble->Version.value())));
+
+ Expected<const sframe::Header<E> &> Header =
+ getDataSliceAs<sframe::Header<E>>(Contents, 0);
+ if (!Header)
+ return Header.takeError();
+ return SFrameParser(Contents, *Header);
+}
+
+template class llvm::object::SFrameParser<endianness::big>;
+template class llvm::object::SFrameParser<endianness::little>;