xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp (revision 972a253a57b6f144b0e4a3e2080a2a0076ec55a0)
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 
1081ad6265SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
1181ad6265SDimitry Andric 
1281ad6265SDimitry Andric #include "../common/ThreadPostMortemTrace.h"
1381ad6265SDimitry Andric #include "LibiptDecoder.h"
1481ad6265SDimitry Andric #include "TraceIntelPT.h"
1581ad6265SDimitry Andric 
1681ad6265SDimitry Andric #include <utility>
1781ad6265SDimitry Andric 
1881ad6265SDimitry Andric using namespace lldb;
1981ad6265SDimitry Andric using namespace lldb_private;
2081ad6265SDimitry Andric using namespace lldb_private::trace_intel_pt;
2181ad6265SDimitry Andric using namespace llvm;
2281ad6265SDimitry Andric 
2381ad6265SDimitry Andric ThreadDecoder::ThreadDecoder(const ThreadSP &thread_sp, TraceIntelPT &trace)
2481ad6265SDimitry Andric     : m_thread_sp(thread_sp), m_trace(trace) {}
2581ad6265SDimitry Andric 
26*972a253aSDimitry Andric Expected<Optional<uint64_t>> ThreadDecoder::FindLowestTSC() {
27*972a253aSDimitry Andric   Optional<uint64_t> lowest_tsc;
28*972a253aSDimitry Andric   Error err = m_trace.OnThreadBufferRead(
29*972a253aSDimitry Andric       m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) -> llvm::Error {
30*972a253aSDimitry Andric         Expected<Optional<uint64_t>> tsc = FindLowestTSCInTrace(m_trace, data);
31*972a253aSDimitry Andric         if (!tsc)
32*972a253aSDimitry Andric           return tsc.takeError();
33*972a253aSDimitry Andric         lowest_tsc = *tsc;
34*972a253aSDimitry Andric         return Error::success();
35*972a253aSDimitry Andric       });
36*972a253aSDimitry Andric   if (err)
37*972a253aSDimitry Andric     return std::move(err);
38*972a253aSDimitry Andric   return lowest_tsc;
39*972a253aSDimitry Andric }
40*972a253aSDimitry Andric 
4181ad6265SDimitry Andric Expected<DecodedThreadSP> ThreadDecoder::Decode() {
4281ad6265SDimitry Andric   if (!m_decoded_thread.hasValue()) {
4381ad6265SDimitry Andric     if (Expected<DecodedThreadSP> decoded_thread = DoDecode()) {
4481ad6265SDimitry Andric       m_decoded_thread = *decoded_thread;
4581ad6265SDimitry Andric     } else {
4681ad6265SDimitry Andric       return decoded_thread.takeError();
4781ad6265SDimitry Andric     }
4881ad6265SDimitry Andric   }
4981ad6265SDimitry Andric   return *m_decoded_thread;
5081ad6265SDimitry Andric }
5181ad6265SDimitry Andric 
5281ad6265SDimitry Andric llvm::Expected<DecodedThreadSP> ThreadDecoder::DoDecode() {
53753f127fSDimitry Andric   return m_trace.GetThreadTimer(m_thread_sp->GetID())
54753f127fSDimitry Andric       .TimeTask(
5581ad6265SDimitry Andric           "Decoding instructions", [&]() -> Expected<DecodedThreadSP> {
56*972a253aSDimitry Andric             DecodedThreadSP decoded_thread_sp = std::make_shared<DecodedThread>(
57*972a253aSDimitry Andric                 m_thread_sp, m_trace.GetPerfZeroTscConversion());
5881ad6265SDimitry Andric 
5981ad6265SDimitry Andric             Error err = m_trace.OnThreadBufferRead(
6081ad6265SDimitry Andric                 m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) {
6181ad6265SDimitry Andric                   return DecodeSingleTraceForThread(*decoded_thread_sp, m_trace,
6281ad6265SDimitry Andric                                                     data);
6381ad6265SDimitry Andric                 });
6481ad6265SDimitry Andric 
6581ad6265SDimitry Andric             if (err)
6681ad6265SDimitry Andric               return std::move(err);
6781ad6265SDimitry Andric             return decoded_thread_sp;
6881ad6265SDimitry Andric           });
6981ad6265SDimitry Andric }
70