• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ThreadKDP(Process & process,lldb::tid_t tid)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 
~ThreadKDP()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 *
GetName()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 *
GetQueueName()64 ThreadKDP::GetQueueName ()
65 {
66     return NULL;
67 }
68 
69 void
RefreshStateAfterStop()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
ThreadIDIsValid(lldb::tid_t thread)87 ThreadKDP::ThreadIDIsValid (lldb::tid_t thread)
88 {
89     return thread != 0;
90 }
91 
92 void
Dump(Log * log,uint32_t index)93 ThreadKDP::Dump(Log *log, uint32_t index)
94 {
95 }
96 
97 
98 bool
ShouldStop(bool & step_more)99 ThreadKDP::ShouldStop (bool &step_more)
100 {
101     return true;
102 }
103 lldb::RegisterContextSP
GetRegisterContext()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
CreateRegisterContextForFrame(StackFrame * frame)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 bool
CalculateStopInfo()152 ThreadKDP::CalculateStopInfo ()
153 {
154     ProcessSP process_sp (GetProcess());
155     if (process_sp)
156     {
157         if (m_cached_stop_info_sp)
158         {
159             SetStopInfo (m_cached_stop_info_sp);
160         }
161         else
162         {
163             SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
164         }
165         return true;
166     }
167     return false;
168 }
169 
170 void
SetStopInfoFrom_KDP_EXCEPTION(const DataExtractor & exc_reply_packet)171 ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
172 {
173     lldb::offset_t offset = 0;
174     uint8_t reply_command = exc_reply_packet.GetU8(&offset);
175     if (reply_command == CommunicationKDP::KDP_EXCEPTION)
176     {
177         offset = 8;
178         const uint32_t count = exc_reply_packet.GetU32 (&offset);
179         if (count >= 1)
180         {
181             //const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
182             offset += 4; // Skip the useless CPU field
183             const uint32_t exc_type = exc_reply_packet.GetU32 (&offset);
184             const uint32_t exc_code = exc_reply_packet.GetU32 (&offset);
185             const uint32_t exc_subcode = exc_reply_packet.GetU32 (&offset);
186             // We have to make a copy of the stop info because the thread list
187             // will iterate through the threads and clear all stop infos..
188 
189             // Let the StopInfoMachException::CreateStopReasonWithMachException()
190             // function update the PC if needed as we might hit a software breakpoint
191             // and need to decrement the PC (i386 and x86_64 need this) and KDP
192             // doesn't do this for us.
193             const bool pc_already_adjusted = false;
194             const bool adjust_pc_if_needed = true;
195 
196             m_cached_stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException (*this,
197                                                                                               exc_type,
198                                                                                               2,
199                                                                                               exc_code,
200                                                                                               exc_subcode,
201                                                                                               0,
202                                                                                               pc_already_adjusted,
203                                                                                               adjust_pc_if_needed);
204         }
205     }
206 }
207 
208