blob: 5c278d44893f73007408cfe7d234d64ea3576666 [file] [log] [blame]
Stephen Wilsonf6f40332010-07-24 02:19:04 +00001//===-- LinuxThread.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
Stephen Wilsone0c20da2011-01-19 01:36:10 +000010// C Includes
Stephen Wilsonf6f40332010-07-24 02:19:04 +000011#include <errno.h>
12
Stephen Wilsonf6f40332010-07-24 02:19:04 +000013// C++ Includes
14// Other libraries and framework includes
15#include "lldb/Target/Process.h"
Stephen Wilsonc8c74e02011-01-04 21:43:19 +000016#include "lldb/Target/StopInfo.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000017#include "lldb/Target/Target.h"
18
19#include "LinuxThread.h"
20#include "ProcessLinux.h"
21#include "ProcessMonitor.h"
22#include "RegisterContextLinux_x86_64.h"
Stephen Wilsone0c20da2011-01-19 01:36:10 +000023#include "UnwindLLDB.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000024
25using namespace lldb_private;
26
27LinuxThread::LinuxThread(Process &process, lldb::tid_t tid)
28 : Thread(process, tid),
29 m_frame_ap(0),
Stephen Wilson140f69a2011-01-15 00:07:36 +000030 m_stop_info_id(0),
Stephen Wilsonf6f40332010-07-24 02:19:04 +000031 m_note(eNone)
32{
Stephen Wilsonf6f40332010-07-24 02:19:04 +000033}
34
Stephen Wilsonb47794a2011-01-16 16:56:16 +000035LinuxThread::~LinuxThread()
36{
37 DestroyThread();
38}
39
Stephen Wilsonf6f40332010-07-24 02:19:04 +000040ProcessMonitor &
41LinuxThread::GetMonitor()
42{
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000043 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
44 return process.GetMonitor();
Stephen Wilsonf6f40332010-07-24 02:19:04 +000045}
46
47void
48LinuxThread::RefreshStateAfterStop()
49{
Stephen Wilson140f69a2011-01-15 00:07:36 +000050 RefreshPrivateStopReason();
Stephen Wilsonf6f40332010-07-24 02:19:04 +000051}
52
53const char *
54LinuxThread::GetInfo()
55{
56 return NULL;
57}
58
Greg Clayton90ccf882011-01-06 22:35:55 +000059lldb::RegisterContextSP
Stephen Wilsonf6f40332010-07-24 02:19:04 +000060LinuxThread::GetRegisterContext()
61{
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000062 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
63
Greg Clayton90ccf882011-01-06 22:35:55 +000064 if (!m_reg_context_sp)
65 {
66 ArchSpec arch = process.GetTarget().GetArchitecture();
67
68 switch (arch.GetGenericCPUType())
69 {
70 default:
71 assert(false && "CPU type not supported!");
72 break;
73
74 case ArchSpec::eCPU_x86_64:
75 m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
76 break;
77 }
78 }
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000079 return m_reg_context_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +000080}
81
82bool
83LinuxThread::SaveFrameZeroState(RegisterCheckpoint &checkpoint)
84{
85 return false;
86}
87
88bool
89LinuxThread::RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint)
90{
91 return false;
92}
93
Greg Clayton90ccf882011-01-06 22:35:55 +000094lldb::RegisterContextSP
Stephen Wilsone0c20da2011-01-19 01:36:10 +000095LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
Stephen Wilsonf6f40332010-07-24 02:19:04 +000096{
Greg Clayton90ccf882011-01-06 22:35:55 +000097 lldb::RegisterContextSP reg_ctx_sp;
98 uint32_t concrete_frame_idx = 0;
Stephen Wilsone0c20da2011-01-19 01:36:10 +000099
Greg Clayton90ccf882011-01-06 22:35:55 +0000100 if (frame)
101 concrete_frame_idx = frame->GetConcreteFrameIndex();
102
103 if (concrete_frame_idx == 0)
104 reg_ctx_sp = GetRegisterContext();
105 else
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000106 reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
107
Greg Clayton90ccf882011-01-06 22:35:55 +0000108 return reg_ctx_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000109}
110
Stephen Wilsoned560022011-01-04 21:45:02 +0000111lldb::StopInfoSP
112LinuxThread::GetPrivateStopReason()
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000113{
Stephen Wilson140f69a2011-01-15 00:07:36 +0000114 const uint32_t process_stop_id = GetProcess().GetStopID();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000115
Stephen Wilson140f69a2011-01-15 00:07:36 +0000116 if (m_stop_info_id != process_stop_id || !m_stop_info || !m_stop_info->IsValid())
117 RefreshPrivateStopReason();
118 return m_stop_info;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000119}
120
Stephen Wilsond61182d2011-01-04 21:45:57 +0000121Unwind *
122LinuxThread::GetUnwinder()
123{
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000124 if (m_unwinder_ap.get() == NULL)
125 m_unwinder_ap.reset(new UnwindLLDB(*this));
126
Stephen Wilsond61182d2011-01-04 21:45:57 +0000127 return m_unwinder_ap.get();
128}
129
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000130bool
131LinuxThread::WillResume(lldb::StateType resume_state)
132{
133 SetResumeState(resume_state);
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000134
135 ClearStackFrames();
136 if (m_unwinder_ap.get())
137 m_unwinder_ap->Clear();
138
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000139 return Thread::WillResume(resume_state);
140}
141
142bool
143LinuxThread::Resume()
144{
145 lldb::StateType resume_state = GetResumeState();
146 ProcessMonitor &monitor = GetMonitor();
147 bool status;
148
149 switch (GetResumeState())
150 {
151 default:
152 assert(false && "Unexpected state for resume!");
153 status = false;
154 break;
155
156 case lldb::eStateSuspended:
157 // FIXME: Implement process suspension.
158 status = false;
159
160 case lldb::eStateRunning:
161 SetState(resume_state);
162 status = monitor.Resume(GetID());
163 break;
164
165 case lldb::eStateStepping:
166 SetState(resume_state);
Stephen Wilsonf3cbdc22011-01-19 01:35:00 +0000167 status = monitor.SingleStep(GetID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000168 break;
169 }
170
171 m_note = eNone;
172 return status;
173}
174
175void
176LinuxThread::BreakNotify()
177{
178 bool status;
179
Greg Clayton90ccf882011-01-06 22:35:55 +0000180 status = GetRegisterContextLinux()->UpdateAfterBreakpoint();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000181 assert(status && "Breakpoint update failed!");
182
183 // With our register state restored, resolve the breakpoint object
184 // corresponding to our current PC.
185 lldb::addr_t pc = GetRegisterContext()->GetPC();
Greg Clayton90ccf882011-01-06 22:35:55 +0000186 lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000187 assert(bp_site && bp_site->ValidForThisThread(this));
188
189 m_note = eBreak;
190 m_breakpoint = bp_site;
191}
192
193void
194LinuxThread::TraceNotify()
195{
196 m_note = eTrace;
197}
198
199void
200LinuxThread::ExitNotify()
201{
202 m_note = eExit;
203}
Stephen Wilson140f69a2011-01-15 00:07:36 +0000204
205void
206LinuxThread::RefreshPrivateStopReason()
207{
208 m_stop_info_id = GetProcess().GetStopID();
209
210 switch (m_note) {
211
212 default:
213 case eNone:
214 m_stop_info.reset();
215 break;
216
217 case eBreak:
218 m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
219 *this, m_breakpoint->GetID());
220 break;
221
222 case eTrace:
223 m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
224 break;
225
226 case eExit:
227 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, SIGCHLD);
228 break;
229 }
230}