LinuxThread.cpp revision ed56002a20abc5c62010753afe969686d5b114ce
1//===-- 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/StopInfo.h"
17#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
64RegisterContextLinux *
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
88lldb::StopInfoSP
89LinuxThread::GetPrivateStopReason()
90{
91    lldb::StopInfoSP stop_info;
92
93    switch (m_note)
94    {
95    default:
96        break;
97
98    case eBreak:
99        stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
100            *this, m_breakpoint->GetID());
101        break;
102
103    case eTrace:
104        stop_info = StopInfo::CreateStopReasonToTrace(*this);
105        break;
106    }
107
108    return stop_info;
109}
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}
181