blob: 0b3fb8b6f692db919c4ad96134812949f9cceb0a [file] [log] [blame]
Dean Michael Berrisb1801712018-08-22 07:37:55 +00001//===- FileHeaderReader.cpp - XRay File Header Reader --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "llvm/XRay/FileHeaderReader.h"
10
11namespace llvm {
12namespace xray {
13
14// Populates the FileHeader reference by reading the first 32 bytes of the file.
15Expected<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?
19
20 // First 32 bytes of the file will always be the header. We assume a certain
21 // format here:
22 //
23 // (2) uint16 : version
24 // (2) uint16 : type
25 // (4) uint32 : bitfield
26 // (8) uint64 : cycle frequency
27 // (16) - : padding
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);
35
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);
42
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);
49
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.",
58 OffsetPtr);
59
60 std::memcpy(&FileHeader.FreeFormData,
61 HeaderExtractor.getData().bytes_begin() + OffsetPtr, 16);
62
63 // Manually advance the offset pointer 16 bytes, after getting a raw memcpy
64 // from the underlying data.
65 OffsetPtr += 16;
Dean Michael Berrisb1801712018-08-22 07:37:55 +000066 return std::move(FileHeader);
67}
68
69} // namespace xray
70} // namespace llvm