xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1*f6aab3d8Srobert //===-- ScriptedThread.cpp ------------------------------------------------===//
2*f6aab3d8Srobert //
3*f6aab3d8Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*f6aab3d8Srobert // See https://llvm.org/LICENSE.txt for license information.
5*f6aab3d8Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*f6aab3d8Srobert //
7*f6aab3d8Srobert //===----------------------------------------------------------------------===//
8*f6aab3d8Srobert 
9*f6aab3d8Srobert #include "ScriptedThread.h"
10*f6aab3d8Srobert 
11*f6aab3d8Srobert #include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
12*f6aab3d8Srobert #include "Plugins/Process/Utility/StopInfoMachException.h"
13*f6aab3d8Srobert #include "lldb/Target/OperatingSystem.h"
14*f6aab3d8Srobert #include "lldb/Target/Process.h"
15*f6aab3d8Srobert #include "lldb/Target/RegisterContext.h"
16*f6aab3d8Srobert #include "lldb/Target/StopInfo.h"
17*f6aab3d8Srobert #include "lldb/Target/Unwind.h"
18*f6aab3d8Srobert #include "lldb/Utility/DataBufferHeap.h"
19*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
20*f6aab3d8Srobert #include <memory>
21*f6aab3d8Srobert #include <optional>
22*f6aab3d8Srobert 
23*f6aab3d8Srobert using namespace lldb;
24*f6aab3d8Srobert using namespace lldb_private;
25*f6aab3d8Srobert 
CheckInterpreterAndScriptObject() const26*f6aab3d8Srobert void ScriptedThread::CheckInterpreterAndScriptObject() const {
27*f6aab3d8Srobert   lldbassert(m_script_object_sp && "Invalid Script Object.");
28*f6aab3d8Srobert   lldbassert(GetInterface() && "Invalid Scripted Thread Interface.");
29*f6aab3d8Srobert }
30*f6aab3d8Srobert 
31*f6aab3d8Srobert llvm::Expected<std::shared_ptr<ScriptedThread>>
Create(ScriptedProcess & process,StructuredData::Generic * script_object)32*f6aab3d8Srobert ScriptedThread::Create(ScriptedProcess &process,
33*f6aab3d8Srobert                        StructuredData::Generic *script_object) {
34*f6aab3d8Srobert   if (!process.IsValid())
35*f6aab3d8Srobert     return llvm::createStringError(llvm::inconvertibleErrorCode(),
36*f6aab3d8Srobert                                    "Invalid scripted process.");
37*f6aab3d8Srobert 
38*f6aab3d8Srobert   process.CheckInterpreterAndScriptObject();
39*f6aab3d8Srobert 
40*f6aab3d8Srobert   auto scripted_thread_interface =
41*f6aab3d8Srobert       process.GetInterface().CreateScriptedThreadInterface();
42*f6aab3d8Srobert   if (!scripted_thread_interface)
43*f6aab3d8Srobert     return llvm::createStringError(
44*f6aab3d8Srobert         llvm::inconvertibleErrorCode(),
45*f6aab3d8Srobert         "Failed to create scripted thread interface.");
46*f6aab3d8Srobert 
47*f6aab3d8Srobert   llvm::StringRef thread_class_name;
48*f6aab3d8Srobert   if (!script_object) {
49*f6aab3d8Srobert     std::optional<std::string> class_name =
50*f6aab3d8Srobert         process.GetInterface().GetScriptedThreadPluginName();
51*f6aab3d8Srobert     if (!class_name || class_name->empty())
52*f6aab3d8Srobert       return llvm::createStringError(
53*f6aab3d8Srobert           llvm::inconvertibleErrorCode(),
54*f6aab3d8Srobert           "Failed to get scripted thread class name.");
55*f6aab3d8Srobert     thread_class_name = *class_name;
56*f6aab3d8Srobert   }
57*f6aab3d8Srobert 
58*f6aab3d8Srobert   ExecutionContext exe_ctx(process);
59*f6aab3d8Srobert   StructuredData::GenericSP owned_script_object_sp =
60*f6aab3d8Srobert       scripted_thread_interface->CreatePluginObject(
61*f6aab3d8Srobert           thread_class_name, exe_ctx, process.m_scripted_metadata.GetArgsSP(),
62*f6aab3d8Srobert           script_object);
63*f6aab3d8Srobert 
64*f6aab3d8Srobert   if (!owned_script_object_sp)
65*f6aab3d8Srobert     return llvm::createStringError(llvm::inconvertibleErrorCode(),
66*f6aab3d8Srobert                                    "Failed to create script object.");
67*f6aab3d8Srobert   if (!owned_script_object_sp->IsValid())
68*f6aab3d8Srobert     return llvm::createStringError(llvm::inconvertibleErrorCode(),
69*f6aab3d8Srobert                                    "Created script object is invalid.");
70*f6aab3d8Srobert 
71*f6aab3d8Srobert   lldb::tid_t tid = scripted_thread_interface->GetThreadID();
72*f6aab3d8Srobert 
73*f6aab3d8Srobert   return std::make_shared<ScriptedThread>(process, scripted_thread_interface,
74*f6aab3d8Srobert                                           tid, owned_script_object_sp);
75*f6aab3d8Srobert }
76*f6aab3d8Srobert 
ScriptedThread(ScriptedProcess & process,ScriptedThreadInterfaceSP interface_sp,lldb::tid_t tid,StructuredData::GenericSP script_object_sp)77*f6aab3d8Srobert ScriptedThread::ScriptedThread(ScriptedProcess &process,
78*f6aab3d8Srobert                                ScriptedThreadInterfaceSP interface_sp,
79*f6aab3d8Srobert                                lldb::tid_t tid,
80*f6aab3d8Srobert                                StructuredData::GenericSP script_object_sp)
81*f6aab3d8Srobert     : Thread(process, tid), m_scripted_process(process),
82*f6aab3d8Srobert       m_scripted_thread_interface_sp(interface_sp),
83*f6aab3d8Srobert       m_script_object_sp(script_object_sp) {}
84*f6aab3d8Srobert 
~ScriptedThread()85*f6aab3d8Srobert ScriptedThread::~ScriptedThread() { DestroyThread(); }
86*f6aab3d8Srobert 
GetName()87*f6aab3d8Srobert const char *ScriptedThread::GetName() {
88*f6aab3d8Srobert   CheckInterpreterAndScriptObject();
89*f6aab3d8Srobert   std::optional<std::string> thread_name = GetInterface()->GetName();
90*f6aab3d8Srobert   if (!thread_name)
91*f6aab3d8Srobert     return nullptr;
92*f6aab3d8Srobert   return ConstString(thread_name->c_str()).AsCString();
93*f6aab3d8Srobert }
94*f6aab3d8Srobert 
GetQueueName()95*f6aab3d8Srobert const char *ScriptedThread::GetQueueName() {
96*f6aab3d8Srobert   CheckInterpreterAndScriptObject();
97*f6aab3d8Srobert   std::optional<std::string> queue_name = GetInterface()->GetQueue();
98*f6aab3d8Srobert   if (!queue_name)
99*f6aab3d8Srobert     return nullptr;
100*f6aab3d8Srobert   return ConstString(queue_name->c_str()).AsCString();
101*f6aab3d8Srobert }
102*f6aab3d8Srobert 
WillResume(StateType resume_state)103*f6aab3d8Srobert void ScriptedThread::WillResume(StateType resume_state) {}
104*f6aab3d8Srobert 
ClearStackFrames()105*f6aab3d8Srobert void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); }
106*f6aab3d8Srobert 
GetRegisterContext()107*f6aab3d8Srobert RegisterContextSP ScriptedThread::GetRegisterContext() {
108*f6aab3d8Srobert   if (!m_reg_context_sp)
109*f6aab3d8Srobert     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
110*f6aab3d8Srobert   return m_reg_context_sp;
111*f6aab3d8Srobert }
112*f6aab3d8Srobert 
113*f6aab3d8Srobert RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)114*f6aab3d8Srobert ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) {
115*f6aab3d8Srobert   const uint32_t concrete_frame_idx =
116*f6aab3d8Srobert       frame ? frame->GetConcreteFrameIndex() : 0;
117*f6aab3d8Srobert 
118*f6aab3d8Srobert   if (concrete_frame_idx)
119*f6aab3d8Srobert     return GetUnwinder().CreateRegisterContextForFrame(frame);
120*f6aab3d8Srobert 
121*f6aab3d8Srobert   lldb::RegisterContextSP reg_ctx_sp;
122*f6aab3d8Srobert   Status error;
123*f6aab3d8Srobert 
124*f6aab3d8Srobert   std::optional<std::string> reg_data = GetInterface()->GetRegisterContext();
125*f6aab3d8Srobert   if (!reg_data)
126*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
127*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.",
128*f6aab3d8Srobert         error, LLDBLog::Thread);
129*f6aab3d8Srobert 
130*f6aab3d8Srobert   DataBufferSP data_sp(
131*f6aab3d8Srobert       std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));
132*f6aab3d8Srobert 
133*f6aab3d8Srobert   if (!data_sp->GetByteSize())
134*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
135*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error,
136*f6aab3d8Srobert         LLDBLog::Thread);
137*f6aab3d8Srobert 
138*f6aab3d8Srobert   std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
139*f6aab3d8Srobert       std::make_shared<RegisterContextMemory>(
140*f6aab3d8Srobert           *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS);
141*f6aab3d8Srobert   if (!reg_ctx_memory)
142*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
143*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error,
144*f6aab3d8Srobert         LLDBLog::Thread);
145*f6aab3d8Srobert 
146*f6aab3d8Srobert   reg_ctx_memory->SetAllRegisterData(data_sp);
147*f6aab3d8Srobert   m_reg_context_sp = reg_ctx_memory;
148*f6aab3d8Srobert 
149*f6aab3d8Srobert   return m_reg_context_sp;
150*f6aab3d8Srobert }
151*f6aab3d8Srobert 
LoadArtificialStackFrames()152*f6aab3d8Srobert bool ScriptedThread::LoadArtificialStackFrames() {
153*f6aab3d8Srobert   StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames();
154*f6aab3d8Srobert 
155*f6aab3d8Srobert   Status error;
156*f6aab3d8Srobert   if (!arr_sp)
157*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<bool>(
158*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.",
159*f6aab3d8Srobert         error, LLDBLog::Thread);
160*f6aab3d8Srobert 
161*f6aab3d8Srobert   size_t arr_size = arr_sp->GetSize();
162*f6aab3d8Srobert   if (arr_size > std::numeric_limits<uint32_t>::max())
163*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<bool>(
164*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION,
165*f6aab3d8Srobert         llvm::Twine(
166*f6aab3d8Srobert             "StackFrame array size (" + llvm::Twine(arr_size) +
167*f6aab3d8Srobert             llvm::Twine(
168*f6aab3d8Srobert                 ") is greater than maximum authorized for a StackFrameList."))
169*f6aab3d8Srobert             .str(),
170*f6aab3d8Srobert         error, LLDBLog::Thread);
171*f6aab3d8Srobert 
172*f6aab3d8Srobert   StackFrameListSP frames = GetStackFrameList();
173*f6aab3d8Srobert 
174*f6aab3d8Srobert   for (size_t idx = 0; idx < arr_size; idx++) {
175*f6aab3d8Srobert     StructuredData::Dictionary *dict;
176*f6aab3d8Srobert     if (!arr_sp->GetItemAtIndexAsDictionary(idx, dict) || !dict)
177*f6aab3d8Srobert       return ScriptedInterface::ErrorWithMessage<bool>(
178*f6aab3d8Srobert           LLVM_PRETTY_FUNCTION,
179*f6aab3d8Srobert           llvm::Twine(
180*f6aab3d8Srobert               "Couldn't get artificial stackframe dictionary at index (" +
181*f6aab3d8Srobert               llvm::Twine(idx) + llvm::Twine(") from stackframe array."))
182*f6aab3d8Srobert               .str(),
183*f6aab3d8Srobert           error, LLDBLog::Thread);
184*f6aab3d8Srobert 
185*f6aab3d8Srobert     lldb::addr_t pc;
186*f6aab3d8Srobert     if (!dict->GetValueForKeyAsInteger("pc", pc))
187*f6aab3d8Srobert       return ScriptedInterface::ErrorWithMessage<bool>(
188*f6aab3d8Srobert           LLVM_PRETTY_FUNCTION,
189*f6aab3d8Srobert           "Couldn't find value for key 'pc' in stackframe dictionary.", error,
190*f6aab3d8Srobert           LLDBLog::Thread);
191*f6aab3d8Srobert 
192*f6aab3d8Srobert     Address symbol_addr;
193*f6aab3d8Srobert     symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget());
194*f6aab3d8Srobert 
195*f6aab3d8Srobert     lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
196*f6aab3d8Srobert     bool cfa_is_valid = false;
197*f6aab3d8Srobert     const bool behaves_like_zeroth_frame = false;
198*f6aab3d8Srobert     SymbolContext sc;
199*f6aab3d8Srobert     symbol_addr.CalculateSymbolContext(&sc);
200*f6aab3d8Srobert 
201*f6aab3d8Srobert     StackFrameSP synth_frame_sp = std::make_shared<StackFrame>(
202*f6aab3d8Srobert         this->shared_from_this(), idx, idx, cfa, cfa_is_valid, pc,
203*f6aab3d8Srobert         StackFrame::Kind::Artificial, behaves_like_zeroth_frame, &sc);
204*f6aab3d8Srobert 
205*f6aab3d8Srobert     if (!frames->SetFrameAtIndex(static_cast<uint32_t>(idx), synth_frame_sp))
206*f6aab3d8Srobert       return ScriptedInterface::ErrorWithMessage<bool>(
207*f6aab3d8Srobert           LLVM_PRETTY_FUNCTION,
208*f6aab3d8Srobert           llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) +
209*f6aab3d8Srobert                       llvm::Twine(") to ScriptedThread StackFrameList."))
210*f6aab3d8Srobert               .str(),
211*f6aab3d8Srobert           error, LLDBLog::Thread);
212*f6aab3d8Srobert   }
213*f6aab3d8Srobert 
214*f6aab3d8Srobert   return true;
215*f6aab3d8Srobert }
216*f6aab3d8Srobert 
CalculateStopInfo()217*f6aab3d8Srobert bool ScriptedThread::CalculateStopInfo() {
218*f6aab3d8Srobert   StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason();
219*f6aab3d8Srobert 
220*f6aab3d8Srobert   Status error;
221*f6aab3d8Srobert   if (!dict_sp)
222*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<bool>(
223*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
224*f6aab3d8Srobert         LLDBLog::Thread);
225*f6aab3d8Srobert 
226*f6aab3d8Srobert   lldb::StopInfoSP stop_info_sp;
227*f6aab3d8Srobert   lldb::StopReason stop_reason_type;
228*f6aab3d8Srobert 
229*f6aab3d8Srobert   if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type))
230*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<bool>(
231*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION,
232*f6aab3d8Srobert         "Couldn't find value for key 'type' in stop reason dictionary.", error,
233*f6aab3d8Srobert         LLDBLog::Thread);
234*f6aab3d8Srobert 
235*f6aab3d8Srobert   StructuredData::Dictionary *data_dict;
236*f6aab3d8Srobert   if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict))
237*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<bool>(
238*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION,
239*f6aab3d8Srobert         "Couldn't find value for key 'data' in stop reason dictionary.", error,
240*f6aab3d8Srobert         LLDBLog::Thread);
241*f6aab3d8Srobert 
242*f6aab3d8Srobert   switch (stop_reason_type) {
243*f6aab3d8Srobert   case lldb::eStopReasonNone:
244*f6aab3d8Srobert     return true;
245*f6aab3d8Srobert   case lldb::eStopReasonBreakpoint: {
246*f6aab3d8Srobert     lldb::break_id_t break_id;
247*f6aab3d8Srobert     data_dict->GetValueForKeyAsInteger("break_id", break_id,
248*f6aab3d8Srobert                                        LLDB_INVALID_BREAK_ID);
249*f6aab3d8Srobert     stop_info_sp =
250*f6aab3d8Srobert         StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id);
251*f6aab3d8Srobert   } break;
252*f6aab3d8Srobert   case lldb::eStopReasonSignal: {
253*f6aab3d8Srobert     int signal;
254*f6aab3d8Srobert     llvm::StringRef description;
255*f6aab3d8Srobert     data_dict->GetValueForKeyAsInteger("signal", signal,
256*f6aab3d8Srobert                                        LLDB_INVALID_SIGNAL_NUMBER);
257*f6aab3d8Srobert     data_dict->GetValueForKeyAsString("desc", description);
258*f6aab3d8Srobert     stop_info_sp =
259*f6aab3d8Srobert         StopInfo::CreateStopReasonWithSignal(*this, signal, description.data());
260*f6aab3d8Srobert   } break;
261*f6aab3d8Srobert   case lldb::eStopReasonException: {
262*f6aab3d8Srobert #if defined(__APPLE__)
263*f6aab3d8Srobert     StructuredData::Dictionary *mach_exception;
264*f6aab3d8Srobert     if (data_dict->GetValueForKeyAsDictionary("mach_exception",
265*f6aab3d8Srobert                                               mach_exception)) {
266*f6aab3d8Srobert       llvm::StringRef value;
267*f6aab3d8Srobert       mach_exception->GetValueForKeyAsString("type", value);
268*f6aab3d8Srobert       auto exc_type =
269*f6aab3d8Srobert           StopInfoMachException::MachException::ExceptionCode(value.data());
270*f6aab3d8Srobert 
271*f6aab3d8Srobert       if (!exc_type)
272*f6aab3d8Srobert         return false;
273*f6aab3d8Srobert 
274*f6aab3d8Srobert       uint32_t exc_data_size = 0;
275*f6aab3d8Srobert       llvm::SmallVector<uint64_t, 3> raw_codes;
276*f6aab3d8Srobert 
277*f6aab3d8Srobert       StructuredData::Array *exc_rawcodes;
278*f6aab3d8Srobert       mach_exception->GetValueForKeyAsArray("rawCodes", exc_rawcodes);
279*f6aab3d8Srobert       if (exc_rawcodes) {
280*f6aab3d8Srobert         auto fetch_data = [&raw_codes](StructuredData::Object *obj) {
281*f6aab3d8Srobert           if (!obj)
282*f6aab3d8Srobert             return false;
283*f6aab3d8Srobert           raw_codes.push_back(obj->GetIntegerValue());
284*f6aab3d8Srobert           return true;
285*f6aab3d8Srobert         };
286*f6aab3d8Srobert 
287*f6aab3d8Srobert         exc_rawcodes->ForEach(fetch_data);
288*f6aab3d8Srobert         exc_data_size = raw_codes.size();
289*f6aab3d8Srobert       }
290*f6aab3d8Srobert 
291*f6aab3d8Srobert       stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException(
292*f6aab3d8Srobert           *this, *exc_type, exc_data_size,
293*f6aab3d8Srobert           exc_data_size >= 1 ? raw_codes[0] : 0,
294*f6aab3d8Srobert           exc_data_size >= 2 ? raw_codes[1] : 0,
295*f6aab3d8Srobert           exc_data_size >= 3 ? raw_codes[2] : 0);
296*f6aab3d8Srobert 
297*f6aab3d8Srobert       break;
298*f6aab3d8Srobert     }
299*f6aab3d8Srobert #endif
300*f6aab3d8Srobert     stop_info_sp =
301*f6aab3d8Srobert         StopInfo::CreateStopReasonWithException(*this, "EXC_BAD_ACCESS");
302*f6aab3d8Srobert   } break;
303*f6aab3d8Srobert   default:
304*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<bool>(
305*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION,
306*f6aab3d8Srobert         llvm::Twine("Unsupported stop reason type (" +
307*f6aab3d8Srobert                     llvm::Twine(stop_reason_type) + llvm::Twine(")."))
308*f6aab3d8Srobert             .str(),
309*f6aab3d8Srobert         error, LLDBLog::Thread);
310*f6aab3d8Srobert   }
311*f6aab3d8Srobert 
312*f6aab3d8Srobert   if (!stop_info_sp)
313*f6aab3d8Srobert     return false;
314*f6aab3d8Srobert 
315*f6aab3d8Srobert   SetStopInfo(stop_info_sp);
316*f6aab3d8Srobert   return true;
317*f6aab3d8Srobert }
318*f6aab3d8Srobert 
RefreshStateAfterStop()319*f6aab3d8Srobert void ScriptedThread::RefreshStateAfterStop() {
320*f6aab3d8Srobert   GetRegisterContext()->InvalidateIfNeeded(/*force=*/false);
321*f6aab3d8Srobert   LoadArtificialStackFrames();
322*f6aab3d8Srobert }
323*f6aab3d8Srobert 
GetInterface() const324*f6aab3d8Srobert lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const {
325*f6aab3d8Srobert   return m_scripted_thread_interface_sp;
326*f6aab3d8Srobert }
327*f6aab3d8Srobert 
GetDynamicRegisterInfo()328*f6aab3d8Srobert std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
329*f6aab3d8Srobert   CheckInterpreterAndScriptObject();
330*f6aab3d8Srobert 
331*f6aab3d8Srobert   if (!m_register_info_sp) {
332*f6aab3d8Srobert     StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
333*f6aab3d8Srobert 
334*f6aab3d8Srobert     Status error;
335*f6aab3d8Srobert     if (!reg_info)
336*f6aab3d8Srobert       return ScriptedInterface::ErrorWithMessage<
337*f6aab3d8Srobert           std::shared_ptr<DynamicRegisterInfo>>(
338*f6aab3d8Srobert           LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.",
339*f6aab3d8Srobert           error, LLDBLog::Thread);
340*f6aab3d8Srobert 
341*f6aab3d8Srobert     m_register_info_sp = std::make_shared<DynamicRegisterInfo>(
342*f6aab3d8Srobert         *reg_info, m_scripted_process.GetTarget().GetArchitecture());
343*f6aab3d8Srobert   }
344*f6aab3d8Srobert 
345*f6aab3d8Srobert   return m_register_info_sp;
346*f6aab3d8Srobert }
347*f6aab3d8Srobert 
FetchThreadExtendedInfo()348*f6aab3d8Srobert StructuredData::ObjectSP ScriptedThread::FetchThreadExtendedInfo() {
349*f6aab3d8Srobert   CheckInterpreterAndScriptObject();
350*f6aab3d8Srobert 
351*f6aab3d8Srobert   Status error;
352*f6aab3d8Srobert   StructuredData::ArraySP extended_info_sp = GetInterface()->GetExtendedInfo();
353*f6aab3d8Srobert 
354*f6aab3d8Srobert   if (!extended_info_sp || !extended_info_sp->GetSize())
355*f6aab3d8Srobert     return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
356*f6aab3d8Srobert         LLVM_PRETTY_FUNCTION, "No extended information found", error);
357*f6aab3d8Srobert 
358*f6aab3d8Srobert   return extended_info_sp;
359*f6aab3d8Srobert }
360