diff options
author | Johnny Chen <johnny.chen@apple.com> | 2012-01-05 19:17:38 +0000 |
---|---|---|
committer | Johnny Chen <johnny.chen@apple.com> | 2012-01-05 19:17:38 +0000 |
commit | 30213ffc28b97229c0d06b1332eaced3deba62d7 (patch) | |
tree | 32b27820081f772dedf9dcec828ab8aef3406c96 /lldb/source/Plugins/Process/Linux | |
parent | 99ab273a778d4836981f71dd7c947785dc3816b8 (diff) | |
download | bcm5719-llvm-30213ffc28b97229c0d06b1332eaced3deba62d7.tar.gz bcm5719-llvm-30213ffc28b97229c0d06b1332eaced3deba62d7.zip |
This patch combines common code from Linux and FreeBSD into
a new POSIX platform. It also contains fixes for 64bit FreeBSD.
The patch is based on changes by Mark Peek <mp@FreeBSD.org> and
"K. Macy" <kmacy@freebsd.org> in their github repo located at
https://github.com/fbsd/lldb.
llvm-svn: 147609
Diffstat (limited to 'lldb/source/Plugins/Process/Linux')
18 files changed, 74 insertions, 3746 deletions
diff --git a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp index 5bcafbd5072..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp +++ b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.cpp @@ -1,60 +0,0 @@ -//===-- LinuxStopInfo.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LinuxStopInfo.h" - -using namespace lldb; -using namespace lldb_private; - - -//===----------------------------------------------------------------------===// -// LinuxLimboStopInfo - -LinuxLimboStopInfo::~LinuxLimboStopInfo() { } - -lldb::StopReason -LinuxLimboStopInfo::GetStopReason() const -{ - return lldb::eStopReasonTrace; -} - -const char * -LinuxLimboStopInfo::GetDescription() -{ - return "thread exiting"; -} - -bool -LinuxLimboStopInfo::ShouldStop(Event *event_ptr) -{ - return true; -} - -bool -LinuxLimboStopInfo::ShouldNotify(Event *event_ptr) -{ - return true; -} - -//===----------------------------------------------------------------------===// -// LinuxCrashStopInfo - -LinuxCrashStopInfo::~LinuxCrashStopInfo() { } - -lldb::StopReason -LinuxCrashStopInfo::GetStopReason() const -{ - return lldb::eStopReasonException; -} - -const char * -LinuxCrashStopInfo::GetDescription() -{ - return ProcessMessage::GetCrashReasonString(m_crash_reason); -} diff --git a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h index 96b402a594c..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h +++ b/lldb/source/Plugins/Process/Linux/LinuxStopInfo.h @@ -1,92 +0,0 @@ -//===-- LinuxStopInfo.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_LinuxStopInfo_H_ -#define liblldb_LinuxStopInfo_H_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Target/StopInfo.h" - -#include "LinuxThread.h" -#include "ProcessMessage.h" - -//===----------------------------------------------------------------------===// -/// @class LinuxStopInfo -/// @brief Simple base class for all Linux-specific StopInfo objects. -/// -class LinuxStopInfo - : public lldb_private::StopInfo -{ -public: - LinuxStopInfo(lldb_private::Thread &thread, uint32_t status) - : StopInfo(thread, status) - { } -}; - -//===----------------------------------------------------------------------===// -/// @class LinuxLimboStopInfo -/// @brief Represents the stop state of a process ready to exit. -/// -class LinuxLimboStopInfo - : public LinuxStopInfo -{ -public: - LinuxLimboStopInfo(LinuxThread &thread) - : LinuxStopInfo(thread, 0) - { } - - ~LinuxLimboStopInfo(); - - lldb::StopReason - GetStopReason() const; - - const char * - GetDescription(); - - bool - ShouldStop(lldb_private::Event *event_ptr); - - bool - ShouldNotify(lldb_private::Event *event_ptr); -}; - - -//===----------------------------------------------------------------------===// -/// @class LinuxCrashStopInfo -/// @brief Represents the stop state of process that is ready to crash. -/// -class LinuxCrashStopInfo - : public LinuxStopInfo -{ -public: - LinuxCrashStopInfo(LinuxThread &thread, uint32_t status, - ProcessMessage::CrashReason reason) - : LinuxStopInfo(thread, status), - m_crash_reason(reason) - { } - - ~LinuxCrashStopInfo(); - - lldb::StopReason - GetStopReason() const; - - const char * - GetDescription(); - - ProcessMessage::CrashReason - GetCrashReason() const; - -private: - ProcessMessage::CrashReason m_crash_reason; -}; - -#endif diff --git a/lldb/source/Plugins/Process/Linux/LinuxThread.cpp b/lldb/source/Plugins/Process/Linux/LinuxThread.cpp index 7745cc9360f..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxThread.cpp +++ b/lldb/source/Plugins/Process/Linux/LinuxThread.cpp @@ -1,350 +0,0 @@ -//===-- LinuxThread.cpp -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Debugger.h" -#include "lldb/Host/Host.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Target.h" -#include "LinuxStopInfo.h" -#include "LinuxThread.h" -#include "ProcessLinux.h" -#include "ProcessLinuxLog.h" -#include "ProcessMonitor.h" -#include "RegisterContextLinux_i386.h" -#include "RegisterContextLinux_x86_64.h" -#include "UnwindLLDB.h" - -using namespace lldb_private; - - -LinuxThread::LinuxThread(Process &process, lldb::tid_t tid) - : Thread(process, tid), - m_frame_ap(0) -{ - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("LinuxThread::%s (tid = %i)", __FUNCTION__, tid); -} - -LinuxThread::~LinuxThread() -{ - DestroyThread(); -} - -ProcessMonitor & -LinuxThread::GetMonitor() -{ - ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess()); - return process.GetMonitor(); -} - -void -LinuxThread::RefreshStateAfterStop() -{ - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("LinuxThread::%s ()", __FUNCTION__); - - // Let all threads recover from stopping and do any clean up based - // on the previous thread state (if any). - ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess()); - process.GetThreadList().RefreshStateAfterStop(); -} - -const char * -LinuxThread::GetInfo() -{ - return NULL; -} - -lldb::RegisterContextSP -LinuxThread::GetRegisterContext() -{ - if (!m_reg_context_sp) - { - ArchSpec arch = Host::GetArchitecture(); - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_32_i486: - case ArchSpec::eCore_x86_32_i486sx: - m_reg_context_sp.reset(new RegisterContextLinux_i386(*this, 0)); - break; - - case ArchSpec::eCore_x86_64_x86_64: - m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0)); - break; - } - } - return m_reg_context_sp; -} - -lldb::RegisterContextSP -LinuxThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - uint32_t concrete_frame_idx = 0; - - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("LinuxThread::%s ()", __FUNCTION__); - - if (frame) - concrete_frame_idx = frame->GetConcreteFrameIndex(); - - if (concrete_frame_idx == 0) - reg_ctx_sp = GetRegisterContext(); - else - { - assert(GetUnwinder()); - reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame); - } - - return reg_ctx_sp; -} - -lldb::StopInfoSP -LinuxThread::GetPrivateStopReason() -{ - return m_stop_info; -} - -Unwind * -LinuxThread::GetUnwinder() -{ - if (m_unwinder_ap.get() == NULL) - m_unwinder_ap.reset(new UnwindLLDB(*this)); - - return m_unwinder_ap.get(); -} - -bool -LinuxThread::WillResume(lldb::StateType resume_state) -{ - SetResumeState(resume_state); - - ClearStackFrames(); - if (m_unwinder_ap.get()) - m_unwinder_ap->Clear(); - - return Thread::WillResume(resume_state); -} - -bool -LinuxThread::Resume() -{ - lldb::StateType resume_state = GetResumeState(); - ProcessMonitor &monitor = GetMonitor(); - bool status; - - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("LinuxThread::%s ()", __FUNCTION__); - - switch (resume_state) - { - default: - assert(false && "Unexpected state for resume!"); - status = false; - break; - - case lldb::eStateRunning: - SetState(resume_state); - status = monitor.Resume(GetID(), GetResumeSignal()); - break; - - case lldb::eStateStepping: - SetState(resume_state); - status = monitor.SingleStep(GetID(), GetResumeSignal()); - break; - } - - return status; -} - -void -LinuxThread::Notify(const ProcessMessage &message) -{ - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log) - log->Printf ("LinuxThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind()); - - switch (message.GetKind()) - { - default: - assert(false && "Unexpected message kind!"); - break; - - case ProcessMessage::eLimboMessage: - LimboNotify(message); - break; - - case ProcessMessage::eSignalMessage: - SignalNotify(message); - break; - - case ProcessMessage::eSignalDeliveredMessage: - SignalDeliveredNotify(message); - break; - - case ProcessMessage::eTraceMessage: - TraceNotify(message); - break; - - case ProcessMessage::eBreakpointMessage: - BreakNotify(message); - break; - - case ProcessMessage::eCrashMessage: - CrashNotify(message); - break; - } -} - -void -LinuxThread::BreakNotify(const ProcessMessage &message) -{ - bool status; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - - assert(GetRegisterContextLinux()); - status = GetRegisterContextLinux()->UpdateAfterBreakpoint(); - assert(status && "Breakpoint update failed!"); - - // With our register state restored, resolve the breakpoint object - // corresponding to our current PC. - assert(GetRegisterContext()); - lldb::addr_t pc = GetRegisterContext()->GetPC(); - if (log) - log->Printf ("LinuxThread::%s () PC=0x%8.8llx", __FUNCTION__, pc); - lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc)); - assert(bp_site); - lldb::break_id_t bp_id = bp_site->GetID(); - assert(bp_site && bp_site->ValidForThisThread(this)); - - - m_breakpoint = bp_site; - m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id); -} - -void -LinuxThread::TraceNotify(const ProcessMessage &message) -{ - m_stop_info = StopInfo::CreateStopReasonToTrace(*this); -} - -void -LinuxThread::LimboNotify(const ProcessMessage &message) -{ - m_stop_info = lldb::StopInfoSP(new LinuxLimboStopInfo(*this)); -} - -void -LinuxThread::SignalNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - - m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo); - SetResumeSignal(signo); -} - -void -LinuxThread::SignalDeliveredNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - - // Just treat debugger generated signal events like breakpoints for now. - m_stop_info = StopInfo::CreateStopReasonToTrace(*this); - SetResumeSignal(signo); -} - -void -LinuxThread::CrashNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - - assert(message.GetKind() == ProcessMessage::eCrashMessage); - - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log) - log->Printf ("LinuxThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason()); - - m_stop_info = lldb::StopInfoSP(new LinuxCrashStopInfo( - *this, signo, message.GetCrashReason())); - SetResumeSignal(signo); -} - -unsigned -LinuxThread::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - ArchSpec arch = Host::GetArchitecture(); - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_32_i486: - case ArchSpec::eCore_x86_32_i486sx: - reg = RegisterContextLinux_i386::GetRegisterIndexFromOffset(offset); - break; - - case ArchSpec::eCore_x86_64_x86_64: - reg = RegisterContextLinux_x86_64::GetRegisterIndexFromOffset(offset); - break; - } - return reg; -} - -const char * -LinuxThread::GetRegisterName(unsigned reg) -{ - const char * name; - ArchSpec arch = Host::GetArchitecture(); - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_32_i486: - case ArchSpec::eCore_x86_32_i486sx: - name = RegisterContextLinux_i386::GetRegisterName(reg); - break; - - case ArchSpec::eCore_x86_64_x86_64: - name = RegisterContextLinux_x86_64::GetRegisterName(reg); - break; - } - return name; -} - -const char * -LinuxThread::GetRegisterNameFromOffset(unsigned offset) -{ - return GetRegisterName(GetRegisterIndexFromOffset(offset)); -} - diff --git a/lldb/source/Plugins/Process/Linux/LinuxThread.h b/lldb/source/Plugins/Process/Linux/LinuxThread.h index f6253107d24..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/LinuxThread.h +++ b/lldb/source/Plugins/Process/Linux/LinuxThread.h @@ -1,102 +0,0 @@ -//===-- LinuxThread.h -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_LinuxThread_H_ -#define liblldb_LinuxThread_H_ - -// C Includes -// C++ Includes -#include <memory> - -// Other libraries and framework includes -#include "lldb/Target/Thread.h" - -class ProcessMessage; -class ProcessMonitor; -class RegisterContextLinux; - -//------------------------------------------------------------------------------ -// @class LinuxThread -// @brief Abstraction of a linux process (thread). -class LinuxThread - : public lldb_private::Thread -{ -public: - LinuxThread(lldb_private::Process &process, lldb::tid_t tid); - - virtual ~LinuxThread(); - - void - RefreshStateAfterStop(); - - bool - WillResume(lldb::StateType resume_state); - - const char * - GetInfo(); - - virtual lldb::RegisterContextSP - GetRegisterContext(); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - //-------------------------------------------------------------------------- - // These static functions provide a mapping from the register offset - // back to the register index or name for use in debugging or log - // output. - - static unsigned - GetRegisterIndexFromOffset(unsigned offset); - - static const char * - GetRegisterName(unsigned reg); - - static const char * - GetRegisterNameFromOffset(unsigned offset); - - //-------------------------------------------------------------------------- - // These methods form a specialized interface to linux threads. - // - bool Resume(); - - void Notify(const ProcessMessage &message); - -private: - RegisterContextLinux * - GetRegisterContextLinux () - { - if (!m_reg_context_sp) - GetRegisterContext(); - return (RegisterContextLinux *)m_reg_context_sp.get(); - } - - std::auto_ptr<lldb_private::StackFrame> m_frame_ap; - - lldb::BreakpointSiteSP m_breakpoint; - lldb::StopInfoSP m_stop_info; - - ProcessMonitor & - GetMonitor(); - - lldb::StopInfoSP - GetPrivateStopReason(); - - void BreakNotify(const ProcessMessage &message); - void TraceNotify(const ProcessMessage &message); - void LimboNotify(const ProcessMessage &message); - void SignalNotify(const ProcessMessage &message); - void SignalDeliveredNotify(const ProcessMessage &message); - void CrashNotify(const ProcessMessage &message); - - lldb_private::Unwind * - GetUnwinder(); -}; - -#endif // #ifndef liblldb_LinuxThread_H_ diff --git a/lldb/source/Plugins/Process/Linux/Makefile b/lldb/source/Plugins/Process/Linux/Makefile index d2260f5cad3..850a0290b62 100644 --- a/lldb/source/Plugins/Process/Linux/Makefile +++ b/lldb/source/Plugins/Process/Linux/Makefile @@ -12,6 +12,6 @@ LIBRARYNAME := lldbPluginProcessLinux BUILD_ARCHIVE = 1 # Extend the include path so we may locate UnwindLLDB.h -CPPFLAGS += -I $(LLDB_LEVEL)/source/Plugins/Utility +CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp index 2171a6dbb2f..a8c33bc701d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp @@ -20,10 +20,10 @@ #include "lldb/Target/Target.h" #include "ProcessLinux.h" -#include "ProcessLinuxLog.h" +#include "ProcessPOSIXLog.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "ProcessMonitor.h" -#include "LinuxThread.h" +#include "POSIXThread.h" using namespace lldb; using namespace lldb_private; @@ -50,42 +50,21 @@ ProcessLinux::Initialize() CreateInstance); Log::Callbacks log_callbacks = { - ProcessLinuxLog::DisableLog, - ProcessLinuxLog::EnableLog, - ProcessLinuxLog::ListLogCategories + ProcessPOSIXLog::DisableLog, + ProcessPOSIXLog::EnableLog, + ProcessPOSIXLog::ListLogCategories }; Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks); + ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic()); } } -void -ProcessLinux::Terminate() -{ -} - -const char * -ProcessLinux::GetPluginNameStatic() -{ - return "plugin.process.linux"; -} - -const char * -ProcessLinux::GetPluginDescriptionStatic() -{ - return "Process plugin for Linux"; -} - - //------------------------------------------------------------------------------ // Constructors and destructors. ProcessLinux::ProcessLinux(Target& target, Listener &listener) - : Process(target, listener), - m_monitor(NULL), - m_module(NULL), - m_in_limbo(false), - m_exit_now(false) + : ProcessPOSIX(target, listener) { #if 0 // FIXME: Putting this code in the ctor and saving the byte order in a @@ -98,409 +77,28 @@ ProcessLinux::ProcessLinux(Target& target, Listener &listener) #endif } -ProcessLinux::~ProcessLinux() -{ - delete m_monitor; -} - -//------------------------------------------------------------------------------ -// Process protocol. - -bool -ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name) -{ - // For now we are just making sure the file exists for a given module - ModuleSP exe_module_sp(target.GetExecutableModule()); - if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); - return false; -} - -Error -ProcessLinux::DoAttachToProcessWithID(lldb::pid_t pid) -{ - Error error; - assert(m_monitor == NULL); - - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("ProcessLinux::%s(pid = %i)", __FUNCTION__, GetID()); - - m_monitor = new ProcessMonitor(this, pid, error); - - if (!error.Success()) - return error; - - SetID(pid); - return error; -} - -Error -ProcessLinux::WillLaunch(Module* module) -{ - Error error; - return error; -} - -Error -ProcessLinux::DoLaunch (Module *module, - const ProcessLaunchInfo &launch_info) -{ - Error error; - assert(m_monitor == NULL); - - SetPrivateState(eStateLaunching); - - const char *stdin_path = NULL; - const char *stdout_path = NULL; - const char *stderr_path = NULL; - const char *working_dir = launch_info.GetWorkingDirectory(); - - const ProcessLaunchInfo::FileAction *file_action; - file_action = launch_info.GetFileActionForFD (STDIN_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stdin_path = file_action->GetPath(); - } - file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stdout_path = file_action->GetPath(); - } - file_action = launch_info.GetFileActionForFD (STDERR_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stderr_path = file_action->GetPath(); - } - - m_monitor = new ProcessMonitor (this, - module, - launch_info.GetArguments().GetConstArgumentVector(), - launch_info.GetEnvironmentEntries().GetConstArgumentVector(), - stdin_path, - stdout_path, - stderr_path, - error); - - m_module = module; - - if (!error.Success()) - return error; - - SetID(m_monitor->GetPID()); - return error; -} - -void -ProcessLinux::DidLaunch() -{ -} - -Error -ProcessLinux::DoResume() -{ - StateType state = GetPrivateState(); - - assert(state == eStateStopped || state == eStateCrashed); - - // We are about to resume a thread that will cause the process to exit so - // set our exit status now. Do not change our state if the inferior - // crashed. - if (state == eStateStopped) - { - if (m_in_limbo) - SetExitStatus(m_exit_status, NULL); - else - SetPrivateState(eStateRunning); - } - - bool did_resume = false; - uint32_t thread_count = m_thread_list.GetSize(false); - for (uint32_t i = 0; i < thread_count; ++i) - { - LinuxThread *thread = static_cast<LinuxThread*>( - m_thread_list.GetThreadAtIndex(i, false).get()); - did_resume = thread->Resume() || did_resume; - } - assert(did_resume && "Process resume failed!"); - - return Error(); -} - -addr_t -ProcessLinux::GetImageInfoAddress() -{ - Target *target = &GetTarget(); - ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); - Address addr = obj_file->GetImageInfoAddress(); - - if (addr.IsValid()) - return addr.GetLoadAddress(target); - else - return LLDB_INVALID_ADDRESS; -} - -Error -ProcessLinux::DoHalt(bool &caused_stop) -{ - Error error; - - if (IsStopped()) - { - caused_stop = false; - } - else if (kill(GetID(), SIGSTOP)) - { - caused_stop = false; - error.SetErrorToErrno(); - } - else - { - caused_stop = true; - } - - return error; -} - -Error -ProcessLinux::DoDetach() -{ - Error error; - - error = m_monitor->Detach(); - if (error.Success()) - SetPrivateState(eStateDetached); - - return error; -} - -Error -ProcessLinux::DoSignal(int signal) -{ - Error error; - - if (kill(GetID(), signal)) - error.SetErrorToErrno(); - - return error; -} - -Error -ProcessLinux::DoDestroy() -{ - Error error; - - if (!HasExited()) - { - // Drive the exit event to completion (do not keep the inferior in - // limbo). - m_exit_now = true; - - if (kill(m_monitor->GetPID(), SIGKILL) && error.Success()) - { - error.SetErrorToErrno(); - return error; - } - - SetPrivateState(eStateExited); - } - - return error; -} - -void -ProcessLinux::SendMessage(const ProcessMessage &message) -{ - Mutex::Locker lock(m_message_mutex); - - switch (message.GetKind()) - { - default: - assert(false && "Unexpected process message!"); - break; - - case ProcessMessage::eInvalidMessage: - return; - - case ProcessMessage::eLimboMessage: - m_in_limbo = true; - m_exit_status = message.GetExitStatus(); - if (m_exit_now) - { - SetPrivateState(eStateExited); - m_monitor->Detach(); - } - else - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eExitMessage: - m_exit_status = message.GetExitStatus(); - SetExitStatus(m_exit_status, NULL); - break; - - case ProcessMessage::eTraceMessage: - case ProcessMessage::eBreakpointMessage: - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eSignalMessage: - case ProcessMessage::eSignalDeliveredMessage: - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eCrashMessage: - SetPrivateState(eStateCrashed); - break; - } - - m_message_queue.push(message); -} - void -ProcessLinux::RefreshStateAfterStop() -{ - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) - log->Printf ("ProcessLinux::%s()", __FUNCTION__); - - Mutex::Locker lock(m_message_mutex); - if (m_message_queue.empty()) - return; - - ProcessMessage &message = m_message_queue.front(); - - // Resolve the thread this message corresponds to and pass it along. - // FIXME: we're really dealing with the pid here. This should get - // fixed when this code is fixed to handle multiple threads. - lldb::tid_t tid = message.GetTID(); - if (log) - log->Printf ("ProcessLinux::%s() pid = %i", __FUNCTION__, tid); - LinuxThread *thread = static_cast<LinuxThread*>( - GetThreadList().FindThreadByID(tid, false).get()); - - assert(thread); - thread->Notify(message); - - m_message_queue.pop(); -} - -bool -ProcessLinux::IsAlive() -{ - StateType state = GetPrivateState(); - return state != eStateDetached && state != eStateExited && state != eStateInvalid; -} - -size_t -ProcessLinux::DoReadMemory(addr_t vm_addr, - void *buf, size_t size, Error &error) -{ - assert(m_monitor); - return m_monitor->ReadMemory(vm_addr, buf, size, error); -} - -size_t -ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size, - Error &error) -{ - assert(m_monitor); - return m_monitor->WriteMemory(vm_addr, buf, size, error); -} - -addr_t -ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions, - Error &error) -{ - addr_t allocated_addr = LLDB_INVALID_ADDRESS; - - unsigned prot = 0; - if (permissions & lldb::ePermissionsReadable) - prot |= eMmapProtRead; - if (permissions & lldb::ePermissionsWritable) - prot |= eMmapProtWrite; - if (permissions & lldb::ePermissionsExecutable) - prot |= eMmapProtExec; - - if (InferiorCallMmap(this, allocated_addr, 0, size, prot, - eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { - m_addr_to_mmap_size[allocated_addr] = size; - error.Clear(); - } else { - allocated_addr = LLDB_INVALID_ADDRESS; - error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); - } - - return allocated_addr; -} - -Error -ProcessLinux::DoDeallocateMemory(lldb::addr_t addr) +ProcessLinux::Terminate() { - Error error; - MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); - if (pos != m_addr_to_mmap_size.end() && - InferiorCallMunmap(this, addr, pos->second)) - m_addr_to_mmap_size.erase (pos); - else - error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr); - - return error; } - -size_t -ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) -{ - static const uint8_t g_i386_opcode[] = { 0xCC }; - - ArchSpec arch = GetTarget().GetArchitecture(); - const uint8_t *opcode = NULL; - size_t opcode_size = 0; - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_64_x86_64: - opcode = g_i386_opcode; - opcode_size = sizeof(g_i386_opcode); - break; - } - - bp_site->SetTrapOpcode(opcode, opcode_size); - return opcode_size; -} - -Error -ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site) +const char * +ProcessLinux::GetPluginNameStatic() { - return EnableSoftwareBreakpoint(bp_site); + return "linux"; } -Error -ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site) +const char * +ProcessLinux::GetPluginDescriptionStatic() { - return DisableSoftwareBreakpoint(bp_site); + return "Process plugin for Linux"; } -uint32_t -ProcessLinux::UpdateThreadListIfNeeded() -{ - // Do not allow recursive updates. - return m_thread_list.GetSize(false); -} uint32_t ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD)); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessLinux::%s() (pid = %i)", __FUNCTION__, GetID()); // Update the process thread list with this new thread. @@ -508,61 +106,15 @@ ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thre assert(m_monitor); ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); if (!thread_sp) - thread_sp.reset(new LinuxThread(*this, GetID())); + thread_sp.reset(new POSIXThread(*this, GetID())); - if (log && log->GetMask().Test(LINUX_LOG_VERBOSE)) + if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessLinux::%s() updated pid = %i", __FUNCTION__, GetID()); new_thread_list.AddThread(thread_sp); return new_thread_list.GetSize(false); } -ByteOrder -ProcessLinux::GetByteOrder() const -{ - // FIXME: We should be able to extract this value directly. See comment in - // ProcessLinux(). - return m_byte_order; -} - -size_t -ProcessLinux::PutSTDIN(const char *buf, size_t len, Error &error) -{ - ssize_t status; - if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) - { - error.SetErrorToErrno(); - return 0; - } - return status; -} - -size_t -ProcessLinux::GetSTDOUT(char *buf, size_t len, Error &error) -{ - ssize_t bytes_read; - - // The terminal file descriptor is always in non-block mode. - if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0) - { - if (errno != EAGAIN) - error.SetErrorToErrno(); - return 0; - } - return bytes_read; -} - -size_t -ProcessLinux::GetSTDERR(char *buf, size_t len, Error &error) -{ - return GetSTDOUT(buf, len, error); -} - -UnixSignals & -ProcessLinux::GetUnixSignals() -{ - return m_linux_signals; -} //------------------------------------------------------------------------------ // ProcessInterface protocol. @@ -601,39 +153,3 @@ ProcessLinux::EnablePluginLogging(Stream *strm, Args &command) { return NULL; } - -//------------------------------------------------------------------------------ -// Utility functions. - -bool -ProcessLinux::HasExited() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateDetached: - case eStateExited: - return true; - } - - return false; -} - -bool -ProcessLinux::IsStopped() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateStopped: - case eStateCrashed: - case eStateSuspended: - return true; - } - - return false; -} diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.h b/lldb/source/Plugins/Process/Linux/ProcessLinux.h index 1f67d54de63..cef8a662171 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.h @@ -19,11 +19,12 @@ #include "lldb/Target/Process.h" #include "LinuxSignals.h" #include "ProcessMessage.h" +#include "ProcessPOSIX.h" class ProcessMonitor; class ProcessLinux : - public lldb_private::Process + public ProcessPOSIX { public: //------------------------------------------------------------------ @@ -51,97 +52,8 @@ public: ProcessLinux(lldb_private::Target& target, lldb_private::Listener &listener); - virtual - ~ProcessLinux(); - - //------------------------------------------------------------------ - // Process protocol. - //------------------------------------------------------------------ - virtual bool - CanDebug(lldb_private::Target &target, bool plugin_specified_by_name); - - virtual lldb_private::Error - WillLaunch(lldb_private::Module *module); - - virtual lldb_private::Error - DoAttachToProcessWithID(lldb::pid_t pid); - - virtual lldb_private::Error - DoLaunch (lldb_private::Module *exe_module, - const lldb_private::ProcessLaunchInfo &launch_info); - - virtual void - DidLaunch(); - - virtual lldb_private::Error - DoResume(); - - virtual lldb_private::Error - DoHalt(bool &caused_stop); - - virtual lldb_private::Error - DoDetach(); - - virtual lldb_private::Error - DoSignal(int signal); - - virtual lldb_private::Error - DoDestroy(); - - virtual void - RefreshStateAfterStop(); - - virtual bool - IsAlive(); - - virtual size_t - DoReadMemory(lldb::addr_t vm_addr, - void *buf, - size_t size, - lldb_private::Error &error); - - virtual size_t - DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error); - - virtual lldb::addr_t - DoAllocateMemory(size_t size, uint32_t permissions, - lldb_private::Error &error); - - virtual lldb_private::Error - DoDeallocateMemory(lldb::addr_t ptr); - - virtual size_t - GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site); - - virtual lldb_private::Error - EnableBreakpoint(lldb_private::BreakpointSite *bp_site); - - virtual lldb_private::Error - DisableBreakpoint(lldb_private::BreakpointSite *bp_site); - virtual uint32_t - UpdateThreadListIfNeeded(); - - uint32_t - UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); - - virtual lldb::ByteOrder - GetByteOrder() const; - - virtual lldb::addr_t - GetImageInfoAddress(); - - virtual size_t - PutSTDIN(const char *buf, size_t len, lldb_private::Error &error); - - virtual size_t - GetSTDOUT(char *buf, size_t len, lldb_private::Error &error); - - virtual size_t - GetSTDERR(char *buf, size_t len, lldb_private::Error &error); - + UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list); //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -165,59 +77,11 @@ public: EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command); - //-------------------------------------------------------------------------- - // ProcessLinux internal API. - - /// Registers the given message with this process. - void SendMessage(const ProcessMessage &message); - - ProcessMonitor & - GetMonitor() { assert(m_monitor); return *m_monitor; } - - lldb_private::UnixSignals & - GetUnixSignals(); - private: - /// Target byte order. - lldb::ByteOrder m_byte_order; - - /// Process monitor; - ProcessMonitor *m_monitor; - - /// The module we are executing. - lldb_private::Module *m_module; - - /// Message queue notifying this instance of inferior process state changes. - lldb_private::Mutex m_message_mutex; - std::queue<ProcessMessage> m_message_queue; - - /// True when the process has entered a state of "limbo". - /// - /// This flag qualifies eStateStopped. It lets us know that when we - /// continue from this state the process will exit. Also, when true, - /// Process::m_exit_status is set. - bool m_in_limbo; - - /// Drive any exit events to completion. - bool m_exit_now; /// Linux-specific signal set. LinuxSignals m_linux_signals; - /// Updates the loaded sections provided by the executable. - /// - /// FIXME: It would probably be better to delegate this task to the - /// DynamicLoader plugin, when we have one. - void UpdateLoadedSections(); - - /// Returns true if the process has exited. - bool HasExited(); - - /// Returns true if the process is stopped. - bool IsStopped(); - - typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap; - MMapMap m_addr_to_mmap_size; }; #endif // liblldb_MacOSXProcess_H_ diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp index c07263e891c..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.cpp @@ -1,193 +0,0 @@ -//===-- ProcessLinuxLog.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessLinuxLog.h" - -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/StreamFile.h" - -#include "ProcessLinux.h" - -using namespace lldb; -using namespace lldb_private; - - -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_lob_sp the first time this function is -// called. -static LogSP & -GetLog () -{ - static LogSP g_log_sp; - return g_log_sp; -} - -LogSP -ProcessLinuxLog::GetLogIfAllCategoriesSet (uint32_t mask) -{ - LogSP log(GetLog ()); - if (log && mask) - { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return LogSP(); - } - return log; -} - -void -ProcessLinuxLog::DisableLog (Args &args, Stream *feedback_strm) -{ - LogSP log (GetLog ()); - if (log) - { - uint32_t flag_bits = 0; - - const size_t argc = args.GetArgumentCount (); - if (argc > 0) - { - flag_bits = log->GetMask().Get(); - for (size_t i = 0; i < argc; ++i) - { - const char *arg = args.GetArgumentAtIndex (i); - - - if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~LINUX_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~LINUX_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~LINUX_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~LINUX_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~LINUX_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~LINUX_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~LINUX_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~LINUX_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~LINUX_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~LINUX_LOG_PROCESS; - else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits &= ~LINUX_LOG_PTRACE; - else if (::strcasecmp (arg, "registers") == 0 ) flag_bits &= ~LINUX_LOG_REGISTERS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~LINUX_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~LINUX_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~LINUX_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~LINUX_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories (feedback_strm); - } - - } - } - - if (flag_bits == 0) - GetLog ().reset(); - else - log->GetMask().Reset (flag_bits); - } - - return; -} - -LogSP -ProcessLinuxLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm) -{ - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the same. - uint32_t flag_bits = 0; - LogSP log(GetLog ()); - if (log) - flag_bits = log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) - { - log = make_shared<Log>(log_stream_sp); - GetLog () = log; - } - - if (log) - { - bool got_unknown_category = false; - const size_t argc = args.GetArgumentCount(); - for (size_t i=0; i<argc; ++i) - { - const char *arg = args.GetArgumentAtIndex(i); - - if (::strcasecmp (arg, "all") == 0 ) flag_bits |= LINUX_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= LINUX_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= LINUX_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= LINUX_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= LINUX_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= LINUX_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= LINUX_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= LINUX_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= LINUX_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= LINUX_LOG_PROCESS; - else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits |= LINUX_LOG_PTRACE; - else if (::strcasecmp (arg, "registers") == 0 ) flag_bits |= LINUX_LOG_REGISTERS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= LINUX_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= LINUX_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= LINUX_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= LINUX_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListLogCategories (feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = LINUX_LOG_DEFAULT; - log->GetMask().Reset(flag_bits); - log->GetOptions().Reset(log_options); - } - return log; -} - -void -ProcessLinuxLog::ListLogCategories (Stream *strm) -{ - strm->Printf ("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " async - log asynchronous activity\n" - " break - log breakpoints\n" - " communication - log communication activity\n" - " default - enable the default set of logging categories for liblldb\n" - " packets - log gdb remote packets\n" - " memory - log memory reads and writes\n" - " data-short - log memory bytes for memory reads and writes for short transactions only\n" - " data-long - log memory bytes for memory reads and writes for all transactions\n" - " process - log process events and activities\n" -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION - " ptrace - log all calls to ptrace\n" -#endif - " registers - log register read/writes\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n", ProcessLinux::GetPluginNameStatic()); -} - - -void -ProcessLinuxLog::LogIf (uint32_t mask, const char *format, ...) -{ - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (mask)); - if (log) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } -} - -int ProcessLinuxLog::m_nestinglevel; diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h index 0553df6d1e4..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h +++ b/lldb/source/Plugins/Process/Linux/ProcessLinuxLog.h @@ -1,98 +0,0 @@ -//===-- ProcessLinuxLog.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ProcessLinuxLog_h_ -#define liblldb_ProcessLinuxLog_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes - -// Project includes -#include "lldb/Core/Log.h" - -#define LINUX_LOG_VERBOSE (1u << 0) -#define LINUX_LOG_PROCESS (1u << 1) -#define LINUX_LOG_THREAD (1u << 2) -#define LINUX_LOG_PACKETS (1u << 3) -#define LINUX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls -#define LINUX_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes -#define LINUX_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes -#define LINUX_LOG_BREAKPOINTS (1u << 7) -#define LINUX_LOG_WATCHPOINTS (1u << 8) -#define LINUX_LOG_STEP (1u << 9) -#define LINUX_LOG_COMM (1u << 10) -#define LINUX_LOG_ASYNC (1u << 11) -#define LINUX_LOG_PTRACE (1u << 12) -#define LINUX_LOG_REGISTERS (1u << 13) -#define LINUX_LOG_ALL (UINT32_MAX) -#define LINUX_LOG_DEFAULT LINUX_LOG_PACKETS - -// The size which determines "short memory reads/writes". -#define LINUX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t)) - -class ProcessLinuxLog -{ - static int m_nestinglevel; - -public: - static lldb::LogSP - GetLogIfAllCategoriesSet(uint32_t mask = 0); - - static void - DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm); - - static lldb::LogSP - EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, - lldb_private::Args &args, lldb_private::Stream *feedback_strm); - - static void - ListLogCategories (lldb_private::Stream *strm); - - static void - LogIf (uint32_t mask, const char *format, ...); - - // The following functions can be used to enable the client to limit - // logging to only the top level function calls. This is useful for - // recursive functions. FIXME: not thread safe! - // Example: - // void NestingFunc() { - // LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet(LINUX_LOG_ALL)); - // if (log) - // { - // ProcessLinuxLog::IncNestLevel(); - // if (ProcessLinuxLog::AtTopNestLevel()) - // log->Print(msg); - // } - // NestingFunc(); - // if (log) - // ProcessLinuxLog::DecNestLevel(); - // } - - static bool - AtTopNestLevel() - { - return m_nestinglevel == 1; - } - - static void - IncNestLevel() - { - ++m_nestinglevel; - } - - static void - DecNestLevel() - { - --m_nestinglevel; - assert(m_nestinglevel >= 0); - } -}; - -#endif // liblldb_ProcessLinuxLog_h_ diff --git a/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp b/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp index ad3fc7f3629..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMessage.cpp @@ -1,245 +0,0 @@ -//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessMessage.h" - -using namespace lldb_private; - -const char * -ProcessMessage::GetCrashReasonString(CrashReason reason) -{ - const char *str = NULL; - - switch (reason) - { - default: - assert(false && "invalid CrashReason"); - break; - - case eInvalidAddress: - str = "invalid address"; - break; - case ePrivilegedAddress: - str = "address access protected"; - break; - case eIllegalOpcode: - str = "illegal instruction"; - break; - case eIllegalOperand: - str = "illegal instruction operand"; - break; - case eIllegalAddressingMode: - str = "illegal addressing mode"; - break; - case eIllegalTrap: - str = "illegal trap"; - break; - case ePrivilegedOpcode: - str = "privileged instruction"; - break; - case ePrivilegedRegister: - str = "privileged register"; - break; - case eCoprocessorError: - str = "coprocessor error"; - break; - case eInternalStackError: - str = "internal stack error"; - break; - case eIllegalAlignment: - str = "illegal alignment"; - break; - case eIllegalAddress: - str = "illegal address"; - break; - case eHardwareError: - str = "hardware error"; - break; - case eIntegerDivideByZero: - str = "integer divide by zero"; - break; - case eIntegerOverflow: - str = "integer overflow"; - break; - case eFloatDivideByZero: - str = "floating point divide by zero"; - break; - case eFloatOverflow: - str = "floating point overflow"; - break; - case eFloatUnderflow: - str = "floating point underflow"; - break; - case eFloatInexactResult: - str = "inexact floating point result"; - break; - case eFloatInvalidOperation: - str = "invalid floating point operation"; - break; - case eFloatSubscriptRange: - str = "invalid floating point subscript range"; - break; - } - - return str; -} - -const char * -ProcessMessage::PrintCrashReason(CrashReason reason) -{ -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION - // Just return the code in asci for integration builds. - chcar str[8]; - sprintf(str, "%d", reason); -#else - const char *str = NULL; - - switch (reason) - { - default: - assert(false && "invalid CrashReason"); - break; - - case eInvalidCrashReason: - str = "eInvalidCrashReason"; - break; - - // SIGSEGV crash rcase easons. - case eInvalidAddress: - str = "eInvalidAddress"; - break; - case ePrivilegedAddress: - str = "ePrivilegedAddress"; - break; - - // SIGILL crash rcase easons. - case eIllegalOpcode: - str = "eIllegalOpcode"; - break; - case eIllegalOperand: - str = "eIllegalOperand"; - break; - case eIllegalAddressingMode: - str = "eIllegalAddressingMode"; - break; - case eIllegalTrap: - str = "eIllegalTrap"; - break; - case ePrivilegedOpcode: - str = "ePrivilegedOpcode"; - break; - case ePrivilegedRegister: - str = "ePrivilegedRegister"; - break; - case eCoprocessorError: - str = "eCoprocessorError"; - break; - case eInternalStackError: - str = "eInternalStackError"; - break; - - // SIGBUS crash rcase easons: - case eIllegalAlignment: - str = "eIllegalAlignment"; - break; - case eIllegalAddress: - str = "eIllegalAddress"; - break; - case eHardwareError: - str = "eHardwareError"; - break; - - // SIGFPE crash rcase easons: - case eIntegerDivideByZero: - str = "eIntegerDivideByZero"; - break; - case eIntegerOverflow: - str = "eIntegerOverflow"; - break; - case eFloatDivideByZero: - str = "eFloatDivideByZero"; - break; - case eFloatOverflow: - str = "eFloatOverflow"; - break; - case eFloatUnderflow: - str = "eFloatUnderflow"; - break; - case eFloatInexactResult: - str = "eFloatInexactResult"; - break; - case eFloatInvalidOperation: - str = "eFloatInvalidOperation"; - break; - case eFloatSubscriptRange: - str = "eFloatSubscriptRange"; - break; - } -#endif - - return str; -} - -const char * -ProcessMessage::PrintCrashReason() const -{ - return PrintCrashReason(m_crash_reason); -} - -const char * -ProcessMessage::PrintKind(Kind kind) -{ -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION - // Just return the code in asci for integration builds. - chcar str[8]; - sprintf(str, "%d", reason); -#else - const char *str = NULL; - - switch (kind) - { - default: - assert(false && "invalid Kind"); - break; - - case eInvalidMessage: - str = "eInvalidMessage"; - break; - case eExitMessage: - str = "eExitMessage"; - break; - case eLimboMessage: - str = "eLimboMessage"; - break; - case eSignalMessage: - str = "eSignalMessage"; - break; - case eSignalDeliveredMessage: - str = "eSignalDeliveredMessage"; - break; - case eTraceMessage: - str = "eTraceMessage"; - break; - case eBreakpointMessage: - str = "eBreakpointMessage"; - break; - case eCrashMessage: - str = "eCrashMessage"; - break; - } -#endif - - return str; -} - -const char * -ProcessMessage::PrintKind() const -{ - return PrintKind(m_kind); -} diff --git a/lldb/source/Plugins/Process/Linux/ProcessMessage.h b/lldb/source/Plugins/Process/Linux/ProcessMessage.h index 826567e582b..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMessage.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMessage.h @@ -1,171 +0,0 @@ -//===-- ProcessMessage.h ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ProcessMessage_H_ -#define liblldb_ProcessMessage_H_ - -#include <cassert> - -#include "lldb/lldb-defines.h" -#include "lldb/lldb-types.h" - -class ProcessMessage -{ -public: - - /// The type of signal this message can correspond to. - enum Kind - { - eInvalidMessage, - eExitMessage, - eLimboMessage, - eSignalMessage, - eSignalDeliveredMessage, - eTraceMessage, - eBreakpointMessage, - eCrashMessage - }; - - enum CrashReason - { - eInvalidCrashReason, - - // SIGSEGV crash reasons. - eInvalidAddress, - ePrivilegedAddress, - - // SIGILL crash reasons. - eIllegalOpcode, - eIllegalOperand, - eIllegalAddressingMode, - eIllegalTrap, - ePrivilegedOpcode, - ePrivilegedRegister, - eCoprocessorError, - eInternalStackError, - - // SIGBUS crash reasons, - eIllegalAlignment, - eIllegalAddress, - eHardwareError, - - // SIGFPE crash reasons, - eIntegerDivideByZero, - eIntegerOverflow, - eFloatDivideByZero, - eFloatOverflow, - eFloatUnderflow, - eFloatInexactResult, - eFloatInvalidOperation, - eFloatSubscriptRange - }; - - ProcessMessage() - : m_tid(LLDB_INVALID_PROCESS_ID), - m_kind(eInvalidMessage), - m_crash_reason(eInvalidCrashReason), - m_status(0), - m_addr(0) { } - - Kind GetKind() const { return m_kind; } - - lldb::tid_t GetTID() const { return m_tid; } - - /// Indicates that the thread @p tid is about to exit with status @p status. - static ProcessMessage Limbo(lldb::tid_t tid, int status) { - return ProcessMessage(tid, eLimboMessage, status); - } - - /// Indicates that the thread @p tid had the signal @p signum delivered. - static ProcessMessage Signal(lldb::tid_t tid, int signum) { - return ProcessMessage(tid, eSignalMessage, signum); - } - - /// Indicates that a signal @p signum generated by the debugging process was - /// delivered to the thread @p tid. - static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) { - return ProcessMessage(tid, eSignalDeliveredMessage, signum); - } - - /// Indicates that the thread @p tid encountered a trace point. - static ProcessMessage Trace(lldb::tid_t tid) { - return ProcessMessage(tid, eTraceMessage); - } - - /// Indicates that the thread @p tid encountered a break point. - static ProcessMessage Break(lldb::tid_t tid) { - return ProcessMessage(tid, eBreakpointMessage); - } - - /// Indicates that the thread @p tid crashed. - static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason, - int signo, lldb::addr_t fault_addr) { - ProcessMessage message(pid, eCrashMessage, signo, fault_addr); - message.m_crash_reason = reason; - return message; - } - - int GetExitStatus() const { - assert(GetKind() == eExitMessage || GetKind() == eLimboMessage); - return m_status; - } - - int GetSignal() const { - assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage || - GetKind() == eSignalDeliveredMessage); - return m_status; - } - - int GetStopStatus() const { - assert(GetKind() == eSignalMessage); - return m_status; - } - - CrashReason GetCrashReason() const { - assert(GetKind() == eCrashMessage); - return m_crash_reason; - } - - lldb::addr_t GetFaultAddress() const { - assert(GetKind() == eCrashMessage); - return m_addr; - } - - static const char * - GetCrashReasonString(CrashReason reason); - - const char * - PrintCrashReason() const; - - static const char * - PrintCrashReason(CrashReason reason); - - const char * - PrintKind() const; - - static const char * - PrintKind(Kind); - -private: - ProcessMessage(lldb::tid_t tid, Kind kind, - int status = 0, lldb::addr_t addr = 0) - : m_tid(tid), - m_kind(kind), - m_crash_reason(eInvalidCrashReason), - m_status(status), - m_addr(addr) { } - - lldb::tid_t m_tid; - Kind m_kind : 8; - CrashReason m_crash_reason : 8; - int m_status; - lldb::addr_t m_addr; -}; - -#endif // #ifndef liblldb_ProcessMessage_H_ diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index c154c5555db..ed69b970f20 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -28,9 +28,9 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/PseudoTerminal.h" -#include "LinuxThread.h" +#include "POSIXThread.h" #include "ProcessLinux.h" -#include "ProcessLinuxLog.h" +#include "ProcessPOSIXLog.h" #include "ProcessMonitor.h" @@ -63,8 +63,8 @@ DisplayBytes (lldb_private::StreamString &s, void *bytes, uint32_t count) static void PtraceDisplayBytes(__ptrace_request &req, void *data) { StreamString buf; - LogSP verbose_log (ProcessLinuxLog::GetLogIfAllCategoriesSet ( - LINUX_LOG_PTRACE | LINUX_LOG_VERBOSE)); + LogSP verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet ( + POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE)); if (verbose_log) { @@ -120,7 +120,7 @@ PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, { long int result; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PTRACE)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE)); if (log) log->Printf("ptrace(%s, %u, %p, %p) called from file %s line %d", @@ -170,10 +170,10 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, size_t remainder; long data; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_ALL)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); if (log) - ProcessLinuxLog::IncNestLevel(); - if (log && ProcessLinuxLog::AtTopNestLevel() && log->GetMask().Test(LINUX_LOG_MEMORY)) + ProcessPOSIXLog::IncNestLevel(); + if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__, pid, word_size, (void*)vm_addr, buf, size); @@ -187,7 +187,7 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, { error.SetErrorToErrno(); if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_read; } @@ -200,10 +200,10 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, for (unsigned i = 0; i < remainder; ++i) dst[i] = ((data >> i*8) & 0xFF); - if (log && ProcessLinuxLog::AtTopNestLevel() && - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_SHORT) && - size <= LINUX_LOG_MEMORY_SHORT_BYTES))) + if (log && ProcessPOSIXLog::AtTopNestLevel() && + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && + size <= POSIX_LOG_MEMORY_SHORT_BYTES))) log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, (void*)vm_addr, *(unsigned long*)dst, (unsigned long)data); @@ -212,7 +212,7 @@ DoReadMemory(lldb::pid_t pid, unsigned word_size, } if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_read; } @@ -224,10 +224,10 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, size_t bytes_written = 0; size_t remainder; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_ALL)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); if (log) - ProcessLinuxLog::IncNestLevel(); - if (log && ProcessLinuxLog::AtTopNestLevel() && log->GetMask().Test(LINUX_LOG_MEMORY)) + ProcessPOSIXLog::IncNestLevel(); + if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__, pid, word_size, (void*)vm_addr, buf, size); @@ -244,10 +244,10 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, for (unsigned i = 0; i < word_size; ++i) data |= (unsigned long)src[i] << i*8; - if (log && ProcessLinuxLog::AtTopNestLevel() && - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_SHORT) && - size <= LINUX_LOG_MEMORY_SHORT_BYTES))) + if (log && ProcessPOSIXLog::AtTopNestLevel() && + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && + size <= POSIX_LOG_MEMORY_SHORT_BYTES))) log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, (void*)vm_addr, *(unsigned long*)src, data); @@ -255,7 +255,7 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, { error.SetErrorToErrno(); if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } } @@ -266,7 +266,7 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, buff, word_size, error) != word_size) { if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } @@ -276,14 +276,14 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, buff, word_size, error) != word_size) { if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } - if (log && ProcessLinuxLog::AtTopNestLevel() && - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(LINUX_LOG_MEMORY_DATA_SHORT) && - size <= LINUX_LOG_MEMORY_SHORT_BYTES))) + if (log && ProcessPOSIXLog::AtTopNestLevel() && + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || + (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && + size <= POSIX_LOG_MEMORY_SHORT_BYTES))) log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, (void*)vm_addr, *(unsigned long*)src, *(unsigned long*)buff); } @@ -292,7 +292,7 @@ DoWriteMemory(lldb::pid_t pid, unsigned word_size, src += word_size; } if (log) - ProcessLinuxLog::DecNestLevel(); + ProcessPOSIXLog::DecNestLevel(); return bytes_written; } @@ -420,7 +420,7 @@ void ReadRegOperation::Execute(ProcessMonitor *monitor) { lldb::pid_t pid = monitor->GetPID(); - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_REGISTERS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); // Set errno to zero so that we can detect a failed peek. errno = 0; @@ -434,7 +434,7 @@ ReadRegOperation::Execute(ProcessMonitor *monitor) } if (log) log->Printf ("ProcessMonitor::%s() reg %s: 0x%x", __FUNCTION__, - LinuxThread::GetRegisterNameFromOffset(m_offset), data); + POSIXThread::GetRegisterNameFromOffset(m_offset), data); } //------------------------------------------------------------------------------ @@ -460,7 +460,7 @@ WriteRegOperation::Execute(ProcessMonitor *monitor) { void* buf; lldb::pid_t pid = monitor->GetPID(); - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_REGISTERS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); if (sizeof(void*) == sizeof(uint64_t)) buf = (void*) m_value.GetAsUInt64(); @@ -472,7 +472,7 @@ WriteRegOperation::Execute(ProcessMonitor *monitor) if (log) log->Printf ("ProcessMonitor::%s() reg %s: %p", __FUNCTION__, - LinuxThread::GetRegisterNameFromOffset(m_offset), buf); + POSIXThread::GetRegisterNameFromOffset(m_offset), buf); if (PTRACE(PTRACE_POKEUSER, pid, (void*)m_offset, buf)) m_result = false; else @@ -794,7 +794,7 @@ ProcessMonitor::AttachArgs::~AttachArgs() /// launching or attaching to the inferior process, and then 2) servicing /// operations such as register reads/writes, stepping, etc. See the comments /// on the Operation class for more info as to why this is needed. -ProcessMonitor::ProcessMonitor(ProcessLinux *process, +ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, Module *module, const char *argv[], const char *envp[], @@ -802,7 +802,7 @@ ProcessMonitor::ProcessMonitor(ProcessLinux *process, const char *stdout_path, const char *stderr_path, lldb_private::Error &error) - : m_process(process), + : m_process(static_cast<ProcessLinux *>(process)), m_operation_thread(LLDB_INVALID_HOST_THREAD), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), @@ -858,10 +858,10 @@ WAIT_AGAIN: } } -ProcessMonitor::ProcessMonitor(ProcessLinux *process, +ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, lldb::pid_t pid, lldb_private::Error &error) - : m_process(process), + : m_process(static_cast<ProcessLinux *>(process)), m_operation_thread(LLDB_INVALID_HOST_THREAD), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), @@ -978,7 +978,7 @@ ProcessMonitor::Launch(LaunchArgs *args) lldb::pid_t pid; lldb::ThreadSP inferior; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); // Propagate the environment if one is not supplied. if (envp == NULL || envp[0] == NULL) @@ -1101,11 +1101,10 @@ ProcessMonitor::Launch(LaunchArgs *args) if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error)) goto FINISH; - // Update the process thread list with this new thread and mark it as - // current. + // Update the process thread list with this new thread. // FIXME: should we be letting UpdateThreadList handle this? // FIXME: by using pids instead of tids, we can only support one thread. - inferior.reset(new LinuxThread(process, pid)); + inferior.reset(new POSIXThread(process, pid)); if (log) log->Printf ("ProcessMonitor::%s() adding pid = %i", __FUNCTION__, pid); process.GetThreadList().AddThread(inferior); @@ -1167,9 +1166,8 @@ ProcessMonitor::Attach(AttachArgs *args) ProcessMonitor *monitor = args->m_monitor; ProcessLinux &process = monitor->GetProcess(); - lldb::ThreadSP inferior; - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PROCESS)); + LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); if (pid <= 1) { @@ -1192,13 +1190,11 @@ ProcessMonitor::Attach(AttachArgs *args) goto FINISH; } - // Update the process thread list with the attached thread and - // mark it as current. - inferior.reset(new LinuxThread(process, pid)); + // Update the process thread list with the attached thread. + inferior.reset(new POSIXThread(process, pid)); if (log) log->Printf ("ProcessMonitor::%s() adding tid = %i", __FUNCTION__, pid); process.GetThreadList().AddThread(inferior); - process.GetThreadList().SetSelectedThreadByID(pid); // Let our process instance know the thread has stopped. process.SendMessage(ProcessMessage::Trace(pid)); @@ -1568,7 +1564,7 @@ ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, } bool -ProcessMonitor::ReadRegisterValue(unsigned offset, RegisterValue &value) +ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value) { bool result; ReadRegOperation op(offset, value, result); diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h index fdccb67745a..03e8c8c4558 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h @@ -24,10 +24,12 @@ namespace lldb_private class Error; class Module; class Scalar; + } // End lldb_private namespace. class ProcessLinux; class Operation; +class ProcessPOSIX; /// @class ProcessMonitor /// @brief Manages communication with the inferior (debugee) process. @@ -47,7 +49,7 @@ public: /// Launches an inferior process ready for debugging. Forms the /// implementation of Process::DoLaunch. - ProcessMonitor(ProcessLinux *process, + ProcessMonitor(ProcessPOSIX *process, lldb_private::Module *module, char const *argv[], char const *envp[], @@ -56,7 +58,7 @@ public: const char *stderr_path, lldb_private::Error &error); - ProcessMonitor(ProcessLinux *process, + ProcessMonitor(ProcessPOSIX *process, lldb::pid_t pid, lldb_private::Error &error); @@ -104,7 +106,7 @@ public: /// /// This method is provided for use by RegisterContextLinux derivatives. bool - ReadRegisterValue(unsigned offset, lldb_private::RegisterValue &value); + ReadRegisterValue(unsigned offset, unsigned size, lldb_private::RegisterValue &value); /// Writes the given value to the register identified by the given /// (architecture dependent) offset. diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h index 4e5d4651f8b..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux.h @@ -1,40 +0,0 @@ -//===-- RegisterContext_x86_64.h --------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextLinux_H_ -#define liblldb_RegisterContextLinux_H_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Target/RegisterContext.h" - -//------------------------------------------------------------------------------ -/// @class RegisterContextLinux -/// -/// @brief Extends RegisterClass with a few virtual operations useful on Linux. -class RegisterContextLinux - : public lldb_private::RegisterContext -{ -public: - RegisterContextLinux(lldb_private::Thread &thread, - uint32_t concrete_frame_idx) - : RegisterContext(thread, concrete_frame_idx) { } - - /// Updates the register state of the associated thread after hitting a - /// breakpoint (if that make sense for the architecture). Default - /// implementation simply returns true for architectures which do not - /// require any update. - /// - /// @return - /// True if the operation succeeded and false otherwise. - virtual bool UpdateAfterBreakpoint() { return true; } -}; - -#endif // #ifndef liblldb_RegisterContextLinux_H_ diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp index 20c3c73c589..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp @@ -1,650 +0,0 @@ -//===-- RegisterContextLinux_i386.cpp ---------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Core/DataExtractor.h" -#include "lldb/Target/Thread.h" -#include "lldb/Host/Endian.h" - -#include "ProcessLinux.h" -#include "ProcessLinuxLog.h" -#include "ProcessMonitor.h" -#include "RegisterContextLinux_i386.h" - -using namespace lldb_private; -using namespace lldb; - -enum -{ - k_first_gpr, - gpr_eax = k_first_gpr, - gpr_ebx, - gpr_ecx, - gpr_edx, - gpr_edi, - gpr_esi, - gpr_ebp, - gpr_esp, - gpr_ss, - gpr_eflags, - gpr_eip, - gpr_cs, - gpr_ds, - gpr_es, - gpr_fs, - gpr_gs, - k_last_gpr = gpr_gs, - - k_first_fpr, - fpu_fcw = k_first_fpr, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_foo, - fpu_fos, - fpu_mxcsr, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - k_last_fpr = fpu_xmm7, - - k_num_registers, - k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, - k_num_fpu_registers = k_last_fpr - k_first_fpr + 1 -}; - -// Number of register sets provided by this context. -enum -{ - k_num_register_sets = 2 -}; - -enum -{ - gcc_eax = 0, - gcc_ecx, - gcc_edx, - gcc_ebx, - gcc_ebp, - gcc_esp, - gcc_esi, - gcc_edi, - gcc_eip, - gcc_eflags -}; - -enum -{ - dwarf_eax = 0, - dwarf_ecx, - dwarf_edx, - dwarf_ebx, - dwarf_esp, - dwarf_ebp, - dwarf_esi, - dwarf_edi, - dwarf_eip, - dwarf_eflags, - dwarf_stmm0 = 11, - dwarf_stmm1, - dwarf_stmm2, - dwarf_stmm3, - dwarf_stmm4, - dwarf_stmm5, - dwarf_stmm6, - dwarf_stmm7, - dwarf_xmm0 = 21, - dwarf_xmm1, - dwarf_xmm2, - dwarf_xmm3, - dwarf_xmm4, - dwarf_xmm5, - dwarf_xmm6, - dwarf_xmm7 -}; - -enum -{ - gdb_eax = 0, - gdb_ecx = 1, - gdb_edx = 2, - gdb_ebx = 3, - gdb_esp = 4, - gdb_ebp = 5, - gdb_esi = 6, - gdb_edi = 7, - gdb_eip = 8, - gdb_eflags = 9, - gdb_cs = 10, - gdb_ss = 11, - gdb_ds = 12, - gdb_es = 13, - gdb_fs = 14, - gdb_gs = 15, - gdb_stmm0 = 16, - gdb_stmm1 = 17, - gdb_stmm2 = 18, - gdb_stmm3 = 19, - gdb_stmm4 = 20, - gdb_stmm5 = 21, - gdb_stmm6 = 22, - gdb_stmm7 = 23, - gdb_fcw = 24, - gdb_fsw = 25, - gdb_ftw = 26, - gdb_fpu_cs = 27, - gdb_ip = 28, - gdb_fpu_ds = 29, - gdb_dp = 30, - gdb_fop = 31, - gdb_xmm0 = 32, - gdb_xmm1 = 33, - gdb_xmm2 = 34, - gdb_xmm3 = 35, - gdb_xmm4 = 36, - gdb_xmm5 = 37, - gdb_xmm6 = 38, - gdb_xmm7 = 39, - gdb_mxcsr = 40, - gdb_mm0 = 41, - gdb_mm1 = 42, - gdb_mm2 = 43, - gdb_mm3 = 44, - gdb_mm4 = 45, - gdb_mm5 = 46, - gdb_mm6 = 47, - gdb_mm7 = 48 -}; - -static const -uint32_t g_gpr_regnums[k_num_gpr_registers] = -{ - gpr_eax, - gpr_ebx, - gpr_ecx, - gpr_edx, - gpr_edi, - gpr_esi, - gpr_ebp, - gpr_esp, - gpr_ss, - gpr_eflags, - gpr_eip, - gpr_cs, - gpr_ds, - gpr_es, - gpr_fs, - gpr_gs, -}; - -static const uint32_t -g_fpu_regnums[k_num_fpu_registers] = -{ - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_foo, - fpu_fos, - fpu_mxcsr, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, -}; - -static const RegisterSet -g_reg_sets[k_num_register_sets] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums }, - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums } -}; - -// Computes the offset of the given GPR in the user data area. -#define GPR_OFFSET(regname) \ - (offsetof(RegisterContextLinux_i386::UserArea, regs) + \ - offsetof(RegisterContextLinux_i386::GPR, regname)) - -// Computes the offset of the given FPR in the user data area. -#define FPR_OFFSET(regname) \ - (offsetof(RegisterContextLinux_i386::UserArea, i387) + \ - offsetof(RegisterContextLinux_i386::FPU, regname)) - -// Number of bytes needed to represent a GPR. -#define GPR_SIZE(reg) sizeof(((RegisterContextLinux_i386::GPR*)NULL)->reg) - -// Number of bytes needed to represent a FPR. -#define FPR_SIZE(reg) sizeof(((RegisterContextLinux_i386::FPU*)NULL)->reg) - -// Number of bytes needed to represent the i'th FP register. -#define FP_SIZE sizeof(((RegisterContextLinux_i386::MMSReg*)NULL)->bytes) - -// Number of bytes needed to represent an XMM register. -#define XMM_SIZE sizeof(RegisterContextLinux_i386::XMMReg) - -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ - { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } } - -#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \ - { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } } - -#define DEFINE_FP(reg, i) \ - { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { dwarf_##reg##i, dwarf_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } } - -#define DEFINE_XMM(reg, i) \ - { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { dwarf_##reg##i, dwarf_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } } - -static RegisterInfo -g_register_infos[k_num_registers] = -{ - // General purpose registers. - DEFINE_GPR(eax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax), - DEFINE_GPR(ebx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx), - DEFINE_GPR(ecx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx), - DEFINE_GPR(edx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx), - DEFINE_GPR(edi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi), - DEFINE_GPR(esi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi), - DEFINE_GPR(ebp, "fp", gcc_ebp, dwarf_ebp, LLDB_INVALID_REGNUM, gdb_ebp), - DEFINE_GPR(esp, "sp", gcc_esp, dwarf_esp, LLDB_INVALID_REGNUM, gdb_esp), - DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ss), - DEFINE_GPR(eflags, "flags", gcc_eflags, dwarf_eflags, LLDB_INVALID_REGNUM, gdb_eflags), - DEFINE_GPR(eip, "pc", gcc_eip, dwarf_eip, LLDB_INVALID_REGNUM, gdb_eip), - DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_cs), - DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ds), - DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_es), - DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fs), - DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gs), - - // Floating point registers. - DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fcw), - DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fsw), - DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftw), - DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop), - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ip), - DEFINE_FPR(cs, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs), - DEFINE_FPR(foo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_dp), - DEFINE_FPR(fos, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds), - DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_mxcsr), - - DEFINE_FP(stmm, 0), - DEFINE_FP(stmm, 1), - DEFINE_FP(stmm, 2), - DEFINE_FP(stmm, 3), - DEFINE_FP(stmm, 4), - DEFINE_FP(stmm, 5), - DEFINE_FP(stmm, 6), - DEFINE_FP(stmm, 7), - - // XMM registers - DEFINE_XMM(xmm, 0), - DEFINE_XMM(xmm, 1), - DEFINE_XMM(xmm, 2), - DEFINE_XMM(xmm, 3), - DEFINE_XMM(xmm, 4), - DEFINE_XMM(xmm, 5), - DEFINE_XMM(xmm, 6), - DEFINE_XMM(xmm, 7), - -}; - -#ifndef NDEBUG -static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); -#endif - -static unsigned GetRegOffset(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_offset; -} - -#if 0 // These functions are currently not in use. -static unsigned GetRegSize(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_size; -} - -static bool IsGPR(unsigned reg) -{ - return reg <= k_last_gpr; // GPR's come first. -} - -static bool IsFPR(unsigned reg) -{ - return (k_first_fpr <= reg && reg <= k_last_fpr); -} -#endif - - -RegisterContextLinux_i386::RegisterContextLinux_i386(Thread &thread, - uint32_t concrete_frame_idx) - : RegisterContextLinux(thread, concrete_frame_idx) -{ -} - -RegisterContextLinux_i386::~RegisterContextLinux_i386() -{ -} - -ProcessMonitor & -RegisterContextLinux_i386::GetMonitor() -{ - ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess()); - return process->GetMonitor(); -} - -void -RegisterContextLinux_i386::Invalidate() -{ -} - -void -RegisterContextLinux_i386::InvalidateAllRegisters() -{ -} - -size_t -RegisterContextLinux_i386::GetRegisterCount() -{ - assert(k_num_register_infos == k_num_registers); - return k_num_registers; -} - -const RegisterInfo * -RegisterContextLinux_i386::GetRegisterInfoAtIndex(uint32_t reg) -{ - assert(k_num_register_infos == k_num_registers); - if (reg < k_num_registers) - return &g_register_infos[reg]; - else - return NULL; -} - -size_t -RegisterContextLinux_i386::GetRegisterSetCount() -{ - return k_num_register_sets; -} - -const RegisterSet * -RegisterContextLinux_i386::GetRegisterSet(uint32_t set) -{ - if (set < k_num_register_sets) - return &g_reg_sets[set]; - else - return NULL; -} - -unsigned -RegisterContextLinux_i386::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < k_num_registers; reg++) - { - if (g_register_infos[reg].byte_offset == offset) - break; - } - assert(reg < k_num_registers && "Invalid register offset."); - return reg; -} - -const char * -RegisterContextLinux_i386::GetRegisterName(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register offset."); - return g_register_infos[reg].name; -} - -bool -RegisterContextLinux_i386::ReadRegister(const RegisterInfo *reg_info, - RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(GetRegOffset(reg), value); -} - -bool -RegisterContextLinux_i386::ReadAllRegisterValues(DataBufferSP &data_sp) -{ - return false; -} - -bool RegisterContextLinux_i386::WriteRegister(const RegisterInfo *reg_info, - const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteRegisterValue(GetRegOffset(reg), value); -} - -bool -RegisterContextLinux_i386::WriteAllRegisterValues(const DataBufferSP &data) -{ - return false; -} - -bool -RegisterContextLinux_i386::UpdateAfterBreakpoint() -{ - // PC points one byte past the int3 responsible for the breakpoint. - lldb::addr_t pc; - - if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) - return false; - - SetPC(pc - 1); - return true; -} - -uint32_t -RegisterContextLinux_i386::ConvertRegisterKindToRegisterNumber(uint32_t kind, - uint32_t num) -{ - if (kind == eRegisterKindGeneric) - { - switch (num) - { - case LLDB_REGNUM_GENERIC_PC: return gpr_eip; - case LLDB_REGNUM_GENERIC_SP: return gpr_esp; - case LLDB_REGNUM_GENERIC_FP: return gpr_ebp; - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags; - case LLDB_REGNUM_GENERIC_RA: - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF) - { - switch (num) - { - case dwarf_eax: return gpr_eax; - case dwarf_edx: return gpr_edx; - case dwarf_ecx: return gpr_ecx; - case dwarf_ebx: return gpr_ebx; - case dwarf_esi: return gpr_esi; - case dwarf_edi: return gpr_edi; - case dwarf_ebp: return gpr_ebp; - case dwarf_esp: return gpr_esp; - case dwarf_eip: return gpr_eip; - case dwarf_xmm0: return fpu_xmm0; - case dwarf_xmm1: return fpu_xmm1; - case dwarf_xmm2: return fpu_xmm2; - case dwarf_xmm3: return fpu_xmm3; - case dwarf_xmm4: return fpu_xmm4; - case dwarf_xmm5: return fpu_xmm5; - case dwarf_xmm6: return fpu_xmm6; - case dwarf_xmm7: return fpu_xmm7; - case dwarf_stmm0: return fpu_stmm0; - case dwarf_stmm1: return fpu_stmm1; - case dwarf_stmm2: return fpu_stmm2; - case dwarf_stmm3: return fpu_stmm3; - case dwarf_stmm4: return fpu_stmm4; - case dwarf_stmm5: return fpu_stmm5; - case dwarf_stmm6: return fpu_stmm6; - case dwarf_stmm7: return fpu_stmm7; - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGDB) - { - switch (num) - { - case gdb_eax : return gpr_eax; - case gdb_ebx : return gpr_ebx; - case gdb_ecx : return gpr_ecx; - case gdb_edx : return gpr_edx; - case gdb_esi : return gpr_esi; - case gdb_edi : return gpr_edi; - case gdb_ebp : return gpr_ebp; - case gdb_esp : return gpr_esp; - case gdb_eip : return gpr_eip; - case gdb_eflags : return gpr_eflags; - case gdb_cs : return gpr_cs; - case gdb_ss : return gpr_ss; - case gdb_ds : return gpr_ds; - case gdb_es : return gpr_es; - case gdb_fs : return gpr_fs; - case gdb_gs : return gpr_gs; - case gdb_stmm0 : return fpu_stmm0; - case gdb_stmm1 : return fpu_stmm1; - case gdb_stmm2 : return fpu_stmm2; - case gdb_stmm3 : return fpu_stmm3; - case gdb_stmm4 : return fpu_stmm4; - case gdb_stmm5 : return fpu_stmm5; - case gdb_stmm6 : return fpu_stmm6; - case gdb_stmm7 : return fpu_stmm7; - case gdb_fcw : return fpu_fcw; - case gdb_fsw : return fpu_fsw; - case gdb_ftw : return fpu_ftw; - case gdb_fpu_cs : return fpu_cs; - case gdb_ip : return fpu_ip; - case gdb_fpu_ds : return fpu_fos; - case gdb_dp : return fpu_foo; - case gdb_fop : return fpu_fop; - case gdb_xmm0 : return fpu_xmm0; - case gdb_xmm1 : return fpu_xmm1; - case gdb_xmm2 : return fpu_xmm2; - case gdb_xmm3 : return fpu_xmm3; - case gdb_xmm4 : return fpu_xmm4; - case gdb_xmm5 : return fpu_xmm5; - case gdb_xmm6 : return fpu_xmm6; - case gdb_xmm7 : return fpu_xmm7; - case gdb_mxcsr : return fpu_mxcsr; - default: - return LLDB_INVALID_REGNUM; - } - } - else if (kind == eRegisterKindLLDB) - { - return num; - } - - return LLDB_INVALID_REGNUM; -} - -bool -RegisterContextLinux_i386::HardwareSingleStep(bool enable) -{ - enum { TRACE_BIT = 0x100 }; - uint64_t eflags; - - if ((eflags = ReadRegisterAsUnsigned(gpr_eflags, -1UL)) == -1UL) - return false; - - if (enable) - { - if (eflags & TRACE_BIT) - return true; - - eflags |= TRACE_BIT; - } - else - { - if (!(eflags & TRACE_BIT)) - return false; - - eflags &= ~TRACE_BIT; - } - - return WriteRegisterFromUnsigned(gpr_eflags, eflags); -} - -void -RegisterContextLinux_i386::LogGPR(const char *title) -{ - LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_REGISTERS)); - if (log) - { - if (title) - log->Printf ("%s", title); - for (uint32_t i=0; i<k_num_gpr_registers; i++) - { - uint32_t reg = gpr_eax + i; - log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&user.regs)[reg]); - } - } -} - -bool -RegisterContextLinux_i386::ReadGPR() -{ - bool result; - - ProcessMonitor &monitor = GetMonitor(); - result = monitor.ReadGPR(&user.regs); - LogGPR("RegisterContextLinux_i386::ReadGPR()"); - return result; -} - -bool -RegisterContextLinux_i386::ReadFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadFPR(&user.i387); -} diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h index 718e831abb0..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_i386.h @@ -1,169 +0,0 @@ -//===-- RegisterContextLinux_i386.h ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextLinux_i386_h_ -#define liblldb_RegisterContextLinux_i386_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Log.h" -#include "RegisterContextLinux.h" - -class RegisterContextLinux_i386 : public RegisterContextLinux -{ -public: - RegisterContextLinux_i386(lldb_private::Thread &thread, - uint32_t concreate_frame_idx); - - ~RegisterContextLinux_i386(); - - void - Invalidate(); - - void - InvalidateAllRegisters(); - - size_t - GetRegisterCount(); - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex(uint32_t reg); - - size_t - GetRegisterSetCount(); - - const lldb_private::RegisterSet * - GetRegisterSet(uint32_t set); - - static unsigned - GetRegisterIndexFromOffset(unsigned offset); - - static const char * - GetRegisterName(unsigned reg); - -#if 0 - bool - ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value); - - bool - ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data); -#endif - - virtual bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - -#if 0 - bool - WriteRegisterValue(uint32_t reg, const lldb_private::Scalar &value); - - bool - WriteRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data, - uint32_t data_offset = 0); -#endif - - virtual bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num); - - bool - HardwareSingleStep(bool enable); - - bool - UpdateAfterBreakpoint(); - - struct GPR - { - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t esi; - uint32_t edi; - uint32_t ebp; - uint32_t eax; - uint32_t ds; - uint32_t es; - uint32_t fs; - uint32_t gs; - uint32_t orig_ax; - uint32_t eip; - uint32_t cs; - uint32_t eflags; - uint32_t esp; - uint32_t ss; - }; - - struct MMSReg - { - uint8_t bytes[8]; - }; - - struct XMMReg - { - uint8_t bytes[16]; - }; - - struct FPU - { - uint16_t fcw; - uint16_t fsw; - uint16_t ftw; - uint16_t fop; - uint32_t ip; - uint32_t cs; - uint32_t foo; - uint32_t fos; - uint32_t mxcsr; - uint32_t reserved; - MMSReg stmm[8]; - XMMReg xmm[8]; - uint32_t pad[56]; - }; - - struct UserArea - { - GPR regs; // General purpose registers. - int32_t fpvalid; // True if FPU is being used. - FPU i387; // FPU registers. - uint32_t tsize; // Text segment size. - uint32_t dsize; // Data segment size. - uint32_t ssize; // Stack segment size. - uint32_t start_code; // VM address of text. - uint32_t start_stack; // VM address of stack bottom (top in rsp). - int32_t signal; // Signal causing core dump. - int32_t reserved; // Unused. - uint32_t ar0; // Location of GPR's. - FPU* fpstate; // Location of FPR's. - uint32_t magic; // Identifier for core dumps. - char u_comm[32]; // Command causing core dump. - uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). - }; -private: - UserArea user; - - ProcessMonitor &GetMonitor(); - - void LogGPR(const char *title); - - bool ReadGPR(); - bool ReadFPR(); -}; - -#endif // #ifndef liblldb_RegisterContextLinux_i386_h_ diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp index 040c14eda51..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp @@ -1,759 +0,0 @@ -//===-- RegisterContextLinux_x86_64.cpp -------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <cstring> -#include <errno.h> -#include <stdint.h> - -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Target/Thread.h" -#include "lldb/Host/Endian.h" - -#include "ProcessLinux.h" -#include "ProcessMonitor.h" -#include "RegisterContextLinux_x86_64.h" - -using namespace lldb_private; -using namespace lldb; - -// Internal codes for all x86_64 registers. -enum -{ - k_first_gpr, - gpr_rax = k_first_gpr, - gpr_rbx, - gpr_rcx, - gpr_rdx, - gpr_rdi, - gpr_rsi, - gpr_rbp, - gpr_rsp, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, - gpr_r14, - gpr_r15, - gpr_rip, - gpr_rflags, - gpr_cs, - gpr_fs, - gpr_gs, - gpr_ss, - gpr_ds, - gpr_es, - k_last_gpr = gpr_es, - - k_first_fpr, - fpu_fcw = k_first_fpr, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - fpu_xmm8, - fpu_xmm9, - fpu_xmm10, - fpu_xmm11, - fpu_xmm12, - fpu_xmm13, - fpu_xmm14, - fpu_xmm15, - k_last_fpr = fpu_xmm15, - - k_num_registers, - k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, - k_num_fpu_registers = k_last_fpr - k_first_fpr + 1 -}; - -// Number of register sets provided by this context. -enum -{ - k_num_register_sets = 2 -}; - -enum gcc_dwarf_regnums -{ - gcc_dwarf_gpr_rax = 0, - gcc_dwarf_gpr_rdx, - gcc_dwarf_gpr_rcx, - gcc_dwarf_gpr_rbx, - gcc_dwarf_gpr_rsi, - gcc_dwarf_gpr_rdi, - gcc_dwarf_gpr_rbp, - gcc_dwarf_gpr_rsp, - gcc_dwarf_gpr_r8, - gcc_dwarf_gpr_r9, - gcc_dwarf_gpr_r10, - gcc_dwarf_gpr_r11, - gcc_dwarf_gpr_r12, - gcc_dwarf_gpr_r13, - gcc_dwarf_gpr_r14, - gcc_dwarf_gpr_r15, - gcc_dwarf_gpr_rip, - gcc_dwarf_fpu_xmm0, - gcc_dwarf_fpu_xmm1, - gcc_dwarf_fpu_xmm2, - gcc_dwarf_fpu_xmm3, - gcc_dwarf_fpu_xmm4, - gcc_dwarf_fpu_xmm5, - gcc_dwarf_fpu_xmm6, - gcc_dwarf_fpu_xmm7, - gcc_dwarf_fpu_xmm8, - gcc_dwarf_fpu_xmm9, - gcc_dwarf_fpu_xmm10, - gcc_dwarf_fpu_xmm11, - gcc_dwarf_fpu_xmm12, - gcc_dwarf_fpu_xmm13, - gcc_dwarf_fpu_xmm14, - gcc_dwarf_fpu_xmm15, - gcc_dwarf_fpu_stmm0, - gcc_dwarf_fpu_stmm1, - gcc_dwarf_fpu_stmm2, - gcc_dwarf_fpu_stmm3, - gcc_dwarf_fpu_stmm4, - gcc_dwarf_fpu_stmm5, - gcc_dwarf_fpu_stmm6, - gcc_dwarf_fpu_stmm7 -}; - -enum gdb_regnums -{ - gdb_gpr_rax = 0, - gdb_gpr_rbx = 1, - gdb_gpr_rcx = 2, - gdb_gpr_rdx = 3, - gdb_gpr_rsi = 4, - gdb_gpr_rdi = 5, - gdb_gpr_rbp = 6, - gdb_gpr_rsp = 7, - gdb_gpr_r8 = 8, - gdb_gpr_r9 = 9, - gdb_gpr_r10 = 10, - gdb_gpr_r11 = 11, - gdb_gpr_r12 = 12, - gdb_gpr_r13 = 13, - gdb_gpr_r14 = 14, - gdb_gpr_r15 = 15, - gdb_gpr_rip = 16, - gdb_gpr_rflags = 17, - gdb_gpr_cs = 18, - gdb_gpr_ss = 19, - gdb_gpr_ds = 20, - gdb_gpr_es = 21, - gdb_gpr_fs = 22, - gdb_gpr_gs = 23, - gdb_fpu_stmm0 = 24, - gdb_fpu_stmm1 = 25, - gdb_fpu_stmm2 = 26, - gdb_fpu_stmm3 = 27, - gdb_fpu_stmm4 = 28, - gdb_fpu_stmm5 = 29, - gdb_fpu_stmm6 = 30, - gdb_fpu_stmm7 = 31, - gdb_fpu_fcw = 32, - gdb_fpu_fsw = 33, - gdb_fpu_ftw = 34, - gdb_fpu_cs = 35, - gdb_fpu_ip = 36, - gdb_fpu_ds = 37, - gdb_fpu_dp = 38, - gdb_fpu_fop = 39, - gdb_fpu_xmm0 = 40, - gdb_fpu_xmm1 = 41, - gdb_fpu_xmm2 = 42, - gdb_fpu_xmm3 = 43, - gdb_fpu_xmm4 = 44, - gdb_fpu_xmm5 = 45, - gdb_fpu_xmm6 = 46, - gdb_fpu_xmm7 = 47, - gdb_fpu_xmm8 = 48, - gdb_fpu_xmm9 = 49, - gdb_fpu_xmm10 = 50, - gdb_fpu_xmm11 = 51, - gdb_fpu_xmm12 = 52, - gdb_fpu_xmm13 = 53, - gdb_fpu_xmm14 = 54, - gdb_fpu_xmm15 = 55, - gdb_fpu_mxcsr = 56 -}; - -static const -uint32_t g_gpr_regnums[k_num_gpr_registers] = -{ - gpr_rax, - gpr_rbx, - gpr_rcx, - gpr_rdx, - gpr_rdi, - gpr_rsi, - gpr_rbp, - gpr_rsp, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, - gpr_r14, - gpr_r15, - gpr_rip, - gpr_rflags, - gpr_cs, - gpr_fs, - gpr_gs, - gpr_ss, - gpr_ds, - gpr_es -}; - -static const uint32_t -g_fpu_regnums[k_num_fpu_registers] = -{ - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - fpu_xmm8, - fpu_xmm9, - fpu_xmm10, - fpu_xmm11, - fpu_xmm12, - fpu_xmm13, - fpu_xmm14, - fpu_xmm15 -}; - -static const RegisterSet -g_reg_sets[k_num_register_sets] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums }, - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums } -}; - -// Computes the offset of the given GPR in the user data area. -#define GPR_OFFSET(regname) \ - (offsetof(RegisterContextLinux_x86_64::UserArea, regs) + \ - offsetof(RegisterContextLinux_x86_64::GPR, regname)) - -// Computes the offset of the given FPR in the user data area. -#define FPR_OFFSET(regname) \ - (offsetof(RegisterContextLinux_x86_64::UserArea, i387) + \ - offsetof(RegisterContextLinux_x86_64::FPU, regname)) - -// Number of bytes needed to represent a GPR. -#define GPR_SIZE(reg) sizeof(((RegisterContextLinux_x86_64::GPR*)NULL)->reg) - -// Number of bytes needed to represent a FPR. -#define FPR_SIZE(reg) sizeof(((RegisterContextLinux_x86_64::FPU*)NULL)->reg) - -// Number of bytes needed to represent the i'th FP register. -#define FP_SIZE sizeof(((RegisterContextLinux_x86_64::MMSReg*)NULL)->bytes) - -// Number of bytes needed to represent an XMM register. -#define XMM_SIZE sizeof(RegisterContextLinux_x86_64::XMMReg) - -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ - { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } } - -#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \ - { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } } - -#define DEFINE_FP(reg, i) \ - { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } } - -#define DEFINE_XMM(reg, i) \ - { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } } - -#define REG_CONTEXT_SIZE (sizeof(RegisterContextLinux_x86_64::GPR) + sizeof(RegisterContextLinux_x86_64::FPU)) - -static RegisterInfo -g_register_infos[k_num_registers] = -{ - // General purpose registers. - DEFINE_GPR(rax, NULL, gcc_dwarf_gpr_rax, gcc_dwarf_gpr_rax, LLDB_INVALID_REGNUM, gdb_gpr_rax), - DEFINE_GPR(rbx, NULL, gcc_dwarf_gpr_rbx, gcc_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, gdb_gpr_rbx), - DEFINE_GPR(rcx, NULL, gcc_dwarf_gpr_rcx, gcc_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, gdb_gpr_rcx), - DEFINE_GPR(rdx, NULL, gcc_dwarf_gpr_rdx, gcc_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, gdb_gpr_rdx), - DEFINE_GPR(rdi, NULL, gcc_dwarf_gpr_rdi, gcc_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, gdb_gpr_rdi), - DEFINE_GPR(rsi, NULL, gcc_dwarf_gpr_rsi, gcc_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, gdb_gpr_rsi), - DEFINE_GPR(rbp, "fp", gcc_dwarf_gpr_rbp, gcc_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, gdb_gpr_rbp), - DEFINE_GPR(rsp, "sp", gcc_dwarf_gpr_rsp, gcc_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, gdb_gpr_rsp), - DEFINE_GPR(r8, NULL, gcc_dwarf_gpr_r8, gcc_dwarf_gpr_r8, LLDB_INVALID_REGNUM, gdb_gpr_r8), - DEFINE_GPR(r9, NULL, gcc_dwarf_gpr_r9, gcc_dwarf_gpr_r9, LLDB_INVALID_REGNUM, gdb_gpr_r9), - DEFINE_GPR(r10, NULL, gcc_dwarf_gpr_r10, gcc_dwarf_gpr_r10, LLDB_INVALID_REGNUM, gdb_gpr_r10), - DEFINE_GPR(r11, NULL, gcc_dwarf_gpr_r11, gcc_dwarf_gpr_r11, LLDB_INVALID_REGNUM, gdb_gpr_r11), - DEFINE_GPR(r12, NULL, gcc_dwarf_gpr_r12, gcc_dwarf_gpr_r12, LLDB_INVALID_REGNUM, gdb_gpr_r12), - DEFINE_GPR(r13, NULL, gcc_dwarf_gpr_r13, gcc_dwarf_gpr_r13, LLDB_INVALID_REGNUM, gdb_gpr_r13), - DEFINE_GPR(r14, NULL, gcc_dwarf_gpr_r14, gcc_dwarf_gpr_r14, LLDB_INVALID_REGNUM, gdb_gpr_r14), - DEFINE_GPR(r15, NULL, gcc_dwarf_gpr_r15, gcc_dwarf_gpr_r15, LLDB_INVALID_REGNUM, gdb_gpr_r15), - DEFINE_GPR(rip, "pc", gcc_dwarf_gpr_rip, gcc_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, gdb_gpr_rip), - DEFINE_GPR(rflags, "flags", LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags), - DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_cs), - DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_fs), - DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_gs), - DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ss), - DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ds), - DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_es), - - // i387 Floating point registers. - DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw), - DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw), - DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ftw), - DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop), - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip), - // FIXME: Extract segment from ip. - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs), - DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp), - // FIXME: Extract segment from dp. - DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds), - DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr), - DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - - // FP registers. - DEFINE_FP(stmm, 0), - DEFINE_FP(stmm, 1), - DEFINE_FP(stmm, 2), - DEFINE_FP(stmm, 3), - DEFINE_FP(stmm, 4), - DEFINE_FP(stmm, 5), - DEFINE_FP(stmm, 6), - DEFINE_FP(stmm, 7), - - // XMM registers - DEFINE_XMM(xmm, 0), - DEFINE_XMM(xmm, 1), - DEFINE_XMM(xmm, 2), - DEFINE_XMM(xmm, 3), - DEFINE_XMM(xmm, 4), - DEFINE_XMM(xmm, 5), - DEFINE_XMM(xmm, 6), - DEFINE_XMM(xmm, 7), - DEFINE_XMM(xmm, 8), - DEFINE_XMM(xmm, 9), - DEFINE_XMM(xmm, 10), - DEFINE_XMM(xmm, 11), - DEFINE_XMM(xmm, 12), - DEFINE_XMM(xmm, 13), - DEFINE_XMM(xmm, 14), - DEFINE_XMM(xmm, 15) -}; - -static unsigned GetRegOffset(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_offset; -} - -#if 0 // These functions are currently not being used. -static unsigned GetRegSize(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_size; -} - -static bool IsGPR(unsigned reg) -{ - return reg <= k_last_gpr; // GPR's come first. -} - -static bool IsFPR(unsigned reg) -{ - return (k_first_fpr <= reg && reg <= k_last_fpr); -} -#endif - -RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, - uint32_t concrete_frame_idx) - : RegisterContextLinux(thread, concrete_frame_idx) -{ -} - -RegisterContextLinux_x86_64::~RegisterContextLinux_x86_64() -{ -} - -ProcessMonitor & -RegisterContextLinux_x86_64::GetMonitor() -{ - ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess()); - return process->GetMonitor(); -} - -void -RegisterContextLinux_x86_64::Invalidate() -{ -} - -void -RegisterContextLinux_x86_64::InvalidateAllRegisters() -{ -} - -size_t -RegisterContextLinux_x86_64::GetRegisterCount() -{ - return k_num_registers; -} - -const RegisterInfo * -RegisterContextLinux_x86_64::GetRegisterInfoAtIndex(uint32_t reg) -{ - if (reg < k_num_registers) - return &g_register_infos[reg]; - else - return NULL; -} - -size_t -RegisterContextLinux_x86_64::GetRegisterSetCount() -{ - return k_num_register_sets; -} - -const RegisterSet * -RegisterContextLinux_x86_64::GetRegisterSet(uint32_t set) -{ - if (set < k_num_register_sets) - return &g_reg_sets[set]; - else - return NULL; -} - -unsigned -RegisterContextLinux_x86_64::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < k_num_registers; reg++) - { - if (g_register_infos[reg].byte_offset == offset) - break; - } - assert(reg < k_num_registers && "Invalid register offset."); - return reg; -} - -const char * -RegisterContextLinux_x86_64::GetRegisterName(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register offset."); - return g_register_infos[reg].name; -} - -bool -RegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, - RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(GetRegOffset(reg), value); -} - -bool -RegisterContextLinux_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp) -{ - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && ReadGPR () && ReadFPR ()) - { - uint8_t *dst = data_sp->GetBytes(); - ::memcpy (dst, &user.regs, sizeof(user.regs)); - dst += sizeof(user.regs); - - ::memcpy (dst, &user.i387, sizeof(user.i387)); - return true; - } - return false; -} - -bool -RegisterContextLinux_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteRegisterValue(GetRegOffset(reg), value); -} - -bool -RegisterContextLinux_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp) -{ - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - const uint8_t *src = data_sp->GetBytes(); - ::memcpy (&user.regs, src, sizeof(user.regs)); - src += sizeof(user.regs); - - ::memcpy (&user.i387, src, sizeof(user.i387)); - return WriteGPR() & WriteFPR(); - } - return false; -} - -bool -RegisterContextLinux_x86_64::UpdateAfterBreakpoint() -{ - // PC points one byte past the int3 responsible for the breakpoint. - lldb::addr_t pc; - - if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) - return false; - - SetPC(pc - 1); - return true; -} - -uint32_t -RegisterContextLinux_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind, - uint32_t num) -{ - if (kind == eRegisterKindGeneric) - { - switch (num) - { - case LLDB_REGNUM_GENERIC_PC: return gpr_rip; - case LLDB_REGNUM_GENERIC_SP: return gpr_rsp; - case LLDB_REGNUM_GENERIC_FP: return gpr_rbp; - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags; - case LLDB_REGNUM_GENERIC_RA: - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF) - { - switch (num) - { - case gcc_dwarf_gpr_rax: return gpr_rax; - case gcc_dwarf_gpr_rdx: return gpr_rdx; - case gcc_dwarf_gpr_rcx: return gpr_rcx; - case gcc_dwarf_gpr_rbx: return gpr_rbx; - case gcc_dwarf_gpr_rsi: return gpr_rsi; - case gcc_dwarf_gpr_rdi: return gpr_rdi; - case gcc_dwarf_gpr_rbp: return gpr_rbp; - case gcc_dwarf_gpr_rsp: return gpr_rsp; - case gcc_dwarf_gpr_r8: return gpr_r8; - case gcc_dwarf_gpr_r9: return gpr_r9; - case gcc_dwarf_gpr_r10: return gpr_r10; - case gcc_dwarf_gpr_r11: return gpr_r11; - case gcc_dwarf_gpr_r12: return gpr_r12; - case gcc_dwarf_gpr_r13: return gpr_r13; - case gcc_dwarf_gpr_r14: return gpr_r14; - case gcc_dwarf_gpr_r15: return gpr_r15; - case gcc_dwarf_gpr_rip: return gpr_rip; - case gcc_dwarf_fpu_xmm0: return fpu_xmm0; - case gcc_dwarf_fpu_xmm1: return fpu_xmm1; - case gcc_dwarf_fpu_xmm2: return fpu_xmm2; - case gcc_dwarf_fpu_xmm3: return fpu_xmm3; - case gcc_dwarf_fpu_xmm4: return fpu_xmm4; - case gcc_dwarf_fpu_xmm5: return fpu_xmm5; - case gcc_dwarf_fpu_xmm6: return fpu_xmm6; - case gcc_dwarf_fpu_xmm7: return fpu_xmm7; - case gcc_dwarf_fpu_xmm8: return fpu_xmm8; - case gcc_dwarf_fpu_xmm9: return fpu_xmm9; - case gcc_dwarf_fpu_xmm10: return fpu_xmm10; - case gcc_dwarf_fpu_xmm11: return fpu_xmm11; - case gcc_dwarf_fpu_xmm12: return fpu_xmm12; - case gcc_dwarf_fpu_xmm13: return fpu_xmm13; - case gcc_dwarf_fpu_xmm14: return fpu_xmm14; - case gcc_dwarf_fpu_xmm15: return fpu_xmm15; - case gcc_dwarf_fpu_stmm0: return fpu_stmm0; - case gcc_dwarf_fpu_stmm1: return fpu_stmm1; - case gcc_dwarf_fpu_stmm2: return fpu_stmm2; - case gcc_dwarf_fpu_stmm3: return fpu_stmm3; - case gcc_dwarf_fpu_stmm4: return fpu_stmm4; - case gcc_dwarf_fpu_stmm5: return fpu_stmm5; - case gcc_dwarf_fpu_stmm6: return fpu_stmm6; - case gcc_dwarf_fpu_stmm7: return fpu_stmm7; - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGDB) - { - switch (num) - { - case gdb_gpr_rax : return gpr_rax; - case gdb_gpr_rbx : return gpr_rbx; - case gdb_gpr_rcx : return gpr_rcx; - case gdb_gpr_rdx : return gpr_rdx; - case gdb_gpr_rsi : return gpr_rsi; - case gdb_gpr_rdi : return gpr_rdi; - case gdb_gpr_rbp : return gpr_rbp; - case gdb_gpr_rsp : return gpr_rsp; - case gdb_gpr_r8 : return gpr_r8; - case gdb_gpr_r9 : return gpr_r9; - case gdb_gpr_r10 : return gpr_r10; - case gdb_gpr_r11 : return gpr_r11; - case gdb_gpr_r12 : return gpr_r12; - case gdb_gpr_r13 : return gpr_r13; - case gdb_gpr_r14 : return gpr_r14; - case gdb_gpr_r15 : return gpr_r15; - case gdb_gpr_rip : return gpr_rip; - case gdb_gpr_rflags : return gpr_rflags; - case gdb_gpr_cs : return gpr_cs; - case gdb_gpr_ss : return gpr_ss; - case gdb_gpr_ds : return gpr_ds; - case gdb_gpr_es : return gpr_es; - case gdb_gpr_fs : return gpr_fs; - case gdb_gpr_gs : return gpr_gs; - case gdb_fpu_stmm0 : return fpu_stmm0; - case gdb_fpu_stmm1 : return fpu_stmm1; - case gdb_fpu_stmm2 : return fpu_stmm2; - case gdb_fpu_stmm3 : return fpu_stmm3; - case gdb_fpu_stmm4 : return fpu_stmm4; - case gdb_fpu_stmm5 : return fpu_stmm5; - case gdb_fpu_stmm6 : return fpu_stmm6; - case gdb_fpu_stmm7 : return fpu_stmm7; - case gdb_fpu_fcw : return fpu_fcw; - case gdb_fpu_fsw : return fpu_fsw; - case gdb_fpu_ftw : return fpu_ftw; - case gdb_fpu_cs : return fpu_cs; - case gdb_fpu_ip : return fpu_ip; - case gdb_fpu_ds : return fpu_ds; - case gdb_fpu_dp : return fpu_dp; - case gdb_fpu_fop : return fpu_fop; - case gdb_fpu_xmm0 : return fpu_xmm0; - case gdb_fpu_xmm1 : return fpu_xmm1; - case gdb_fpu_xmm2 : return fpu_xmm2; - case gdb_fpu_xmm3 : return fpu_xmm3; - case gdb_fpu_xmm4 : return fpu_xmm4; - case gdb_fpu_xmm5 : return fpu_xmm5; - case gdb_fpu_xmm6 : return fpu_xmm6; - case gdb_fpu_xmm7 : return fpu_xmm7; - case gdb_fpu_xmm8 : return fpu_xmm8; - case gdb_fpu_xmm9 : return fpu_xmm9; - case gdb_fpu_xmm10 : return fpu_xmm10; - case gdb_fpu_xmm11 : return fpu_xmm11; - case gdb_fpu_xmm12 : return fpu_xmm12; - case gdb_fpu_xmm13 : return fpu_xmm13; - case gdb_fpu_xmm14 : return fpu_xmm14; - case gdb_fpu_xmm15 : return fpu_xmm15; - case gdb_fpu_mxcsr : return fpu_mxcsr; - default: - return LLDB_INVALID_REGNUM; - } - } - else if (kind == eRegisterKindLLDB) - { - return num; - } - - return LLDB_INVALID_REGNUM; -} - -bool -RegisterContextLinux_x86_64::HardwareSingleStep(bool enable) -{ - enum { TRACE_BIT = 0x100 }; - uint64_t rflags; - - if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL) - return false; - - if (enable) - { - if (rflags & TRACE_BIT) - return true; - - rflags |= TRACE_BIT; - } - else - { - if (!(rflags & TRACE_BIT)) - return false; - - rflags &= ~TRACE_BIT; - } - - return WriteRegisterFromUnsigned(gpr_rflags, rflags); -} - -bool -RegisterContextLinux_x86_64::ReadGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadGPR(&user.regs); -} - -bool -RegisterContextLinux_x86_64::ReadFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadFPR(&user.i387); -} - -bool -RegisterContextLinux_x86_64::WriteGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteGPR(&user.regs); -} - -bool -RegisterContextLinux_x86_64::WriteFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteFPR(&user.i387); -} diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h index def85f6840d..3dc6c7298da 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h @@ -10,67 +10,7 @@ #ifndef liblldb_RegisterContextLinux_x86_64_H_ #define liblldb_RegisterContextLinux_x86_64_H_ -#include "RegisterContextLinux.h" - -class ProcessMonitor; - -class RegisterContextLinux_x86_64 - : public RegisterContextLinux -{ -public: - RegisterContextLinux_x86_64 (lldb_private::Thread &thread, - uint32_t concrete_frame_idx); - - ~RegisterContextLinux_x86_64(); - - void - Invalidate(); - - void - InvalidateAllRegisters(); - - size_t - GetRegisterCount(); - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex(uint32_t reg); - - size_t - GetRegisterSetCount(); - - const lldb_private::RegisterSet * - GetRegisterSet(uint32_t set); - - static unsigned - GetRegisterIndexFromOffset(unsigned offset); - - static const char * - GetRegisterName(unsigned reg); - - virtual bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - virtual bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num); - - bool - HardwareSingleStep(bool enable); - - bool - UpdateAfterBreakpoint(); - - struct GPR + typedef struct _GPR { uint64_t r15; uint64_t r14; @@ -99,67 +39,6 @@ public: uint64_t es; uint64_t fs; uint64_t gs; - }; - - struct MMSReg - { - uint8_t bytes[10]; - uint8_t pad[6]; - }; - - struct XMMReg - { - uint8_t bytes[16]; - }; - - struct FPU - { - uint16_t fcw; - uint16_t fsw; - uint16_t ftw; - uint16_t fop; - uint64_t ip; - uint64_t dp; - uint32_t mxcsr; - uint32_t mxcsrmask; - MMSReg stmm[8]; - XMMReg xmm[16]; - uint32_t padding[24]; - }; - - struct UserArea - { - GPR regs; // General purpose registers. - int32_t fpvalid; // True if FPU is being used. - int32_t pad0; - FPU i387; // FPU registers. - uint64_t tsize; // Text segment size. - uint64_t dsize; // Data segment size. - uint64_t ssize; // Stack segment size. - uint64_t start_code; // VM address of text. - uint64_t start_stack; // VM address of stack bottom (top in rsp). - int64_t signal; // Signal causing core dump. - int32_t reserved; // Unused. - int32_t pad1; - uint64_t ar0; // Location of GPR's. - FPU* fpstate; // Location of FPR's. - uint64_t magic; // Identifier for core dumps. - char u_comm[32]; // Command causing core dump. - uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7). - uint64_t error_code; // CPU error code. - uint64_t fault_address; // Control register CR3. - }; - -private: - UserArea user; - - ProcessMonitor &GetMonitor(); - - bool ReadGPR(); - bool ReadFPR(); - - bool WriteGPR(); - bool WriteFPR(); -}; + } GPR; -#endif // #ifndef liblldb_RegisterContextLinux_x86_64_H_ +#endif |