blob: 6d4733afcb264cbbc1c73ddb26bba27ebe266c52 [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"
16#include "lldb/Target/Target.h"
17
18#include "LinuxThread.h"
19#include "ProcessLinux.h"
20#include "ProcessMonitor.h"
21#include "RegisterContextLinux_x86_64.h"
22
23using namespace lldb_private;
24
25LinuxThread::LinuxThread(Process &process, lldb::tid_t tid)
26 : Thread(process, tid),
27 m_frame_ap(0),
28 m_register_ap(0),
29 m_note(eNone)
30{
31 ArchSpec arch = process.GetTarget().GetArchitecture();
32
33 switch (arch.GetGenericCPUType())
34 {
35 default:
36 assert(false && "CPU type not supported!");
37 break;
38
39 case ArchSpec::eCPU_x86_64:
40 m_register_ap.reset(new RegisterContextLinux_x86_64(*this, NULL));
41 break;
42 }
43}
44
45ProcessMonitor &
46LinuxThread::GetMonitor()
47{
48 ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess());
49 return process->GetMonitor();
50}
51
52void
53LinuxThread::RefreshStateAfterStop()
54{
55}
56
57const char *
58LinuxThread::GetInfo()
59{
60 return NULL;
61}
62
63uint32_t
64LinuxThread::GetStackFrameCount()
65{
66 return 0;
67}
68
69lldb::StackFrameSP
70LinuxThread::GetStackFrameAtIndex(uint32_t idx)
71{
72 if (idx == 0)
73 {
74 RegisterContextLinux *regs = GetRegisterContext();
75 StackFrame *frame = new StackFrame(
76 idx, *this, regs->GetFP(), regs->GetPC());
77 return lldb::StackFrameSP(frame);
78 }
79 else
80 return lldb::StackFrameSP();
81}
82
83RegisterContextLinux *
84LinuxThread::GetRegisterContext()
85{
86 return m_register_ap.get();
87}
88
89bool
90LinuxThread::SaveFrameZeroState(RegisterCheckpoint &checkpoint)
91{
92 return false;
93}
94
95bool
96LinuxThread::RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint)
97{
98 return false;
99}
100
101RegisterContextLinux *
102LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
103{
104 return new RegisterContextLinux_x86_64(*this, frame);
105}
106
107bool
108LinuxThread::GetRawStopReason(StopInfo *stop_info)
109{
110 stop_info->Clear();
111
112 switch (m_note)
113 {
114 default:
115 stop_info->SetStopReasonToNone();
116 break;
117
118 case eBreak:
119 stop_info->SetStopReasonWithBreakpointSiteID(m_breakpoint->GetID());
120 break;
121
122 case eTrace:
123 stop_info->SetStopReasonToTrace();
124 }
125
126 return true;
127}
128
129bool
130LinuxThread::WillResume(lldb::StateType resume_state)
131{
132 SetResumeState(resume_state);
133 return Thread::WillResume(resume_state);
134}
135
136bool
137LinuxThread::Resume()
138{
139 lldb::StateType resume_state = GetResumeState();
140 ProcessMonitor &monitor = GetMonitor();
141 bool status;
142
143 switch (GetResumeState())
144 {
145 default:
146 assert(false && "Unexpected state for resume!");
147 status = false;
148 break;
149
150 case lldb::eStateSuspended:
151 // FIXME: Implement process suspension.
152 status = false;
153
154 case lldb::eStateRunning:
155 SetState(resume_state);
156 status = monitor.Resume(GetID());
157 break;
158
159 case lldb::eStateStepping:
160 SetState(resume_state);
161 status = GetRegisterContext()->HardwareSingleStep(true);
162 break;
163 }
164
165 m_note = eNone;
166 return status;
167}
168
169void
170LinuxThread::BreakNotify()
171{
172 bool status;
173
174 status = GetRegisterContext()->UpdateAfterBreakpoint();
175 assert(status && "Breakpoint update failed!");
176
177 // With our register state restored, resolve the breakpoint object
178 // corresponding to our current PC.
179 lldb::addr_t pc = GetRegisterContext()->GetPC();
180 lldb::BreakpointSiteSP bp_site =
181 GetProcess().GetBreakpointSiteList().FindByAddress(pc);
182 assert(bp_site && bp_site->ValidForThisThread(this));
183
184 m_note = eBreak;
185 m_breakpoint = bp_site;
186}
187
188void
189LinuxThread::TraceNotify()
190{
191 m_note = eTrace;
192}
193
194void
195LinuxThread::ExitNotify()
196{
197 m_note = eExit;
198}