1 //===-- ThreadKDP.cpp -----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 #include "lldb/Host/SafeMachO.h"
13 #include "lldb/Breakpoint/Watchpoint.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Target/RegisterContext.h"
16 #include "lldb/Target/StopInfo.h"
17 #include "lldb/Target/Target.h"
18 #include "lldb/Target/Unwind.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/DataExtractor.h"
21 #include "lldb/Utility/State.h"
22 #include "lldb/Utility/StreamString.h"
24 #include "Plugins/Process/Utility/StopInfoMachException.h"
25 #include "ProcessKDP.h"
26 #include "ProcessKDPLog.h"
27 #include "RegisterContextKDP_arm.h"
28 #include "RegisterContextKDP_arm64.h"
29 #include "RegisterContextKDP_i386.h"
30 #include "RegisterContextKDP_x86_64.h"
35 using namespace lldb_private
;
39 ThreadKDP::ThreadKDP(Process
&process
, lldb::tid_t tid
)
40 : Thread(process
, tid
), m_thread_name(), m_dispatch_queue_name(),
41 m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS
) {
42 Log
*log
= GetLog(KDPLog::Thread
);
43 LLDB_LOG(log
, "this = {0}, tid = {1:x}", this, GetID());
46 ThreadKDP::~ThreadKDP() {
47 Log
*log
= GetLog(KDPLog::Thread
);
48 LLDB_LOG(log
, "this = {0}, tid = {1:x}", this, GetID());
52 const char *ThreadKDP::GetName() {
53 if (m_thread_name
.empty())
55 return m_thread_name
.c_str();
58 const char *ThreadKDP::GetQueueName() { return nullptr; }
60 void ThreadKDP::RefreshStateAfterStop() {
61 // Invalidate all registers in our register context. We don't set "force" to
62 // true because the stop reply packet might have had some register values
63 // that were expedited and these will already be copied into the register
64 // context by the time this function gets called. The KDPRegisterContext
65 // class has been made smart enough to detect when it needs to invalidate
66 // which registers are valid by putting hooks in the register read and
67 // register supply functions where they check the process stop ID and do the
69 const bool force
= false;
70 lldb::RegisterContextSP
reg_ctx_sp(GetRegisterContext());
72 reg_ctx_sp
->InvalidateIfNeeded(force
);
75 bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread
) { return thread
!= 0; }
77 void ThreadKDP::Dump(Log
*log
, uint32_t index
) {}
79 bool ThreadKDP::ShouldStop(bool &step_more
) { return true; }
80 lldb::RegisterContextSP
ThreadKDP::GetRegisterContext() {
81 if (!m_reg_context_sp
)
82 m_reg_context_sp
= CreateRegisterContextForFrame(nullptr);
83 return m_reg_context_sp
;
86 lldb::RegisterContextSP
87 ThreadKDP::CreateRegisterContextForFrame(StackFrame
*frame
) {
88 lldb::RegisterContextSP reg_ctx_sp
;
89 uint32_t concrete_frame_idx
= 0;
92 concrete_frame_idx
= frame
->GetConcreteFrameIndex();
94 if (concrete_frame_idx
== 0) {
95 ProcessSP
process_sp(CalculateProcess());
97 switch (static_cast<ProcessKDP
*>(process_sp
.get())
100 case llvm::MachO::CPU_TYPE_ARM
:
102 std::make_shared
<RegisterContextKDP_arm
>(*this, concrete_frame_idx
);
104 case llvm::MachO::CPU_TYPE_ARM64
:
105 reg_ctx_sp
= std::make_shared
<RegisterContextKDP_arm64
>(
106 *this, concrete_frame_idx
);
108 case llvm::MachO::CPU_TYPE_I386
:
109 reg_ctx_sp
= std::make_shared
<RegisterContextKDP_i386
>(
110 *this, concrete_frame_idx
);
112 case llvm::MachO::CPU_TYPE_X86_64
:
113 reg_ctx_sp
= std::make_shared
<RegisterContextKDP_x86_64
>(
114 *this, concrete_frame_idx
);
117 llvm_unreachable("Add CPU type support in KDP");
121 reg_ctx_sp
= GetUnwinder().CreateRegisterContextForFrame(frame
);
126 bool ThreadKDP::CalculateStopInfo() {
127 ProcessSP
process_sp(GetProcess());
129 if (m_cached_stop_info_sp
) {
130 SetStopInfo(m_cached_stop_info_sp
);
132 SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP
));
139 void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
140 const DataExtractor
&exc_reply_packet
) {
141 lldb::offset_t offset
= 0;
142 uint8_t reply_command
= exc_reply_packet
.GetU8(&offset
);
143 if (reply_command
== CommunicationKDP::KDP_EXCEPTION
) {
145 const uint32_t count
= exc_reply_packet
.GetU32(&offset
);
147 // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
148 offset
+= 4; // Skip the useless CPU field
149 const uint32_t exc_type
= exc_reply_packet
.GetU32(&offset
);
150 const uint32_t exc_code
= exc_reply_packet
.GetU32(&offset
);
151 const uint32_t exc_subcode
= exc_reply_packet
.GetU32(&offset
);
152 // We have to make a copy of the stop info because the thread list will
153 // iterate through the threads and clear all stop infos..
155 // Let the StopInfoMachException::CreateStopReasonWithMachException()
156 // function update the PC if needed as we might hit a software breakpoint
157 // and need to decrement the PC (i386 and x86_64 need this) and KDP
158 // doesn't do this for us.
159 const bool pc_already_adjusted
= false;
160 const bool adjust_pc_if_needed
= true;
162 m_cached_stop_info_sp
=
163 StopInfoMachException::CreateStopReasonWithMachException(
164 *this, exc_type
, 2, exc_code
, exc_subcode
, 0, pc_already_adjusted
,
165 adjust_pc_if_needed
);