LinuxThread.cpp revision f6f40333e91c97cc3b3ad5fb9fc0549079a96788
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/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} 199