1 //===-- LibiptDecoder.h --======---------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H
10 #define LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H
12 #include "DecodedThread.h"
13 #include "PerfContextSwitchDecoder.h"
14 #include "forward-declarations.h"
18 namespace lldb_private
{
19 namespace trace_intel_pt
{
21 /// This struct represents a contiguous section of a trace that starts at a PSB
22 /// and ends right before the next PSB or the end of the trace.
24 /// The memory offset of a PSB packet that is a synchronization point for the
25 /// decoder. A decoder normally looks first for a PSB packet and then it
28 /// The timestamp associated with the PSB packet above.
29 std::optional
<uint64_t> tsc
;
30 /// Size in bytes of this block
32 /// The first ip for this PSB block.
33 /// This is \a std::nullopt if tracing was disabled when the PSB block was
34 /// emitted. This means that eventually there's be an enablement event that
35 /// will come with an ip.
36 std::optional
<lldb::addr_t
> starting_ip
;
39 /// This struct represents a continuous execution of a thread in a cpu,
40 /// delimited by a context switch in and out, and a list of Intel PT subtraces
41 /// that belong to this execution.
42 struct IntelPTThreadContinousExecution
{
43 ThreadContinuousExecution thread_execution
;
44 std::vector
<PSBBlock
> psb_blocks
;
46 IntelPTThreadContinousExecution(
47 const ThreadContinuousExecution
&thread_execution
)
48 : thread_execution(thread_execution
) {}
50 /// Comparator by time
51 bool operator<(const IntelPTThreadContinousExecution
&o
) const;
54 /// Decode a raw Intel PT trace for a single thread given in \p buffer and
55 /// append the decoded instructions and errors in \p decoded_thread. It uses the
56 /// low level libipt library underneath.
59 /// An \a llvm::Error if the decoder couldn't be properly set up.
60 llvm::Error
DecodeSingleTraceForThread(DecodedThread
&decoded_thread
,
61 TraceIntelPT
&trace_intel_pt
,
62 llvm::ArrayRef
<uint8_t> buffer
);
64 /// Decode a raw Intel PT trace for a single thread that was collected in a per
67 /// \param[out] decoded_thread
68 /// All decoded instructions, errors and events will be appended to this
71 /// \param[in] trace_intel_pt
72 /// The main Trace object that contains all the information related to the
75 /// \param[in] buffers
76 /// A map from cpu core id to raw intel pt buffers.
78 /// \param[in] executions
79 /// A list of chunks of timed executions of the same given thread. It is used
80 /// to identify if some executions have missing intel pt data and also to
81 /// determine in which core a certain part of the execution ocurred.
84 /// An \a llvm::Error if the decoder couldn't be properly set up, i.e. no
85 /// instructions were attempted to be decoded.
86 llvm::Error
DecodeSystemWideTraceForThread(
87 DecodedThread
&decoded_thread
, TraceIntelPT
&trace_intel_pt
,
88 const llvm::DenseMap
<lldb::cpu_id_t
, llvm::ArrayRef
<uint8_t>> &buffers
,
89 const std::vector
<IntelPTThreadContinousExecution
> &executions
);
91 /// Given an intel pt trace, split it in chunks delimited by PSB packets. Each
92 /// of these chunks is guaranteed to have been executed continuously.
94 /// \param[in] trace_intel_pt
95 /// The main Trace object that contains all the information related to the
99 /// The intel pt buffer that belongs to a single thread or to a single cpu
102 /// \param[in] expect_tscs
103 /// If \b true, an error is return if a packet without TSC is found.
106 /// A list of continuous executions sorted by time, or an \a llvm::Error in
107 /// case of failures.
108 llvm::Expected
<std::vector
<PSBBlock
>>
109 SplitTraceIntoPSBBlock(TraceIntelPT
&trace_intel_pt
,
110 llvm::ArrayRef
<uint8_t> buffer
, bool expect_tscs
);
112 /// Find the lowest TSC in the given trace.
115 /// The lowest TSC value in this trace if available, \a std::nullopt if the
116 /// trace is empty or the trace contains no timing information, or an \a
117 /// llvm::Error if it was not possible to set up the decoder.
118 llvm::Expected
<std::optional
<uint64_t>>
119 FindLowestTSCInTrace(TraceIntelPT
&trace_intel_pt
,
120 llvm::ArrayRef
<uint8_t> buffer
);
122 } // namespace trace_intel_pt
123 } // namespace lldb_private
125 #endif // LLDB_SOURCE_PLUGINS_TRACE_LIBIPT_DECODER_H