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 18namespace lldb_private { 19namespace 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. 23struct 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. 42struct IntelPTThreadContinousExecution { 43 ThreadContinuousExecution thread_execution; 44 std::vector<PSBBlock> psb_blocks; 45 46 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. 60llvm::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. 86llvm::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. 108llvm::Expected<std::vector<PSBBlock>> 109SplitTraceIntoPSBBlock(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. 118llvm::Expected<std::optional<uint64_t>> 119FindLowestTSCInTrace(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