1*81ad6265SDimitry Andric //===-- ThreadDecoder.cpp --======-----------------------------------------===// 2*81ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3*81ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 4*81ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5*81ad6265SDimitry Andric // 6*81ad6265SDimitry Andric //===----------------------------------------------------------------------===// 7*81ad6265SDimitry Andric 8*81ad6265SDimitry Andric #include "ThreadDecoder.h" 9*81ad6265SDimitry Andric 10*81ad6265SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 11*81ad6265SDimitry Andric 12*81ad6265SDimitry Andric #include "../common/ThreadPostMortemTrace.h" 13*81ad6265SDimitry Andric #include "LibiptDecoder.h" 14*81ad6265SDimitry Andric #include "TraceIntelPT.h" 15*81ad6265SDimitry Andric 16*81ad6265SDimitry Andric #include <utility> 17*81ad6265SDimitry Andric 18*81ad6265SDimitry Andric using namespace lldb; 19*81ad6265SDimitry Andric using namespace lldb_private; 20*81ad6265SDimitry Andric using namespace lldb_private::trace_intel_pt; 21*81ad6265SDimitry Andric using namespace llvm; 22*81ad6265SDimitry Andric 23*81ad6265SDimitry Andric ThreadDecoder::ThreadDecoder(const ThreadSP &thread_sp, TraceIntelPT &trace) 24*81ad6265SDimitry Andric : m_thread_sp(thread_sp), m_trace(trace) {} 25*81ad6265SDimitry Andric 26*81ad6265SDimitry Andric Expected<DecodedThreadSP> ThreadDecoder::Decode() { 27*81ad6265SDimitry Andric if (!m_decoded_thread.hasValue()) { 28*81ad6265SDimitry Andric if (Expected<DecodedThreadSP> decoded_thread = DoDecode()) { 29*81ad6265SDimitry Andric m_decoded_thread = *decoded_thread; 30*81ad6265SDimitry Andric } else { 31*81ad6265SDimitry Andric return decoded_thread.takeError(); 32*81ad6265SDimitry Andric } 33*81ad6265SDimitry Andric } 34*81ad6265SDimitry Andric return *m_decoded_thread; 35*81ad6265SDimitry Andric } 36*81ad6265SDimitry Andric 37*81ad6265SDimitry Andric llvm::Expected<DecodedThreadSP> ThreadDecoder::DoDecode() { 38*81ad6265SDimitry Andric return m_trace.GetTimer() 39*81ad6265SDimitry Andric .ForThread(m_thread_sp->GetID()) 40*81ad6265SDimitry Andric .TimeTask<Expected<DecodedThreadSP>>( 41*81ad6265SDimitry Andric "Decoding instructions", [&]() -> Expected<DecodedThreadSP> { 42*81ad6265SDimitry Andric DecodedThreadSP decoded_thread_sp = 43*81ad6265SDimitry Andric std::make_shared<DecodedThread>(m_thread_sp); 44*81ad6265SDimitry Andric 45*81ad6265SDimitry Andric Error err = m_trace.OnThreadBufferRead( 46*81ad6265SDimitry Andric m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) { 47*81ad6265SDimitry Andric return DecodeSingleTraceForThread(*decoded_thread_sp, m_trace, 48*81ad6265SDimitry Andric data); 49*81ad6265SDimitry Andric }); 50*81ad6265SDimitry Andric 51*81ad6265SDimitry Andric if (err) 52*81ad6265SDimitry Andric return std::move(err); 53*81ad6265SDimitry Andric return decoded_thread_sp; 54*81ad6265SDimitry Andric }); 55*81ad6265SDimitry Andric } 56