xref: /llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp (revision a50ea2f76f993f65c8756067f7ad5a21e560b0c9)
1b0aa7076SWalter Erquinigo //===-- TraceCursorIntelPT.cpp --------------------------------------------===//
2b0aa7076SWalter Erquinigo //
3b0aa7076SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b0aa7076SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information.
5b0aa7076SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b0aa7076SWalter Erquinigo //
7b0aa7076SWalter Erquinigo //===----------------------------------------------------------------------===//
8b0aa7076SWalter Erquinigo 
9b0aa7076SWalter Erquinigo #include "TraceCursorIntelPT.h"
10b0aa7076SWalter Erquinigo #include "DecodedThread.h"
11b0aa7076SWalter Erquinigo #include "TraceIntelPT.h"
12b0aa7076SWalter Erquinigo #include <cstdlib>
13f190ce62SKazu Hirata #include <optional>
14b0aa7076SWalter Erquinigo 
15b0aa7076SWalter Erquinigo using namespace lldb;
16b0aa7076SWalter Erquinigo using namespace lldb_private;
17b0aa7076SWalter Erquinigo using namespace lldb_private::trace_intel_pt;
18b0aa7076SWalter Erquinigo using namespace llvm;
19b0aa7076SWalter Erquinigo 
TraceCursorIntelPT(ThreadSP thread_sp,DecodedThreadSP decoded_thread_sp,const std::optional<LinuxPerfZeroTscConversion> & tsc_conversion,std::optional<uint64_t> beginning_of_time_nanos)204f676c25SWalter Erquinigo TraceCursorIntelPT::TraceCursorIntelPT(
214f676c25SWalter Erquinigo     ThreadSP thread_sp, DecodedThreadSP decoded_thread_sp,
222fe83274SKazu Hirata     const std::optional<LinuxPerfZeroTscConversion> &tsc_conversion,
232fe83274SKazu Hirata     std::optional<uint64_t> beginning_of_time_nanos)
244f676c25SWalter Erquinigo     : TraceCursor(thread_sp), m_decoded_thread_sp(decoded_thread_sp),
254f676c25SWalter Erquinigo       m_tsc_conversion(tsc_conversion),
264f676c25SWalter Erquinigo       m_beginning_of_time_nanos(beginning_of_time_nanos) {
27f9b4ea0cSJakob Johnson   Seek(0, lldb::eTraceCursorSeekTypeEnd);
28b0aa7076SWalter Erquinigo }
29b0aa7076SWalter Erquinigo 
Next()30f91d8281SWalter Erquinigo void TraceCursorIntelPT::Next() {
31b0aa7076SWalter Erquinigo   m_pos += IsForwards() ? 1 : -1;
324f676c25SWalter Erquinigo   ClearTimingRangesIfInvalid();
334f676c25SWalter Erquinigo }
34ca922a35SAlisamar Husain 
ClearTimingRangesIfInvalid()354f676c25SWalter Erquinigo void TraceCursorIntelPT::ClearTimingRangesIfInvalid() {
364f676c25SWalter Erquinigo   if (m_tsc_range_calculated) {
374f676c25SWalter Erquinigo     if (!m_tsc_range || m_pos < 0 || !m_tsc_range->InRange(m_pos)) {
38*a50ea2f7SNicholas Mosier       m_tsc_range = std::nullopt;
394f676c25SWalter Erquinigo       m_tsc_range_calculated = false;
404f676c25SWalter Erquinigo     }
414f676c25SWalter Erquinigo   }
42ca922a35SAlisamar Husain 
434f676c25SWalter Erquinigo   if (m_nanoseconds_range_calculated) {
444f676c25SWalter Erquinigo     if (!m_nanoseconds_range || m_pos < 0 ||
454f676c25SWalter Erquinigo         !m_nanoseconds_range->InRange(m_pos)) {
46*a50ea2f7SNicholas Mosier       m_nanoseconds_range = std::nullopt;
474f676c25SWalter Erquinigo       m_nanoseconds_range_calculated = false;
484f676c25SWalter Erquinigo     }
494f676c25SWalter Erquinigo   }
504f676c25SWalter Erquinigo }
514f676c25SWalter Erquinigo 
522fe83274SKazu Hirata const std::optional<DecodedThread::TSCRange> &
GetTSCRange() const534f676c25SWalter Erquinigo TraceCursorIntelPT::GetTSCRange() const {
544f676c25SWalter Erquinigo   if (!m_tsc_range_calculated) {
554f676c25SWalter Erquinigo     m_tsc_range_calculated = true;
564f676c25SWalter Erquinigo     m_tsc_range = m_decoded_thread_sp->GetTSCRangeByIndex(m_pos);
574f676c25SWalter Erquinigo   }
584f676c25SWalter Erquinigo   return m_tsc_range;
594f676c25SWalter Erquinigo }
604f676c25SWalter Erquinigo 
612fe83274SKazu Hirata const std::optional<DecodedThread::NanosecondsRange> &
GetNanosecondsRange() const624f676c25SWalter Erquinigo TraceCursorIntelPT::GetNanosecondsRange() const {
634f676c25SWalter Erquinigo   if (!m_nanoseconds_range_calculated) {
644f676c25SWalter Erquinigo     m_nanoseconds_range_calculated = true;
654f676c25SWalter Erquinigo     m_nanoseconds_range =
664f676c25SWalter Erquinigo         m_decoded_thread_sp->GetNanosecondsRangeByIndex(m_pos);
674f676c25SWalter Erquinigo   }
684f676c25SWalter Erquinigo   return m_nanoseconds_range;
69b0aa7076SWalter Erquinigo }
70b0aa7076SWalter Erquinigo 
Seek(int64_t offset,lldb::TraceCursorSeekType origin)71f9b4ea0cSJakob Johnson bool TraceCursorIntelPT::Seek(int64_t offset,
72f9b4ea0cSJakob Johnson                               lldb::TraceCursorSeekType origin) {
73b0aa7076SWalter Erquinigo   switch (origin) {
74f9b4ea0cSJakob Johnson   case lldb::eTraceCursorSeekTypeBeginning:
75f91d8281SWalter Erquinigo     m_pos = offset;
76f91d8281SWalter Erquinigo     break;
77f9b4ea0cSJakob Johnson   case lldb::eTraceCursorSeekTypeEnd:
78a7d6c3efSWalter Erquinigo     m_pos = m_decoded_thread_sp->GetItemsCount() - 1 + offset;
79f91d8281SWalter Erquinigo     break;
80f9b4ea0cSJakob Johnson   case lldb::eTraceCursorSeekTypeCurrent:
81f91d8281SWalter Erquinigo     m_pos += offset;
82b0aa7076SWalter Erquinigo   }
834f676c25SWalter Erquinigo 
844f676c25SWalter Erquinigo   ClearTimingRangesIfInvalid();
85ca922a35SAlisamar Husain 
86f91d8281SWalter Erquinigo   return HasValue();
87f91d8281SWalter Erquinigo }
88f91d8281SWalter Erquinigo 
HasValue() const89f91d8281SWalter Erquinigo bool TraceCursorIntelPT::HasValue() const {
904f676c25SWalter Erquinigo   return m_pos >= 0 &&
914f676c25SWalter Erquinigo          static_cast<uint64_t>(m_pos) < m_decoded_thread_sp->GetItemsCount();
92b0aa7076SWalter Erquinigo }
93b0aa7076SWalter Erquinigo 
GetItemKind() const94a7d6c3efSWalter Erquinigo lldb::TraceItemKind TraceCursorIntelPT::GetItemKind() const {
95a7d6c3efSWalter Erquinigo   return m_decoded_thread_sp->GetItemKindByIndex(m_pos);
96b0aa7076SWalter Erquinigo }
97b0aa7076SWalter Erquinigo 
GetError() const984bae7066SAlex Langford llvm::StringRef TraceCursorIntelPT::GetError() const {
99a7d6c3efSWalter Erquinigo   return m_decoded_thread_sp->GetErrorByIndex(m_pos);
100b0aa7076SWalter Erquinigo }
101b0aa7076SWalter Erquinigo 
GetLoadAddress() const102a7d6c3efSWalter Erquinigo lldb::addr_t TraceCursorIntelPT::GetLoadAddress() const {
103d8499590SAlisamar Husain   return m_decoded_thread_sp->GetInstructionLoadAddress(m_pos);
104b0aa7076SWalter Erquinigo }
105b0aa7076SWalter Erquinigo 
GetHWClock() const1061da3a795SFangrui Song std::optional<uint64_t> TraceCursorIntelPT::GetHWClock() const {
1072fe83274SKazu Hirata   if (const std::optional<DecodedThread::TSCRange> &range = GetTSCRange())
1084f676c25SWalter Erquinigo     return range->tsc;
109d920ab4aSKazu Hirata   return std::nullopt;
11004195843SWalter Erquinigo }
1114f676c25SWalter Erquinigo 
GetWallClockTime() const1122fe83274SKazu Hirata std::optional<double> TraceCursorIntelPT::GetWallClockTime() const {
1132fe83274SKazu Hirata   if (const std::optional<DecodedThread::NanosecondsRange> &range =
1144f676c25SWalter Erquinigo           GetNanosecondsRange())
1154f676c25SWalter Erquinigo     return range->GetInterpolatedTime(m_pos, *m_beginning_of_time_nanos,
1164f676c25SWalter Erquinigo                                       *m_tsc_conversion);
117d920ab4aSKazu Hirata   return std::nullopt;
11822077627SJakob Johnson }
11904195843SWalter Erquinigo 
GetCPU() const120f9b4ea0cSJakob Johnson lldb::cpu_id_t TraceCursorIntelPT::GetCPU() const {
1214a843d92SWalter Erquinigo   return m_decoded_thread_sp->GetCPUByIndex(m_pos);
1224a843d92SWalter Erquinigo }
1234a843d92SWalter Erquinigo 
GetEventType() const124a7d6c3efSWalter Erquinigo lldb::TraceEvent TraceCursorIntelPT::GetEventType() const {
125a7d6c3efSWalter Erquinigo   return m_decoded_thread_sp->GetEventByIndex(m_pos);
126b0aa7076SWalter Erquinigo }
12705b4bf25SWalter Erquinigo 
GoToId(user_id_t id)12805b4bf25SWalter Erquinigo bool TraceCursorIntelPT::GoToId(user_id_t id) {
129efbfde0dSWalter Erquinigo   if (!HasId(id))
13005b4bf25SWalter Erquinigo     return false;
13105b4bf25SWalter Erquinigo   m_pos = id;
1324f676c25SWalter Erquinigo   ClearTimingRangesIfInvalid();
13305b4bf25SWalter Erquinigo   return true;
13405b4bf25SWalter Erquinigo }
13505b4bf25SWalter Erquinigo 
HasId(lldb::user_id_t id) const136efbfde0dSWalter Erquinigo bool TraceCursorIntelPT::HasId(lldb::user_id_t id) const {
1374f676c25SWalter Erquinigo   return id < m_decoded_thread_sp->GetItemsCount();
138efbfde0dSWalter Erquinigo }
139efbfde0dSWalter Erquinigo 
GetId() const14005b4bf25SWalter Erquinigo user_id_t TraceCursorIntelPT::GetId() const { return m_pos; }
141e17cae07SWalter Erquinigo 
GetSyncPointMetadata() const1421da3a795SFangrui Song std::optional<std::string> TraceCursorIntelPT::GetSyncPointMetadata() const {
143e17cae07SWalter Erquinigo   return formatv("offset = 0x{0:x}",
144e17cae07SWalter Erquinigo                  m_decoded_thread_sp->GetSyncPointOffsetByIndex(m_pos))
145e17cae07SWalter Erquinigo       .str();
146e17cae07SWalter Erquinigo }
147