72 lines · cpp
1//===- FileHeaderReader.cpp - XRay File Header Reader --------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8#include "llvm/XRay/FileHeaderReader.h"9 10using namespace llvm;11using namespace llvm::xray;12 13// Populates the FileHeader reference by reading the first 32 bytes of the file.14Expected<XRayFileHeader>15xray::readBinaryFormatHeader(DataExtractor &HeaderExtractor,16 uint64_t &OffsetPtr) {17 // FIXME: Maybe deduce whether the data is little or big-endian using some18 // magic bytes in the beginning of the file?19 20 // First 32 bytes of the file will always be the header. We assume a certain21 // format here:22 //23 // (2) uint16 : version24 // (2) uint16 : type25 // (4) uint32 : bitfield26 // (8) uint64 : cycle frequency27 // (16) - : padding28 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 %" PRId64 ".",35 OffsetPtr);36 37 PreReadOffset = OffsetPtr;38 FileHeader.Type = HeaderExtractor.getU16(&OffsetPtr);39 if (OffsetPtr == PreReadOffset)40 return createStringError(41 std::make_error_code(std::errc::invalid_argument),42 "Failed reading file type from file header at offset %" PRId64 ".",43 OffsetPtr);44 45 PreReadOffset = OffsetPtr;46 uint32_t Bitfield = HeaderExtractor.getU32(&OffsetPtr);47 if (OffsetPtr == PreReadOffset)48 return createStringError(49 std::make_error_code(std::errc::invalid_argument),50 "Failed reading flag bits from file header at offset %" PRId64 ".",51 OffsetPtr);52 53 FileHeader.ConstantTSC = Bitfield & 1uL;54 FileHeader.NonstopTSC = Bitfield & 1uL << 1;55 PreReadOffset = OffsetPtr;56 FileHeader.CycleFrequency = HeaderExtractor.getU64(&OffsetPtr);57 if (OffsetPtr == PreReadOffset)58 return createStringError(59 std::make_error_code(std::errc::invalid_argument),60 "Failed reading cycle frequency from file header at offset %" PRId6461 ".",62 OffsetPtr);63 64 std::memcpy(&FileHeader.FreeFormData,65 HeaderExtractor.getData().bytes_begin() + OffsetPtr, 16);66 67 // Manually advance the offset pointer 16 bytes, after getting a raw memcpy68 // from the underlying data.69 OffsetPtr += 16;70 return std::move(FileHeader);71}72