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