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