16423b502SWalter Erquinigo //===-- LibiptDecoder.h --======---------------------------------*- C++ -*-===// 26423b502SWalter Erquinigo // 36423b502SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46423b502SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information. 56423b502SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66423b502SWalter Erquinigo // 76423b502SWalter Erquinigo //===----------------------------------------------------------------------===// 86423b502SWalter Erquinigo 96423b502SWalter Erquinigo #ifndef LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 106423b502SWalter Erquinigo #define LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 116423b502SWalter Erquinigo 126423b502SWalter Erquinigo #include "DecodedThread.h" 13a19fcc2bSWalter Erquinigo #include "PerfContextSwitchDecoder.h" 146423b502SWalter Erquinigo #include "forward-declarations.h" 15a19fcc2bSWalter Erquinigo #include "intel-pt.h" 16f190ce62SKazu Hirata #include <optional> 17a19fcc2bSWalter Erquinigo 186423b502SWalter Erquinigo namespace lldb_private { 196423b502SWalter Erquinigo namespace trace_intel_pt { 206423b502SWalter Erquinigo 21e17cae07SWalter Erquinigo /// This struct represents a contiguous section of a trace that starts at a PSB 22e17cae07SWalter Erquinigo /// and ends right before the next PSB or the end of the trace. 23e17cae07SWalter Erquinigo struct PSBBlock { 24d179ea12SWalter Erquinigo /// The memory offset of a PSB packet that is a synchronization point for the 25d179ea12SWalter Erquinigo /// decoder. A decoder normally looks first for a PSB packet and then it 26d179ea12SWalter Erquinigo /// starts decoding. 27a19fcc2bSWalter Erquinigo uint64_t psb_offset; 2867c24051SWalter Erquinigo /// The timestamp associated with the PSB packet above. 29*2fe83274SKazu Hirata std::optional<uint64_t> tsc; 30e17cae07SWalter Erquinigo /// Size in bytes of this block 31e17cae07SWalter Erquinigo uint64_t size; 32e17cae07SWalter Erquinigo /// The first ip for this PSB block. 338b5c302eSKazu Hirata /// This is \a std::nullopt if tracing was disabled when the PSB block was 348b5c302eSKazu Hirata /// emitted. This means that eventually there's be an enablement event that 358b5c302eSKazu Hirata /// will come with an ip. 36*2fe83274SKazu Hirata std::optional<lldb::addr_t> starting_ip; 37a19fcc2bSWalter Erquinigo }; 38a19fcc2bSWalter Erquinigo 396a5355e8SWalter Erquinigo /// This struct represents a continuous execution of a thread in a cpu, 40a19fcc2bSWalter Erquinigo /// delimited by a context switch in and out, and a list of Intel PT subtraces 41a19fcc2bSWalter Erquinigo /// that belong to this execution. 42a19fcc2bSWalter Erquinigo struct IntelPTThreadContinousExecution { 43a19fcc2bSWalter Erquinigo ThreadContinuousExecution thread_execution; 44e17cae07SWalter Erquinigo std::vector<PSBBlock> psb_blocks; 45a19fcc2bSWalter Erquinigo IntelPTThreadContinousExecutionIntelPTThreadContinousExecution46a19fcc2bSWalter Erquinigo IntelPTThreadContinousExecution( 47a19fcc2bSWalter Erquinigo const ThreadContinuousExecution &thread_execution) 48a19fcc2bSWalter Erquinigo : thread_execution(thread_execution) {} 49a19fcc2bSWalter Erquinigo 50a19fcc2bSWalter Erquinigo /// Comparator by time 51a19fcc2bSWalter Erquinigo bool operator<(const IntelPTThreadContinousExecution &o) const; 52a19fcc2bSWalter Erquinigo }; 53a19fcc2bSWalter Erquinigo 54a7d6c3efSWalter Erquinigo /// Decode a raw Intel PT trace for a single thread given in \p buffer and 55a7d6c3efSWalter Erquinigo /// append the decoded instructions and errors in \p decoded_thread. It uses the 56a7d6c3efSWalter Erquinigo /// low level libipt library underneath. 57a7d6c3efSWalter Erquinigo /// 58a7d6c3efSWalter Erquinigo /// \return 59a7d6c3efSWalter Erquinigo /// An \a llvm::Error if the decoder couldn't be properly set up. 60a7d6c3efSWalter Erquinigo llvm::Error DecodeSingleTraceForThread(DecodedThread &decoded_thread, 61a7d6c3efSWalter Erquinigo TraceIntelPT &trace_intel_pt, 62e0cfe20aSWalter Erquinigo llvm::ArrayRef<uint8_t> buffer); 636423b502SWalter Erquinigo 64ea37cd52SWalter Erquinigo /// Decode a raw Intel PT trace for a single thread that was collected in a per 65ea37cd52SWalter Erquinigo /// cpu core basis. 6667c24051SWalter Erquinigo /// 67ea37cd52SWalter Erquinigo /// \param[out] decoded_thread 68ea37cd52SWalter Erquinigo /// All decoded instructions, errors and events will be appended to this 69ea37cd52SWalter Erquinigo /// object. 7067c24051SWalter Erquinigo /// 7167c24051SWalter Erquinigo /// \param[in] trace_intel_pt 72ea37cd52SWalter Erquinigo /// The main Trace object that contains all the information related to the 73ea37cd52SWalter Erquinigo /// trace session. 7467c24051SWalter Erquinigo /// 7567c24051SWalter Erquinigo /// \param[in] buffers 7667c24051SWalter Erquinigo /// A map from cpu core id to raw intel pt buffers. 7767c24051SWalter Erquinigo /// 7867c24051SWalter Erquinigo /// \param[in] executions 79ea37cd52SWalter Erquinigo /// A list of chunks of timed executions of the same given thread. It is used 80ea37cd52SWalter Erquinigo /// to identify if some executions have missing intel pt data and also to 81ea37cd52SWalter Erquinigo /// determine in which core a certain part of the execution ocurred. 82a7d6c3efSWalter Erquinigo /// 83a7d6c3efSWalter Erquinigo /// \return 84a7d6c3efSWalter Erquinigo /// An \a llvm::Error if the decoder couldn't be properly set up, i.e. no 85a7d6c3efSWalter Erquinigo /// instructions were attempted to be decoded. 86a7d6c3efSWalter Erquinigo llvm::Error DecodeSystemWideTraceForThread( 87a19fcc2bSWalter Erquinigo DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, 886a5355e8SWalter Erquinigo const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers, 89a19fcc2bSWalter Erquinigo const std::vector<IntelPTThreadContinousExecution> &executions); 90a19fcc2bSWalter Erquinigo 91d179ea12SWalter Erquinigo /// Given an intel pt trace, split it in chunks delimited by PSB packets. Each 92d179ea12SWalter Erquinigo /// of these chunks is guaranteed to have been executed continuously. 9367c24051SWalter Erquinigo /// 9467c24051SWalter Erquinigo /// \param[in] trace_intel_pt 95d179ea12SWalter Erquinigo /// The main Trace object that contains all the information related to the 96d179ea12SWalter Erquinigo /// trace session. 9767c24051SWalter Erquinigo /// 9867c24051SWalter Erquinigo /// \param[in] buffer 99d179ea12SWalter Erquinigo /// The intel pt buffer that belongs to a single thread or to a single cpu 100d179ea12SWalter Erquinigo /// core. 10167c24051SWalter Erquinigo /// 102e17cae07SWalter Erquinigo /// \param[in] expect_tscs 103e17cae07SWalter Erquinigo /// If \b true, an error is return if a packet without TSC is found. 104e17cae07SWalter Erquinigo /// 10567c24051SWalter Erquinigo /// \return 106d179ea12SWalter Erquinigo /// A list of continuous executions sorted by time, or an \a llvm::Error in 107d179ea12SWalter Erquinigo /// case of failures. 108e17cae07SWalter Erquinigo llvm::Expected<std::vector<PSBBlock>> 109e17cae07SWalter Erquinigo SplitTraceIntoPSBBlock(TraceIntelPT &trace_intel_pt, 110e17cae07SWalter Erquinigo llvm::ArrayRef<uint8_t> buffer, bool expect_tscs); 111a19fcc2bSWalter Erquinigo 1124f676c25SWalter Erquinigo /// Find the lowest TSC in the given trace. 1134f676c25SWalter Erquinigo /// 1144f676c25SWalter Erquinigo /// \return 115768cae4aSKazu Hirata /// The lowest TSC value in this trace if available, \a std::nullopt if the 1164f676c25SWalter Erquinigo /// trace is empty or the trace contains no timing information, or an \a 1174f676c25SWalter Erquinigo /// llvm::Error if it was not possible to set up the decoder. 118*2fe83274SKazu Hirata llvm::Expected<std::optional<uint64_t>> 1194f676c25SWalter Erquinigo FindLowestTSCInTrace(TraceIntelPT &trace_intel_pt, 1204f676c25SWalter Erquinigo llvm::ArrayRef<uint8_t> buffer); 1214f676c25SWalter Erquinigo 1226423b502SWalter Erquinigo } // namespace trace_intel_pt 1236423b502SWalter Erquinigo } // namespace lldb_private 1246423b502SWalter Erquinigo 1256423b502SWalter Erquinigo #endif // LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H 126