blob: ebda0d8965cc0e5fe1870ff9462b81f31bf64f48 [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
Stephen Wilson708b4472011-02-28 22:52:38 +000015#include "lldb/Host/Host.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000016#include "lldb/Target/Process.h"
Stephen Wilsonc8c74e02011-01-04 21:43:19 +000017#include "lldb/Target/StopInfo.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000018#include "lldb/Target/Target.h"
19
20#include "LinuxThread.h"
21#include "ProcessLinux.h"
22#include "ProcessMonitor.h"
Stephen Wilson708b4472011-02-28 22:52:38 +000023#include "RegisterContextLinux_i386.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000024#include "RegisterContextLinux_x86_64.h"
Stephen Wilsone0c20da2011-01-19 01:36:10 +000025#include "UnwindLLDB.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000026
27using namespace lldb_private;
28
29LinuxThread::LinuxThread(Process &process, lldb::tid_t tid)
30 : Thread(process, tid),
31 m_frame_ap(0),
Stephen Wilson140f69a2011-01-15 00:07:36 +000032 m_stop_info_id(0),
Stephen Wilsonf6f40332010-07-24 02:19:04 +000033 m_note(eNone)
34{
Stephen Wilsonf6f40332010-07-24 02:19:04 +000035}
36
Stephen Wilsonb47794a2011-01-16 16:56:16 +000037LinuxThread::~LinuxThread()
38{
39 DestroyThread();
40}
41
Stephen Wilsonf6f40332010-07-24 02:19:04 +000042ProcessMonitor &
43LinuxThread::GetMonitor()
44{
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000045 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
46 return process.GetMonitor();
Stephen Wilsonf6f40332010-07-24 02:19:04 +000047}
48
49void
50LinuxThread::RefreshStateAfterStop()
51{
Stephen Wilson140f69a2011-01-15 00:07:36 +000052 RefreshPrivateStopReason();
Stephen Wilsonf6f40332010-07-24 02:19:04 +000053}
54
55const char *
56LinuxThread::GetInfo()
57{
58 return NULL;
59}
60
Greg Clayton90ccf882011-01-06 22:35:55 +000061lldb::RegisterContextSP
Stephen Wilsonf6f40332010-07-24 02:19:04 +000062LinuxThread::GetRegisterContext()
63{
Greg Clayton90ccf882011-01-06 22:35:55 +000064 if (!m_reg_context_sp)
65 {
Stephen Wilson708b4472011-02-28 22:52:38 +000066 ArchSpec arch = Host::GetArchitecture();
Greg Clayton90ccf882011-01-06 22:35:55 +000067
Stephen Wilsona1f0b722011-02-24 19:17:09 +000068 switch (arch.GetCore())
Greg Clayton90ccf882011-01-06 22:35:55 +000069 {
70 default:
71 assert(false && "CPU type not supported!");
72 break;
73
Stephen Wilson708b4472011-02-28 22:52:38 +000074 case ArchSpec::eCore_x86_32_i386:
75 case ArchSpec::eCore_x86_32_i486:
76 case ArchSpec::eCore_x86_32_i486sx:
77 m_reg_context_sp.reset(new RegisterContextLinux_i386(*this, 0));
78 break;
79
Stephen Wilsona1f0b722011-02-24 19:17:09 +000080 case ArchSpec::eCore_x86_64_x86_64:
Greg Clayton90ccf882011-01-06 22:35:55 +000081 m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
82 break;
83 }
84 }
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000085 return m_reg_context_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +000086}
87
88bool
89LinuxThread::SaveFrameZeroState(RegisterCheckpoint &checkpoint)
90{
91 return false;
92}
93
94bool
95LinuxThread::RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint)
96{
97 return false;
98}
99
Greg Clayton90ccf882011-01-06 22:35:55 +0000100lldb::RegisterContextSP
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000101LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000102{
Greg Clayton90ccf882011-01-06 22:35:55 +0000103 lldb::RegisterContextSP reg_ctx_sp;
104 uint32_t concrete_frame_idx = 0;
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000105
Greg Clayton90ccf882011-01-06 22:35:55 +0000106 if (frame)
107 concrete_frame_idx = frame->GetConcreteFrameIndex();
Stephen Wilson708b4472011-02-28 22:52:38 +0000108
Greg Clayton90ccf882011-01-06 22:35:55 +0000109 if (concrete_frame_idx == 0)
110 reg_ctx_sp = GetRegisterContext();
111 else
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000112 reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
113
Greg Clayton90ccf882011-01-06 22:35:55 +0000114 return reg_ctx_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000115}
116
Stephen Wilsoned560022011-01-04 21:45:02 +0000117lldb::StopInfoSP
118LinuxThread::GetPrivateStopReason()
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000119{
Stephen Wilson140f69a2011-01-15 00:07:36 +0000120 const uint32_t process_stop_id = GetProcess().GetStopID();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000121
Stephen Wilson140f69a2011-01-15 00:07:36 +0000122 if (m_stop_info_id != process_stop_id || !m_stop_info || !m_stop_info->IsValid())
123 RefreshPrivateStopReason();
124 return m_stop_info;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000125}
126
Stephen Wilsond61182d2011-01-04 21:45:57 +0000127Unwind *
128LinuxThread::GetUnwinder()
129{
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000130 if (m_unwinder_ap.get() == NULL)
131 m_unwinder_ap.reset(new UnwindLLDB(*this));
132
Stephen Wilsond61182d2011-01-04 21:45:57 +0000133 return m_unwinder_ap.get();
134}
135
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000136bool
137LinuxThread::WillResume(lldb::StateType resume_state)
138{
139 SetResumeState(resume_state);
Stephen Wilsone0c20da2011-01-19 01:36:10 +0000140
141 ClearStackFrames();
142 if (m_unwinder_ap.get())
143 m_unwinder_ap->Clear();
144
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000145 return Thread::WillResume(resume_state);
146}
147
148bool
149LinuxThread::Resume()
150{
151 lldb::StateType resume_state = GetResumeState();
152 ProcessMonitor &monitor = GetMonitor();
153 bool status;
154
155 switch (GetResumeState())
156 {
157 default:
158 assert(false && "Unexpected state for resume!");
159 status = false;
160 break;
161
162 case lldb::eStateSuspended:
163 // FIXME: Implement process suspension.
164 status = false;
165
166 case lldb::eStateRunning:
167 SetState(resume_state);
168 status = monitor.Resume(GetID());
169 break;
170
171 case lldb::eStateStepping:
172 SetState(resume_state);
Stephen Wilsonf3cbdc22011-01-19 01:35:00 +0000173 status = monitor.SingleStep(GetID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000174 break;
175 }
176
177 m_note = eNone;
178 return status;
179}
180
181void
182LinuxThread::BreakNotify()
183{
184 bool status;
185
Greg Clayton90ccf882011-01-06 22:35:55 +0000186 status = GetRegisterContextLinux()->UpdateAfterBreakpoint();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000187 assert(status && "Breakpoint update failed!");
188
189 // With our register state restored, resolve the breakpoint object
190 // corresponding to our current PC.
191 lldb::addr_t pc = GetRegisterContext()->GetPC();
Greg Clayton90ccf882011-01-06 22:35:55 +0000192 lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000193 assert(bp_site && bp_site->ValidForThisThread(this));
194
195 m_note = eBreak;
196 m_breakpoint = bp_site;
197}
198
199void
200LinuxThread::TraceNotify()
201{
202 m_note = eTrace;
203}
204
205void
206LinuxThread::ExitNotify()
207{
208 m_note = eExit;
209}
Stephen Wilson140f69a2011-01-15 00:07:36 +0000210
211void
212LinuxThread::RefreshPrivateStopReason()
213{
214 m_stop_info_id = GetProcess().GetStopID();
215
216 switch (m_note) {
217
218 default:
219 case eNone:
220 m_stop_info.reset();
221 break;
222
223 case eBreak:
224 m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
225 *this, m_breakpoint->GetID());
226 break;
227
228 case eTrace:
229 m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
230 break;
231
232 case eExit:
233 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, SIGCHLD);
234 break;
235 }
236}