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 if (FileHeader
.Version
!= 1 && FileHeader
.Version
!= 2 &&
67 FileHeader
.Version
!= 3)
68 return createStringError(std::make_error_code(std::errc::invalid_argument
),
69 "Unsupported XRay file version: %d at offset %d",
70 FileHeader
.Version
, OffsetPtr
);
71 return std::move(FileHeader
);