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