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 13 #include <cstdlib> 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(ThreadSP thread_sp, 21 DecodedThreadSP decoded_thread_sp) 22 : TraceCursor(thread_sp), m_decoded_thread_sp(decoded_thread_sp) { 23 Seek(0, SeekType::End); 24 } 25 26 void TraceCursorIntelPT::CalculateTscRange() { 27 // If we failed, then we look for the exact range 28 if (!m_tsc_range || !m_tsc_range->InRange(m_pos)) 29 m_tsc_range = m_decoded_thread_sp->CalculateTscRange( 30 m_pos, /*hit_range=*/m_tsc_range); 31 } 32 33 void TraceCursorIntelPT::Next() { 34 m_pos += IsForwards() ? 1 : -1; 35 36 // We try to go to a neighbor tsc range that might contain the current pos 37 if (m_tsc_range && !m_tsc_range->InRange(m_pos)) 38 m_tsc_range = IsForwards() ? m_tsc_range->Next() : m_tsc_range->Prev(); 39 40 // If we failed, this call will fix it 41 CalculateTscRange(); 42 } 43 44 bool TraceCursorIntelPT::Seek(int64_t offset, SeekType origin) { 45 switch (origin) { 46 case TraceCursor::SeekType::Beginning: 47 m_pos = offset; 48 break; 49 case TraceCursor::SeekType::End: 50 m_pos = m_decoded_thread_sp->GetItemsCount() - 1 + offset; 51 break; 52 case TraceCursor::SeekType::Current: 53 m_pos += offset; 54 } 55 CalculateTscRange(); 56 57 return HasValue(); 58 } 59 60 bool TraceCursorIntelPT::HasValue() const { 61 return m_pos >= 0 && m_pos < m_decoded_thread_sp->GetItemsCount(); 62 } 63 64 lldb::TraceItemKind TraceCursorIntelPT::GetItemKind() const { 65 return m_decoded_thread_sp->GetItemKindByIndex(m_pos); 66 } 67 68 const char *TraceCursorIntelPT::GetError() const { 69 return m_decoded_thread_sp->GetErrorByIndex(m_pos); 70 } 71 72 lldb::addr_t TraceCursorIntelPT::GetLoadAddress() const { 73 return m_decoded_thread_sp->GetInstructionLoadAddress(m_pos); 74 } 75 76 Optional<uint64_t> 77 TraceCursorIntelPT::GetCounter(lldb::TraceCounter counter_type) const { 78 switch (counter_type) { 79 case lldb::eTraceCounterTSC: 80 if (m_tsc_range) 81 return m_tsc_range->GetTsc(); 82 else 83 return llvm::None; 84 } 85 } 86 87 Optional<lldb::cpu_id_t> TraceCursorIntelPT::GetCPU() const { 88 return m_decoded_thread_sp->GetCPUByIndex(m_pos); 89 } 90 91 lldb::TraceEvent TraceCursorIntelPT::GetEventType() const { 92 return m_decoded_thread_sp->GetEventByIndex(m_pos); 93 } 94 95 bool TraceCursorIntelPT::GoToId(user_id_t id) { 96 if (!HasId(id)) 97 return false; 98 m_pos = id; 99 m_tsc_range = m_decoded_thread_sp->CalculateTscRange(m_pos, m_tsc_range); 100 101 return true; 102 } 103 104 bool TraceCursorIntelPT::HasId(lldb::user_id_t id) const { 105 return static_cast<int64_t>(id) < m_decoded_thread_sp->GetItemsCount(); 106 } 107 108 user_id_t TraceCursorIntelPT::GetId() const { return m_pos; } 109