181ad6265SDimitry Andric //===-- LibiptDecoder.h --======---------------------------------*- C++ -*-===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric 981ad6265SDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 1081ad6265SDimitry Andric #define LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 1181ad6265SDimitry Andric 1281ad6265SDimitry Andric #include "DecodedThread.h" 1381ad6265SDimitry Andric #include "PerfContextSwitchDecoder.h" 1481ad6265SDimitry Andric #include "forward-declarations.h" 1581ad6265SDimitry Andric 1681ad6265SDimitry Andric #include "intel-pt.h" 1781ad6265SDimitry Andric 1881ad6265SDimitry Andric namespace lldb_private { 1981ad6265SDimitry Andric namespace trace_intel_pt { 2081ad6265SDimitry Andric 2181ad6265SDimitry Andric /// This struct represents a point in the intel pt trace that the decoder can start decoding from without errors. 2281ad6265SDimitry Andric struct IntelPTThreadSubtrace { 2381ad6265SDimitry Andric /// The memory offset of a PSB packet that is a synchronization point for the decoder. A decoder normally looks first 2481ad6265SDimitry Andric /// for a PSB packet and then it starts decoding. 2581ad6265SDimitry Andric uint64_t psb_offset; 2681ad6265SDimitry Andric /// The timestamp associated with the PSB packet above. 2781ad6265SDimitry Andric uint64_t tsc; 2881ad6265SDimitry Andric }; 2981ad6265SDimitry Andric 3081ad6265SDimitry Andric /// This struct represents a continuous execution of a thread in a cpu, 3181ad6265SDimitry Andric /// delimited by a context switch in and out, and a list of Intel PT subtraces 3281ad6265SDimitry Andric /// that belong to this execution. 3381ad6265SDimitry Andric struct IntelPTThreadContinousExecution { 3481ad6265SDimitry Andric ThreadContinuousExecution thread_execution; 3581ad6265SDimitry Andric std::vector<IntelPTThreadSubtrace> intelpt_subtraces; 3681ad6265SDimitry Andric 3781ad6265SDimitry Andric IntelPTThreadContinousExecution( 3881ad6265SDimitry Andric const ThreadContinuousExecution &thread_execution) 3981ad6265SDimitry Andric : thread_execution(thread_execution) {} 4081ad6265SDimitry Andric 4181ad6265SDimitry Andric /// Comparator by time 4281ad6265SDimitry Andric bool operator<(const IntelPTThreadContinousExecution &o) const; 4381ad6265SDimitry Andric }; 4481ad6265SDimitry Andric 4581ad6265SDimitry Andric /// Decode a raw Intel PT trace for a single thread given in \p buffer and 4681ad6265SDimitry Andric /// append the decoded instructions and errors in \p decoded_thread. It uses the 4781ad6265SDimitry Andric /// low level libipt library underneath. 4881ad6265SDimitry Andric /// 4981ad6265SDimitry Andric /// \return 5081ad6265SDimitry Andric /// An \a llvm::Error if the decoder couldn't be properly set up. 5181ad6265SDimitry Andric llvm::Error DecodeSingleTraceForThread(DecodedThread &decoded_thread, 5281ad6265SDimitry Andric TraceIntelPT &trace_intel_pt, 5381ad6265SDimitry Andric llvm::ArrayRef<uint8_t> buffer); 5481ad6265SDimitry Andric 5581ad6265SDimitry Andric /// Decode a raw Intel PT trace for a single thread that was collected in a per 5681ad6265SDimitry Andric /// cpu core basis. 5781ad6265SDimitry Andric /// 5881ad6265SDimitry Andric /// \param[out] decoded_thread 5981ad6265SDimitry Andric /// All decoded instructions, errors and events will be appended to this 6081ad6265SDimitry Andric /// object. 6181ad6265SDimitry Andric /// 6281ad6265SDimitry Andric /// \param[in] trace_intel_pt 6381ad6265SDimitry Andric /// The main Trace object that contains all the information related to the 6481ad6265SDimitry Andric /// trace session. 6581ad6265SDimitry Andric /// 6681ad6265SDimitry Andric /// \param[in] buffers 6781ad6265SDimitry Andric /// A map from cpu core id to raw intel pt buffers. 6881ad6265SDimitry Andric /// 6981ad6265SDimitry Andric /// \param[in] executions 7081ad6265SDimitry Andric /// A list of chunks of timed executions of the same given thread. It is used 7181ad6265SDimitry Andric /// to identify if some executions have missing intel pt data and also to 7281ad6265SDimitry Andric /// determine in which core a certain part of the execution ocurred. 7381ad6265SDimitry Andric /// 7481ad6265SDimitry Andric /// \return 7581ad6265SDimitry Andric /// An \a llvm::Error if the decoder couldn't be properly set up, i.e. no 7681ad6265SDimitry Andric /// instructions were attempted to be decoded. 7781ad6265SDimitry Andric llvm::Error DecodeSystemWideTraceForThread( 7881ad6265SDimitry Andric DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, 7981ad6265SDimitry Andric const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers, 8081ad6265SDimitry Andric const std::vector<IntelPTThreadContinousExecution> &executions); 8181ad6265SDimitry Andric 8281ad6265SDimitry Andric /// Given an intel pt trace, split it in chunks delimited by PSB packets. Each of these chunks 8381ad6265SDimitry Andric /// is guaranteed to have been executed continuously. 8481ad6265SDimitry Andric /// 8581ad6265SDimitry Andric /// \param[in] trace_intel_pt 8681ad6265SDimitry Andric /// The main Trace object that contains all the information related to the trace session. 8781ad6265SDimitry Andric /// 8881ad6265SDimitry Andric /// \param[in] buffer 8981ad6265SDimitry Andric /// The intel pt buffer that belongs to a single thread or to a single cpu core. 9081ad6265SDimitry Andric /// 9181ad6265SDimitry Andric /// \return 9281ad6265SDimitry Andric /// A list of continuous executions sorted by time, or an \a llvm::Error in case of failures. 9381ad6265SDimitry Andric llvm::Expected<std::vector<IntelPTThreadSubtrace>> 9481ad6265SDimitry Andric SplitTraceInContinuousExecutions(TraceIntelPT &trace_intel_pt, 9581ad6265SDimitry Andric llvm::ArrayRef<uint8_t> buffer); 9681ad6265SDimitry Andric 97*972a253aSDimitry Andric /// Find the lowest TSC in the given trace. 98*972a253aSDimitry Andric /// 99*972a253aSDimitry Andric /// \return 100*972a253aSDimitry Andric /// The lowest TSC value in this trace if available, \a llvm::None if the 101*972a253aSDimitry Andric /// trace is empty or the trace contains no timing information, or an \a 102*972a253aSDimitry Andric /// llvm::Error if it was not possible to set up the decoder. 103*972a253aSDimitry Andric llvm::Expected<llvm::Optional<uint64_t>> 104*972a253aSDimitry Andric FindLowestTSCInTrace(TraceIntelPT &trace_intel_pt, 105*972a253aSDimitry Andric llvm::ArrayRef<uint8_t> buffer); 106*972a253aSDimitry Andric 10781ad6265SDimitry Andric } // namespace trace_intel_pt 10881ad6265SDimitry Andric } // namespace lldb_private 10981ad6265SDimitry Andric 11081ad6265SDimitry Andric #endif // LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 111