180814287SRaphael Isemann //===-- ThreadKDP.cpp -----------------------------------------------------===//
2a63d08c9SGreg Clayton //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a63d08c9SGreg Clayton //
7a63d08c9SGreg Clayton //===----------------------------------------------------------------------===//
8a63d08c9SGreg Clayton 
9a63d08c9SGreg Clayton #include "ThreadKDP.h"
10a63d08c9SGreg Clayton 
1177044731SPavel Labath #include "lldb/Host/SafeMachO.h"
12a63d08c9SGreg Clayton 
13b9c1b51eSKate Stone #include "lldb/Breakpoint/Watchpoint.h"
14a63d08c9SGreg Clayton #include "lldb/Target/Process.h"
15a63d08c9SGreg Clayton #include "lldb/Target/RegisterContext.h"
16a63d08c9SGreg Clayton #include "lldb/Target/StopInfo.h"
17a63d08c9SGreg Clayton #include "lldb/Target/Target.h"
18a63d08c9SGreg Clayton #include "lldb/Target/Unwind.h"
192da1b597SPavel Labath #include "lldb/Utility/ArchSpec.h"
20666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
21d821c997SPavel Labath #include "lldb/Utility/State.h"
22bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
23a63d08c9SGreg Clayton 
24b9c1b51eSKate Stone #include "Plugins/Process/Utility/StopInfoMachException.h"
25a63d08c9SGreg Clayton #include "ProcessKDP.h"
26a63d08c9SGreg Clayton #include "ProcessKDPLog.h"
27a63d08c9SGreg Clayton #include "RegisterContextKDP_arm.h"
28a332978bSJason Molenda #include "RegisterContextKDP_arm64.h"
29a63d08c9SGreg Clayton #include "RegisterContextKDP_i386.h"
30a63d08c9SGreg Clayton #include "RegisterContextKDP_x86_64.h"
31a63d08c9SGreg Clayton 
32796ac80bSJonas Devlieghere #include <memory>
33796ac80bSJonas Devlieghere 
34a63d08c9SGreg Clayton using namespace lldb;
35a63d08c9SGreg Clayton using namespace lldb_private;
36a63d08c9SGreg Clayton 
37a63d08c9SGreg Clayton // Thread Registers
38a63d08c9SGreg Clayton 
ThreadKDP(Process & process,lldb::tid_t tid)39b9c1b51eSKate Stone ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid)
40b9c1b51eSKate Stone     : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
41b9c1b51eSKate Stone       m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
42*c8fbf803SPavel Labath   Log *log = GetLog(KDPLog::Thread);
437b35b781SPavel Labath   LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
44a63d08c9SGreg Clayton }
45a63d08c9SGreg Clayton 
~ThreadKDP()46b9c1b51eSKate Stone ThreadKDP::~ThreadKDP() {
47*c8fbf803SPavel Labath   Log *log = GetLog(KDPLog::Thread);
487b35b781SPavel Labath   LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
49a63d08c9SGreg Clayton   DestroyThread();
50a63d08c9SGreg Clayton }
51a63d08c9SGreg Clayton 
GetName()52b9c1b51eSKate Stone const char *ThreadKDP::GetName() {
53a63d08c9SGreg Clayton   if (m_thread_name.empty())
5445d8134cSStella Stamenova     return nullptr;
55a63d08c9SGreg Clayton   return m_thread_name.c_str();
56a63d08c9SGreg Clayton }
57a63d08c9SGreg Clayton 
GetQueueName()5845d8134cSStella Stamenova const char *ThreadKDP::GetQueueName() { return nullptr; }
59a63d08c9SGreg Clayton 
RefreshStateAfterStop()60b9c1b51eSKate Stone void ThreadKDP::RefreshStateAfterStop() {
61a63d08c9SGreg Clayton   // Invalidate all registers in our register context. We don't set "force" to
62a63d08c9SGreg Clayton   // true because the stop reply packet might have had some register values
63a63d08c9SGreg Clayton   // that were expedited and these will already be copied into the register
64a63d08c9SGreg Clayton   // context by the time this function gets called. The KDPRegisterContext
65a63d08c9SGreg Clayton   // class has been made smart enough to detect when it needs to invalidate
66a63d08c9SGreg Clayton   // which registers are valid by putting hooks in the register read and
6705097246SAdrian Prantl   // register supply functions where they check the process stop ID and do the
6805097246SAdrian Prantl   // right thing.
69a63d08c9SGreg Clayton   const bool force = false;
701afa68edSGreg Clayton   lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
711afa68edSGreg Clayton   if (reg_ctx_sp)
721afa68edSGreg Clayton     reg_ctx_sp->InvalidateIfNeeded(force);
73a63d08c9SGreg Clayton }
74a63d08c9SGreg Clayton 
ThreadIDIsValid(lldb::tid_t thread)75b9c1b51eSKate Stone bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
76a63d08c9SGreg Clayton 
Dump(Log * log,uint32_t index)77b9c1b51eSKate Stone void ThreadKDP::Dump(Log *log, uint32_t index) {}
78a63d08c9SGreg Clayton 
ShouldStop(bool & step_more)79b9c1b51eSKate Stone bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
GetRegisterContext()80b9c1b51eSKate Stone lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
8145d8134cSStella Stamenova   if (!m_reg_context_sp)
8245d8134cSStella Stamenova     m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
83a63d08c9SGreg Clayton   return m_reg_context_sp;
84a63d08c9SGreg Clayton }
85a63d08c9SGreg Clayton 
86a63d08c9SGreg Clayton lldb::RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)87b9c1b51eSKate Stone ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
88a63d08c9SGreg Clayton   lldb::RegisterContextSP reg_ctx_sp;
89a63d08c9SGreg Clayton   uint32_t concrete_frame_idx = 0;
90a63d08c9SGreg Clayton 
91a63d08c9SGreg Clayton   if (frame)
92a63d08c9SGreg Clayton     concrete_frame_idx = frame->GetConcreteFrameIndex();
93a63d08c9SGreg Clayton 
94b9c1b51eSKate Stone   if (concrete_frame_idx == 0) {
951ac04c30SGreg Clayton     ProcessSP process_sp(CalculateProcess());
96b9c1b51eSKate Stone     if (process_sp) {
97b9c1b51eSKate Stone       switch (static_cast<ProcessKDP *>(process_sp.get())
98b9c1b51eSKate Stone                   ->GetCommunication()
99b9c1b51eSKate Stone                   .GetCPUType()) {
100510938e5SCharles Davis       case llvm::MachO::CPU_TYPE_ARM:
101796ac80bSJonas Devlieghere         reg_ctx_sp =
102796ac80bSJonas Devlieghere             std::make_shared<RegisterContextKDP_arm>(*this, concrete_frame_idx);
103a63d08c9SGreg Clayton         break;
104a332978bSJason Molenda       case llvm::MachO::CPU_TYPE_ARM64:
105796ac80bSJonas Devlieghere         reg_ctx_sp = std::make_shared<RegisterContextKDP_arm64>(
106796ac80bSJonas Devlieghere             *this, concrete_frame_idx);
107a332978bSJason Molenda         break;
108510938e5SCharles Davis       case llvm::MachO::CPU_TYPE_I386:
109796ac80bSJonas Devlieghere         reg_ctx_sp = std::make_shared<RegisterContextKDP_i386>(
110796ac80bSJonas Devlieghere             *this, concrete_frame_idx);
111a63d08c9SGreg Clayton         break;
112510938e5SCharles Davis       case llvm::MachO::CPU_TYPE_X86_64:
113796ac80bSJonas Devlieghere         reg_ctx_sp = std::make_shared<RegisterContextKDP_x86_64>(
114796ac80bSJonas Devlieghere             *this, concrete_frame_idx);
115a63d08c9SGreg Clayton         break;
116a63d08c9SGreg Clayton       default:
117a322f36cSDavid Blaikie         llvm_unreachable("Add CPU type support in KDP");
118a63d08c9SGreg Clayton       }
119a63d08c9SGreg Clayton     }
120b9c1b51eSKate Stone   } else {
12112ba989eSJonas Devlieghere     reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
122b3ae8761SGreg Clayton   }
123a63d08c9SGreg Clayton   return reg_ctx_sp;
124a63d08c9SGreg Clayton }
125a63d08c9SGreg Clayton 
CalculateStopInfo()126b9c1b51eSKate Stone bool ThreadKDP::CalculateStopInfo() {
1271ac04c30SGreg Clayton   ProcessSP process_sp(GetProcess());
128b9c1b51eSKate Stone   if (process_sp) {
129b9c1b51eSKate Stone     if (m_cached_stop_info_sp) {
13097d5cf05SGreg Clayton       SetStopInfo(m_cached_stop_info_sp);
131b9c1b51eSKate Stone     } else {
132a63d08c9SGreg Clayton       SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
133a63d08c9SGreg Clayton     }
1346e0ff1a3SGreg Clayton     return true;
1351ac04c30SGreg Clayton   }
1366e0ff1a3SGreg Clayton   return false;
137a63d08c9SGreg Clayton }
138a63d08c9SGreg Clayton 
SetStopInfoFrom_KDP_EXCEPTION(const DataExtractor & exc_reply_packet)139b9c1b51eSKate Stone void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
140b9c1b51eSKate Stone     const DataExtractor &exc_reply_packet) {
141c7bece56SGreg Clayton   lldb::offset_t offset = 0;
14297d5cf05SGreg Clayton   uint8_t reply_command = exc_reply_packet.GetU8(&offset);
143b9c1b51eSKate Stone   if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
14497d5cf05SGreg Clayton     offset = 8;
14597d5cf05SGreg Clayton     const uint32_t count = exc_reply_packet.GetU32(&offset);
146b9c1b51eSKate Stone     if (count >= 1) {
14797d5cf05SGreg Clayton       // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
14897d5cf05SGreg Clayton       offset += 4; // Skip the useless CPU field
14997d5cf05SGreg Clayton       const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
15097d5cf05SGreg Clayton       const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
15197d5cf05SGreg Clayton       const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
15205097246SAdrian Prantl       // We have to make a copy of the stop info because the thread list will
15305097246SAdrian Prantl       // iterate through the threads and clear all stop infos..
15497d5cf05SGreg Clayton 
15597d5cf05SGreg Clayton       // Let the StopInfoMachException::CreateStopReasonWithMachException()
15697d5cf05SGreg Clayton       // function update the PC if needed as we might hit a software breakpoint
15797d5cf05SGreg Clayton       // and need to decrement the PC (i386 and x86_64 need this) and KDP
15897d5cf05SGreg Clayton       // doesn't do this for us.
15997d5cf05SGreg Clayton       const bool pc_already_adjusted = false;
16097d5cf05SGreg Clayton       const bool adjust_pc_if_needed = true;
16197d5cf05SGreg Clayton 
162b9c1b51eSKate Stone       m_cached_stop_info_sp =
163b9c1b51eSKate Stone           StopInfoMachException::CreateStopReasonWithMachException(
164b9c1b51eSKate Stone               *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
16597d5cf05SGreg Clayton               adjust_pc_if_needed);
16697d5cf05SGreg Clayton     }
16797d5cf05SGreg Clayton   }
16897d5cf05SGreg Clayton }
169