1//===-- xray_records.h ------------------------------------------*- C++ -*-===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of XRay, a dynamic runtime instrumentation system.
10//
11// This header exposes some record types useful for the XRay in-memory logging
12// implementation.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef XRAY_XRAY_RECORDS_H
17#define XRAY_XRAY_RECORDS_H
18
19#include <cstdint>
20
21namespace __xray {
22
23enum FileTypes {
24  NAIVE_LOG = 0,
25  FDR_LOG = 1,
26};
27
28// FDR mode use of the union field in the XRayFileHeader.
29struct alignas(16) FdrAdditionalHeaderData {
30  uint64_t ThreadBufferSize;
31};
32
33static_assert(sizeof(FdrAdditionalHeaderData) == 16,
34              "FdrAdditionalHeaderData != 16 bytes");
35
36// This data structure is used to describe the contents of the file. We use this
37// for versioning the supported XRay file formats.
38struct alignas(32) XRayFileHeader {
39  uint16_t Version = 0;
40
41  // The type of file we're writing out. See the FileTypes enum for more
42  // information. This allows different implementations of the XRay logging to
43  // have different files for different information being stored.
44  uint16_t Type = 0;
45
46  // What follows are a set of flags that indicate useful things for when
47  // reading the data in the file.
48  bool ConstantTSC : 1;
49  bool NonstopTSC : 1;
50
51  // The frequency by which TSC increases per-second.
52  alignas(8) uint64_t CycleFrequency = 0;
53
54  union {
55    char FreeForm[16];
56    // The current civiltime timestamp, as retrieved from 'clock_gettime'. This
57    // allows readers of the file to determine when the file was created or
58    // written down.
59    struct timespec TS;
60
61    struct FdrAdditionalHeaderData FdrData;
62  };
63} __attribute__((packed));
64
65static_assert(sizeof(XRayFileHeader) == 32, "XRayFileHeader != 32 bytes");
66
67enum RecordTypes {
68  NORMAL = 0,
69  ARG_PAYLOAD = 1,
70};
71
72struct alignas(32) XRayRecord {
73  // This is the type of the record being written. We use 16 bits to allow us to
74  // treat this as a discriminant, and so that the first 4 bytes get packed
75  // properly. See RecordTypes for more supported types.
76  uint16_t RecordType = RecordTypes::NORMAL;
77
78  // The CPU where the thread is running. We assume number of CPUs <= 256.
79  uint8_t CPU = 0;
80
81  // The type of the event. One of the following:
82  //   ENTER = 0
83  //   EXIT = 1
84  //   TAIL_EXIT = 2
85  //   ENTER_ARG = 3
86  uint8_t Type = 0;
87
88  // The function ID for the record.
89  int32_t FuncId = 0;
90
91  // Get the full 8 bytes of the TSC when we get the log record.
92  uint64_t TSC = 0;
93
94  // The thread ID for the currently running thread.
95  uint32_t TId = 0;
96
97  // The ID of process that is currently running
98  uint32_t PId = 0;
99
100  // Use some bytes in the end of the record for buffers.
101  char Buffer[8] = {};
102} __attribute__((packed));
103
104static_assert(sizeof(XRayRecord) == 32, "XRayRecord != 32 bytes");
105
106struct alignas(32) XRayArgPayload {
107  // We use the same 16 bits as a discriminant for the records in the log here
108  // too, and so that the first 4 bytes are packed properly.
109  uint16_t RecordType = RecordTypes::ARG_PAYLOAD;
110
111  // Add a few bytes to pad.
112  uint8_t Padding[2] = {};
113
114  // The function ID for the record.
115  int32_t FuncId = 0;
116
117  // The thread ID for the currently running thread.
118  uint32_t TId = 0;
119
120  // The ID of process that is currently running
121  uint32_t PId = 0;
122
123  // The argument payload.
124  uint64_t Arg = 0;
125
126  // The rest of this record ought to be left as padding.
127  uint8_t TailPadding[8] = {};
128} __attribute__((packed));
129
130static_assert(sizeof(XRayArgPayload) == 32, "XRayArgPayload != 32 bytes");
131
132} // namespace __xray
133
134#endif // XRAY_XRAY_RECORDS_H
135