diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
| commit | d9484dd61cc151c4f34c31e07f693fefa66316b5 (patch) | |
| tree | ab0560b3da293f1fafd3269c59692e929418f5c2 /contrib/llvm/lib/XRay/FileHeaderReader.cpp | |
| parent | 79e0962d4c3cf1f0acf359a9d69cb3ac68c414c4 (diff) | |
| parent | d8e91e46262bc44006913e6796843909f1ac7bcd (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/XRay/FileHeaderReader.cpp')
| -rw-r--r-- | contrib/llvm/lib/XRay/FileHeaderReader.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/contrib/llvm/lib/XRay/FileHeaderReader.cpp b/contrib/llvm/lib/XRay/FileHeaderReader.cpp new file mode 100644 index 000000000000..0b3fb8b6f692 --- /dev/null +++ b/contrib/llvm/lib/XRay/FileHeaderReader.cpp @@ -0,0 +1,70 @@ +//===- FileHeaderReader.cpp - XRay File Header Reader --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "llvm/XRay/FileHeaderReader.h" + +namespace llvm { +namespace xray { + +// Populates the FileHeader reference by reading the first 32 bytes of the file. +Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor, + uint32_t &OffsetPtr) { + // FIXME: Maybe deduce whether the data is little or big-endian using some + // magic bytes in the beginning of the file? + + // First 32 bytes of the file will always be the header. We assume a certain + // format here: + // + // (2) uint16 : version + // (2) uint16 : type + // (4) uint32 : bitfield + // (8) uint64 : cycle frequency + // (16) - : padding + XRayFileHeader FileHeader; + auto PreReadOffset = OffsetPtr; + FileHeader.Version = HeaderExtractor.getU16(&OffsetPtr); + if (OffsetPtr == PreReadOffset) + return createStringError( + std::make_error_code(std::errc::invalid_argument), + "Failed reading version from file header at offset %d.", OffsetPtr); + + PreReadOffset = OffsetPtr; + FileHeader.Type = HeaderExtractor.getU16(&OffsetPtr); + if (OffsetPtr == PreReadOffset) + return createStringError( + std::make_error_code(std::errc::invalid_argument), + "Failed reading file type from file header at offset %d.", OffsetPtr); + + PreReadOffset = OffsetPtr; + uint32_t Bitfield = HeaderExtractor.getU32(&OffsetPtr); + if (OffsetPtr == PreReadOffset) + return createStringError( + std::make_error_code(std::errc::invalid_argument), + "Failed reading flag bits from file header at offset %d.", OffsetPtr); + + FileHeader.ConstantTSC = Bitfield & 1uL; + FileHeader.NonstopTSC = Bitfield & 1uL << 1; + PreReadOffset = OffsetPtr; + FileHeader.CycleFrequency = HeaderExtractor.getU64(&OffsetPtr); + if (OffsetPtr == PreReadOffset) + return createStringError( + std::make_error_code(std::errc::invalid_argument), + "Failed reading cycle frequency from file header at offset %d.", + OffsetPtr); + + std::memcpy(&FileHeader.FreeFormData, + HeaderExtractor.getData().bytes_begin() + OffsetPtr, 16); + + // Manually advance the offset pointer 16 bytes, after getting a raw memcpy + // from the underlying data. + OffsetPtr += 16; + return std::move(FileHeader); +} + +} // namespace xray +} // namespace llvm |
