xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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 #include "intel-pt.h"
16*bdd1243dSDimitry Andric #include <optional>
1781ad6265SDimitry Andric 
1881ad6265SDimitry Andric namespace lldb_private {
1981ad6265SDimitry Andric namespace trace_intel_pt {
2081ad6265SDimitry Andric 
21*bdd1243dSDimitry Andric /// This struct represents a contiguous section of a trace that starts at a PSB
22*bdd1243dSDimitry Andric /// and ends right before the next PSB or the end of the trace.
23*bdd1243dSDimitry Andric struct PSBBlock {
24*bdd1243dSDimitry Andric   /// The memory offset of a PSB packet that is a synchronization point for the
25*bdd1243dSDimitry Andric   /// decoder. A decoder normally looks first for a PSB packet and then it
26*bdd1243dSDimitry Andric   /// starts decoding.
2781ad6265SDimitry Andric   uint64_t psb_offset;
2881ad6265SDimitry Andric   /// The timestamp associated with the PSB packet above.
29*bdd1243dSDimitry Andric   std::optional<uint64_t> tsc;
30*bdd1243dSDimitry Andric   /// Size in bytes of this block
31*bdd1243dSDimitry Andric   uint64_t size;
32*bdd1243dSDimitry Andric   /// The first ip for this PSB block.
33*bdd1243dSDimitry Andric   /// This is \a std::nullopt if tracing was disabled when the PSB block was
34*bdd1243dSDimitry Andric   /// emitted.  This means that eventually there's be an enablement event that
35*bdd1243dSDimitry Andric   /// will come with an ip.
36*bdd1243dSDimitry Andric   std::optional<lldb::addr_t> starting_ip;
3781ad6265SDimitry Andric };
3881ad6265SDimitry Andric 
3981ad6265SDimitry Andric /// This struct represents a continuous execution of a thread in a cpu,
4081ad6265SDimitry Andric /// delimited by a context switch in and out, and a list of Intel PT subtraces
4181ad6265SDimitry Andric /// that belong to this execution.
4281ad6265SDimitry Andric struct IntelPTThreadContinousExecution {
4381ad6265SDimitry Andric   ThreadContinuousExecution thread_execution;
44*bdd1243dSDimitry Andric   std::vector<PSBBlock> psb_blocks;
4581ad6265SDimitry Andric 
IntelPTThreadContinousExecutionIntelPTThreadContinousExecution4681ad6265SDimitry Andric   IntelPTThreadContinousExecution(
4781ad6265SDimitry Andric       const ThreadContinuousExecution &thread_execution)
4881ad6265SDimitry Andric       : thread_execution(thread_execution) {}
4981ad6265SDimitry Andric 
5081ad6265SDimitry Andric   /// Comparator by time
5181ad6265SDimitry Andric   bool operator<(const IntelPTThreadContinousExecution &o) const;
5281ad6265SDimitry Andric };
5381ad6265SDimitry Andric 
5481ad6265SDimitry Andric /// Decode a raw Intel PT trace for a single thread given in \p buffer and
5581ad6265SDimitry Andric /// append the decoded instructions and errors in \p decoded_thread. It uses the
5681ad6265SDimitry Andric /// low level libipt library underneath.
5781ad6265SDimitry Andric ///
5881ad6265SDimitry Andric /// \return
5981ad6265SDimitry Andric ///   An \a llvm::Error if the decoder couldn't be properly set up.
6081ad6265SDimitry Andric llvm::Error DecodeSingleTraceForThread(DecodedThread &decoded_thread,
6181ad6265SDimitry Andric                                        TraceIntelPT &trace_intel_pt,
6281ad6265SDimitry Andric                                        llvm::ArrayRef<uint8_t> buffer);
6381ad6265SDimitry Andric 
6481ad6265SDimitry Andric /// Decode a raw Intel PT trace for a single thread that was collected in a per
6581ad6265SDimitry Andric /// cpu core basis.
6681ad6265SDimitry Andric ///
6781ad6265SDimitry Andric /// \param[out] decoded_thread
6881ad6265SDimitry Andric ///   All decoded instructions, errors and events will be appended to this
6981ad6265SDimitry Andric ///   object.
7081ad6265SDimitry Andric ///
7181ad6265SDimitry Andric /// \param[in] trace_intel_pt
7281ad6265SDimitry Andric ///   The main Trace object that contains all the information related to the
7381ad6265SDimitry Andric ///   trace session.
7481ad6265SDimitry Andric ///
7581ad6265SDimitry Andric /// \param[in] buffers
7681ad6265SDimitry Andric ///   A map from cpu core id to raw intel pt buffers.
7781ad6265SDimitry Andric ///
7881ad6265SDimitry Andric /// \param[in] executions
7981ad6265SDimitry Andric ///   A list of chunks of timed executions of the same given thread. It is used
8081ad6265SDimitry Andric ///   to identify if some executions have missing intel pt data and also to
8181ad6265SDimitry Andric ///   determine in which core a certain part of the execution ocurred.
8281ad6265SDimitry Andric ///
8381ad6265SDimitry Andric /// \return
8481ad6265SDimitry Andric ///   An \a llvm::Error if the decoder couldn't be properly set up, i.e. no
8581ad6265SDimitry Andric ///   instructions were attempted to be decoded.
8681ad6265SDimitry Andric llvm::Error DecodeSystemWideTraceForThread(
8781ad6265SDimitry Andric     DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt,
8881ad6265SDimitry Andric     const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers,
8981ad6265SDimitry Andric     const std::vector<IntelPTThreadContinousExecution> &executions);
9081ad6265SDimitry Andric 
91*bdd1243dSDimitry Andric /// Given an intel pt trace, split it in chunks delimited by PSB packets. Each
92*bdd1243dSDimitry Andric /// of these chunks is guaranteed to have been executed continuously.
9381ad6265SDimitry Andric ///
9481ad6265SDimitry Andric /// \param[in] trace_intel_pt
95*bdd1243dSDimitry Andric ///   The main Trace object that contains all the information related to the
96*bdd1243dSDimitry Andric ///   trace session.
9781ad6265SDimitry Andric ///
9881ad6265SDimitry Andric /// \param[in] buffer
99*bdd1243dSDimitry Andric ///   The intel pt buffer that belongs to a single thread or to a single cpu
100*bdd1243dSDimitry Andric ///   core.
101*bdd1243dSDimitry Andric ///
102*bdd1243dSDimitry Andric /// \param[in] expect_tscs
103*bdd1243dSDimitry Andric ///   If \b true, an error is return if a packet without TSC is found.
10481ad6265SDimitry Andric ///
10581ad6265SDimitry Andric /// \return
106*bdd1243dSDimitry Andric ///   A list of continuous executions sorted by time, or an \a llvm::Error in
107*bdd1243dSDimitry Andric ///   case of failures.
108*bdd1243dSDimitry Andric llvm::Expected<std::vector<PSBBlock>>
109*bdd1243dSDimitry Andric SplitTraceIntoPSBBlock(TraceIntelPT &trace_intel_pt,
110*bdd1243dSDimitry Andric                        llvm::ArrayRef<uint8_t> buffer, bool expect_tscs);
11181ad6265SDimitry Andric 
112972a253aSDimitry Andric /// Find the lowest TSC in the given trace.
113972a253aSDimitry Andric ///
114972a253aSDimitry Andric /// \return
115*bdd1243dSDimitry Andric ///     The lowest TSC value in this trace if available, \a std::nullopt if the
116972a253aSDimitry Andric ///     trace is empty or the trace contains no timing information, or an \a
117972a253aSDimitry Andric ///     llvm::Error if it was not possible to set up the decoder.
118*bdd1243dSDimitry Andric llvm::Expected<std::optional<uint64_t>>
119972a253aSDimitry Andric FindLowestTSCInTrace(TraceIntelPT &trace_intel_pt,
120972a253aSDimitry Andric                      llvm::ArrayRef<uint8_t> buffer);
121972a253aSDimitry Andric 
12281ad6265SDimitry Andric } // namespace trace_intel_pt
12381ad6265SDimitry Andric } // namespace lldb_private
12481ad6265SDimitry Andric 
12581ad6265SDimitry Andric #endif // LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H
126