1 //===- FileHeaderReader.cpp - XRay File Header Reader --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 #include "llvm/XRay/FileHeaderReader.h"
14 // Populates the FileHeader reference by reading the first 32 bytes of the file.
15 Expected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor,
16 uint32_t &OffsetPtr) {
17 // FIXME: Maybe deduce whether the data is little or big-endian using some
18 // magic bytes in the beginning of the file?
20 // First 32 bytes of the file will always be the header. We assume a certain
23 // (2) uint16 : version
25 // (4) uint32 : bitfield
26 // (8) uint64 : cycle frequency
28 XRayFileHeader FileHeader;
29 auto PreReadOffset = OffsetPtr;
30 FileHeader.Version = HeaderExtractor.getU16(&OffsetPtr);
31 if (OffsetPtr == PreReadOffset)
32 return createStringError(
33 std::make_error_code(std::errc::invalid_argument),
34 "Failed reading version from file header at offset %d.", OffsetPtr);
36 PreReadOffset = OffsetPtr;
37 FileHeader.Type = HeaderExtractor.getU16(&OffsetPtr);
38 if (OffsetPtr == PreReadOffset)
39 return createStringError(
40 std::make_error_code(std::errc::invalid_argument),
41 "Failed reading file type from file header at offset %d.", OffsetPtr);
43 PreReadOffset = OffsetPtr;
44 uint32_t Bitfield = HeaderExtractor.getU32(&OffsetPtr);
45 if (OffsetPtr == PreReadOffset)
46 return createStringError(
47 std::make_error_code(std::errc::invalid_argument),
48 "Failed reading flag bits from file header at offset %d.", OffsetPtr);
50 FileHeader.ConstantTSC = Bitfield & 1uL;
51 FileHeader.NonstopTSC = Bitfield & 1uL << 1;
52 PreReadOffset = OffsetPtr;
53 FileHeader.CycleFrequency = HeaderExtractor.getU64(&OffsetPtr);
54 if (OffsetPtr == PreReadOffset)
55 return createStringError(
56 std::make_error_code(std::errc::invalid_argument),
57 "Failed reading cycle frequency from file header at offset %d.",
60 std::memcpy(&FileHeader.FreeFormData,
61 HeaderExtractor.getData().bytes_begin() + OffsetPtr, 16);
63 // Manually advance the offset pointer 16 bytes, after getting a raw memcpy
64 // from the underlying data.
66 return std::move(FileHeader);