blob: c4c8bf56ab7c73fff7dd1cbeb73be9f479c54f40 [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),
29 m_register_ap(0),
30 m_note(eNone)
31{
32 ArchSpec arch = process.GetTarget().GetArchitecture();
33
34 switch (arch.GetGenericCPUType())
35 {
36 default:
37 assert(false && "CPU type not supported!");
38 break;
39
40 case ArchSpec::eCPU_x86_64:
41 m_register_ap.reset(new RegisterContextLinux_x86_64(*this, NULL));
42 break;
43 }
44}
45
46ProcessMonitor &
47LinuxThread::GetMonitor()
48{
49 ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess());
50 return process->GetMonitor();
51}
52
53void
54LinuxThread::RefreshStateAfterStop()
55{
56}
57
58const char *
59LinuxThread::GetInfo()
60{
61 return NULL;
62}
63
Stephen Wilsonf6f40332010-07-24 02:19:04 +000064RegisterContextLinux *
65LinuxThread::GetRegisterContext()
66{
67 return m_register_ap.get();
68}
69
70bool
71LinuxThread::SaveFrameZeroState(RegisterCheckpoint &checkpoint)
72{
73 return false;
74}
75
76bool
77LinuxThread::RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint)
78{
79 return false;
80}
81
82RegisterContextLinux *
83LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
84{
85 return new RegisterContextLinux_x86_64(*this, frame);
86}
87
Stephen Wilsoned560022011-01-04 21:45:02 +000088lldb::StopInfoSP
89LinuxThread::GetPrivateStopReason()
Stephen Wilsonf6f40332010-07-24 02:19:04 +000090{
Stephen Wilsoned560022011-01-04 21:45:02 +000091 lldb::StopInfoSP stop_info;
Stephen Wilsonf6f40332010-07-24 02:19:04 +000092
93 switch (m_note)
94 {
95 default:
Stephen Wilsonf6f40332010-07-24 02:19:04 +000096 break;
97
98 case eBreak:
Stephen Wilsoned560022011-01-04 21:45:02 +000099 stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
100 *this, m_breakpoint->GetID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000101 break;
102
103 case eTrace:
Stephen Wilsoned560022011-01-04 21:45:02 +0000104 stop_info = StopInfo::CreateStopReasonToTrace(*this);
105 break;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000106 }
107
Stephen Wilsoned560022011-01-04 21:45:02 +0000108 return stop_info;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000109}
110
Stephen Wilsond61182d2011-01-04 21:45:57 +0000111Unwind *
112LinuxThread::GetUnwinder()
113{
114 return m_unwinder_ap.get();
115}
116
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000117bool
118LinuxThread::WillResume(lldb::StateType resume_state)
119{
120 SetResumeState(resume_state);
121 return Thread::WillResume(resume_state);
122}
123
124bool
125LinuxThread::Resume()
126{
127 lldb::StateType resume_state = GetResumeState();
128 ProcessMonitor &monitor = GetMonitor();
129 bool status;
130
131 switch (GetResumeState())
132 {
133 default:
134 assert(false && "Unexpected state for resume!");
135 status = false;
136 break;
137
138 case lldb::eStateSuspended:
139 // FIXME: Implement process suspension.
140 status = false;
141
142 case lldb::eStateRunning:
143 SetState(resume_state);
144 status = monitor.Resume(GetID());
145 break;
146
147 case lldb::eStateStepping:
148 SetState(resume_state);
149 status = GetRegisterContext()->HardwareSingleStep(true);
150 break;
151 }
152
153 m_note = eNone;
154 return status;
155}
156
157void
158LinuxThread::BreakNotify()
159{
160 bool status;
161
162 status = GetRegisterContext()->UpdateAfterBreakpoint();
163 assert(status && "Breakpoint update failed!");
164
165 // With our register state restored, resolve the breakpoint object
166 // corresponding to our current PC.
167 lldb::addr_t pc = GetRegisterContext()->GetPC();
168 lldb::BreakpointSiteSP bp_site =
169 GetProcess().GetBreakpointSiteList().FindByAddress(pc);
170 assert(bp_site && bp_site->ValidForThisThread(this));
171
172 m_note = eBreak;
173 m_breakpoint = bp_site;
174}
175
176void
177LinuxThread::TraceNotify()
178{
179 m_note = eTrace;
180}
181
182void
183LinuxThread::ExitNotify()
184{
185 m_note = eExit;
186}