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