blob: de1ca5124b0db8b1437cf0b05d9dd5610be48950 [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
10#include <errno.h>
11
12// C Includes
13// 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"
23
24using namespace lldb_private;
25
26LinuxThread::LinuxThread(Process &process, lldb::tid_t tid)
27 : Thread(process, tid),
28 m_frame_ap(0),
Stephen Wilson140f69a2011-01-15 00:07:36 +000029 m_stop_info_id(0),
Stephen Wilsonf6f40332010-07-24 02:19:04 +000030 m_note(eNone)
31{
Stephen Wilsonf6f40332010-07-24 02:19:04 +000032}
33
Stephen Wilsonb47794a2011-01-16 16:56:16 +000034LinuxThread::~LinuxThread()
35{
36 DestroyThread();
37}
38
Stephen Wilsonf6f40332010-07-24 02:19:04 +000039ProcessMonitor &
40LinuxThread::GetMonitor()
41{
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000042 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
43 return process.GetMonitor();
Stephen Wilsonf6f40332010-07-24 02:19:04 +000044}
45
46void
47LinuxThread::RefreshStateAfterStop()
48{
Stephen Wilson140f69a2011-01-15 00:07:36 +000049 RefreshPrivateStopReason();
Stephen Wilsonf6f40332010-07-24 02:19:04 +000050}
51
52const char *
53LinuxThread::GetInfo()
54{
55 return NULL;
56}
57
Greg Clayton90ccf882011-01-06 22:35:55 +000058lldb::RegisterContextSP
Stephen Wilsonf6f40332010-07-24 02:19:04 +000059LinuxThread::GetRegisterContext()
60{
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000061 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
62
Greg Clayton90ccf882011-01-06 22:35:55 +000063 if (!m_reg_context_sp)
64 {
65 ArchSpec arch = process.GetTarget().GetArchitecture();
66
67 switch (arch.GetGenericCPUType())
68 {
69 default:
70 assert(false && "CPU type not supported!");
71 break;
72
73 case ArchSpec::eCPU_x86_64:
74 m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
75 break;
76 }
77 }
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000078 return m_reg_context_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +000079}
80
81bool
82LinuxThread::SaveFrameZeroState(RegisterCheckpoint &checkpoint)
83{
84 return false;
85}
86
87bool
88LinuxThread::RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint)
89{
90 return false;
91}
92
Greg Clayton90ccf882011-01-06 22:35:55 +000093lldb::RegisterContextSP
94LinuxThread::CreateRegisterContextForFrame (lldb_private::StackFrame *frame)
Stephen Wilsonf6f40332010-07-24 02:19:04 +000095{
Greg Clayton90ccf882011-01-06 22:35:55 +000096 lldb::RegisterContextSP reg_ctx_sp;
97 uint32_t concrete_frame_idx = 0;
98 if (frame)
99 concrete_frame_idx = frame->GetConcreteFrameIndex();
100
101 if (concrete_frame_idx == 0)
102 reg_ctx_sp = GetRegisterContext();
103 else
104 reg_ctx_sp.reset (new RegisterContextLinux_x86_64(*this, frame->GetConcreteFrameIndex()));
105 return reg_ctx_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000106}
107
Stephen Wilsoned560022011-01-04 21:45:02 +0000108lldb::StopInfoSP
109LinuxThread::GetPrivateStopReason()
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000110{
Stephen Wilson140f69a2011-01-15 00:07:36 +0000111 const uint32_t process_stop_id = GetProcess().GetStopID();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000112
Stephen Wilson140f69a2011-01-15 00:07:36 +0000113 if (m_stop_info_id != process_stop_id || !m_stop_info || !m_stop_info->IsValid())
114 RefreshPrivateStopReason();
115 return m_stop_info;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000116}
117
Stephen Wilsond61182d2011-01-04 21:45:57 +0000118Unwind *
119LinuxThread::GetUnwinder()
120{
121 return m_unwinder_ap.get();
122}
123
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000124bool
125LinuxThread::WillResume(lldb::StateType resume_state)
126{
127 SetResumeState(resume_state);
128 return Thread::WillResume(resume_state);
129}
130
131bool
132LinuxThread::Resume()
133{
134 lldb::StateType resume_state = GetResumeState();
135 ProcessMonitor &monitor = GetMonitor();
136 bool status;
137
138 switch (GetResumeState())
139 {
140 default:
141 assert(false && "Unexpected state for resume!");
142 status = false;
143 break;
144
145 case lldb::eStateSuspended:
146 // FIXME: Implement process suspension.
147 status = false;
148
149 case lldb::eStateRunning:
150 SetState(resume_state);
151 status = monitor.Resume(GetID());
152 break;
153
154 case lldb::eStateStepping:
155 SetState(resume_state);
156 status = GetRegisterContext()->HardwareSingleStep(true);
157 break;
158 }
159
160 m_note = eNone;
161 return status;
162}
163
164void
165LinuxThread::BreakNotify()
166{
167 bool status;
168
Greg Clayton90ccf882011-01-06 22:35:55 +0000169 status = GetRegisterContextLinux()->UpdateAfterBreakpoint();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000170 assert(status && "Breakpoint update failed!");
171
172 // With our register state restored, resolve the breakpoint object
173 // corresponding to our current PC.
174 lldb::addr_t pc = GetRegisterContext()->GetPC();
Greg Clayton90ccf882011-01-06 22:35:55 +0000175 lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000176 assert(bp_site && bp_site->ValidForThisThread(this));
177
178 m_note = eBreak;
179 m_breakpoint = bp_site;
180}
181
182void
183LinuxThread::TraceNotify()
184{
185 m_note = eTrace;
186}
187
188void
189LinuxThread::ExitNotify()
190{
191 m_note = eExit;
192}
Stephen Wilson140f69a2011-01-15 00:07:36 +0000193
194void
195LinuxThread::RefreshPrivateStopReason()
196{
197 m_stop_info_id = GetProcess().GetStopID();
198
199 switch (m_note) {
200
201 default:
202 case eNone:
203 m_stop_info.reset();
204 break;
205
206 case eBreak:
207 m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
208 *this, m_breakpoint->GetID());
209 break;
210
211 case eTrace:
212 m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
213 break;
214
215 case eExit:
216 m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, SIGCHLD);
217 break;
218 }
219}