1 | //===-- TraceIntelPTGDBRemotePackets.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 | #ifndef LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H |
10 | #define LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H |
11 | |
12 | #include "lldb/Utility/TraceGDBRemotePackets.h" |
13 | |
14 | #include "llvm/Support/JSON.h" |
15 | |
16 | #include <chrono> |
17 | #include <optional> |
18 | |
19 | /// See docs/lldb-gdb-remote.txt for more information. |
20 | /// |
21 | /// Do not use system-dependent types, like size_t, because they might cause |
22 | /// issues when compiling on arm. |
23 | namespace lldb_private { |
24 | |
25 | // List of data kinds used by jLLDBGetState and jLLDBGetBinaryData. |
26 | struct IntelPTDataKinds { |
27 | static const char *kProcFsCpuInfo; |
28 | static const char *kIptTrace; |
29 | static const char *kPerfContextSwitchTrace; |
30 | }; |
31 | |
32 | /// jLLDBTraceStart gdb-remote packet |
33 | /// \{ |
34 | struct TraceIntelPTStartRequest : TraceStartRequest { |
35 | /// Size in bytes to use for each thread's trace buffer. |
36 | uint64_t ipt_trace_size; |
37 | |
38 | /// Whether to enable TSC |
39 | bool enable_tsc; |
40 | |
41 | /// PSB packet period |
42 | std::optional<uint64_t> psb_period; |
43 | |
44 | /// Required when doing "process tracing". |
45 | /// |
46 | /// Limit in bytes on all the thread traces started by this "process trace" |
47 | /// instance. When a thread is about to be traced and the limit would be hit, |
48 | /// then a "tracing" stop event is triggered. |
49 | std::optional<uint64_t> process_buffer_size_limit; |
50 | |
51 | /// Whether to have a trace buffer per thread or per cpu cpu. |
52 | std::optional<bool> per_cpu_tracing; |
53 | |
54 | /// Disable the cgroup filtering that is automatically applied in per cpu |
55 | /// mode. |
56 | std::optional<bool> disable_cgroup_filtering; |
57 | |
58 | bool IsPerCpuTracing() const; |
59 | }; |
60 | |
61 | bool fromJSON(const llvm::json::Value &value, TraceIntelPTStartRequest &packet, |
62 | llvm::json::Path path); |
63 | |
64 | llvm::json::Value toJSON(const TraceIntelPTStartRequest &packet); |
65 | /// \} |
66 | |
67 | /// Helper structure to help parse long numbers that can't |
68 | /// be easily represented by a JSON number that is compatible with |
69 | /// Javascript (52 bits) or that can also be represented as hex. |
70 | /// |
71 | /// \{ |
72 | struct JSONUINT64 { |
73 | uint64_t value; |
74 | }; |
75 | |
76 | llvm::json::Value toJSON(const JSONUINT64 &uint64, bool hex); |
77 | |
78 | bool fromJSON(const llvm::json::Value &value, JSONUINT64 &uint64, |
79 | llvm::json::Path path); |
80 | /// \} |
81 | |
82 | /// jLLDBTraceGetState gdb-remote packet |
83 | /// \{ |
84 | |
85 | /// TSC to wall time conversion values defined in the Linux perf_event_open API |
86 | /// when the capibilities cap_user_time and cap_user_time_zero are set. See the |
87 | /// See the documentation of `time_zero` in |
88 | /// https://man7.org/linux/man-pages/man2/perf_event_open.2.html for more |
89 | /// information. |
90 | struct LinuxPerfZeroTscConversion { |
91 | /// Convert TSC value to nanosecond wall time. The beginning of time (0 |
92 | /// nanoseconds) is defined by the kernel at boot time and has no particularly |
93 | /// useful meaning. On the other hand, this value is constant for an entire |
94 | /// trace session. |
95 | /// See 'time_zero' section of |
96 | /// https://man7.org/linux/man-pages/man2/perf_event_open.2.html |
97 | /// |
98 | /// \param[in] tsc |
99 | /// The TSC value to be converted. |
100 | /// |
101 | /// \return |
102 | /// Nanosecond wall time. |
103 | uint64_t ToNanos(uint64_t tsc) const; |
104 | |
105 | uint64_t ToTSC(uint64_t nanos) const; |
106 | |
107 | uint32_t time_mult; |
108 | uint16_t time_shift; |
109 | JSONUINT64 time_zero; |
110 | }; |
111 | |
112 | struct TraceIntelPTGetStateResponse : TraceGetStateResponse { |
113 | /// The TSC to wall time conversion if it exists, otherwise \b nullptr. |
114 | std::optional<LinuxPerfZeroTscConversion> tsc_perf_zero_conversion; |
115 | bool using_cgroup_filtering = false; |
116 | }; |
117 | |
118 | bool fromJSON(const llvm::json::Value &value, |
119 | LinuxPerfZeroTscConversion &packet, llvm::json::Path path); |
120 | |
121 | llvm::json::Value toJSON(const LinuxPerfZeroTscConversion &packet); |
122 | |
123 | bool fromJSON(const llvm::json::Value &value, |
124 | TraceIntelPTGetStateResponse &packet, llvm::json::Path path); |
125 | |
126 | llvm::json::Value toJSON(const TraceIntelPTGetStateResponse &packet); |
127 | /// \} |
128 | |
129 | } // namespace lldb_private |
130 | |
131 | #endif // LLDB_UTILITY_TRACEINTELPTGDBREMOTEPACKETS_H |
132 | |