FileHeaderReader.cpp revision 343171
1238106Sdes//===- FileHeaderReader.cpp - XRay File Header Reader --------------------===// 2238106Sdes// 3238106Sdes// The LLVM Compiler Infrastructure 4238106Sdes// 5238106Sdes// This file is distributed under the University of Illinois Open Source 6238106Sdes// License. See LICENSE.TXT for details. 7238106Sdes// 8238106Sdes//===----------------------------------------------------------------------===// 9238106Sdes#include "llvm/XRay/FileHeaderReader.h" 10238106Sdes 11238106Sdesnamespace llvm { 12238106Sdesnamespace xray { 13238106Sdes 14238106Sdes// Populates the FileHeader reference by reading the first 32 bytes of the file. 15238106SdesExpected<XRayFileHeader> readBinaryFormatHeader(DataExtractor &HeaderExtractor, 16238106Sdes uint32_t &OffsetPtr) { 17238106Sdes // FIXME: Maybe deduce whether the data is little or big-endian using some 18238106Sdes // magic bytes in the beginning of the file? 19238106Sdes 20238106Sdes // First 32 bytes of the file will always be the header. We assume a certain 21238106Sdes // format here: 22238106Sdes // 23238106Sdes // (2) uint16 : version 24266114Sdes // (2) uint16 : type 25266114Sdes // (4) uint32 : bitfield 26266114Sdes // (8) uint64 : cycle frequency 27266114Sdes // (16) - : padding 28266114Sdes XRayFileHeader FileHeader; 29266114Sdes auto PreReadOffset = OffsetPtr; 30266114Sdes FileHeader.Version = HeaderExtractor.getU16(&OffsetPtr); 31266114Sdes if (OffsetPtr == PreReadOffset) 32266114Sdes return createStringError( 33266114Sdes std::make_error_code(std::errc::invalid_argument), 34238106Sdes "Failed reading version from file header at offset %d.", OffsetPtr); 35238106Sdes 36238106Sdes PreReadOffset = OffsetPtr; 37238106Sdes FileHeader.Type = HeaderExtractor.getU16(&OffsetPtr); 38238106Sdes if (OffsetPtr == PreReadOffset) 39238106Sdes return createStringError( 40238106Sdes std::make_error_code(std::errc::invalid_argument), 41238106Sdes "Failed reading file type from file header at offset %d.", OffsetPtr); 42238106Sdes 43238106Sdes PreReadOffset = OffsetPtr; 44238106Sdes uint32_t Bitfield = HeaderExtractor.getU32(&OffsetPtr); 45238106Sdes if (OffsetPtr == PreReadOffset) 46368129Scy return createStringError( 47368129Scy std::make_error_code(std::errc::invalid_argument), 48368129Scy "Failed reading flag bits from file header at offset %d.", OffsetPtr); 49238106Sdes 50238106Sdes FileHeader.ConstantTSC = Bitfield & 1uL; 51238106Sdes FileHeader.NonstopTSC = Bitfield & 1uL << 1; 52266114Sdes PreReadOffset = OffsetPtr; 53356345Scy FileHeader.CycleFrequency = HeaderExtractor.getU64(&OffsetPtr); 54238106Sdes if (OffsetPtr == PreReadOffset) 55238106Sdes return createStringError( 56238106Sdes std::make_error_code(std::errc::invalid_argument), 57238106Sdes "Failed reading cycle frequency from file header at offset %d.", 58238106Sdes OffsetPtr); 59238106Sdes 60238106Sdes std::memcpy(&FileHeader.FreeFormData, 61238106Sdes HeaderExtractor.getData().bytes_begin() + OffsetPtr, 16); 62238106Sdes 63238106Sdes // Manually advance the offset pointer 16 bytes, after getting a raw memcpy 64238106Sdes // from the underlying data. 65266114Sdes OffsetPtr += 16; 66356345Scy return std::move(FileHeader); 67356345Scy} 68356345Scy 69238106Sdes} // namespace xray 70238106Sdes} // namespace llvm 71238106Sdes