Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
39645 views
1
//===-- TraceCursorIntelPT.cpp --------------------------------------------===//
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
#include "TraceCursorIntelPT.h"
10
#include "DecodedThread.h"
11
#include "TraceIntelPT.h"
12
#include <cstdlib>
13
#include <optional>
14
15
using namespace lldb;
16
using namespace lldb_private;
17
using namespace lldb_private::trace_intel_pt;
18
using namespace llvm;
19
20
TraceCursorIntelPT::TraceCursorIntelPT(
21
ThreadSP thread_sp, DecodedThreadSP decoded_thread_sp,
22
const std::optional<LinuxPerfZeroTscConversion> &tsc_conversion,
23
std::optional<uint64_t> beginning_of_time_nanos)
24
: TraceCursor(thread_sp), m_decoded_thread_sp(decoded_thread_sp),
25
m_tsc_conversion(tsc_conversion),
26
m_beginning_of_time_nanos(beginning_of_time_nanos) {
27
Seek(0, lldb::eTraceCursorSeekTypeEnd);
28
}
29
30
void TraceCursorIntelPT::Next() {
31
m_pos += IsForwards() ? 1 : -1;
32
ClearTimingRangesIfInvalid();
33
}
34
35
void TraceCursorIntelPT::ClearTimingRangesIfInvalid() {
36
if (m_tsc_range_calculated) {
37
if (!m_tsc_range || m_pos < 0 || !m_tsc_range->InRange(m_pos)) {
38
m_tsc_range = std::nullopt;
39
m_tsc_range_calculated = false;
40
}
41
}
42
43
if (m_nanoseconds_range_calculated) {
44
if (!m_nanoseconds_range || m_pos < 0 ||
45
!m_nanoseconds_range->InRange(m_pos)) {
46
m_nanoseconds_range = std::nullopt;
47
m_nanoseconds_range_calculated = false;
48
}
49
}
50
}
51
52
const std::optional<DecodedThread::TSCRange> &
53
TraceCursorIntelPT::GetTSCRange() const {
54
if (!m_tsc_range_calculated) {
55
m_tsc_range_calculated = true;
56
m_tsc_range = m_decoded_thread_sp->GetTSCRangeByIndex(m_pos);
57
}
58
return m_tsc_range;
59
}
60
61
const std::optional<DecodedThread::NanosecondsRange> &
62
TraceCursorIntelPT::GetNanosecondsRange() const {
63
if (!m_nanoseconds_range_calculated) {
64
m_nanoseconds_range_calculated = true;
65
m_nanoseconds_range =
66
m_decoded_thread_sp->GetNanosecondsRangeByIndex(m_pos);
67
}
68
return m_nanoseconds_range;
69
}
70
71
bool TraceCursorIntelPT::Seek(int64_t offset,
72
lldb::TraceCursorSeekType origin) {
73
switch (origin) {
74
case lldb::eTraceCursorSeekTypeBeginning:
75
m_pos = offset;
76
break;
77
case lldb::eTraceCursorSeekTypeEnd:
78
m_pos = m_decoded_thread_sp->GetItemsCount() - 1 + offset;
79
break;
80
case lldb::eTraceCursorSeekTypeCurrent:
81
m_pos += offset;
82
}
83
84
ClearTimingRangesIfInvalid();
85
86
return HasValue();
87
}
88
89
bool TraceCursorIntelPT::HasValue() const {
90
return m_pos >= 0 &&
91
static_cast<uint64_t>(m_pos) < m_decoded_thread_sp->GetItemsCount();
92
}
93
94
lldb::TraceItemKind TraceCursorIntelPT::GetItemKind() const {
95
return m_decoded_thread_sp->GetItemKindByIndex(m_pos);
96
}
97
98
llvm::StringRef TraceCursorIntelPT::GetError() const {
99
return m_decoded_thread_sp->GetErrorByIndex(m_pos);
100
}
101
102
lldb::addr_t TraceCursorIntelPT::GetLoadAddress() const {
103
return m_decoded_thread_sp->GetInstructionLoadAddress(m_pos);
104
}
105
106
std::optional<uint64_t> TraceCursorIntelPT::GetHWClock() const {
107
if (const std::optional<DecodedThread::TSCRange> &range = GetTSCRange())
108
return range->tsc;
109
return std::nullopt;
110
}
111
112
std::optional<double> TraceCursorIntelPT::GetWallClockTime() const {
113
if (const std::optional<DecodedThread::NanosecondsRange> &range =
114
GetNanosecondsRange())
115
return range->GetInterpolatedTime(m_pos, *m_beginning_of_time_nanos,
116
*m_tsc_conversion);
117
return std::nullopt;
118
}
119
120
lldb::cpu_id_t TraceCursorIntelPT::GetCPU() const {
121
return m_decoded_thread_sp->GetCPUByIndex(m_pos);
122
}
123
124
lldb::TraceEvent TraceCursorIntelPT::GetEventType() const {
125
return m_decoded_thread_sp->GetEventByIndex(m_pos);
126
}
127
128
bool TraceCursorIntelPT::GoToId(user_id_t id) {
129
if (!HasId(id))
130
return false;
131
m_pos = id;
132
ClearTimingRangesIfInvalid();
133
return true;
134
}
135
136
bool TraceCursorIntelPT::HasId(lldb::user_id_t id) const {
137
return id < m_decoded_thread_sp->GetItemsCount();
138
}
139
140
user_id_t TraceCursorIntelPT::GetId() const { return m_pos; }
141
142
std::optional<std::string> TraceCursorIntelPT::GetSyncPointMetadata() const {
143
return formatv("offset = 0x{0:x}",
144
m_decoded_thread_sp->GetSyncPointOffsetByIndex(m_pos))
145
.str();
146
}
147
148