]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/XRay/FileHeaderReader.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / XRay / FileHeaderReader.cpp
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
11 namespace llvm {
12 namespace xray {
13
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?
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