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 
13a63d08c9SGreg Clayton #include "llvm/Support/MachO.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"
29a63d08c9SGreg Clayton #include "RegisterContextKDP_i386.h"
30a63d08c9SGreg Clayton #include "RegisterContextKDP_x86_64.h"
3197d5cf05SGreg Clayton #include "Plugins/Process/Utility/StopInfoMachException.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 
404f465cffSJim Ingham ThreadKDP::ThreadKDP (Process &process, lldb::tid_t tid) :
414f465cffSJim Ingham     Thread(process, tid),
42a63d08c9SGreg Clayton     m_thread_name (),
43a63d08c9SGreg Clayton     m_dispatch_queue_name (),
44a63d08c9SGreg Clayton     m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
45a63d08c9SGreg Clayton {
461ac04c30SGreg Clayton     ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID());
47a63d08c9SGreg Clayton }
48a63d08c9SGreg Clayton 
49a63d08c9SGreg Clayton ThreadKDP::~ThreadKDP ()
50a63d08c9SGreg Clayton {
511ac04c30SGreg Clayton     ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID());
52a63d08c9SGreg Clayton     DestroyThread();
53a63d08c9SGreg Clayton }
54a63d08c9SGreg Clayton 
55a63d08c9SGreg Clayton const char *
56a63d08c9SGreg Clayton ThreadKDP::GetName ()
57a63d08c9SGreg Clayton {
58a63d08c9SGreg Clayton     if (m_thread_name.empty())
59a63d08c9SGreg Clayton         return NULL;
60a63d08c9SGreg Clayton     return m_thread_name.c_str();
61a63d08c9SGreg Clayton }
62a63d08c9SGreg Clayton 
63a63d08c9SGreg Clayton const char *
64a63d08c9SGreg Clayton ThreadKDP::GetQueueName ()
65a63d08c9SGreg Clayton {
66a63d08c9SGreg Clayton     return NULL;
67a63d08c9SGreg Clayton }
68a63d08c9SGreg Clayton 
69a63d08c9SGreg Clayton void
70a63d08c9SGreg Clayton ThreadKDP::RefreshStateAfterStop()
71a63d08c9SGreg Clayton {
72a63d08c9SGreg Clayton     // Invalidate all registers in our register context. We don't set "force" to
73a63d08c9SGreg Clayton     // true because the stop reply packet might have had some register values
74a63d08c9SGreg Clayton     // that were expedited and these will already be copied into the register
75a63d08c9SGreg Clayton     // context by the time this function gets called. The KDPRegisterContext
76a63d08c9SGreg Clayton     // class has been made smart enough to detect when it needs to invalidate
77a63d08c9SGreg Clayton     // which registers are valid by putting hooks in the register read and
78a63d08c9SGreg Clayton     // register supply functions where they check the process stop ID and do
79a63d08c9SGreg Clayton     // the right thing.
80a63d08c9SGreg Clayton     const bool force = false;
811afa68edSGreg Clayton     lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
821afa68edSGreg Clayton     if (reg_ctx_sp)
831afa68edSGreg Clayton         reg_ctx_sp->InvalidateIfNeeded (force);
84a63d08c9SGreg Clayton }
85a63d08c9SGreg Clayton 
86a63d08c9SGreg Clayton bool
87a63d08c9SGreg Clayton ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
88a63d08c9SGreg Clayton {
89a63d08c9SGreg Clayton     return thread != 0;
90a63d08c9SGreg Clayton }
91a63d08c9SGreg Clayton 
92a63d08c9SGreg Clayton void
93a63d08c9SGreg Clayton ThreadKDP::Dump(Log *log, uint32_t index)
94a63d08c9SGreg Clayton {
95a63d08c9SGreg Clayton }
96a63d08c9SGreg Clayton 
97a63d08c9SGreg Clayton 
98a63d08c9SGreg Clayton bool
99a63d08c9SGreg Clayton ThreadKDP::ShouldStop (bool &step_more)
100a63d08c9SGreg Clayton {
101a63d08c9SGreg Clayton     return true;
102a63d08c9SGreg Clayton }
103a63d08c9SGreg Clayton lldb::RegisterContextSP
104a63d08c9SGreg Clayton ThreadKDP::GetRegisterContext ()
105a63d08c9SGreg Clayton {
106a63d08c9SGreg Clayton     if (m_reg_context_sp.get() == NULL)
107a63d08c9SGreg Clayton         m_reg_context_sp = CreateRegisterContextForFrame (NULL);
108a63d08c9SGreg Clayton     return m_reg_context_sp;
109a63d08c9SGreg Clayton }
110a63d08c9SGreg Clayton 
111a63d08c9SGreg Clayton lldb::RegisterContextSP
112*b57e4a1bSJason Molenda ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame)
113a63d08c9SGreg Clayton {
114a63d08c9SGreg Clayton     lldb::RegisterContextSP reg_ctx_sp;
115a63d08c9SGreg Clayton     uint32_t concrete_frame_idx = 0;
116a63d08c9SGreg Clayton 
117a63d08c9SGreg Clayton     if (frame)
118a63d08c9SGreg Clayton         concrete_frame_idx = frame->GetConcreteFrameIndex ();
119a63d08c9SGreg Clayton 
120a63d08c9SGreg Clayton     if (concrete_frame_idx == 0)
121a63d08c9SGreg Clayton     {
1221ac04c30SGreg Clayton         ProcessSP process_sp (CalculateProcess());
1231ac04c30SGreg Clayton         if (process_sp)
1241ac04c30SGreg Clayton         {
1251ac04c30SGreg Clayton             switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType())
126a63d08c9SGreg Clayton             {
127510938e5SCharles Davis                 case llvm::MachO::CPU_TYPE_ARM:
128a63d08c9SGreg Clayton                     reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
129a63d08c9SGreg Clayton                     break;
130510938e5SCharles Davis                 case llvm::MachO::CPU_TYPE_I386:
131a63d08c9SGreg Clayton                     reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
132a63d08c9SGreg Clayton                     break;
133510938e5SCharles Davis                 case llvm::MachO::CPU_TYPE_X86_64:
134a63d08c9SGreg Clayton                     reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
135a63d08c9SGreg Clayton                     break;
136a63d08c9SGreg Clayton                 default:
137a63d08c9SGreg Clayton                     assert (!"Add CPU type support in KDP");
138a63d08c9SGreg Clayton                     break;
139a63d08c9SGreg Clayton             }
140a63d08c9SGreg Clayton         }
1411ac04c30SGreg Clayton     }
142b3ae8761SGreg Clayton     else
143b3ae8761SGreg Clayton     {
144b3ae8761SGreg Clayton         Unwind *unwinder = GetUnwinder ();
145b3ae8761SGreg Clayton         if (unwinder)
146b3ae8761SGreg Clayton             reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
147b3ae8761SGreg Clayton     }
148a63d08c9SGreg Clayton     return reg_ctx_sp;
149a63d08c9SGreg Clayton }
150a63d08c9SGreg Clayton 
1516e0ff1a3SGreg Clayton bool
1526e0ff1a3SGreg Clayton ThreadKDP::CalculateStopInfo ()
153a63d08c9SGreg Clayton {
1541ac04c30SGreg Clayton     ProcessSP process_sp (GetProcess());
1551ac04c30SGreg Clayton     if (process_sp)
1561ac04c30SGreg Clayton     {
15797d5cf05SGreg Clayton         if (m_cached_stop_info_sp)
1586e0ff1a3SGreg Clayton         {
15997d5cf05SGreg Clayton             SetStopInfo (m_cached_stop_info_sp);
1606e0ff1a3SGreg Clayton         }
16197d5cf05SGreg Clayton         else
1626e0ff1a3SGreg Clayton         {
163a63d08c9SGreg Clayton             SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
164a63d08c9SGreg Clayton         }
1656e0ff1a3SGreg Clayton         return true;
1661ac04c30SGreg Clayton     }
1676e0ff1a3SGreg Clayton     return false;
168a63d08c9SGreg Clayton }
169a63d08c9SGreg Clayton 
17097d5cf05SGreg Clayton void
17197d5cf05SGreg Clayton ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
17297d5cf05SGreg Clayton {
173c7bece56SGreg Clayton     lldb::offset_t offset = 0;
17497d5cf05SGreg Clayton     uint8_t reply_command = exc_reply_packet.GetU8(&offset);
17597d5cf05SGreg Clayton     if (reply_command == CommunicationKDP::KDP_EXCEPTION)
17697d5cf05SGreg Clayton     {
17797d5cf05SGreg Clayton         offset = 8;
17897d5cf05SGreg Clayton         const uint32_t count = exc_reply_packet.GetU32 (&offset);
17997d5cf05SGreg Clayton         if (count >= 1)
18097d5cf05SGreg Clayton         {
18197d5cf05SGreg Clayton             //const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
18297d5cf05SGreg Clayton             offset += 4; // Skip the useless CPU field
18397d5cf05SGreg Clayton             const uint32_t exc_type = exc_reply_packet.GetU32 (&offset);
18497d5cf05SGreg Clayton             const uint32_t exc_code = exc_reply_packet.GetU32 (&offset);
18597d5cf05SGreg Clayton             const uint32_t exc_subcode = exc_reply_packet.GetU32 (&offset);
18697d5cf05SGreg Clayton             // We have to make a copy of the stop info because the thread list
18797d5cf05SGreg Clayton             // will iterate through the threads and clear all stop infos..
18897d5cf05SGreg Clayton 
18997d5cf05SGreg Clayton             // Let the StopInfoMachException::CreateStopReasonWithMachException()
19097d5cf05SGreg Clayton             // function update the PC if needed as we might hit a software breakpoint
19197d5cf05SGreg Clayton             // and need to decrement the PC (i386 and x86_64 need this) and KDP
19297d5cf05SGreg Clayton             // doesn't do this for us.
19397d5cf05SGreg Clayton             const bool pc_already_adjusted = false;
19497d5cf05SGreg Clayton             const bool adjust_pc_if_needed = true;
19597d5cf05SGreg Clayton 
19697d5cf05SGreg Clayton             m_cached_stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException (*this,
19797d5cf05SGreg Clayton                                                                                               exc_type,
19897d5cf05SGreg Clayton                                                                                               2,
19997d5cf05SGreg Clayton                                                                                               exc_code,
20097d5cf05SGreg Clayton                                                                                               exc_subcode,
20197d5cf05SGreg Clayton                                                                                               0,
20297d5cf05SGreg Clayton                                                                                               pc_already_adjusted,
20397d5cf05SGreg Clayton                                                                                               adjust_pc_if_needed);
20497d5cf05SGreg Clayton         }
20597d5cf05SGreg Clayton     }
20697d5cf05SGreg Clayton }
207a63d08c9SGreg Clayton 
208