xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
181ad6265SDimitry Andric //===-- ThreadDecoder.cpp --======-----------------------------------------===//
281ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
381ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
481ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
581ad6265SDimitry Andric //
681ad6265SDimitry Andric //===----------------------------------------------------------------------===//
781ad6265SDimitry Andric 
881ad6265SDimitry Andric #include "ThreadDecoder.h"
981ad6265SDimitry Andric #include "../common/ThreadPostMortemTrace.h"
1081ad6265SDimitry Andric #include "LibiptDecoder.h"
1181ad6265SDimitry Andric #include "TraceIntelPT.h"
12*bdd1243dSDimitry Andric #include "llvm/Support/MemoryBuffer.h"
13*bdd1243dSDimitry Andric #include <optional>
1481ad6265SDimitry Andric #include <utility>
1581ad6265SDimitry Andric 
1681ad6265SDimitry Andric using namespace lldb;
1781ad6265SDimitry Andric using namespace lldb_private;
1881ad6265SDimitry Andric using namespace lldb_private::trace_intel_pt;
1981ad6265SDimitry Andric using namespace llvm;
2081ad6265SDimitry Andric 
ThreadDecoder(const ThreadSP & thread_sp,TraceIntelPT & trace)2181ad6265SDimitry Andric ThreadDecoder::ThreadDecoder(const ThreadSP &thread_sp, TraceIntelPT &trace)
2281ad6265SDimitry Andric     : m_thread_sp(thread_sp), m_trace(trace) {}
2381ad6265SDimitry Andric 
FindLowestTSC()24*bdd1243dSDimitry Andric Expected<std::optional<uint64_t>> ThreadDecoder::FindLowestTSC() {
25*bdd1243dSDimitry Andric   std::optional<uint64_t> lowest_tsc;
26972a253aSDimitry Andric   Error err = m_trace.OnThreadBufferRead(
27972a253aSDimitry Andric       m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) -> llvm::Error {
28*bdd1243dSDimitry Andric         Expected<std::optional<uint64_t>> tsc =
29*bdd1243dSDimitry Andric             FindLowestTSCInTrace(m_trace, data);
30972a253aSDimitry Andric         if (!tsc)
31972a253aSDimitry Andric           return tsc.takeError();
32972a253aSDimitry Andric         lowest_tsc = *tsc;
33972a253aSDimitry Andric         return Error::success();
34972a253aSDimitry Andric       });
35972a253aSDimitry Andric   if (err)
36972a253aSDimitry Andric     return std::move(err);
37972a253aSDimitry Andric   return lowest_tsc;
38972a253aSDimitry Andric }
39972a253aSDimitry Andric 
Decode()4081ad6265SDimitry Andric Expected<DecodedThreadSP> ThreadDecoder::Decode() {
41*bdd1243dSDimitry Andric   if (!m_decoded_thread.has_value()) {
4281ad6265SDimitry Andric     if (Expected<DecodedThreadSP> decoded_thread = DoDecode()) {
4381ad6265SDimitry Andric       m_decoded_thread = *decoded_thread;
4481ad6265SDimitry Andric     } else {
4581ad6265SDimitry Andric       return decoded_thread.takeError();
4681ad6265SDimitry Andric     }
4781ad6265SDimitry Andric   }
4881ad6265SDimitry Andric   return *m_decoded_thread;
4981ad6265SDimitry Andric }
5081ad6265SDimitry Andric 
DoDecode()5181ad6265SDimitry Andric llvm::Expected<DecodedThreadSP> ThreadDecoder::DoDecode() {
52753f127fSDimitry Andric   return m_trace.GetThreadTimer(m_thread_sp->GetID())
53*bdd1243dSDimitry Andric       .TimeTask("Decoding instructions", [&]() -> Expected<DecodedThreadSP> {
54972a253aSDimitry Andric         DecodedThreadSP decoded_thread_sp = std::make_shared<DecodedThread>(
55972a253aSDimitry Andric             m_thread_sp, m_trace.GetPerfZeroTscConversion());
5681ad6265SDimitry Andric 
5781ad6265SDimitry Andric         Error err = m_trace.OnThreadBufferRead(
5881ad6265SDimitry Andric             m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) {
5981ad6265SDimitry Andric               return DecodeSingleTraceForThread(*decoded_thread_sp, m_trace,
6081ad6265SDimitry Andric                                                 data);
6181ad6265SDimitry Andric             });
6281ad6265SDimitry Andric 
6381ad6265SDimitry Andric         if (err)
6481ad6265SDimitry Andric           return std::move(err);
6581ad6265SDimitry Andric         return decoded_thread_sp;
6681ad6265SDimitry Andric       });
6781ad6265SDimitry Andric }
68