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