xref: /src/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
1cfca06d7SDimitry Andric //===-- ThreadGDBRemote.cpp -----------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste 
9f034231aSEd Maste #include "ThreadGDBRemote.h"
10f034231aSEd Maste 
11f21a844fSEd Maste #include "lldb/Breakpoint/Watchpoint.h"
12f21a844fSEd Maste #include "lldb/Target/Platform.h"
13f034231aSEd Maste #include "lldb/Target/Process.h"
14f034231aSEd Maste #include "lldb/Target/RegisterContext.h"
15f034231aSEd Maste #include "lldb/Target/StopInfo.h"
16866dcdacSEd Maste #include "lldb/Target/SystemRuntime.h"
17f034231aSEd Maste #include "lldb/Target/Target.h"
185e95aa85SEd Maste #include "lldb/Target/UnixSignals.h"
19f034231aSEd Maste #include "lldb/Target/Unwind.h"
2074a628f7SDimitry Andric #include "lldb/Utility/DataExtractor.h"
2194994d37SDimitry Andric #include "lldb/Utility/State.h"
2274a628f7SDimitry Andric #include "lldb/Utility/StreamString.h"
235f29bb8aSDimitry Andric #include "lldb/Utility/StringExtractorGDBRemote.h"
24f034231aSEd Maste 
25f034231aSEd Maste #include "ProcessGDBRemote.h"
26f034231aSEd Maste #include "ProcessGDBRemoteLog.h"
275f29bb8aSDimitry Andric 
285f29bb8aSDimitry Andric #include <memory>
29f034231aSEd Maste 
30f034231aSEd Maste using namespace lldb;
31f034231aSEd Maste using namespace lldb_private;
325e95aa85SEd Maste using namespace lldb_private::process_gdb_remote;
33f034231aSEd Maste 
34f034231aSEd Maste // Thread Registers
35f034231aSEd Maste 
ThreadGDBRemote(Process & process,lldb::tid_t tid)3614f1b3e8SDimitry Andric ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
3714f1b3e8SDimitry Andric     : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
385e95aa85SEd Maste       m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS),
3914f1b3e8SDimitry Andric       m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),
407fed546dSDimitry Andric       m_queue_serial_number(LLDB_INVALID_QUEUE_ID),
4114f1b3e8SDimitry Andric       m_associated_with_libdispatch_queue(eLazyBoolCalculate) {
426f8fc217SDimitry Andric   Log *log = GetLog(GDBRLog::Thread);
4374a628f7SDimitry Andric   LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this, process.GetID(),
4474a628f7SDimitry Andric            GetID());
45b60736ecSDimitry Andric   // At this point we can clone reg_info for architectures supporting
46b60736ecSDimitry Andric   // run-time update to register sizes and offsets..
47b60736ecSDimitry Andric   auto &gdb_process = static_cast<ProcessGDBRemote &>(process);
48b60736ecSDimitry Andric   if (!gdb_process.m_register_info_sp->IsReconfigurable())
49b60736ecSDimitry Andric     m_reg_info_sp = gdb_process.m_register_info_sp;
50b60736ecSDimitry Andric   else
51b60736ecSDimitry Andric     m_reg_info_sp = std::make_shared<GDBRemoteDynamicRegisterInfo>(
52b60736ecSDimitry Andric         *gdb_process.m_register_info_sp);
53f034231aSEd Maste }
54f034231aSEd Maste 
~ThreadGDBRemote()5514f1b3e8SDimitry Andric ThreadGDBRemote::~ThreadGDBRemote() {
56f034231aSEd Maste   ProcessSP process_sp(GetProcess());
576f8fc217SDimitry Andric   Log *log = GetLog(GDBRLog::Thread);
5874a628f7SDimitry Andric   LLDB_LOG(log, "this = {0}, pid = {1}, tid = {2}", this,
5914f1b3e8SDimitry Andric            process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());
60f034231aSEd Maste   DestroyThread();
61f034231aSEd Maste }
62f034231aSEd Maste 
GetName()6314f1b3e8SDimitry Andric const char *ThreadGDBRemote::GetName() {
64f034231aSEd Maste   if (m_thread_name.empty())
65f73363f1SDimitry Andric     return nullptr;
66f034231aSEd Maste   return m_thread_name.c_str();
67f034231aSEd Maste }
68f034231aSEd Maste 
ClearQueueInfo()6914f1b3e8SDimitry Andric void ThreadGDBRemote::ClearQueueInfo() {
705e95aa85SEd Maste   m_dispatch_queue_name.clear();
715e95aa85SEd Maste   m_queue_kind = eQueueKindUnknown;
727fed546dSDimitry Andric   m_queue_serial_number = 0;
737fed546dSDimitry Andric   m_dispatch_queue_t = LLDB_INVALID_ADDRESS;
747fed546dSDimitry Andric   m_associated_with_libdispatch_queue = eLazyBoolCalculate;
755e95aa85SEd Maste }
765e95aa85SEd Maste 
SetQueueInfo(std::string && queue_name,QueueKind queue_kind,uint64_t queue_serial,addr_t dispatch_queue_t,LazyBool associated_with_libdispatch_queue)7714f1b3e8SDimitry Andric void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name,
7814f1b3e8SDimitry Andric                                    QueueKind queue_kind, uint64_t queue_serial,
7914f1b3e8SDimitry Andric                                    addr_t dispatch_queue_t,
8014f1b3e8SDimitry Andric                                    LazyBool associated_with_libdispatch_queue) {
815e95aa85SEd Maste   m_dispatch_queue_name = queue_name;
825e95aa85SEd Maste   m_queue_kind = queue_kind;
837fed546dSDimitry Andric   m_queue_serial_number = queue_serial;
847fed546dSDimitry Andric   m_dispatch_queue_t = dispatch_queue_t;
857fed546dSDimitry Andric   m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
865e95aa85SEd Maste }
875e95aa85SEd Maste 
GetQueueName()8814f1b3e8SDimitry Andric const char *ThreadGDBRemote::GetQueueName() {
8914f1b3e8SDimitry Andric   // If our cached queue info is valid, then someone called
90f73363f1SDimitry Andric   // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned
91f73363f1SDimitry Andric   // from the stop reply packet. In this case we trust that the info is valid
92f73363f1SDimitry Andric   // in m_dispatch_queue_name without refetching it
9314f1b3e8SDimitry Andric   if (CachedQueueInfoIsValid()) {
945e95aa85SEd Maste     if (m_dispatch_queue_name.empty())
955e95aa85SEd Maste       return nullptr;
965e95aa85SEd Maste     else
975e95aa85SEd Maste       return m_dispatch_queue_name.c_str();
985e95aa85SEd Maste   }
99f034231aSEd Maste   // Always re-fetch the dispatch queue name since it can change
100f034231aSEd Maste 
1017fed546dSDimitry Andric   if (m_associated_with_libdispatch_queue == eLazyBoolNo)
1027fed546dSDimitry Andric     return nullptr;
1037fed546dSDimitry Andric 
10414f1b3e8SDimitry Andric   if (m_thread_dispatch_qaddr != 0 &&
10514f1b3e8SDimitry Andric       m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
106f034231aSEd Maste     ProcessSP process_sp(GetProcess());
10714f1b3e8SDimitry Andric     if (process_sp) {
108866dcdacSEd Maste       SystemRuntime *runtime = process_sp->GetSystemRuntime();
109866dcdacSEd Maste       if (runtime)
11014f1b3e8SDimitry Andric         m_dispatch_queue_name =
11114f1b3e8SDimitry Andric             runtime->GetQueueNameFromThreadQAddress(m_thread_dispatch_qaddr);
1125e95aa85SEd Maste       else
1135e95aa85SEd Maste         m_dispatch_queue_name.clear();
1145e95aa85SEd Maste 
1155e95aa85SEd Maste       if (!m_dispatch_queue_name.empty())
116f21a844fSEd Maste         return m_dispatch_queue_name.c_str();
117f21a844fSEd Maste     }
118f034231aSEd Maste   }
119f73363f1SDimitry Andric   return nullptr;
120f034231aSEd Maste }
121f034231aSEd Maste 
GetQueueKind()12214f1b3e8SDimitry Andric QueueKind ThreadGDBRemote::GetQueueKind() {
12314f1b3e8SDimitry Andric   // If our cached queue info is valid, then someone called
124f73363f1SDimitry Andric   // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned
125f73363f1SDimitry Andric   // from the stop reply packet. In this case we trust that the info is valid
126f73363f1SDimitry Andric   // in m_dispatch_queue_name without refetching it
12714f1b3e8SDimitry Andric   if (CachedQueueInfoIsValid()) {
1287fed546dSDimitry Andric     return m_queue_kind;
1297fed546dSDimitry Andric   }
1307fed546dSDimitry Andric 
1317fed546dSDimitry Andric   if (m_associated_with_libdispatch_queue == eLazyBoolNo)
1327fed546dSDimitry Andric     return eQueueKindUnknown;
1337fed546dSDimitry Andric 
13414f1b3e8SDimitry Andric   if (m_thread_dispatch_qaddr != 0 &&
13514f1b3e8SDimitry Andric       m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
1367fed546dSDimitry Andric     ProcessSP process_sp(GetProcess());
13714f1b3e8SDimitry Andric     if (process_sp) {
1387fed546dSDimitry Andric       SystemRuntime *runtime = process_sp->GetSystemRuntime();
1397fed546dSDimitry Andric       if (runtime)
1407fed546dSDimitry Andric         m_queue_kind = runtime->GetQueueKind(m_thread_dispatch_qaddr);
1417fed546dSDimitry Andric       return m_queue_kind;
1427fed546dSDimitry Andric     }
1437fed546dSDimitry Andric   }
1447fed546dSDimitry Andric   return eQueueKindUnknown;
1457fed546dSDimitry Andric }
1467fed546dSDimitry Andric 
GetQueueID()14714f1b3e8SDimitry Andric queue_id_t ThreadGDBRemote::GetQueueID() {
14814f1b3e8SDimitry Andric   // If our cached queue info is valid, then someone called
149f73363f1SDimitry Andric   // ThreadGDBRemote::SetQueueInfo(...) with valid information that was gleaned
150f73363f1SDimitry Andric   // from the stop reply packet. In this case we trust that the info is valid
151f73363f1SDimitry Andric   // in m_dispatch_queue_name without refetching it
1525e95aa85SEd Maste   if (CachedQueueInfoIsValid())
1537fed546dSDimitry Andric     return m_queue_serial_number;
1545e95aa85SEd Maste 
1557fed546dSDimitry Andric   if (m_associated_with_libdispatch_queue == eLazyBoolNo)
1567fed546dSDimitry Andric     return LLDB_INVALID_QUEUE_ID;
1577fed546dSDimitry Andric 
15814f1b3e8SDimitry Andric   if (m_thread_dispatch_qaddr != 0 &&
15914f1b3e8SDimitry Andric       m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
160f21a844fSEd Maste     ProcessSP process_sp(GetProcess());
16114f1b3e8SDimitry Andric     if (process_sp) {
162866dcdacSEd Maste       SystemRuntime *runtime = process_sp->GetSystemRuntime();
16314f1b3e8SDimitry Andric       if (runtime) {
164866dcdacSEd Maste         return runtime->GetQueueIDFromThreadQAddress(m_thread_dispatch_qaddr);
165f21a844fSEd Maste       }
166f21a844fSEd Maste     }
167f21a844fSEd Maste   }
168f21a844fSEd Maste   return LLDB_INVALID_QUEUE_ID;
169f21a844fSEd Maste }
170f21a844fSEd Maste 
GetQueue()17114f1b3e8SDimitry Andric QueueSP ThreadGDBRemote::GetQueue() {
1720cac4ca3SEd Maste   queue_id_t queue_id = GetQueueID();
1730cac4ca3SEd Maste   QueueSP queue;
17414f1b3e8SDimitry Andric   if (queue_id != LLDB_INVALID_QUEUE_ID) {
1750cac4ca3SEd Maste     ProcessSP process_sp(GetProcess());
17614f1b3e8SDimitry Andric     if (process_sp) {
1770cac4ca3SEd Maste       queue = process_sp->GetQueueList().FindQueueByID(queue_id);
1780cac4ca3SEd Maste     }
1790cac4ca3SEd Maste   }
1800cac4ca3SEd Maste   return queue;
1810cac4ca3SEd Maste }
1820cac4ca3SEd Maste 
GetQueueLibdispatchQueueAddress()18314f1b3e8SDimitry Andric addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress() {
18414f1b3e8SDimitry Andric   if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) {
18514f1b3e8SDimitry Andric     if (m_thread_dispatch_qaddr != 0 &&
18614f1b3e8SDimitry Andric         m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
1870cac4ca3SEd Maste       ProcessSP process_sp(GetProcess());
18814f1b3e8SDimitry Andric       if (process_sp) {
1890cac4ca3SEd Maste         SystemRuntime *runtime = process_sp->GetSystemRuntime();
19014f1b3e8SDimitry Andric         if (runtime) {
19114f1b3e8SDimitry Andric           m_dispatch_queue_t =
19214f1b3e8SDimitry Andric               runtime->GetLibdispatchQueueAddressFromThreadQAddress(
19314f1b3e8SDimitry Andric                   m_thread_dispatch_qaddr);
1940cac4ca3SEd Maste         }
1950cac4ca3SEd Maste       }
1960cac4ca3SEd Maste     }
1977fed546dSDimitry Andric   }
1987fed546dSDimitry Andric   return m_dispatch_queue_t;
1997fed546dSDimitry Andric }
2007fed546dSDimitry Andric 
SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t)20114f1b3e8SDimitry Andric void ThreadGDBRemote::SetQueueLibdispatchQueueAddress(
20214f1b3e8SDimitry Andric     lldb::addr_t dispatch_queue_t) {
2037fed546dSDimitry Andric   m_dispatch_queue_t = dispatch_queue_t;
2047fed546dSDimitry Andric }
2057fed546dSDimitry Andric 
ThreadHasQueueInformation() const20614f1b3e8SDimitry Andric bool ThreadGDBRemote::ThreadHasQueueInformation() const {
20794994d37SDimitry Andric   return m_thread_dispatch_qaddr != 0 &&
20814f1b3e8SDimitry Andric          m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS &&
20914f1b3e8SDimitry Andric          m_dispatch_queue_t != LLDB_INVALID_ADDRESS &&
21094994d37SDimitry Andric          m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0;
2117fed546dSDimitry Andric }
2127fed546dSDimitry Andric 
GetAssociatedWithLibdispatchQueue()21314f1b3e8SDimitry Andric LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() {
2147fed546dSDimitry Andric   return m_associated_with_libdispatch_queue;
2157fed546dSDimitry Andric }
2167fed546dSDimitry Andric 
SetAssociatedWithLibdispatchQueue(LazyBool associated_with_libdispatch_queue)21714f1b3e8SDimitry Andric void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue(
21814f1b3e8SDimitry Andric     LazyBool associated_with_libdispatch_queue) {
2197fed546dSDimitry Andric   m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
2200cac4ca3SEd Maste }
2210cac4ca3SEd Maste 
FetchThreadExtendedInfo()22214f1b3e8SDimitry Andric StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
2230cac4ca3SEd Maste   StructuredData::ObjectSP object_sp;
2240cac4ca3SEd Maste   const lldb::user_id_t tid = GetProtocolID();
2256f8fc217SDimitry Andric   Log *log = GetLog(GDBRLog::Thread);
226ead24645SDimitry Andric   LLDB_LOGF(log, "Fetching extended information for thread %4.4" PRIx64, tid);
2270cac4ca3SEd Maste   ProcessSP process_sp(GetProcess());
22814f1b3e8SDimitry Andric   if (process_sp) {
22914f1b3e8SDimitry Andric     ProcessGDBRemote *gdb_process =
23014f1b3e8SDimitry Andric         static_cast<ProcessGDBRemote *>(process_sp.get());
2310cac4ca3SEd Maste     object_sp = gdb_process->GetExtendedInfoForThread(tid);
2320cac4ca3SEd Maste   }
2330cac4ca3SEd Maste   return object_sp;
2340cac4ca3SEd Maste }
2350cac4ca3SEd Maste 
WillResume(StateType resume_state)23614f1b3e8SDimitry Andric void ThreadGDBRemote::WillResume(StateType resume_state) {
237f034231aSEd Maste   int signo = GetResumeSignal();
238f034231aSEd Maste   const lldb::user_id_t tid = GetProtocolID();
2396f8fc217SDimitry Andric   Log *log = GetLog(GDBRLog::Thread);
240ead24645SDimitry Andric   LLDB_LOGF(log, "Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
24114f1b3e8SDimitry Andric             StateAsCString(resume_state));
242f034231aSEd Maste 
243f034231aSEd Maste   ProcessSP process_sp(GetProcess());
24414f1b3e8SDimitry Andric   if (process_sp) {
24514f1b3e8SDimitry Andric     ProcessGDBRemote *gdb_process =
24614f1b3e8SDimitry Andric         static_cast<ProcessGDBRemote *>(process_sp.get());
24714f1b3e8SDimitry Andric     switch (resume_state) {
248f034231aSEd Maste     case eStateSuspended:
249f034231aSEd Maste     case eStateStopped:
250f034231aSEd Maste       // Don't append anything for threads that should stay stopped.
251f034231aSEd Maste       break;
252f034231aSEd Maste 
253f034231aSEd Maste     case eStateRunning:
254027f1c96SDimitry Andric       if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
255f034231aSEd Maste         gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
256f034231aSEd Maste       else
257f034231aSEd Maste         gdb_process->m_continue_c_tids.push_back(tid);
258f034231aSEd Maste       break;
259f034231aSEd Maste 
260f034231aSEd Maste     case eStateStepping:
261027f1c96SDimitry Andric       if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
262f034231aSEd Maste         gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
263f034231aSEd Maste       else
264f034231aSEd Maste         gdb_process->m_continue_s_tids.push_back(tid);
265f034231aSEd Maste       break;
266f034231aSEd Maste 
267f034231aSEd Maste     default:
268f034231aSEd Maste       break;
269f034231aSEd Maste     }
270f034231aSEd Maste   }
271f034231aSEd Maste }
272f034231aSEd Maste 
RefreshStateAfterStop()27314f1b3e8SDimitry Andric void ThreadGDBRemote::RefreshStateAfterStop() {
274f034231aSEd Maste   // Invalidate all registers in our register context. We don't set "force" to
275f034231aSEd Maste   // true because the stop reply packet might have had some register values
276f034231aSEd Maste   // that were expedited and these will already be copied into the register
277f73363f1SDimitry Andric   // context by the time this function gets called. The
278f73363f1SDimitry Andric   // GDBRemoteRegisterContext class has been made smart enough to detect when
279f73363f1SDimitry Andric   // it needs to invalidate which registers are valid by putting hooks in the
280f73363f1SDimitry Andric   // register read and register supply functions where they check the process
281f73363f1SDimitry Andric   // stop ID and do the right thing.
282f034231aSEd Maste   const bool force = false;
283f034231aSEd Maste   GetRegisterContext()->InvalidateIfNeeded(force);
284f034231aSEd Maste }
285f034231aSEd Maste 
ThreadIDIsValid(lldb::tid_t thread)28614f1b3e8SDimitry Andric bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) {
287f034231aSEd Maste   return thread != 0;
288f034231aSEd Maste }
289f034231aSEd Maste 
Dump(Log * log,uint32_t index)29014f1b3e8SDimitry Andric void ThreadGDBRemote::Dump(Log *log, uint32_t index) {}
291f034231aSEd Maste 
ShouldStop(bool & step_more)29214f1b3e8SDimitry Andric bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; }
GetRegisterContext()29314f1b3e8SDimitry Andric lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() {
294f73363f1SDimitry Andric   if (!m_reg_context_sp)
295f73363f1SDimitry Andric     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
296f034231aSEd Maste   return m_reg_context_sp;
297f034231aSEd Maste }
298f034231aSEd Maste 
299f034231aSEd Maste lldb::RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)30014f1b3e8SDimitry Andric ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
301f034231aSEd Maste   lldb::RegisterContextSP reg_ctx_sp;
302f034231aSEd Maste   uint32_t concrete_frame_idx = 0;
303f034231aSEd Maste 
304f034231aSEd Maste   if (frame)
305f034231aSEd Maste     concrete_frame_idx = frame->GetConcreteFrameIndex();
306f034231aSEd Maste 
30714f1b3e8SDimitry Andric   if (concrete_frame_idx == 0) {
308f034231aSEd Maste     ProcessSP process_sp(GetProcess());
30914f1b3e8SDimitry Andric     if (process_sp) {
31014f1b3e8SDimitry Andric       ProcessGDBRemote *gdb_process =
31114f1b3e8SDimitry Andric           static_cast<ProcessGDBRemote *>(process_sp.get());
312706b4fc4SDimitry Andric       bool pSupported =
313706b4fc4SDimitry Andric           gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
31414f1b3e8SDimitry Andric       bool read_all_registers_at_once =
315706b4fc4SDimitry Andric           !pSupported || gdb_process->m_use_g_packet_for_reading;
316706b4fc4SDimitry Andric       bool write_all_registers_at_once = !pSupported;
3175f29bb8aSDimitry Andric       reg_ctx_sp = std::make_shared<GDBRemoteRegisterContext>(
318b60736ecSDimitry Andric           *this, concrete_frame_idx, m_reg_info_sp, read_all_registers_at_once,
319b60736ecSDimitry Andric           write_all_registers_at_once);
320f034231aSEd Maste     }
32114f1b3e8SDimitry Andric   } else {
322cfca06d7SDimitry Andric     reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
323f034231aSEd Maste   }
324f034231aSEd Maste   return reg_ctx_sp;
325f034231aSEd Maste }
326f034231aSEd Maste 
PrivateSetRegisterValue(uint32_t reg,llvm::ArrayRef<uint8_t> data)32714f1b3e8SDimitry Andric bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg,
32814f1b3e8SDimitry Andric                                               llvm::ArrayRef<uint8_t> data) {
32914f1b3e8SDimitry Andric   GDBRemoteRegisterContext *gdb_reg_ctx =
33014f1b3e8SDimitry Andric       static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
331f034231aSEd Maste   assert(gdb_reg_ctx);
33214f1b3e8SDimitry Andric   return gdb_reg_ctx->PrivateSetRegisterValue(reg, data);
333f034231aSEd Maste }
334f034231aSEd Maste 
PrivateSetRegisterValue(uint32_t reg,uint64_t regval)33514f1b3e8SDimitry Andric bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) {
33614f1b3e8SDimitry Andric   GDBRemoteRegisterContext *gdb_reg_ctx =
33714f1b3e8SDimitry Andric       static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
338e81d9d49SDimitry Andric   assert(gdb_reg_ctx);
339e81d9d49SDimitry Andric   return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval);
340e81d9d49SDimitry Andric }
341e81d9d49SDimitry Andric 
CalculateStopInfo()34214f1b3e8SDimitry Andric bool ThreadGDBRemote::CalculateStopInfo() {
343f034231aSEd Maste   ProcessSP process_sp(GetProcess());
344f034231aSEd Maste   if (process_sp)
34514f1b3e8SDimitry Andric     return static_cast<ProcessGDBRemote *>(process_sp.get())
34614f1b3e8SDimitry Andric         ->CalculateThreadStopInfo(this);
347f034231aSEd Maste   return false;
348f034231aSEd Maste }
3496f8fc217SDimitry Andric 
3506f8fc217SDimitry Andric llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
GetSiginfo(size_t max_size) const3516f8fc217SDimitry Andric ThreadGDBRemote::GetSiginfo(size_t max_size) const {
3526f8fc217SDimitry Andric   ProcessSP process_sp(GetProcess());
3536f8fc217SDimitry Andric   if (!process_sp)
3546f8fc217SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
3556f8fc217SDimitry Andric                                    "no process");
3566f8fc217SDimitry Andric   ProcessGDBRemote *gdb_process =
3576f8fc217SDimitry Andric       static_cast<ProcessGDBRemote *>(process_sp.get());
3586f8fc217SDimitry Andric   if (!gdb_process->m_gdb_comm.GetQXferSigInfoReadSupported())
3596f8fc217SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
3606f8fc217SDimitry Andric                                    "qXfer:siginfo:read not supported");
3616f8fc217SDimitry Andric 
3626f8fc217SDimitry Andric   llvm::Expected<std::string> response =
3636f8fc217SDimitry Andric       gdb_process->m_gdb_comm.ReadExtFeature("siginfo", "");
3646f8fc217SDimitry Andric   if (!response)
3656f8fc217SDimitry Andric     return response.takeError();
3666f8fc217SDimitry Andric 
3676f8fc217SDimitry Andric   return llvm::MemoryBuffer::getMemBufferCopy(response.get());
3686f8fc217SDimitry Andric }
369