1*0b57cec5SDimitry Andric //===-- ThreadGDBRemote.cpp -------------------------------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "ThreadGDBRemote.h" 10*0b57cec5SDimitry Andric 11*0b57cec5SDimitry Andric #include "lldb/Breakpoint/Watchpoint.h" 12*0b57cec5SDimitry Andric #include "lldb/Target/Platform.h" 13*0b57cec5SDimitry Andric #include "lldb/Target/Process.h" 14*0b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h" 15*0b57cec5SDimitry Andric #include "lldb/Target/StopInfo.h" 16*0b57cec5SDimitry Andric #include "lldb/Target/SystemRuntime.h" 17*0b57cec5SDimitry Andric #include "lldb/Target/Target.h" 18*0b57cec5SDimitry Andric #include "lldb/Target/UnixSignals.h" 19*0b57cec5SDimitry Andric #include "lldb/Target/Unwind.h" 20*0b57cec5SDimitry Andric #include "lldb/Utility/DataExtractor.h" 21*0b57cec5SDimitry Andric #include "lldb/Utility/State.h" 22*0b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 23*0b57cec5SDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h" 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric #include "ProcessGDBRemote.h" 26*0b57cec5SDimitry Andric #include "ProcessGDBRemoteLog.h" 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric #include <memory> 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric using namespace lldb; 31*0b57cec5SDimitry Andric using namespace lldb_private; 32*0b57cec5SDimitry Andric using namespace lldb_private::process_gdb_remote; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric // Thread Registers 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid) 37*0b57cec5SDimitry Andric : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(), 38*0b57cec5SDimitry Andric m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS), 39*0b57cec5SDimitry Andric m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown), 40*0b57cec5SDimitry Andric m_queue_serial_number(LLDB_INVALID_QUEUE_ID), 41*0b57cec5SDimitry Andric m_associated_with_libdispatch_queue(eLazyBoolCalculate) { 42*0b57cec5SDimitry Andric Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 43*0b57cec5SDimitry Andric LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(), 44*0b57cec5SDimitry Andric GetID()); 45*0b57cec5SDimitry Andric } 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric ThreadGDBRemote::~ThreadGDBRemote() { 48*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 49*0b57cec5SDimitry Andric Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 50*0b57cec5SDimitry Andric LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, 51*0b57cec5SDimitry Andric process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID()); 52*0b57cec5SDimitry Andric DestroyThread(); 53*0b57cec5SDimitry Andric } 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric const char *ThreadGDBRemote::GetName() { 56*0b57cec5SDimitry Andric if (m_thread_name.empty()) 57*0b57cec5SDimitry Andric return nullptr; 58*0b57cec5SDimitry Andric return m_thread_name.c_str(); 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric void ThreadGDBRemote::ClearQueueInfo() { 62*0b57cec5SDimitry Andric m_dispatch_queue_name.clear(); 63*0b57cec5SDimitry Andric m_queue_kind = eQueueKindUnknown; 64*0b57cec5SDimitry Andric m_queue_serial_number = 0; 65*0b57cec5SDimitry Andric m_dispatch_queue_t = LLDB_INVALID_ADDRESS; 66*0b57cec5SDimitry Andric m_associated_with_libdispatch_queue = eLazyBoolCalculate; 67*0b57cec5SDimitry Andric } 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name, 70*0b57cec5SDimitry Andric QueueKind queue_kind, uint64_t queue_serial, 71*0b57cec5SDimitry Andric addr_t dispatch_queue_t, 72*0b57cec5SDimitry Andric LazyBool associated_with_libdispatch_queue) { 73*0b57cec5SDimitry Andric m_dispatch_queue_name = queue_name; 74*0b57cec5SDimitry Andric m_queue_kind = queue_kind; 75*0b57cec5SDimitry Andric m_queue_serial_number = queue_serial; 76*0b57cec5SDimitry Andric m_dispatch_queue_t = dispatch_queue_t; 77*0b57cec5SDimitry Andric m_associated_with_libdispatch_queue = associated_with_libdispatch_queue; 78*0b57cec5SDimitry Andric } 79*0b57cec5SDimitry Andric 80*0b57cec5SDimitry Andric const char *ThreadGDBRemote::GetQueueName() { 81*0b57cec5SDimitry Andric // If our cached queue info is valid, then someone called 82*0b57cec5SDimitry Andric // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned 83*0b57cec5SDimitry Andric // from the stop reply packet. In this case we trust that the info is valid 84*0b57cec5SDimitry Andric // in m_dispatch_queue_name without refetching it 85*0b57cec5SDimitry Andric if (CachedQueueInfoIsValid()) { 86*0b57cec5SDimitry Andric if (m_dispatch_queue_name.empty()) 87*0b57cec5SDimitry Andric return nullptr; 88*0b57cec5SDimitry Andric else 89*0b57cec5SDimitry Andric return m_dispatch_queue_name.c_str(); 90*0b57cec5SDimitry Andric } 91*0b57cec5SDimitry Andric // Always re-fetch the dispatch queue name since it can change 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric if (m_associated_with_libdispatch_queue == eLazyBoolNo) 94*0b57cec5SDimitry Andric return nullptr; 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric if (m_thread_dispatch_qaddr != 0 && 97*0b57cec5SDimitry Andric m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 98*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 99*0b57cec5SDimitry Andric if (process_sp) { 100*0b57cec5SDimitry Andric SystemRuntime *runtime = process_sp->GetSystemRuntime(); 101*0b57cec5SDimitry Andric if (runtime) 102*0b57cec5SDimitry Andric m_dispatch_queue_name = 103*0b57cec5SDimitry Andric runtime->GetQueueNameFromThreadQAddress(m_thread_dispatch_qaddr); 104*0b57cec5SDimitry Andric else 105*0b57cec5SDimitry Andric m_dispatch_queue_name.clear(); 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric if (!m_dispatch_queue_name.empty()) 108*0b57cec5SDimitry Andric return m_dispatch_queue_name.c_str(); 109*0b57cec5SDimitry Andric } 110*0b57cec5SDimitry Andric } 111*0b57cec5SDimitry Andric return nullptr; 112*0b57cec5SDimitry Andric } 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric QueueKind ThreadGDBRemote::GetQueueKind() { 115*0b57cec5SDimitry Andric // If our cached queue info is valid, then someone called 116*0b57cec5SDimitry Andric // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned 117*0b57cec5SDimitry Andric // from the stop reply packet. In this case we trust that the info is valid 118*0b57cec5SDimitry Andric // in m_dispatch_queue_name without refetching it 119*0b57cec5SDimitry Andric if (CachedQueueInfoIsValid()) { 120*0b57cec5SDimitry Andric return m_queue_kind; 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric if (m_associated_with_libdispatch_queue == eLazyBoolNo) 124*0b57cec5SDimitry Andric return eQueueKindUnknown; 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric if (m_thread_dispatch_qaddr != 0 && 127*0b57cec5SDimitry Andric m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 128*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 129*0b57cec5SDimitry Andric if (process_sp) { 130*0b57cec5SDimitry Andric SystemRuntime *runtime = process_sp->GetSystemRuntime(); 131*0b57cec5SDimitry Andric if (runtime) 132*0b57cec5SDimitry Andric m_queue_kind = runtime->GetQueueKind(m_thread_dispatch_qaddr); 133*0b57cec5SDimitry Andric return m_queue_kind; 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric } 136*0b57cec5SDimitry Andric return eQueueKindUnknown; 137*0b57cec5SDimitry Andric } 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric queue_id_t ThreadGDBRemote::GetQueueID() { 140*0b57cec5SDimitry Andric // If our cached queue info is valid, then someone called 141*0b57cec5SDimitry Andric // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned 142*0b57cec5SDimitry Andric // from the stop reply packet. In this case we trust that the info is valid 143*0b57cec5SDimitry Andric // in m_dispatch_queue_name without refetching it 144*0b57cec5SDimitry Andric if (CachedQueueInfoIsValid()) 145*0b57cec5SDimitry Andric return m_queue_serial_number; 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric if (m_associated_with_libdispatch_queue == eLazyBoolNo) 148*0b57cec5SDimitry Andric return LLDB_INVALID_QUEUE_ID; 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric if (m_thread_dispatch_qaddr != 0 && 151*0b57cec5SDimitry Andric m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 152*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 153*0b57cec5SDimitry Andric if (process_sp) { 154*0b57cec5SDimitry Andric SystemRuntime *runtime = process_sp->GetSystemRuntime(); 155*0b57cec5SDimitry Andric if (runtime) { 156*0b57cec5SDimitry Andric return runtime->GetQueueIDFromThreadQAddress(m_thread_dispatch_qaddr); 157*0b57cec5SDimitry Andric } 158*0b57cec5SDimitry Andric } 159*0b57cec5SDimitry Andric } 160*0b57cec5SDimitry Andric return LLDB_INVALID_QUEUE_ID; 161*0b57cec5SDimitry Andric } 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric QueueSP ThreadGDBRemote::GetQueue() { 164*0b57cec5SDimitry Andric queue_id_t queue_id = GetQueueID(); 165*0b57cec5SDimitry Andric QueueSP queue; 166*0b57cec5SDimitry Andric if (queue_id != LLDB_INVALID_QUEUE_ID) { 167*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 168*0b57cec5SDimitry Andric if (process_sp) { 169*0b57cec5SDimitry Andric queue = process_sp->GetQueueList().FindQueueByID(queue_id); 170*0b57cec5SDimitry Andric } 171*0b57cec5SDimitry Andric } 172*0b57cec5SDimitry Andric return queue; 173*0b57cec5SDimitry Andric } 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress() { 176*0b57cec5SDimitry Andric if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) { 177*0b57cec5SDimitry Andric if (m_thread_dispatch_qaddr != 0 && 178*0b57cec5SDimitry Andric m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) { 179*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 180*0b57cec5SDimitry Andric if (process_sp) { 181*0b57cec5SDimitry Andric SystemRuntime *runtime = process_sp->GetSystemRuntime(); 182*0b57cec5SDimitry Andric if (runtime) { 183*0b57cec5SDimitry Andric m_dispatch_queue_t = 184*0b57cec5SDimitry Andric runtime->GetLibdispatchQueueAddressFromThreadQAddress( 185*0b57cec5SDimitry Andric m_thread_dispatch_qaddr); 186*0b57cec5SDimitry Andric } 187*0b57cec5SDimitry Andric } 188*0b57cec5SDimitry Andric } 189*0b57cec5SDimitry Andric } 190*0b57cec5SDimitry Andric return m_dispatch_queue_t; 191*0b57cec5SDimitry Andric } 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric void ThreadGDBRemote::SetQueueLibdispatchQueueAddress( 194*0b57cec5SDimitry Andric lldb::addr_t dispatch_queue_t) { 195*0b57cec5SDimitry Andric m_dispatch_queue_t = dispatch_queue_t; 196*0b57cec5SDimitry Andric } 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric bool ThreadGDBRemote::ThreadHasQueueInformation() const { 199*0b57cec5SDimitry Andric return m_thread_dispatch_qaddr != 0 && 200*0b57cec5SDimitry Andric m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS && 201*0b57cec5SDimitry Andric m_dispatch_queue_t != LLDB_INVALID_ADDRESS && 202*0b57cec5SDimitry Andric m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0; 203*0b57cec5SDimitry Andric } 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() { 206*0b57cec5SDimitry Andric return m_associated_with_libdispatch_queue; 207*0b57cec5SDimitry Andric } 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue( 210*0b57cec5SDimitry Andric LazyBool associated_with_libdispatch_queue) { 211*0b57cec5SDimitry Andric m_associated_with_libdispatch_queue = associated_with_libdispatch_queue; 212*0b57cec5SDimitry Andric } 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() { 215*0b57cec5SDimitry Andric StructuredData::ObjectSP object_sp; 216*0b57cec5SDimitry Andric const lldb::user_id_t tid = GetProtocolID(); 217*0b57cec5SDimitry Andric Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 218*0b57cec5SDimitry Andric if (log) 219*0b57cec5SDimitry Andric log->Printf("Fetching extended information for thread %4.4" PRIx64, tid); 220*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 221*0b57cec5SDimitry Andric if (process_sp) { 222*0b57cec5SDimitry Andric ProcessGDBRemote *gdb_process = 223*0b57cec5SDimitry Andric static_cast<ProcessGDBRemote *>(process_sp.get()); 224*0b57cec5SDimitry Andric object_sp = gdb_process->GetExtendedInfoForThread(tid); 225*0b57cec5SDimitry Andric } 226*0b57cec5SDimitry Andric return object_sp; 227*0b57cec5SDimitry Andric } 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric void ThreadGDBRemote::WillResume(StateType resume_state) { 230*0b57cec5SDimitry Andric int signo = GetResumeSignal(); 231*0b57cec5SDimitry Andric const lldb::user_id_t tid = GetProtocolID(); 232*0b57cec5SDimitry Andric Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD)); 233*0b57cec5SDimitry Andric if (log) 234*0b57cec5SDimitry Andric log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, 235*0b57cec5SDimitry Andric StateAsCString(resume_state)); 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 238*0b57cec5SDimitry Andric if (process_sp) { 239*0b57cec5SDimitry Andric ProcessGDBRemote *gdb_process = 240*0b57cec5SDimitry Andric static_cast<ProcessGDBRemote *>(process_sp.get()); 241*0b57cec5SDimitry Andric switch (resume_state) { 242*0b57cec5SDimitry Andric case eStateSuspended: 243*0b57cec5SDimitry Andric case eStateStopped: 244*0b57cec5SDimitry Andric // Don't append anything for threads that should stay stopped. 245*0b57cec5SDimitry Andric break; 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric case eStateRunning: 248*0b57cec5SDimitry Andric if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) 249*0b57cec5SDimitry Andric gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo)); 250*0b57cec5SDimitry Andric else 251*0b57cec5SDimitry Andric gdb_process->m_continue_c_tids.push_back(tid); 252*0b57cec5SDimitry Andric break; 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric case eStateStepping: 255*0b57cec5SDimitry Andric if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) 256*0b57cec5SDimitry Andric gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo)); 257*0b57cec5SDimitry Andric else 258*0b57cec5SDimitry Andric gdb_process->m_continue_s_tids.push_back(tid); 259*0b57cec5SDimitry Andric break; 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric default: 262*0b57cec5SDimitry Andric break; 263*0b57cec5SDimitry Andric } 264*0b57cec5SDimitry Andric } 265*0b57cec5SDimitry Andric } 266*0b57cec5SDimitry Andric 267*0b57cec5SDimitry Andric void ThreadGDBRemote::RefreshStateAfterStop() { 268*0b57cec5SDimitry Andric // Invalidate all registers in our register context. We don't set "force" to 269*0b57cec5SDimitry Andric // true because the stop reply packet might have had some register values 270*0b57cec5SDimitry Andric // that were expedited and these will already be copied into the register 271*0b57cec5SDimitry Andric // context by the time this function gets called. The 272*0b57cec5SDimitry Andric // GDBRemoteRegisterContext class has been made smart enough to detect when 273*0b57cec5SDimitry Andric // it needs to invalidate which registers are valid by putting hooks in the 274*0b57cec5SDimitry Andric // register read and register supply functions where they check the process 275*0b57cec5SDimitry Andric // stop ID and do the right thing. 276*0b57cec5SDimitry Andric const bool force = false; 277*0b57cec5SDimitry Andric GetRegisterContext()->InvalidateIfNeeded(force); 278*0b57cec5SDimitry Andric } 279*0b57cec5SDimitry Andric 280*0b57cec5SDimitry Andric bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) { 281*0b57cec5SDimitry Andric return thread != 0; 282*0b57cec5SDimitry Andric } 283*0b57cec5SDimitry Andric 284*0b57cec5SDimitry Andric void ThreadGDBRemote::Dump(Log *log, uint32_t index) {} 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; } 287*0b57cec5SDimitry Andric lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() { 288*0b57cec5SDimitry Andric if (!m_reg_context_sp) 289*0b57cec5SDimitry Andric m_reg_context_sp = CreateRegisterContextForFrame(nullptr); 290*0b57cec5SDimitry Andric return m_reg_context_sp; 291*0b57cec5SDimitry Andric } 292*0b57cec5SDimitry Andric 293*0b57cec5SDimitry Andric lldb::RegisterContextSP 294*0b57cec5SDimitry Andric ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) { 295*0b57cec5SDimitry Andric lldb::RegisterContextSP reg_ctx_sp; 296*0b57cec5SDimitry Andric uint32_t concrete_frame_idx = 0; 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric if (frame) 299*0b57cec5SDimitry Andric concrete_frame_idx = frame->GetConcreteFrameIndex(); 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric if (concrete_frame_idx == 0) { 302*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 303*0b57cec5SDimitry Andric if (process_sp) { 304*0b57cec5SDimitry Andric ProcessGDBRemote *gdb_process = 305*0b57cec5SDimitry Andric static_cast<ProcessGDBRemote *>(process_sp.get()); 306*0b57cec5SDimitry Andric // read_all_registers_at_once will be true if 'p' packet is not 307*0b57cec5SDimitry Andric // supported. 308*0b57cec5SDimitry Andric bool read_all_registers_at_once = 309*0b57cec5SDimitry Andric !gdb_process->GetGDBRemote().GetpPacketSupported(GetID()); 310*0b57cec5SDimitry Andric reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>( 311*0b57cec5SDimitry Andric *this, concrete_frame_idx, gdb_process->m_register_info, 312*0b57cec5SDimitry Andric read_all_registers_at_once); 313*0b57cec5SDimitry Andric } 314*0b57cec5SDimitry Andric } else { 315*0b57cec5SDimitry Andric Unwind *unwinder = GetUnwinder(); 316*0b57cec5SDimitry Andric if (unwinder != nullptr) 317*0b57cec5SDimitry Andric reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); 318*0b57cec5SDimitry Andric } 319*0b57cec5SDimitry Andric return reg_ctx_sp; 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, 323*0b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> data) { 324*0b57cec5SDimitry Andric GDBRemoteRegisterContext *gdb_reg_ctx = 325*0b57cec5SDimitry Andric static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get()); 326*0b57cec5SDimitry Andric assert(gdb_reg_ctx); 327*0b57cec5SDimitry Andric return gdb_reg_ctx->PrivateSetRegisterValue(reg, data); 328*0b57cec5SDimitry Andric } 329*0b57cec5SDimitry Andric 330*0b57cec5SDimitry Andric bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) { 331*0b57cec5SDimitry Andric GDBRemoteRegisterContext *gdb_reg_ctx = 332*0b57cec5SDimitry Andric static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get()); 333*0b57cec5SDimitry Andric assert(gdb_reg_ctx); 334*0b57cec5SDimitry Andric return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval); 335*0b57cec5SDimitry Andric } 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric bool ThreadGDBRemote::CalculateStopInfo() { 338*0b57cec5SDimitry Andric ProcessSP process_sp(GetProcess()); 339*0b57cec5SDimitry Andric if (process_sp) 340*0b57cec5SDimitry Andric return static_cast<ProcessGDBRemote *>(process_sp.get()) 341*0b57cec5SDimitry Andric ->CalculateThreadStopInfo(this); 342*0b57cec5SDimitry Andric return false; 343*0b57cec5SDimitry Andric } 344