xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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