xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.h (revision 972a253a57b6f144b0e4a3e2080a2a0076ec55a0)
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