1a63d08c9SGreg Clayton //===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===//
2a63d08c9SGreg Clayton //
3a63d08c9SGreg Clayton //                     The LLVM Compiler Infrastructure
4a63d08c9SGreg Clayton //
5a63d08c9SGreg Clayton // This file is distributed under the University of Illinois Open Source
6a63d08c9SGreg Clayton // License. See LICENSE.TXT for details.
7a63d08c9SGreg Clayton //
8a63d08c9SGreg Clayton //===----------------------------------------------------------------------===//
9a63d08c9SGreg Clayton 
10a63d08c9SGreg Clayton #include "ThreadKDP.h"
11a63d08c9SGreg Clayton 
1246d005dbSJim Ingham #include "lldb/Utility/SafeMachO.h"
13a63d08c9SGreg Clayton 
14b9c1b51eSKate Stone #include "lldb/Breakpoint/Watchpoint.h"
15a63d08c9SGreg Clayton #include "lldb/Core/ArchSpec.h"
16a63d08c9SGreg Clayton #include "lldb/Core/State.h"
17a63d08c9SGreg Clayton #include "lldb/Target/Process.h"
18a63d08c9SGreg Clayton #include "lldb/Target/RegisterContext.h"
19a63d08c9SGreg Clayton #include "lldb/Target/StopInfo.h"
20a63d08c9SGreg Clayton #include "lldb/Target/Target.h"
21a63d08c9SGreg Clayton #include "lldb/Target/Unwind.h"
22*666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h"
23bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
24a63d08c9SGreg Clayton 
25b9c1b51eSKate Stone #include "Plugins/Process/Utility/StopInfoMachException.h"
26a63d08c9SGreg Clayton #include "ProcessKDP.h"
27a63d08c9SGreg Clayton #include "ProcessKDPLog.h"
28a63d08c9SGreg Clayton #include "RegisterContextKDP_arm.h"
29a332978bSJason Molenda #include "RegisterContextKDP_arm64.h"
30a63d08c9SGreg Clayton #include "RegisterContextKDP_i386.h"
31a63d08c9SGreg Clayton #include "RegisterContextKDP_x86_64.h"
32a63d08c9SGreg Clayton 
33a63d08c9SGreg Clayton using namespace lldb;
34a63d08c9SGreg Clayton using namespace lldb_private;
35a63d08c9SGreg Clayton 
36a63d08c9SGreg Clayton //----------------------------------------------------------------------
37a63d08c9SGreg Clayton // Thread Registers
38a63d08c9SGreg Clayton //----------------------------------------------------------------------
39a63d08c9SGreg Clayton 
40b9c1b51eSKate Stone ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid)
41b9c1b51eSKate Stone     : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
42b9c1b51eSKate Stone       m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
437b35b781SPavel Labath   Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
447b35b781SPavel Labath   LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
45a63d08c9SGreg Clayton }
46a63d08c9SGreg Clayton 
47b9c1b51eSKate Stone ThreadKDP::~ThreadKDP() {
487b35b781SPavel Labath   Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
497b35b781SPavel Labath   LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
50a63d08c9SGreg Clayton   DestroyThread();
51a63d08c9SGreg Clayton }
52a63d08c9SGreg Clayton 
53b9c1b51eSKate Stone const char *ThreadKDP::GetName() {
54a63d08c9SGreg Clayton   if (m_thread_name.empty())
55a63d08c9SGreg Clayton     return NULL;
56a63d08c9SGreg Clayton   return m_thread_name.c_str();
57a63d08c9SGreg Clayton }
58a63d08c9SGreg Clayton 
59b9c1b51eSKate Stone const char *ThreadKDP::GetQueueName() { return NULL; }
60a63d08c9SGreg Clayton 
61b9c1b51eSKate Stone void ThreadKDP::RefreshStateAfterStop() {
62a63d08c9SGreg Clayton   // Invalidate all registers in our register context. We don't set "force" to
63a63d08c9SGreg Clayton   // true because the stop reply packet might have had some register values
64a63d08c9SGreg Clayton   // that were expedited and these will already be copied into the register
65a63d08c9SGreg Clayton   // context by the time this function gets called. The KDPRegisterContext
66a63d08c9SGreg Clayton   // class has been made smart enough to detect when it needs to invalidate
67a63d08c9SGreg Clayton   // which registers are valid by putting hooks in the register read and
68a63d08c9SGreg Clayton   // register supply functions where they check the process stop ID and do
69a63d08c9SGreg Clayton   // the right thing.
70a63d08c9SGreg Clayton   const bool force = false;
711afa68edSGreg Clayton   lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
721afa68edSGreg Clayton   if (reg_ctx_sp)
731afa68edSGreg Clayton     reg_ctx_sp->InvalidateIfNeeded(force);
74a63d08c9SGreg Clayton }
75a63d08c9SGreg Clayton 
76b9c1b51eSKate Stone bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
77a63d08c9SGreg Clayton 
78b9c1b51eSKate Stone void ThreadKDP::Dump(Log *log, uint32_t index) {}
79a63d08c9SGreg Clayton 
80b9c1b51eSKate Stone bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
81b9c1b51eSKate Stone lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
82a63d08c9SGreg Clayton   if (m_reg_context_sp.get() == NULL)
83a63d08c9SGreg Clayton     m_reg_context_sp = CreateRegisterContextForFrame(NULL);
84a63d08c9SGreg Clayton   return m_reg_context_sp;
85a63d08c9SGreg Clayton }
86a63d08c9SGreg Clayton 
87a63d08c9SGreg Clayton lldb::RegisterContextSP
88b9c1b51eSKate Stone ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
89a63d08c9SGreg Clayton   lldb::RegisterContextSP reg_ctx_sp;
90a63d08c9SGreg Clayton   uint32_t concrete_frame_idx = 0;
91a63d08c9SGreg Clayton 
92a63d08c9SGreg Clayton   if (frame)
93a63d08c9SGreg Clayton     concrete_frame_idx = frame->GetConcreteFrameIndex();
94a63d08c9SGreg Clayton 
95b9c1b51eSKate Stone   if (concrete_frame_idx == 0) {
961ac04c30SGreg Clayton     ProcessSP process_sp(CalculateProcess());
97b9c1b51eSKate Stone     if (process_sp) {
98b9c1b51eSKate Stone       switch (static_cast<ProcessKDP *>(process_sp.get())
99b9c1b51eSKate Stone                   ->GetCommunication()
100b9c1b51eSKate Stone                   .GetCPUType()) {
101510938e5SCharles Davis       case llvm::MachO::CPU_TYPE_ARM:
102a63d08c9SGreg Clayton         reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx));
103a63d08c9SGreg Clayton         break;
104a332978bSJason Molenda       case llvm::MachO::CPU_TYPE_ARM64:
105b9c1b51eSKate Stone         reg_ctx_sp.reset(
106b9c1b51eSKate Stone             new RegisterContextKDP_arm64(*this, concrete_frame_idx));
107a332978bSJason Molenda         break;
108510938e5SCharles Davis       case llvm::MachO::CPU_TYPE_I386:
109b9c1b51eSKate Stone         reg_ctx_sp.reset(
110b9c1b51eSKate Stone             new RegisterContextKDP_i386(*this, concrete_frame_idx));
111a63d08c9SGreg Clayton         break;
112510938e5SCharles Davis       case llvm::MachO::CPU_TYPE_X86_64:
113b9c1b51eSKate Stone         reg_ctx_sp.reset(
114b9c1b51eSKate Stone             new RegisterContextKDP_x86_64(*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 {
121b3ae8761SGreg Clayton     Unwind *unwinder = GetUnwinder();
122b3ae8761SGreg Clayton     if (unwinder)
123b3ae8761SGreg Clayton       reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
124b3ae8761SGreg Clayton   }
125a63d08c9SGreg Clayton   return reg_ctx_sp;
126a63d08c9SGreg Clayton }
127a63d08c9SGreg Clayton 
128b9c1b51eSKate Stone bool ThreadKDP::CalculateStopInfo() {
1291ac04c30SGreg Clayton   ProcessSP process_sp(GetProcess());
130b9c1b51eSKate Stone   if (process_sp) {
131b9c1b51eSKate Stone     if (m_cached_stop_info_sp) {
13297d5cf05SGreg Clayton       SetStopInfo(m_cached_stop_info_sp);
133b9c1b51eSKate Stone     } else {
134a63d08c9SGreg Clayton       SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
135a63d08c9SGreg Clayton     }
1366e0ff1a3SGreg Clayton     return true;
1371ac04c30SGreg Clayton   }
1386e0ff1a3SGreg Clayton   return false;
139a63d08c9SGreg Clayton }
140a63d08c9SGreg Clayton 
141b9c1b51eSKate Stone void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
142b9c1b51eSKate Stone     const DataExtractor &exc_reply_packet) {
143c7bece56SGreg Clayton   lldb::offset_t offset = 0;
14497d5cf05SGreg Clayton   uint8_t reply_command = exc_reply_packet.GetU8(&offset);
145b9c1b51eSKate Stone   if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
14697d5cf05SGreg Clayton     offset = 8;
14797d5cf05SGreg Clayton     const uint32_t count = exc_reply_packet.GetU32(&offset);
148b9c1b51eSKate Stone     if (count >= 1) {
14997d5cf05SGreg Clayton       // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
15097d5cf05SGreg Clayton       offset += 4; // Skip the useless CPU field
15197d5cf05SGreg Clayton       const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
15297d5cf05SGreg Clayton       const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
15397d5cf05SGreg Clayton       const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
15497d5cf05SGreg Clayton       // We have to make a copy of the stop info because the thread list
15597d5cf05SGreg Clayton       // will iterate through the threads and clear all stop infos..
15697d5cf05SGreg Clayton 
15797d5cf05SGreg Clayton       // Let the StopInfoMachException::CreateStopReasonWithMachException()
15897d5cf05SGreg Clayton       // function update the PC if needed as we might hit a software breakpoint
15997d5cf05SGreg Clayton       // and need to decrement the PC (i386 and x86_64 need this) and KDP
16097d5cf05SGreg Clayton       // doesn't do this for us.
16197d5cf05SGreg Clayton       const bool pc_already_adjusted = false;
16297d5cf05SGreg Clayton       const bool adjust_pc_if_needed = true;
16397d5cf05SGreg Clayton 
164b9c1b51eSKate Stone       m_cached_stop_info_sp =
165b9c1b51eSKate Stone           StopInfoMachException::CreateStopReasonWithMachException(
166b9c1b51eSKate Stone               *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
16797d5cf05SGreg Clayton               adjust_pc_if_needed);
16897d5cf05SGreg Clayton     }
16997d5cf05SGreg Clayton   }
17097d5cf05SGreg Clayton }
171