Add a new Process plugin for Linux.
This component is still at an early stage, but allows for simple
breakpoint/step-over operations and basic process control.
The makefiles are set up to build the plugin under Linux only.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@109318 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/Linux/LinuxThread.cpp b/source/Plugins/Process/Linux/LinuxThread.cpp
new file mode 100644
index 0000000..6d4733a
--- /dev/null
+++ b/source/Plugins/Process/Linux/LinuxThread.cpp
@@ -0,0 +1,198 @@
+//===-- LinuxThread.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <errno.h>
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "LinuxThread.h"
+#include "ProcessLinux.h"
+#include "ProcessMonitor.h"
+#include "RegisterContextLinux_x86_64.h"
+
+using namespace lldb_private;
+
+LinuxThread::LinuxThread(Process &process, lldb::tid_t tid)
+ : Thread(process, tid),
+ m_frame_ap(0),
+ m_register_ap(0),
+ m_note(eNone)
+{
+ ArchSpec arch = process.GetTarget().GetArchitecture();
+
+ switch (arch.GetGenericCPUType())
+ {
+ default:
+ assert(false && "CPU type not supported!");
+ break;
+
+ case ArchSpec::eCPU_x86_64:
+ m_register_ap.reset(new RegisterContextLinux_x86_64(*this, NULL));
+ break;
+ }
+}
+
+ProcessMonitor &
+LinuxThread::GetMonitor()
+{
+ ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess());
+ return process->GetMonitor();
+}
+
+void
+LinuxThread::RefreshStateAfterStop()
+{
+}
+
+const char *
+LinuxThread::GetInfo()
+{
+ return NULL;
+}
+
+uint32_t
+LinuxThread::GetStackFrameCount()
+{
+ return 0;
+}
+
+lldb::StackFrameSP
+LinuxThread::GetStackFrameAtIndex(uint32_t idx)
+{
+ if (idx == 0)
+ {
+ RegisterContextLinux *regs = GetRegisterContext();
+ StackFrame *frame = new StackFrame(
+ idx, *this, regs->GetFP(), regs->GetPC());
+ return lldb::StackFrameSP(frame);
+ }
+ else
+ return lldb::StackFrameSP();
+}
+
+RegisterContextLinux *
+LinuxThread::GetRegisterContext()
+{
+ return m_register_ap.get();
+}
+
+bool
+LinuxThread::SaveFrameZeroState(RegisterCheckpoint &checkpoint)
+{
+ return false;
+}
+
+bool
+LinuxThread::RestoreSaveFrameZero(const RegisterCheckpoint &checkpoint)
+{
+ return false;
+}
+
+RegisterContextLinux *
+LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
+{
+ return new RegisterContextLinux_x86_64(*this, frame);
+}
+
+bool
+LinuxThread::GetRawStopReason(StopInfo *stop_info)
+{
+ stop_info->Clear();
+
+ switch (m_note)
+ {
+ default:
+ stop_info->SetStopReasonToNone();
+ break;
+
+ case eBreak:
+ stop_info->SetStopReasonWithBreakpointSiteID(m_breakpoint->GetID());
+ break;
+
+ case eTrace:
+ stop_info->SetStopReasonToTrace();
+ }
+
+ return true;
+}
+
+bool
+LinuxThread::WillResume(lldb::StateType resume_state)
+{
+ SetResumeState(resume_state);
+ return Thread::WillResume(resume_state);
+}
+
+bool
+LinuxThread::Resume()
+{
+ lldb::StateType resume_state = GetResumeState();
+ ProcessMonitor &monitor = GetMonitor();
+ bool status;
+
+ switch (GetResumeState())
+ {
+ default:
+ assert(false && "Unexpected state for resume!");
+ status = false;
+ break;
+
+ case lldb::eStateSuspended:
+ // FIXME: Implement process suspension.
+ status = false;
+
+ case lldb::eStateRunning:
+ SetState(resume_state);
+ status = monitor.Resume(GetID());
+ break;
+
+ case lldb::eStateStepping:
+ SetState(resume_state);
+ status = GetRegisterContext()->HardwareSingleStep(true);
+ break;
+ }
+
+ m_note = eNone;
+ return status;
+}
+
+void
+LinuxThread::BreakNotify()
+{
+ bool status;
+
+ status = GetRegisterContext()->UpdateAfterBreakpoint();
+ assert(status && "Breakpoint update failed!");
+
+ // With our register state restored, resolve the breakpoint object
+ // corresponding to our current PC.
+ lldb::addr_t pc = GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site =
+ GetProcess().GetBreakpointSiteList().FindByAddress(pc);
+ assert(bp_site && bp_site->ValidForThisThread(this));
+
+ m_note = eBreak;
+ m_breakpoint = bp_site;
+}
+
+void
+LinuxThread::TraceNotify()
+{
+ m_note = eTrace;
+}
+
+void
+LinuxThread::ExitNotify()
+{
+ m_note = eExit;
+}