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