1 //===-- LibiptDecoder.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_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 10 #define LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 11 12 #include "DecodedThread.h" 13 #include "PerfContextSwitchDecoder.h" 14 #include "forward-declarations.h" 15 #include "intel-pt.h" 16 #include <optional> 17 18 namespace lldb_private { 19 namespace trace_intel_pt { 20 21 /// This struct represents a contiguous section of a trace that starts at a PSB 22 /// and ends right before the next PSB or the end of the trace. 23 struct PSBBlock { 24 /// The memory offset of a PSB packet that is a synchronization point for the 25 /// decoder. A decoder normally looks first for a PSB packet and then it 26 /// starts decoding. 27 uint64_t psb_offset; 28 /// The timestamp associated with the PSB packet above. 29 std::optional<uint64_t> tsc; 30 /// Size in bytes of this block 31 uint64_t size; 32 /// The first ip for this PSB block. 33 /// This is \a std::nullopt if tracing was disabled when the PSB block was 34 /// emitted. This means that eventually there's be an enablement event that 35 /// will come with an ip. 36 std::optional<lldb::addr_t> starting_ip; 37 }; 38 39 /// This struct represents a continuous execution of a thread in a cpu, 40 /// delimited by a context switch in and out, and a list of Intel PT subtraces 41 /// that belong to this execution. 42 struct IntelPTThreadContinousExecution { 43 ThreadContinuousExecution thread_execution; 44 std::vector<PSBBlock> psb_blocks; 45 IntelPTThreadContinousExecutionIntelPTThreadContinousExecution46 IntelPTThreadContinousExecution( 47 const ThreadContinuousExecution &thread_execution) 48 : thread_execution(thread_execution) {} 49 50 /// Comparator by time 51 bool operator<(const IntelPTThreadContinousExecution &o) const; 52 }; 53 54 /// Decode a raw Intel PT trace for a single thread given in \p buffer and 55 /// append the decoded instructions and errors in \p decoded_thread. It uses the 56 /// low level libipt library underneath. 57 /// 58 /// \return 59 /// An \a llvm::Error if the decoder couldn't be properly set up. 60 llvm::Error DecodeSingleTraceForThread(DecodedThread &decoded_thread, 61 TraceIntelPT &trace_intel_pt, 62 llvm::ArrayRef<uint8_t> buffer); 63 64 /// Decode a raw Intel PT trace for a single thread that was collected in a per 65 /// cpu core basis. 66 /// 67 /// \param[out] decoded_thread 68 /// All decoded instructions, errors and events will be appended to this 69 /// object. 70 /// 71 /// \param[in] trace_intel_pt 72 /// The main Trace object that contains all the information related to the 73 /// trace session. 74 /// 75 /// \param[in] buffers 76 /// A map from cpu core id to raw intel pt buffers. 77 /// 78 /// \param[in] executions 79 /// A list of chunks of timed executions of the same given thread. It is used 80 /// to identify if some executions have missing intel pt data and also to 81 /// determine in which core a certain part of the execution ocurred. 82 /// 83 /// \return 84 /// An \a llvm::Error if the decoder couldn't be properly set up, i.e. no 85 /// instructions were attempted to be decoded. 86 llvm::Error DecodeSystemWideTraceForThread( 87 DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, 88 const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers, 89 const std::vector<IntelPTThreadContinousExecution> &executions); 90 91 /// Given an intel pt trace, split it in chunks delimited by PSB packets. Each 92 /// of these chunks is guaranteed to have been executed continuously. 93 /// 94 /// \param[in] trace_intel_pt 95 /// The main Trace object that contains all the information related to the 96 /// trace session. 97 /// 98 /// \param[in] buffer 99 /// The intel pt buffer that belongs to a single thread or to a single cpu 100 /// core. 101 /// 102 /// \param[in] expect_tscs 103 /// If \b true, an error is return if a packet without TSC is found. 104 /// 105 /// \return 106 /// A list of continuous executions sorted by time, or an \a llvm::Error in 107 /// case of failures. 108 llvm::Expected<std::vector<PSBBlock>> 109 SplitTraceIntoPSBBlock(TraceIntelPT &trace_intel_pt, 110 llvm::ArrayRef<uint8_t> buffer, bool expect_tscs); 111 112 /// Find the lowest TSC in the given trace. 113 /// 114 /// \return 115 /// The lowest TSC value in this trace if available, \a std::nullopt if the 116 /// trace is empty or the trace contains no timing information, or an \a 117 /// llvm::Error if it was not possible to set up the decoder. 118 llvm::Expected<std::optional<uint64_t>> 119 FindLowestTSCInTrace(TraceIntelPT &trace_intel_pt, 120 llvm::ArrayRef<uint8_t> buffer); 121 122 } // namespace trace_intel_pt 123 } // namespace lldb_private 124 125 #endif // LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 126