• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- PTDecoder.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 PTDecoder_h_
10 #define PTDecoder_h_
11 
12 // C/C++ Includes
13 #include <vector>
14 
15 #include "lldb/API/SBDebugger.h"
16 #include "lldb/API/SBError.h"
17 #include "lldb/API/SBProcess.h"
18 #include "lldb/API/SBStructuredData.h"
19 #include "lldb/API/SBTraceOptions.h"
20 #include "lldb/lldb-enumerations.h"
21 #include "lldb/lldb-types.h"
22 
23 namespace ptdecoder_private {
24 class Instruction;
25 class InstructionList;
26 class TraceOptions;
27 class Decoder;
28 } // namespace ptdecoder_private
29 
30 namespace ptdecoder {
31 
32 /// \class PTInstruction
33 /// Represents an assembly instruction containing raw
34 ///     instruction bytes, instruction address along with information
35 ///     regarding execution flow context and Intel(R) Processor Trace
36 ///     context.
37 class PTInstruction {
38 public:
39   PTInstruction() = default;
40 
41   PTInstruction(const std::shared_ptr<ptdecoder_private::Instruction> &ptr);
42 
43   ~PTInstruction();
44 
45   // Get instruction address in inferior's memory image
46   uint64_t GetInsnAddress() const;
47 
48   /// Get raw bytes of the instruction in the buffer.
49   ///
50   /// \param[out] buf
51   ///     The buffer where the raw bytes will be written. This buffer should be
52   ///     allocated by the caller of this API. Providing an unallocated buffer
53   ///     is an error. In case of errors, the content of the buffer is not
54   ///     valid.
55   ///
56   /// \param[in] size
57   ///     Number of raw bytes to be written to @buf. Atleast @size bytes of
58   ///     memory should be allocated to @buf otherwise the behaviour of the API
59   ///     is undefined. Providing 0 for this argument is an error.
60   ///
61   /// \return
62   ///     Number of bytes of the instruction actually written to @buf if API
63   ///     succeeds. In case of errors, total number of raw bytes of the
64   ///     instruction is returned.
65   size_t GetRawBytes(void *buf, size_t size) const;
66 
67   // Get error string if it represents an invalid instruction. For a valid
68   // instruction, an empty string is returned
69   std::string GetError() const;
70 
71   // Instruction was executed speculatively or not
72   bool GetSpeculative() const;
73 
74 private:
75   std::shared_ptr<ptdecoder_private::Instruction> m_opaque_sp;
76 };
77 
78 /// \class PTInstructionList
79 /// Represents a list of assembly instructions. Each instruction is of
80 ///     type PTInstruction.
81 class PTInstructionList {
82 public:
83   // Get number of instructions in the list
84   size_t GetSize() const;
85 
86   // Get instruction at index
87   PTInstruction GetInstructionAtIndex(uint32_t idx);
88 
89   void Clear();
90 
91 private:
92   friend class PTDecoder;
93 
94   void SetSP(const std::shared_ptr<ptdecoder_private::InstructionList> &ptr);
95 
96   std::shared_ptr<ptdecoder_private::InstructionList> m_opaque_sp;
97 };
98 
99 /// \class PTTraceOptions
100 /// Provides configuration options like trace type, trace buffer size,
101 ///     meta data buffer size along with other Intel(R) Processor Trace
102 ///     specific options.
103 class PTTraceOptions {
104 public:
105   lldb::TraceType GetType() const;
106 
107   uint64_t GetTraceBufferSize() const;
108 
109   uint64_t GetMetaDataBufferSize() const;
110 
111   /// Get Intel(R) Processor Trace specific configuration options (apart from
112   /// trace buffer size, meta data buffer size and TraceType) formatted as
113   /// json text i.e. {"Name":Value,"Name":Value} pairs, where "Value" is a
114   /// 64-bit unsigned integer in hex format. For "Name", please refer to
115   /// SBProcess::StartTrace API description for setting SBTraceOptions.
116   ///
117   /// \return
118   ///     A string formatted as json text {"Name":Value,"Name":Value}
119   lldb::SBStructuredData GetTraceParams(lldb::SBError &error);
120 
121 private:
122   friend class PTDecoder;
123 
124   void SetSP(const std::shared_ptr<ptdecoder_private::TraceOptions> &ptr);
125 
126   std::shared_ptr<ptdecoder_private::TraceOptions> m_opaque_sp;
127 };
128 
129 /// \class PTDecoder
130 /// This class makes use of Intel(R) Processor Trace hardware feature
131 ///     (implememted inside LLDB) to gather trace data for an inferior (being
132 ///     debugged with LLDB) to provide meaningful information out of it.
133 ///
134 ///     Currently the meaningful information comprises of the execution flow
135 ///     of the inferior (in terms of assembly instructions executed). The class
136 ///     enables user to:
137 ///     - start the trace with configuration options for a thread/process,
138 ///     - stop the trace for a thread/process,
139 ///     - get the execution flow (assembly instructions) for a thread and
140 ///     - get trace specific information for a thread
141 class PTDecoder {
142 public:
143   PTDecoder(lldb::SBDebugger &sbdebugger);
144 
145   /// Start Intel(R) Processor Trace on a thread or complete process with
146   /// Intel(R) Processor Trace specific configuration options
147   ///
148   /// \param[in] sbprocess
149   ///     A valid process on which this operation will be performed. An error is
150   ///     returned in case of an invalid process.
151   ///
152   /// \param[in] sbtraceoptions
153   ///     Contains thread id information and configuration options:
154   ///
155   ///     For tracing a single thread, provide a valid thread id. If sbprocess
156   ///     doesn't contain this thread id, error will be returned. For tracing
157   ///     complete process, set it to lldb::LLDB_INVALID_THREAD_ID
158   ///     Configuration options comprises of:
159   ///     a) trace buffer size, meta data buffer size, TraceType and
160   ///     b) All other possible Intel(R) Processor Trace specific configuration
161   ///     options (hereafter collectively referred as CUSTOM_OPTIONS), formatted
162   ///     as json text i.e. {"Name":Value,"Name":Value,..} inside
163   ///     sbtraceoptions, where "Value" should be a 64-bit unsigned integer in
164   ///     hex format. For information regarding what all configuration options
165   ///     are currently supported by LLDB and detailed information about
166   ///     CUSTOM_OPTIONS usage, please refer to SBProcess::StartTrace() API
167   ///     description. To know about all possible configuration options of
168   ///     Intel(R) Processor Trace, please refer to Intel(R) 64 and IA-32
169   ///     Architectures Software Developer's Manual.
170   ///
171   ///     TraceType should be set to lldb::TraceType::eTraceTypeProcessorTrace,
172   ///     else error is returned. To find out any other requirement to start
173   ///     tracing successfully, please refer to SBProcess::StartTrace() API
174   ///     description. LLDB's current implementation of Intel(R) Processor Trace
175   ///     feature may round off invalid values for configuration options.
176   ///     Therefore, the configuration options with which the trace was actually
177   ///     started, might be different to the ones with which trace was asked to
178   ///     be started by user. The actual used configuration options can be
179   ///     obtained from GetProcessorTraceInfo() API.
180   ///
181   /// \param[out] sberror
182   ///     An error with the failure reason if API fails. Else success.
183   void StartProcessorTrace(lldb::SBProcess &sbprocess,
184                            lldb::SBTraceOptions &sbtraceoptions,
185                            lldb::SBError &sberror);
186 
187   /// Stop Intel(R) Processor Trace on a thread or complete process.
188   ///
189   /// \param[in] sbprocess
190   ///     A valid process on which this operation will be performed. An error is
191   ///     returned in case of an invalid process.
192   ///
193   /// \param[in] tid
194   ///     Case 1: To stop tracing a single thread, provide a valid thread id. If
195   ///     sbprocess doesn't contain the thread tid, error will be returned.
196   ///     Case 2: To stop tracing complete process, use
197   ///     lldb::LLDB_INVALID_THREAD_ID.
198   ///
199   /// \param[out] sberror
200   ///     An error with the failure reason if API fails. Else success.
201   void StopProcessorTrace(lldb::SBProcess &sbprocess, lldb::SBError &sberror,
202                           lldb::tid_t tid = LLDB_INVALID_THREAD_ID);
203 
204   /// Get instruction log containing the execution flow for a thread of a
205   /// process in terms of assembly instructions executed.
206   ///
207   /// \param[in] sbprocess
208   ///     A valid process on which this operation will be performed. An error is
209   ///     returned in case of an invalid process.
210   ///
211   /// \param[in] tid
212   ///     A valid thread id of the thread for which instruction log is desired.
213   ///     If sbprocess doesn't contain the thread tid, error will be returned.
214   ///
215   /// \param[in] count
216   ///     The number of instructions requested by the user to be returned from
217   ///     the complete instruction log. Complete instruction log refers to all
218   ///     the assembly instructions obtained after decoding the complete raw
219   ///     trace data obtained from LLDB. The length of the complete instruction
220   ///     log is dependent on the trace buffer size with which processor tracing
221   ///     was started for this thread.
222   ///     The number of instructions actually returned are dependent on 'count'
223   ///     and 'offset' parameters of this API.
224   ///
225   /// \param[in] offset
226   ///     The offset in the complete instruction log from where 'count' number
227   ///     of instructions are requested by the user. offset is counted from the
228   ///     end of of this complete instruction log (which means the last executed
229   ///     instruction is at offset 0 (zero)).
230   ///
231   /// \param[out] result_list
232   ///     Depending upon 'count' and 'offset' values, list will be overwritten
233   ///     with the new instructions.
234   ///
235   /// \param[out] sberror
236   ///     An error with the failure reason if API fails. Else success.
237   void GetInstructionLogAtOffset(lldb::SBProcess &sbprocess, lldb::tid_t tid,
238                                  uint32_t offset, uint32_t count,
239                                  PTInstructionList &result_list,
240                                  lldb::SBError &sberror);
241 
242   /// Get Intel(R) Processor Trace specific information for a thread of a
243   /// process. The information contains the actual configuration options with
244   /// which the trace was started for this thread.
245   ///
246   /// \param[in] sbprocess
247   ///     A valid process on which this operation will be performed. An error is
248   ///     returned in case of an invalid process.
249   ///
250   /// \param[in] tid
251   ///     A valid thread id of the thread for which the trace specific
252   ///     information is required. If sbprocess doesn't contain the thread tid,
253   ///     an error will be returned.
254   ///
255   /// \param[out] options
256   ///     Contains actual configuration options (they may be different to the
257   ///     ones with which tracing was asked to be started for this thread during
258   ///     StartProcessorTrace() API call).
259   ///
260   /// \param[out] sberror
261   ///     An error with the failure reason if API fails. Else success.
262   void GetProcessorTraceInfo(lldb::SBProcess &sbprocess, lldb::tid_t tid,
263                              PTTraceOptions &options, lldb::SBError &sberror);
264 
265 private:
266   std::shared_ptr<ptdecoder_private::Decoder> m_opaque_sp;
267 };
268 
269 } // namespace ptdecoder
270 #endif // PTDecoder_h_
271