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