blob: e189064766074059c8b4ae4b01f032a4f6e3324c [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 Wilsonf6f40332010-07-24 02:19:04 +000029 m_note(eNone)
30{
Stephen Wilsonf6f40332010-07-24 02:19:04 +000031}
32
33ProcessMonitor &
34LinuxThread::GetMonitor()
35{
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000036 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
37 return process.GetMonitor();
Stephen Wilsonf6f40332010-07-24 02:19:04 +000038}
39
40void
41LinuxThread::RefreshStateAfterStop()
42{
43}
44
45const char *
46LinuxThread::GetInfo()
47{
48 return NULL;
49}
50
Greg Clayton90ccf882011-01-06 22:35:55 +000051lldb::RegisterContextSP
Stephen Wilsonf6f40332010-07-24 02:19:04 +000052LinuxThread::GetRegisterContext()
53{
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000054 ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
55
Greg Clayton90ccf882011-01-06 22:35:55 +000056 if (!m_reg_context_sp)
57 {
58 ArchSpec arch = process.GetTarget().GetArchitecture();
59
60 switch (arch.GetGenericCPUType())
61 {
62 default:
63 assert(false && "CPU type not supported!");
64 break;
65
66 case ArchSpec::eCPU_x86_64:
67 m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
68 break;
69 }
70 }
Stephen Wilsonbc1418b2011-01-07 00:10:43 +000071 return m_reg_context_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +000072}
73
74bool
75LinuxThread::SaveFrameZeroState(RegisterCheckpoint &checkpoint)
76{
77 return false;
78}
79
80bool
81LinuxThread::RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint)
82{
83 return false;
84}
85
Greg Clayton90ccf882011-01-06 22:35:55 +000086lldb::RegisterContextSP
87LinuxThread::CreateRegisterContextForFrame (lldb_private::StackFrame *frame)
Stephen Wilsonf6f40332010-07-24 02:19:04 +000088{
Greg Clayton90ccf882011-01-06 22:35:55 +000089 lldb::RegisterContextSP reg_ctx_sp;
90 uint32_t concrete_frame_idx = 0;
91 if (frame)
92 concrete_frame_idx = frame->GetConcreteFrameIndex();
93
94 if (concrete_frame_idx == 0)
95 reg_ctx_sp = GetRegisterContext();
96 else
97 reg_ctx_sp.reset (new RegisterContextLinux_x86_64(*this, frame->GetConcreteFrameIndex()));
98 return reg_ctx_sp;
Stephen Wilsonf6f40332010-07-24 02:19:04 +000099}
100
Stephen Wilsoned560022011-01-04 21:45:02 +0000101lldb::StopInfoSP
102LinuxThread::GetPrivateStopReason()
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000103{
Stephen Wilsoned560022011-01-04 21:45:02 +0000104 lldb::StopInfoSP stop_info;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000105
106 switch (m_note)
107 {
108 default:
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000109 break;
110
111 case eBreak:
Stephen Wilsoned560022011-01-04 21:45:02 +0000112 stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
113 *this, m_breakpoint->GetID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000114 break;
115
116 case eTrace:
Stephen Wilsoned560022011-01-04 21:45:02 +0000117 stop_info = StopInfo::CreateStopReasonToTrace(*this);
118 break;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000119 }
120
Stephen Wilsoned560022011-01-04 21:45:02 +0000121 return stop_info;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000122}
123
Stephen Wilsond61182d2011-01-04 21:45:57 +0000124Unwind *
125LinuxThread::GetUnwinder()
126{
127 return m_unwinder_ap.get();
128}
129
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000130bool
131LinuxThread::WillResume(lldb::StateType resume_state)
132{
133 SetResumeState(resume_state);
134 return Thread::WillResume(resume_state);
135}
136
137bool
138LinuxThread::Resume()
139{
140 lldb::StateType resume_state = GetResumeState();
141 ProcessMonitor &monitor = GetMonitor();
142 bool status;
143
144 switch (GetResumeState())
145 {
146 default:
147 assert(false && "Unexpected state for resume!");
148 status = false;
149 break;
150
151 case lldb::eStateSuspended:
152 // FIXME: Implement process suspension.
153 status = false;
154
155 case lldb::eStateRunning:
156 SetState(resume_state);
157 status = monitor.Resume(GetID());
158 break;
159
160 case lldb::eStateStepping:
161 SetState(resume_state);
162 status = GetRegisterContext()->HardwareSingleStep(true);
163 break;
164 }
165
166 m_note = eNone;
167 return status;
168}
169
170void
171LinuxThread::BreakNotify()
172{
173 bool status;
174
Greg Clayton90ccf882011-01-06 22:35:55 +0000175 status = GetRegisterContextLinux()->UpdateAfterBreakpoint();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000176 assert(status && "Breakpoint update failed!");
177
178 // With our register state restored, resolve the breakpoint object
179 // corresponding to our current PC.
180 lldb::addr_t pc = GetRegisterContext()->GetPC();
Greg Clayton90ccf882011-01-06 22:35:55 +0000181 lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000182 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}