blob: b5d3b64a1ef5424f4b74d16af587f0662962efc5 [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
111bool
112LinuxThread::WillResume(lldb::StateType resume_state)
113{
114 SetResumeState(resume_state);
115 return Thread::WillResume(resume_state);
116}
117
118bool
119LinuxThread::Resume()
120{
121 lldb::StateType resume_state = GetResumeState();
122 ProcessMonitor &monitor = GetMonitor();
123 bool status;
124
125 switch (GetResumeState())
126 {
127 default:
128 assert(false && "Unexpected state for resume!");
129 status = false;
130 break;
131
132 case lldb::eStateSuspended:
133 // FIXME: Implement process suspension.
134 status = false;
135
136 case lldb::eStateRunning:
137 SetState(resume_state);
138 status = monitor.Resume(GetID());
139 break;
140
141 case lldb::eStateStepping:
142 SetState(resume_state);
143 status = GetRegisterContext()->HardwareSingleStep(true);
144 break;
145 }
146
147 m_note = eNone;
148 return status;
149}
150
151void
152LinuxThread::BreakNotify()
153{
154 bool status;
155
156 status = GetRegisterContext()->UpdateAfterBreakpoint();
157 assert(status && "Breakpoint update failed!");
158
159 // With our register state restored, resolve the breakpoint object
160 // corresponding to our current PC.
161 lldb::addr_t pc = GetRegisterContext()->GetPC();
162 lldb::BreakpointSiteSP bp_site =
163 GetProcess().GetBreakpointSiteList().FindByAddress(pc);
164 assert(bp_site && bp_site->ValidForThisThread(this));
165
166 m_note = eBreak;
167 m_breakpoint = bp_site;
168}
169
170void
171LinuxThread::TraceNotify()
172{
173 m_note = eTrace;
174}
175
176void
177LinuxThread::ExitNotify()
178{
179 m_note = eExit;
180}