1 //===-- LibiptDecoder.h --======---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H
10 #define LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H
11 
12 #include "DecodedThread.h"
13 #include "PerfContextSwitchDecoder.h"
14 #include "forward-declarations.h"
15 
16 #include "intel-pt.h"
17 
18 namespace lldb_private {
19 namespace trace_intel_pt {
20 
21 /// This struct represents a point in the intel pt trace that the decoder can start decoding from without errors.
22 struct IntelPTThreadSubtrace {
23   /// The memory offset of a PSB packet that is a synchronization point for the decoder. A decoder normally looks first
24   /// for a PSB packet and then it starts decoding.
25   uint64_t psb_offset;
26   /// The timestamp associated with the PSB packet above.
27   uint64_t tsc;
28 };
29 
30 /// This struct represents a continuous execution of a thread in a cpu,
31 /// delimited by a context switch in and out, and a list of Intel PT subtraces
32 /// that belong to this execution.
33 struct IntelPTThreadContinousExecution {
34   ThreadContinuousExecution thread_execution;
35   std::vector<IntelPTThreadSubtrace> intelpt_subtraces;
36 
37   IntelPTThreadContinousExecution(
38       const ThreadContinuousExecution &thread_execution)
39       : thread_execution(thread_execution) {}
40 
41   /// Comparator by time
42   bool operator<(const IntelPTThreadContinousExecution &o) const;
43 };
44 
45 /// Decode a raw Intel PT trace for a single thread given in \p buffer and
46 /// append the decoded instructions and errors in \p decoded_thread. It uses the
47 /// low level libipt library underneath.
48 ///
49 /// \return
50 ///   An \a llvm::Error if the decoder couldn't be properly set up.
51 llvm::Error DecodeSingleTraceForThread(DecodedThread &decoded_thread,
52                                        TraceIntelPT &trace_intel_pt,
53                                        llvm::ArrayRef<uint8_t> buffer);
54 
55 /// Decode a raw Intel PT trace for a single thread that was collected in a per
56 /// cpu core basis.
57 ///
58 /// \param[out] decoded_thread
59 ///   All decoded instructions, errors and events will be appended to this
60 ///   object.
61 ///
62 /// \param[in] trace_intel_pt
63 ///   The main Trace object that contains all the information related to the
64 ///   trace session.
65 ///
66 /// \param[in] buffers
67 ///   A map from cpu core id to raw intel pt buffers.
68 ///
69 /// \param[in] executions
70 ///   A list of chunks of timed executions of the same given thread. It is used
71 ///   to identify if some executions have missing intel pt data and also to
72 ///   determine in which core a certain part of the execution ocurred.
73 ///
74 /// \return
75 ///   An \a llvm::Error if the decoder couldn't be properly set up, i.e. no
76 ///   instructions were attempted to be decoded.
77 llvm::Error DecodeSystemWideTraceForThread(
78     DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt,
79     const llvm::DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers,
80     const std::vector<IntelPTThreadContinousExecution> &executions);
81 
82 /// Given an intel pt trace, split it in chunks delimited by PSB packets. Each of these chunks
83 /// is guaranteed to have been executed continuously.
84 ///
85 /// \param[in] trace_intel_pt
86 ///   The main Trace object that contains all the information related to the trace session.
87 ///
88 /// \param[in] buffer
89 ///   The intel pt buffer that belongs to a single thread or to a single cpu core.
90 ///
91 /// \return
92 ///   A list of continuous executions sorted by time, or an \a llvm::Error in case of failures.
93 llvm::Expected<std::vector<IntelPTThreadSubtrace>>
94 SplitTraceInContinuousExecutions(TraceIntelPT &trace_intel_pt,
95                                  llvm::ArrayRef<uint8_t> buffer);
96 
97 /// Find the lowest TSC in the given trace.
98 ///
99 /// \return
100 ///     The lowest TSC value in this trace if available, \a llvm::None if the
101 ///     trace is empty or the trace contains no timing information, or an \a
102 ///     llvm::Error if it was not possible to set up the decoder.
103 llvm::Expected<llvm::Optional<uint64_t>>
104 FindLowestTSCInTrace(TraceIntelPT &trace_intel_pt,
105                      llvm::ArrayRef<uint8_t> buffer);
106 
107 } // namespace trace_intel_pt
108 } // namespace lldb_private
109 
110 #endif // LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H
111