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 
11a63d08c9SGreg Clayton #include "ThreadKDP.h"
12a63d08c9SGreg Clayton 
13*46d005dbSJim Ingham #include "lldb/Utility/SafeMachO.h"
14a63d08c9SGreg Clayton 
15a63d08c9SGreg Clayton #include "lldb/Core/ArchSpec.h"
16a63d08c9SGreg Clayton #include "lldb/Core/DataExtractor.h"
17a63d08c9SGreg Clayton #include "lldb/Core/StreamString.h"
18a63d08c9SGreg Clayton #include "lldb/Core/State.h"
19a63d08c9SGreg Clayton #include "lldb/Target/Process.h"
20a63d08c9SGreg Clayton #include "lldb/Target/RegisterContext.h"
21a63d08c9SGreg Clayton #include "lldb/Target/StopInfo.h"
22a63d08c9SGreg Clayton #include "lldb/Target/Target.h"
23a63d08c9SGreg Clayton #include "lldb/Target/Unwind.h"
2401a67860SJohnny Chen #include "lldb/Breakpoint/Watchpoint.h"
25a63d08c9SGreg Clayton 
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"
3297d5cf05SGreg Clayton #include "Plugins/Process/Utility/StopInfoMachException.h"
33a63d08c9SGreg Clayton 
34a63d08c9SGreg Clayton using namespace lldb;
35a63d08c9SGreg Clayton using namespace lldb_private;
36a63d08c9SGreg Clayton 
37a63d08c9SGreg Clayton //----------------------------------------------------------------------
38a63d08c9SGreg Clayton // Thread Registers
39a63d08c9SGreg Clayton //----------------------------------------------------------------------
40a63d08c9SGreg Clayton 
414f465cffSJim Ingham ThreadKDP::ThreadKDP (Process &process, lldb::tid_t tid) :
424f465cffSJim Ingham     Thread(process, tid),
43a63d08c9SGreg Clayton     m_thread_name (),
44a63d08c9SGreg Clayton     m_dispatch_queue_name (),
45a63d08c9SGreg Clayton     m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
46a63d08c9SGreg Clayton {
471ac04c30SGreg Clayton     ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID());
48a63d08c9SGreg Clayton }
49a63d08c9SGreg Clayton 
50a63d08c9SGreg Clayton ThreadKDP::~ThreadKDP ()
51a63d08c9SGreg Clayton {
521ac04c30SGreg Clayton     ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID());
53a63d08c9SGreg Clayton     DestroyThread();
54a63d08c9SGreg Clayton }
55a63d08c9SGreg Clayton 
56a63d08c9SGreg Clayton const char *
57a63d08c9SGreg Clayton ThreadKDP::GetName ()
58a63d08c9SGreg Clayton {
59a63d08c9SGreg Clayton     if (m_thread_name.empty())
60a63d08c9SGreg Clayton         return NULL;
61a63d08c9SGreg Clayton     return m_thread_name.c_str();
62a63d08c9SGreg Clayton }
63a63d08c9SGreg Clayton 
64a63d08c9SGreg Clayton const char *
65a63d08c9SGreg Clayton ThreadKDP::GetQueueName ()
66a63d08c9SGreg Clayton {
67a63d08c9SGreg Clayton     return NULL;
68a63d08c9SGreg Clayton }
69a63d08c9SGreg Clayton 
70a63d08c9SGreg Clayton void
71a63d08c9SGreg Clayton ThreadKDP::RefreshStateAfterStop()
72a63d08c9SGreg Clayton {
73a63d08c9SGreg Clayton     // Invalidate all registers in our register context. We don't set "force" to
74a63d08c9SGreg Clayton     // true because the stop reply packet might have had some register values
75a63d08c9SGreg Clayton     // that were expedited and these will already be copied into the register
76a63d08c9SGreg Clayton     // context by the time this function gets called. The KDPRegisterContext
77a63d08c9SGreg Clayton     // class has been made smart enough to detect when it needs to invalidate
78a63d08c9SGreg Clayton     // which registers are valid by putting hooks in the register read and
79a63d08c9SGreg Clayton     // register supply functions where they check the process stop ID and do
80a63d08c9SGreg Clayton     // the right thing.
81a63d08c9SGreg Clayton     const bool force = false;
821afa68edSGreg Clayton     lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
831afa68edSGreg Clayton     if (reg_ctx_sp)
841afa68edSGreg Clayton         reg_ctx_sp->InvalidateIfNeeded (force);
85a63d08c9SGreg Clayton }
86a63d08c9SGreg Clayton 
87a63d08c9SGreg Clayton bool
88a63d08c9SGreg Clayton ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
89a63d08c9SGreg Clayton {
90a63d08c9SGreg Clayton     return thread != 0;
91a63d08c9SGreg Clayton }
92a63d08c9SGreg Clayton 
93a63d08c9SGreg Clayton void
94a63d08c9SGreg Clayton ThreadKDP::Dump(Log *log, uint32_t index)
95a63d08c9SGreg Clayton {
96a63d08c9SGreg Clayton }
97a63d08c9SGreg Clayton 
98a63d08c9SGreg Clayton 
99a63d08c9SGreg Clayton bool
100a63d08c9SGreg Clayton ThreadKDP::ShouldStop (bool &step_more)
101a63d08c9SGreg Clayton {
102a63d08c9SGreg Clayton     return true;
103a63d08c9SGreg Clayton }
104a63d08c9SGreg Clayton lldb::RegisterContextSP
105a63d08c9SGreg Clayton ThreadKDP::GetRegisterContext ()
106a63d08c9SGreg Clayton {
107a63d08c9SGreg Clayton     if (m_reg_context_sp.get() == NULL)
108a63d08c9SGreg Clayton         m_reg_context_sp = CreateRegisterContextForFrame (NULL);
109a63d08c9SGreg Clayton     return m_reg_context_sp;
110a63d08c9SGreg Clayton }
111a63d08c9SGreg Clayton 
112a63d08c9SGreg Clayton lldb::RegisterContextSP
113b57e4a1bSJason Molenda ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame)
114a63d08c9SGreg Clayton {
115a63d08c9SGreg Clayton     lldb::RegisterContextSP reg_ctx_sp;
116a63d08c9SGreg Clayton     uint32_t concrete_frame_idx = 0;
117a63d08c9SGreg Clayton 
118a63d08c9SGreg Clayton     if (frame)
119a63d08c9SGreg Clayton         concrete_frame_idx = frame->GetConcreteFrameIndex ();
120a63d08c9SGreg Clayton 
121a63d08c9SGreg Clayton     if (concrete_frame_idx == 0)
122a63d08c9SGreg Clayton     {
1231ac04c30SGreg Clayton         ProcessSP process_sp (CalculateProcess());
1241ac04c30SGreg Clayton         if (process_sp)
1251ac04c30SGreg Clayton         {
1261ac04c30SGreg Clayton             switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType())
127a63d08c9SGreg Clayton             {
128510938e5SCharles Davis                 case llvm::MachO::CPU_TYPE_ARM:
129a63d08c9SGreg Clayton                     reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
130a63d08c9SGreg Clayton                     break;
131a332978bSJason Molenda                 case llvm::MachO::CPU_TYPE_ARM64:
132a332978bSJason Molenda                     reg_ctx_sp.reset (new RegisterContextKDP_arm64 (*this, concrete_frame_idx));
133a332978bSJason Molenda                     break;
134510938e5SCharles Davis                 case llvm::MachO::CPU_TYPE_I386:
135a63d08c9SGreg Clayton                     reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
136a63d08c9SGreg Clayton                     break;
137510938e5SCharles Davis                 case llvm::MachO::CPU_TYPE_X86_64:
138a63d08c9SGreg Clayton                     reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
139a63d08c9SGreg Clayton                     break;
140a63d08c9SGreg Clayton                 default:
141a63d08c9SGreg Clayton                     assert (!"Add CPU type support in KDP");
142a63d08c9SGreg Clayton                     break;
143a63d08c9SGreg Clayton             }
144a63d08c9SGreg Clayton         }
1451ac04c30SGreg Clayton     }
146b3ae8761SGreg Clayton     else
147b3ae8761SGreg Clayton     {
148b3ae8761SGreg Clayton         Unwind *unwinder = GetUnwinder ();
149b3ae8761SGreg Clayton         if (unwinder)
150b3ae8761SGreg Clayton             reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
151b3ae8761SGreg Clayton     }
152a63d08c9SGreg Clayton     return reg_ctx_sp;
153a63d08c9SGreg Clayton }
154a63d08c9SGreg Clayton 
1556e0ff1a3SGreg Clayton bool
1566e0ff1a3SGreg Clayton ThreadKDP::CalculateStopInfo ()
157a63d08c9SGreg Clayton {
1581ac04c30SGreg Clayton     ProcessSP process_sp (GetProcess());
1591ac04c30SGreg Clayton     if (process_sp)
1601ac04c30SGreg Clayton     {
16197d5cf05SGreg Clayton         if (m_cached_stop_info_sp)
1626e0ff1a3SGreg Clayton         {
16397d5cf05SGreg Clayton             SetStopInfo (m_cached_stop_info_sp);
1646e0ff1a3SGreg Clayton         }
16597d5cf05SGreg Clayton         else
1666e0ff1a3SGreg Clayton         {
167a63d08c9SGreg Clayton             SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
168a63d08c9SGreg Clayton         }
1696e0ff1a3SGreg Clayton         return true;
1701ac04c30SGreg Clayton     }
1716e0ff1a3SGreg Clayton     return false;
172a63d08c9SGreg Clayton }
173a63d08c9SGreg Clayton 
17497d5cf05SGreg Clayton void
17597d5cf05SGreg Clayton ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
17697d5cf05SGreg Clayton {
177c7bece56SGreg Clayton     lldb::offset_t offset = 0;
17897d5cf05SGreg Clayton     uint8_t reply_command = exc_reply_packet.GetU8(&offset);
17997d5cf05SGreg Clayton     if (reply_command == CommunicationKDP::KDP_EXCEPTION)
18097d5cf05SGreg Clayton     {
18197d5cf05SGreg Clayton         offset = 8;
18297d5cf05SGreg Clayton         const uint32_t count = exc_reply_packet.GetU32 (&offset);
18397d5cf05SGreg Clayton         if (count >= 1)
18497d5cf05SGreg Clayton         {
18597d5cf05SGreg Clayton             //const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
18697d5cf05SGreg Clayton             offset += 4; // Skip the useless CPU field
18797d5cf05SGreg Clayton             const uint32_t exc_type = exc_reply_packet.GetU32 (&offset);
18897d5cf05SGreg Clayton             const uint32_t exc_code = exc_reply_packet.GetU32 (&offset);
18997d5cf05SGreg Clayton             const uint32_t exc_subcode = exc_reply_packet.GetU32 (&offset);
19097d5cf05SGreg Clayton             // We have to make a copy of the stop info because the thread list
19197d5cf05SGreg Clayton             // will iterate through the threads and clear all stop infos..
19297d5cf05SGreg Clayton 
19397d5cf05SGreg Clayton             // Let the StopInfoMachException::CreateStopReasonWithMachException()
19497d5cf05SGreg Clayton             // function update the PC if needed as we might hit a software breakpoint
19597d5cf05SGreg Clayton             // and need to decrement the PC (i386 and x86_64 need this) and KDP
19697d5cf05SGreg Clayton             // doesn't do this for us.
19797d5cf05SGreg Clayton             const bool pc_already_adjusted = false;
19897d5cf05SGreg Clayton             const bool adjust_pc_if_needed = true;
19997d5cf05SGreg Clayton 
20097d5cf05SGreg Clayton             m_cached_stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException (*this,
20197d5cf05SGreg Clayton                                                                                               exc_type,
20297d5cf05SGreg Clayton                                                                                               2,
20397d5cf05SGreg Clayton                                                                                               exc_code,
20497d5cf05SGreg Clayton                                                                                               exc_subcode,
20597d5cf05SGreg Clayton                                                                                               0,
20697d5cf05SGreg Clayton                                                                                               pc_already_adjusted,
20797d5cf05SGreg Clayton                                                                                               adjust_pc_if_needed);
20897d5cf05SGreg Clayton         }
20997d5cf05SGreg Clayton     }
21097d5cf05SGreg Clayton }
211a63d08c9SGreg Clayton 
212