xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp (revision 753f127f3ace09432b2baeffd71a308760641a62)
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 
2681ad6265SDimitry Andric Expected<DecodedThreadSP> ThreadDecoder::Decode() {
2781ad6265SDimitry Andric   if (!m_decoded_thread.hasValue()) {
2881ad6265SDimitry Andric     if (Expected<DecodedThreadSP> decoded_thread = DoDecode()) {
2981ad6265SDimitry Andric       m_decoded_thread = *decoded_thread;
3081ad6265SDimitry Andric     } else {
3181ad6265SDimitry Andric       return decoded_thread.takeError();
3281ad6265SDimitry Andric     }
3381ad6265SDimitry Andric   }
3481ad6265SDimitry Andric   return *m_decoded_thread;
3581ad6265SDimitry Andric }
3681ad6265SDimitry Andric 
3781ad6265SDimitry Andric llvm::Expected<DecodedThreadSP> ThreadDecoder::DoDecode() {
38*753f127fSDimitry Andric   return m_trace.GetThreadTimer(m_thread_sp->GetID())
39*753f127fSDimitry Andric       .TimeTask(
4081ad6265SDimitry Andric           "Decoding instructions", [&]() -> Expected<DecodedThreadSP> {
4181ad6265SDimitry Andric             DecodedThreadSP decoded_thread_sp =
4281ad6265SDimitry Andric                 std::make_shared<DecodedThread>(m_thread_sp);
4381ad6265SDimitry Andric 
4481ad6265SDimitry Andric             Error err = m_trace.OnThreadBufferRead(
4581ad6265SDimitry Andric                 m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) {
4681ad6265SDimitry Andric                   return DecodeSingleTraceForThread(*decoded_thread_sp, m_trace,
4781ad6265SDimitry Andric                                                     data);
4881ad6265SDimitry Andric                 });
4981ad6265SDimitry Andric 
5081ad6265SDimitry Andric             if (err)
5181ad6265SDimitry Andric               return std::move(err);
5281ad6265SDimitry Andric             return decoded_thread_sp;
5381ad6265SDimitry Andric           });
5481ad6265SDimitry Andric }
55