]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Plugins / Process / MacOSX-Kernel / ThreadKDP.cpp
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 #include "ThreadKDP.h"
11
12 #include "lldb/Utility/SafeMachO.h"
13
14 #include "lldb/Breakpoint/Watchpoint.h"
15 #include "lldb/Core/ArchSpec.h"
16 #include "lldb/Core/DataExtractor.h"
17 #include "lldb/Core/State.h"
18 #include "lldb/Core/StreamString.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
25 #include "Plugins/Process/Utility/StopInfoMachException.h"
26 #include "ProcessKDP.h"
27 #include "ProcessKDPLog.h"
28 #include "RegisterContextKDP_arm.h"
29 #include "RegisterContextKDP_arm64.h"
30 #include "RegisterContextKDP_i386.h"
31 #include "RegisterContextKDP_x86_64.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), m_thread_name(), m_dispatch_queue_name(),
42       m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
43   ProcessKDPLog::LogIf(KDP_LOG_THREAD,
44                        "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this,
45                        GetID());
46 }
47
48 ThreadKDP::~ThreadKDP() {
49   ProcessKDPLog::LogIf(KDP_LOG_THREAD,
50                        "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this,
51                        GetID());
52   DestroyThread();
53 }
54
55 const char *ThreadKDP::GetName() {
56   if (m_thread_name.empty())
57     return NULL;
58   return m_thread_name.c_str();
59 }
60
61 const char *ThreadKDP::GetQueueName() { return NULL; }
62
63 void ThreadKDP::RefreshStateAfterStop() {
64   // Invalidate all registers in our register context. We don't set "force" to
65   // true because the stop reply packet might have had some register values
66   // that were expedited and these will already be copied into the register
67   // context by the time this function gets called. The KDPRegisterContext
68   // class has been made smart enough to detect when it needs to invalidate
69   // which registers are valid by putting hooks in the register read and
70   // register supply functions where they check the process stop ID and do
71   // the right thing.
72   const bool force = false;
73   lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
74   if (reg_ctx_sp)
75     reg_ctx_sp->InvalidateIfNeeded(force);
76 }
77
78 bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
79
80 void ThreadKDP::Dump(Log *log, uint32_t index) {}
81
82 bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
83 lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
84   if (m_reg_context_sp.get() == NULL)
85     m_reg_context_sp = CreateRegisterContextForFrame(NULL);
86   return m_reg_context_sp;
87 }
88
89 lldb::RegisterContextSP
90 ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
91   lldb::RegisterContextSP reg_ctx_sp;
92   uint32_t concrete_frame_idx = 0;
93
94   if (frame)
95     concrete_frame_idx = frame->GetConcreteFrameIndex();
96
97   if (concrete_frame_idx == 0) {
98     ProcessSP process_sp(CalculateProcess());
99     if (process_sp) {
100       switch (static_cast<ProcessKDP *>(process_sp.get())
101                   ->GetCommunication()
102                   .GetCPUType()) {
103       case llvm::MachO::CPU_TYPE_ARM:
104         reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx));
105         break;
106       case llvm::MachO::CPU_TYPE_ARM64:
107         reg_ctx_sp.reset(
108             new RegisterContextKDP_arm64(*this, concrete_frame_idx));
109         break;
110       case llvm::MachO::CPU_TYPE_I386:
111         reg_ctx_sp.reset(
112             new RegisterContextKDP_i386(*this, concrete_frame_idx));
113         break;
114       case llvm::MachO::CPU_TYPE_X86_64:
115         reg_ctx_sp.reset(
116             new RegisterContextKDP_x86_64(*this, concrete_frame_idx));
117         break;
118       default:
119         assert(!"Add CPU type support in KDP");
120         break;
121       }
122     }
123   } else {
124     Unwind *unwinder = GetUnwinder();
125     if (unwinder)
126       reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
127   }
128   return reg_ctx_sp;
129 }
130
131 bool ThreadKDP::CalculateStopInfo() {
132   ProcessSP process_sp(GetProcess());
133   if (process_sp) {
134     if (m_cached_stop_info_sp) {
135       SetStopInfo(m_cached_stop_info_sp);
136     } else {
137       SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
138     }
139     return true;
140   }
141   return false;
142 }
143
144 void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
145     const DataExtractor &exc_reply_packet) {
146   lldb::offset_t offset = 0;
147   uint8_t reply_command = exc_reply_packet.GetU8(&offset);
148   if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
149     offset = 8;
150     const uint32_t count = exc_reply_packet.GetU32(&offset);
151     if (count >= 1) {
152       // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
153       offset += 4; // Skip the useless CPU field
154       const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
155       const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
156       const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
157       // We have to make a copy of the stop info because the thread list
158       // will iterate through the threads and clear all stop infos..
159
160       // Let the StopInfoMachException::CreateStopReasonWithMachException()
161       // function update the PC if needed as we might hit a software breakpoint
162       // and need to decrement the PC (i386 and x86_64 need this) and KDP
163       // doesn't do this for us.
164       const bool pc_already_adjusted = false;
165       const bool adjust_pc_if_needed = true;
166
167       m_cached_stop_info_sp =
168           StopInfoMachException::CreateStopReasonWithMachException(
169               *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
170               adjust_pc_if_needed);
171     }
172   }
173 }