FileHeaderReader.cpp revision 343210
1//===- 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;
66  return std::move(FileHeader);
67}
68
69} // namespace xray
70} // namespace llvm
71