124528c5dim//===-- xray_records.h ------------------------------------------*- C++ -*-===//
224528c5dim//
38312957dim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48312957dim// See https://llvm.org/LICENSE.txt for license information.
58312957dim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
624528c5dim//
724528c5dim//===----------------------------------------------------------------------===//
824528c5dim//
924528c5dim// This file is a part of XRay, a dynamic runtime instrumentation system.
1024528c5dim//
1124528c5dim// This header exposes some record types useful for the XRay in-memory logging
1224528c5dim// implementation.
1324528c5dim//
1424528c5dim//===----------------------------------------------------------------------===//
1524528c5dim
1624528c5dim#ifndef XRAY_XRAY_RECORDS_H
1724528c5dim#define XRAY_XRAY_RECORDS_H
1824528c5dim
19a14b3e1dim#include <cstdint>
20a14b3e1dim
2124528c5dimnamespace __xray {
2224528c5dim
2324528c5dimenum FileTypes {
2424528c5dim  NAIVE_LOG = 0,
256070792dim  FDR_LOG = 1,
2624528c5dim};
2724528c5dim
286070792dim// FDR mode use of the union field in the XRayFileHeader.
296070792dimstruct alignas(16) FdrAdditionalHeaderData {
306070792dim  uint64_t ThreadBufferSize;
316070792dim};
326070792dim
336070792dimstatic_assert(sizeof(FdrAdditionalHeaderData) == 16,
346070792dim              "FdrAdditionalHeaderData != 16 bytes");
356070792dim
3624528c5dim// This data structure is used to describe the contents of the file. We use this
3724528c5dim// for versioning the supported XRay file formats.
3824528c5dimstruct alignas(32) XRayFileHeader {
3924528c5dim  uint16_t Version = 0;
4024528c5dim
4124528c5dim  // The type of file we're writing out. See the FileTypes enum for more
4224528c5dim  // information. This allows different implementations of the XRay logging to
4324528c5dim  // have different files for different information being stored.
4424528c5dim  uint16_t Type = 0;
4524528c5dim
4624528c5dim  // What follows are a set of flags that indicate useful things for when
4724528c5dim  // reading the data in the file.
4824528c5dim  bool ConstantTSC : 1;
4924528c5dim  bool NonstopTSC : 1;
5024528c5dim
5124528c5dim  // The frequency by which TSC increases per-second.
5224528c5dim  alignas(8) uint64_t CycleFrequency = 0;
536070792dim
546070792dim  union {
556070792dim    char FreeForm[16];
569419380dim    // The current civiltime timestamp, as retrieved from 'clock_gettime'. This
576070792dim    // allows readers of the file to determine when the file was created or
586070792dim    // written down.
596070792dim    struct timespec TS;
606070792dim
616070792dim    struct FdrAdditionalHeaderData FdrData;
626070792dim  };
6324528c5dim} __attribute__((packed));
6424528c5dim
6524528c5dimstatic_assert(sizeof(XRayFileHeader) == 32, "XRayFileHeader != 32 bytes");
6624528c5dim
6724528c5dimenum RecordTypes {
6824528c5dim  NORMAL = 0,
69a14b3e1dim  ARG_PAYLOAD = 1,
7024528c5dim};
7124528c5dim
7224528c5dimstruct alignas(32) XRayRecord {
7324528c5dim  // This is the type of the record being written. We use 16 bits to allow us to
7424528c5dim  // treat this as a discriminant, and so that the first 4 bytes get packed
7524528c5dim  // properly. See RecordTypes for more supported types.
76a14b3e1dim  uint16_t RecordType = RecordTypes::NORMAL;
7724528c5dim
7824528c5dim  // The CPU where the thread is running. We assume number of CPUs <= 256.
7924528c5dim  uint8_t CPU = 0;
8024528c5dim
81a14b3e1dim  // The type of the event. One of the following:
82a14b3e1dim  //   ENTER = 0
83a14b3e1dim  //   EXIT = 1
84a14b3e1dim  //   TAIL_EXIT = 2
85a14b3e1dim  //   ENTER_ARG = 3
8624528c5dim  uint8_t Type = 0;
8724528c5dim
8824528c5dim  // The function ID for the record.
8924528c5dim  int32_t FuncId = 0;
9024528c5dim
9124528c5dim  // Get the full 8 bytes of the TSC when we get the log record.
9224528c5dim  uint64_t TSC = 0;
9324528c5dim
9424528c5dim  // The thread ID for the currently running thread.
9524528c5dim  uint32_t TId = 0;
9624528c5dim
979419380dim  // The ID of process that is currently running
989419380dim  uint32_t PId = 0;
999419380dim
10024528c5dim  // Use some bytes in the end of the record for buffers.
1019419380dim  char Buffer[8] = {};
10224528c5dim} __attribute__((packed));
10324528c5dim
10424528c5dimstatic_assert(sizeof(XRayRecord) == 32, "XRayRecord != 32 bytes");
10524528c5dim
106a14b3e1dimstruct alignas(32) XRayArgPayload {
107a14b3e1dim  // We use the same 16 bits as a discriminant for the records in the log here
108a14b3e1dim  // too, and so that the first 4 bytes are packed properly.
109a14b3e1dim  uint16_t RecordType = RecordTypes::ARG_PAYLOAD;
110a14b3e1dim
111a14b3e1dim  // Add a few bytes to pad.
112a14b3e1dim  uint8_t Padding[2] = {};
113a14b3e1dim
114a14b3e1dim  // The function ID for the record.
115a14b3e1dim  int32_t FuncId = 0;
116a14b3e1dim
117a14b3e1dim  // The thread ID for the currently running thread.
118a14b3e1dim  uint32_t TId = 0;
119a14b3e1dim
1209419380dim  // The ID of process that is currently running
1219419380dim  uint32_t PId = 0;
122a14b3e1dim
123a14b3e1dim  // The argument payload.
124a14b3e1dim  uint64_t Arg = 0;
125a14b3e1dim
126a14b3e1dim  // The rest of this record ought to be left as padding.
127a14b3e1dim  uint8_t TailPadding[8] = {};
128a14b3e1dim} __attribute__((packed));
129a14b3e1dim
130a14b3e1dimstatic_assert(sizeof(XRayArgPayload) == 32, "XRayArgPayload != 32 bytes");
131a14b3e1dim
13224528c5dim} // namespace __xray
13324528c5dim
13424528c5dim#endif // XRAY_XRAY_RECORDS_H
135