16423b502SWalter Erquinigo //===-- ThreadDecoder.cpp --======-----------------------------------------===//
26423b502SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
36423b502SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information.
46423b502SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
56423b502SWalter Erquinigo //
66423b502SWalter Erquinigo //===----------------------------------------------------------------------===//
76423b502SWalter Erquinigo 
86423b502SWalter Erquinigo #include "ThreadDecoder.h"
96423b502SWalter Erquinigo 
106423b502SWalter Erquinigo #include "llvm/Support/MemoryBuffer.h"
116423b502SWalter Erquinigo 
126423b502SWalter Erquinigo #include "../common/ThreadPostMortemTrace.h"
136423b502SWalter Erquinigo #include "LibiptDecoder.h"
146423b502SWalter Erquinigo #include "TraceIntelPT.h"
156423b502SWalter Erquinigo 
166423b502SWalter Erquinigo #include <utility>
176423b502SWalter Erquinigo 
186423b502SWalter Erquinigo using namespace lldb;
196423b502SWalter Erquinigo using namespace lldb_private;
206423b502SWalter Erquinigo using namespace lldb_private::trace_intel_pt;
216423b502SWalter Erquinigo using namespace llvm;
226423b502SWalter Erquinigo 
23e0cfe20aSWalter Erquinigo ThreadDecoder::ThreadDecoder(const ThreadSP &thread_sp, TraceIntelPT &trace)
24e0cfe20aSWalter Erquinigo     : m_thread_sp(thread_sp), m_trace(trace) {}
256423b502SWalter Erquinigo 
266423b502SWalter Erquinigo DecodedThreadSP ThreadDecoder::Decode() {
276423b502SWalter Erquinigo   if (!m_decoded_thread.hasValue())
286423b502SWalter Erquinigo     m_decoded_thread = DoDecode();
296423b502SWalter Erquinigo   return *m_decoded_thread;
306423b502SWalter Erquinigo }
316423b502SWalter Erquinigo 
32e0cfe20aSWalter Erquinigo DecodedThreadSP ThreadDecoder::DoDecode() {
33*bdf3e7e5SWalter Erquinigo   return m_trace.GetTimer()
34*bdf3e7e5SWalter Erquinigo       .ForThread(m_thread_sp->GetID())
35*bdf3e7e5SWalter Erquinigo       .TimeTask<DecodedThreadSP>("Decoding instructions", [&]() {
366423b502SWalter Erquinigo         DecodedThreadSP decoded_thread_sp =
376423b502SWalter Erquinigo             std::make_shared<DecodedThread>(m_thread_sp);
386423b502SWalter Erquinigo 
39e0cfe20aSWalter Erquinigo         Error err = m_trace.OnThreadBufferRead(
40e0cfe20aSWalter Erquinigo             m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) {
41e0cfe20aSWalter Erquinigo               DecodeTrace(*decoded_thread_sp, m_trace, data);
42e0cfe20aSWalter Erquinigo               return Error::success();
43e0cfe20aSWalter Erquinigo             });
44*bdf3e7e5SWalter Erquinigo 
45e0cfe20aSWalter Erquinigo         if (err)
46e0cfe20aSWalter Erquinigo           decoded_thread_sp->AppendError(std::move(err));
476423b502SWalter Erquinigo         return decoded_thread_sp;
48*bdf3e7e5SWalter Erquinigo       });
496423b502SWalter Erquinigo }
50