1 //===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 
11 #include "ThreadKDP.h"
12 
13 #include "llvm/Support/MachO.h"
14 
15 #include "lldb/Core/ArchSpec.h"
16 #include "lldb/Core/DataExtractor.h"
17 #include "lldb/Core/StreamString.h"
18 #include "lldb/Core/State.h"
19 #include "lldb/Target/Process.h"
20 #include "lldb/Target/RegisterContext.h"
21 #include "lldb/Target/StopInfo.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/Unwind.h"
24 #include "lldb/Breakpoint/Watchpoint.h"
25 
26 #include "ProcessKDP.h"
27 #include "ProcessKDPLog.h"
28 #include "RegisterContextKDP_arm.h"
29 #include "RegisterContextKDP_i386.h"
30 #include "RegisterContextKDP_x86_64.h"
31 #include "Plugins/Process/Utility/StopInfoMachException.h"
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 //----------------------------------------------------------------------
37 // Thread Registers
38 //----------------------------------------------------------------------
39 
40 ThreadKDP::ThreadKDP (Process &process, lldb::tid_t tid) :
41     Thread(process, tid),
42     m_thread_name (),
43     m_dispatch_queue_name (),
44     m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
45 {
46     ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID());
47 }
48 
49 ThreadKDP::~ThreadKDP ()
50 {
51     ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID());
52     DestroyThread();
53 }
54 
55 const char *
56 ThreadKDP::GetName ()
57 {
58     if (m_thread_name.empty())
59         return NULL;
60     return m_thread_name.c_str();
61 }
62 
63 const char *
64 ThreadKDP::GetQueueName ()
65 {
66     return NULL;
67 }
68 
69 void
70 ThreadKDP::RefreshStateAfterStop()
71 {
72     // Invalidate all registers in our register context. We don't set "force" to
73     // true because the stop reply packet might have had some register values
74     // that were expedited and these will already be copied into the register
75     // context by the time this function gets called. The KDPRegisterContext
76     // class has been made smart enough to detect when it needs to invalidate
77     // which registers are valid by putting hooks in the register read and
78     // register supply functions where they check the process stop ID and do
79     // the right thing.
80     const bool force = false;
81     lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
82     if (reg_ctx_sp)
83         reg_ctx_sp->InvalidateIfNeeded (force);
84 }
85 
86 bool
87 ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
88 {
89     return thread != 0;
90 }
91 
92 void
93 ThreadKDP::Dump(Log *log, uint32_t index)
94 {
95 }
96 
97 
98 bool
99 ThreadKDP::ShouldStop (bool &step_more)
100 {
101     return true;
102 }
103 lldb::RegisterContextSP
104 ThreadKDP::GetRegisterContext ()
105 {
106     if (m_reg_context_sp.get() == NULL)
107         m_reg_context_sp = CreateRegisterContextForFrame (NULL);
108     return m_reg_context_sp;
109 }
110 
111 lldb::RegisterContextSP
112 ThreadKDP::CreateRegisterContextForFrame (StackFrame *frame)
113 {
114     lldb::RegisterContextSP reg_ctx_sp;
115     uint32_t concrete_frame_idx = 0;
116 
117     if (frame)
118         concrete_frame_idx = frame->GetConcreteFrameIndex ();
119 
120     if (concrete_frame_idx == 0)
121     {
122         ProcessSP process_sp (CalculateProcess());
123         if (process_sp)
124         {
125             switch (static_cast<ProcessKDP *>(process_sp.get())->GetCommunication().GetCPUType())
126             {
127                 case llvm::MachO::CPUTypeARM:
128                     reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
129                     break;
130                 case llvm::MachO::CPUTypeI386:
131                     reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
132                     break;
133                 case llvm::MachO::CPUTypeX86_64:
134                     reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
135                     break;
136                 default:
137                     assert (!"Add CPU type support in KDP");
138                     break;
139             }
140         }
141     }
142     else
143     {
144         Unwind *unwinder = GetUnwinder ();
145         if (unwinder)
146             reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
147     }
148     return reg_ctx_sp;
149 }
150 
151 lldb::StopInfoSP
152 ThreadKDP::GetPrivateStopReason ()
153 {
154     ProcessSP process_sp (GetProcess());
155     if (process_sp)
156     {
157         const uint32_t process_stop_id = process_sp->GetStopID();
158         if (m_thread_stop_reason_stop_id != process_stop_id ||
159             (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
160         {
161             if (IsStillAtLastBreakpointHit())
162                 return m_actual_stop_info_sp;
163 
164             if (m_cached_stop_info_sp)
165                 SetStopInfo (m_cached_stop_info_sp);
166             else
167                 SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
168         }
169     }
170     return m_actual_stop_info_sp;
171 }
172 
173 void
174 ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
175 {
176     lldb::offset_t offset = 0;
177     uint8_t reply_command = exc_reply_packet.GetU8(&offset);
178     if (reply_command == CommunicationKDP::KDP_EXCEPTION)
179     {
180         offset = 8;
181         const uint32_t count = exc_reply_packet.GetU32 (&offset);
182         if (count >= 1)
183         {
184             //const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
185             offset += 4; // Skip the useless CPU field
186             const uint32_t exc_type = exc_reply_packet.GetU32 (&offset);
187             const uint32_t exc_code = exc_reply_packet.GetU32 (&offset);
188             const uint32_t exc_subcode = exc_reply_packet.GetU32 (&offset);
189             // We have to make a copy of the stop info because the thread list
190             // will iterate through the threads and clear all stop infos..
191 
192             // Let the StopInfoMachException::CreateStopReasonWithMachException()
193             // function update the PC if needed as we might hit a software breakpoint
194             // and need to decrement the PC (i386 and x86_64 need this) and KDP
195             // doesn't do this for us.
196             const bool pc_already_adjusted = false;
197             const bool adjust_pc_if_needed = true;
198 
199             m_cached_stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException (*this,
200                                                                                               exc_type,
201                                                                                               2,
202                                                                                               exc_code,
203                                                                                               exc_subcode,
204                                                                                               0,
205                                                                                               pc_already_adjusted,
206                                                                                               adjust_pc_if_needed);
207         }
208     }
209 }
210 
211