xref: /llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.h (revision 2fe8327406050d2585d2ced910a678e28caefcf5)
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