diff options
author | Ed Maste <emaste@FreeBSD.org> | 2015-07-03 16:57:06 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2015-07-03 16:57:06 +0000 |
commit | 5e95aa85bb660d45e9905ef1d7180b2678280660 (patch) | |
tree | 3c2e41c3be19b7fc7666ed45a5f91ec3b6e35f2a /source/Plugins/Process/POSIX | |
parent | 12bd4897ff0678fa663e09d78ebc22dd255ceb86 (diff) |
Notes
Diffstat (limited to 'source/Plugins/Process/POSIX')
17 files changed, 45 insertions, 4240 deletions
diff --git a/source/Plugins/Process/POSIX/CrashReason.cpp b/source/Plugins/Process/POSIX/CrashReason.cpp index 4dd91a6f1de8e..6de13f470c5e8 100644 --- a/source/Plugins/Process/POSIX/CrashReason.cpp +++ b/source/Plugins/Process/POSIX/CrashReason.cpp @@ -134,69 +134,69 @@ GetCrashReasonString (CrashReason reason, lldb::addr_t fault_addr) break; case CrashReason::eInvalidAddress: - str = "invalid address"; + str = "signal SIGSEGV: invalid address"; AppendFaultAddr (str, fault_addr); break; case CrashReason::ePrivilegedAddress: - str = "address access protected"; + str = "signal SIGSEGV: address access protected"; AppendFaultAddr (str, fault_addr); break; case CrashReason::eIllegalOpcode: - str = "illegal instruction"; + str = "signal SIGILL: illegal instruction"; break; case CrashReason::eIllegalOperand: - str = "illegal instruction operand"; + str = "signal SIGILL: illegal instruction operand"; break; case CrashReason::eIllegalAddressingMode: - str = "illegal addressing mode"; + str = "signal SIGILL: illegal addressing mode"; break; case CrashReason::eIllegalTrap: - str = "illegal trap"; + str = "signal SIGILL: illegal trap"; break; case CrashReason::ePrivilegedOpcode: - str = "privileged instruction"; + str = "signal SIGILL: privileged instruction"; break; case CrashReason::ePrivilegedRegister: - str = "privileged register"; + str = "signal SIGILL: privileged register"; break; case CrashReason::eCoprocessorError: - str = "coprocessor error"; + str = "signal SIGILL: coprocessor error"; break; case CrashReason::eInternalStackError: - str = "internal stack error"; + str = "signal SIGILL: internal stack error"; break; case CrashReason::eIllegalAlignment: - str = "illegal alignment"; + str = "signal SIGBUS: illegal alignment"; break; case CrashReason::eIllegalAddress: - str = "illegal address"; + str = "signal SIGBUS: illegal address"; break; case CrashReason::eHardwareError: - str = "hardware error"; + str = "signal SIGBUS: hardware error"; break; case CrashReason::eIntegerDivideByZero: - str = "integer divide by zero"; + str = "signal SIGFPE: integer divide by zero"; break; case CrashReason::eIntegerOverflow: - str = "integer overflow"; + str = "signal SIGFPE: integer overflow"; break; case CrashReason::eFloatDivideByZero: - str = "floating point divide by zero"; + str = "signal SIGFPE: floating point divide by zero"; break; case CrashReason::eFloatOverflow: - str = "floating point overflow"; + str = "signal SIGFPE: floating point overflow"; break; case CrashReason::eFloatUnderflow: - str = "floating point underflow"; + str = "signal SIGFPE: floating point underflow"; break; case CrashReason::eFloatInexactResult: - str = "inexact floating point result"; + str = "signal SIGFPE: inexact floating point result"; break; case CrashReason::eFloatInvalidOperation: - str = "invalid floating point operation"; + str = "signal SIGFPE: invalid floating point operation"; break; case CrashReason::eFloatSubscriptRange: - str = "invalid floating point subscript range"; + str = "signal SIGFPE: invalid floating point subscript range"; break; } diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp b/source/Plugins/Process/POSIX/POSIXStopInfo.cpp deleted file mode 100644 index 3b8cea737bcbd..0000000000000 --- a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//===-- POSIXStopInfo.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "POSIXStopInfo.h" - -using namespace lldb; -using namespace lldb_private; - - -//===----------------------------------------------------------------------===// -// POSIXLimboStopInfo - -POSIXLimboStopInfo::~POSIXLimboStopInfo() { } - -lldb::StopReason -POSIXLimboStopInfo::GetStopReason() const -{ - return lldb::eStopReasonThreadExiting; -} - -const char * -POSIXLimboStopInfo::GetDescription() -{ - return "thread exiting"; -} - -bool -POSIXLimboStopInfo::ShouldStop(Event *event_ptr) -{ - return false; -} - -bool -POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) -{ - return false; -} - -//===----------------------------------------------------------------------===// -// POSIXCrashStopInfo - -POSIXCrashStopInfo::POSIXCrashStopInfo(POSIXThread &thread, - uint32_t status, - CrashReason reason, - lldb::addr_t fault_addr) - : POSIXStopInfo(thread, status) -{ - m_description = ::GetCrashReasonString(reason, fault_addr); -} - -POSIXCrashStopInfo::~POSIXCrashStopInfo() { } - -lldb::StopReason -POSIXCrashStopInfo::GetStopReason() const -{ - return lldb::eStopReasonException; -} - -//===----------------------------------------------------------------------===// -// POSIXNewThreadStopInfo - -POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() { } - -lldb::StopReason -POSIXNewThreadStopInfo::GetStopReason() const -{ - return lldb::eStopReasonNone; -} - -const char * -POSIXNewThreadStopInfo::GetDescription() -{ - return "thread spawned"; -} - -bool -POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr) -{ - return false; -} - -bool -POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr) -{ - return false; -} diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.h b/source/Plugins/Process/POSIX/POSIXStopInfo.h deleted file mode 100644 index a1ee2ea685244..0000000000000 --- a/source/Plugins/Process/POSIX/POSIXStopInfo.h +++ /dev/null @@ -1,110 +0,0 @@ -//===-- POSIXStopInfo.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_POSIXStopInfo_H_ -#define liblldb_POSIXStopInfo_H_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Target/StopInfo.h" - -#include "CrashReason.h" -#include "POSIXThread.h" - -#include <string> - -//===----------------------------------------------------------------------===// -/// @class POSIXStopInfo -/// @brief Simple base class for all POSIX-specific StopInfo objects. -/// -class POSIXStopInfo - : public lldb_private::StopInfo -{ -public: - POSIXStopInfo(lldb_private::Thread &thread, uint32_t status) - : StopInfo(thread, status) - { } -}; - -//===----------------------------------------------------------------------===// -/// @class POSIXLimboStopInfo -/// @brief Represents the stop state of a process ready to exit. -/// -class POSIXLimboStopInfo - : public POSIXStopInfo -{ -public: - POSIXLimboStopInfo(POSIXThread &thread) - : POSIXStopInfo(thread, 0) - { } - - ~POSIXLimboStopInfo(); - - lldb::StopReason - GetStopReason() const; - - const char * - GetDescription(); - - bool - ShouldStop(lldb_private::Event *event_ptr); - - bool - ShouldNotify(lldb_private::Event *event_ptr); -}; - - -//===----------------------------------------------------------------------===// -/// @class POSIXCrashStopInfo -/// @brief Represents the stop state of process that is ready to crash. -/// -class POSIXCrashStopInfo - : public POSIXStopInfo -{ -public: - POSIXCrashStopInfo(POSIXThread &thread, uint32_t status, - CrashReason reason, - lldb::addr_t fault_addr); - ~POSIXCrashStopInfo(); - - lldb::StopReason - GetStopReason() const; -}; - -//===----------------------------------------------------------------------===// -/// @class POSIXNewThreadStopInfo -/// @brief Represents the stop state of process when a new thread is spawned. -/// - -class POSIXNewThreadStopInfo - : public POSIXStopInfo -{ -public: - POSIXNewThreadStopInfo (POSIXThread &thread) - : POSIXStopInfo (thread, 0) - { } - - ~POSIXNewThreadStopInfo(); - - lldb::StopReason - GetStopReason() const; - - const char * - GetDescription(); - - bool - ShouldStop(lldb_private::Event *event_ptr); - - bool - ShouldNotify(lldb_private::Event *event_ptr); -}; - -#endif diff --git a/source/Plugins/Process/POSIX/POSIXThread.cpp b/source/Plugins/Process/POSIX/POSIXThread.cpp deleted file mode 100644 index 1057585e1b2a2..0000000000000 --- a/source/Plugins/Process/POSIX/POSIXThread.cpp +++ /dev/null @@ -1,693 +0,0 @@ -//===-- POSIXThread.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/lldb-python.h" - -// C Includes -#include <errno.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/HostNativeThread.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/ThreadSpec.h" -#include "llvm/ADT/SmallString.h" -#include "POSIXStopInfo.h" -#include "POSIXThread.h" -#include "ProcessPOSIX.h" -#include "ProcessPOSIXLog.h" -#include "Plugins/Process/Linux/ProcessMonitor.h" -#include "RegisterContextPOSIXProcessMonitor_arm64.h" -#include "RegisterContextPOSIXProcessMonitor_mips64.h" -#include "RegisterContextPOSIXProcessMonitor_powerpc.h" -#include "RegisterContextPOSIXProcessMonitor_x86.h" -#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h" -#include "Plugins/Process/Utility/RegisterContextLinux_i386.h" -#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" -#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" -#include "Plugins/Process/Utility/UnwindLLDB.h" - -using namespace lldb; -using namespace lldb_private; - - -POSIXThread::POSIXThread(Process &process, lldb::tid_t tid) - : Thread(process, tid), - m_frame_ap (), - m_breakpoint (), - m_thread_name_valid (false), - m_thread_name (), - m_posix_thread(NULL) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid); - - // Set the current watchpoints for this thread. - Target &target = GetProcess()->GetTarget(); - const WatchpointList &wp_list = target.GetWatchpointList(); - size_t wp_size = wp_list.GetSize(); - - for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) - { - lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx); - if (wp.get() && wp->IsEnabled()) - { - // This watchpoint as been enabled; obviously this "new" thread - // has been created since that watchpoint was enabled. Since - // the POSIXBreakpointProtocol has yet to be initialized, its - // m_watchpoints_initialized member will be FALSE. Attempting to - // read the debug status register to determine if a watchpoint - // has been hit would result in the zeroing of that register. - // Since the active debug registers would have been cloned when - // this thread was created, simply force the m_watchpoints_initized - // member to TRUE and avoid resetting dr6 and dr7. - GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized(); - } - } -} - -POSIXThread::~POSIXThread() -{ - DestroyThread(); -} - -ProcessMonitor & -POSIXThread::GetMonitor() -{ - ProcessSP base = GetProcess(); - ProcessPOSIX &process = static_cast<ProcessPOSIX&>(*base); - return process.GetMonitor(); -} - -// Overridden by FreeBSDThread; this is used only on Linux. -void -POSIXThread::RefreshStateAfterStop() -{ - // Invalidate all registers in our register context. We don't set "force" to - // true because the stop reply packet might have had some register values - // that were expedited and these will already be copied into the register - // context by the time this function gets called. The KDPRegisterContext - // class has been made smart enough to detect when it needs to invalidate - // which registers are valid by putting hooks in the register read and - // register supply functions where they check the process stop ID and do - // the right thing. - //if (StateIsStoppedState(GetState()) - { - const bool force = false; - GetRegisterContext()->InvalidateIfNeeded (force); - } - // FIXME: This should probably happen somewhere else. - SetResumeState(eStateRunning, true); - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log) - log->Printf ("POSIXThread::%s (tid = %" PRIi64 ") setting thread resume state to running", __FUNCTION__, GetID()); -} - -const char * -POSIXThread::GetInfo() -{ - return NULL; -} - -void -POSIXThread::SetName (const char *name) -{ - m_thread_name_valid = (name && name[0]); - if (m_thread_name_valid) - m_thread_name.assign (name); - else - m_thread_name.clear(); -} - -const char * -POSIXThread::GetName () -{ - if (!m_thread_name_valid) - { - llvm::SmallString<32> thread_name; - HostNativeThread::GetName(GetID(), thread_name); - m_thread_name = thread_name.c_str(); - m_thread_name_valid = true; - } - - if (m_thread_name.empty()) - return NULL; - return m_thread_name.c_str(); -} - -lldb::RegisterContextSP -POSIXThread::GetRegisterContext() -{ - if (!m_reg_context_sp) - { - m_posix_thread = NULL; - - RegisterInfoInterface *reg_interface = NULL; - const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture(); - - switch (target_arch.GetTriple().getOS()) - { - case llvm::Triple::FreeBSD: - switch (target_arch.GetMachine()) - { - case llvm::Triple::ppc: -#ifndef __powerpc64__ - reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch); - break; -#endif - case llvm::Triple::ppc64: - reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch); - break; - case llvm::Triple::mips64: - reg_interface = new RegisterContextFreeBSD_mips64(target_arch); - break; - case llvm::Triple::x86: - reg_interface = new RegisterContextFreeBSD_i386(target_arch); - break; - case llvm::Triple::x86_64: - reg_interface = new RegisterContextFreeBSD_x86_64(target_arch); - break; - default: - break; - } - break; - - case llvm::Triple::Linux: - switch (target_arch.GetMachine()) - { - case llvm::Triple::aarch64: - assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host"); - reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm64(target_arch)); - break; - case llvm::Triple::x86: - case llvm::Triple::x86_64: - if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) - { - // 32-bit hosts run with a RegisterContextLinux_i386 context. - reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch)); - } - else - { - assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) && - "Register setting path assumes this is a 64-bit host"); - // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context. - reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_x86_64(target_arch)); - } - break; - default: - break; - } - - default: - break; - } - - assert(reg_interface && "OS or CPU not supported!"); - - switch (target_arch.GetMachine()) - { - case llvm::Triple::aarch64: - { - RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface); - m_posix_thread = reg_ctx; - m_reg_context_sp.reset(reg_ctx); - break; - } - case llvm::Triple::mips64: - { - RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface); - m_posix_thread = reg_ctx; - m_reg_context_sp.reset(reg_ctx); - break; - } - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - { - RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx = new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0, reg_interface); - m_posix_thread = reg_ctx; - m_reg_context_sp.reset(reg_ctx); - break; - } - case llvm::Triple::x86: - case llvm::Triple::x86_64: - { - RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, reg_interface); - m_posix_thread = reg_ctx; - m_reg_context_sp.reset(reg_ctx); - break; - } - default: - break; - } - } - return m_reg_context_sp; -} - -lldb::RegisterContextSP -POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - uint32_t concrete_frame_idx = 0; - - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("POSIXThread::%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::addr_t -POSIXThread::GetThreadPointer () -{ - ProcessMonitor &monitor = GetMonitor(); - addr_t addr; - if (monitor.ReadThreadPointer (GetID(), addr)) - return addr; - else - return LLDB_INVALID_ADDRESS; -} - -bool -POSIXThread::CalculateStopInfo() -{ - SetStopInfo (m_stop_info_sp); - return true; -} - -Unwind * -POSIXThread::GetUnwinder() -{ - if (m_unwinder_ap.get() == NULL) - m_unwinder_ap.reset(new UnwindLLDB(*this)); - - return m_unwinder_ap.get(); -} - -// Overridden by FreeBSDThread; this is used only on Linux. -void -POSIXThread::WillResume(lldb::StateType resume_state) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log) - log->Printf ("POSIXThread::%s (tid = %" PRIi64 ") setting thread resume state to %s", __FUNCTION__, GetID(), StateAsCString(resume_state)); - // TODO: the line below shouldn't really be done, but - // the POSIXThread might rely on this so I will leave this in for now - SetResumeState(resume_state); -} - -void -POSIXThread::DidStop() -{ - // Don't set the thread state to stopped unless we really stopped. -} - -bool -POSIXThread::Resume() -{ - lldb::StateType resume_state = GetResumeState(); - ProcessMonitor &monitor = GetMonitor(); - bool status; - - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log) - log->Printf ("POSIXThread::%s (), resume_state = %s", __FUNCTION__, - StateAsCString(resume_state)); - - 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; - case lldb::eStateStopped: - case lldb::eStateSuspended: - status = true; - break; - } - - return status; -} - -void -POSIXThread::Notify(const ProcessMessage &message) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log) - log->Printf ("POSIXThread::%s () message kind = '%s' for tid %" PRIu64, - __FUNCTION__, message.PrintKind(), GetID()); - - switch (message.GetKind()) - { - default: - assert(false && "Unexpected message kind!"); - break; - - case ProcessMessage::eExitMessage: - // Nothing to be done. - 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::eWatchpointMessage: - WatchNotify(message); - break; - - case ProcessMessage::eCrashMessage: - CrashNotify(message); - break; - - case ProcessMessage::eNewThreadMessage: - ThreadNotify(message); - break; - - case ProcessMessage::eExecMessage: - ExecNotify(message); - break; - } -} - -bool -POSIXThread::EnableHardwareWatchpoint(Watchpoint *wp) -{ - bool wp_set = false; - if (wp) - { - addr_t wp_addr = wp->GetLoadAddress(); - size_t wp_size = wp->GetByteSize(); - bool wp_read = wp->WatchpointRead(); - bool wp_write = wp->WatchpointWrite(); - uint32_t wp_hw_index = wp->GetHardwareIndex(); - POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); - if (reg_ctx) - wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size, - wp_read, wp_write, - wp_hw_index); - } - return wp_set; -} - -bool -POSIXThread::DisableHardwareWatchpoint(Watchpoint *wp) -{ - bool result = false; - if (wp) - { - lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext(); - if (reg_ctx_sp.get()) - result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex()); - } - return result; -} - -uint32_t -POSIXThread::NumSupportedHardwareWatchpoints() -{ - lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext(); - if (reg_ctx_sp.get()) - return reg_ctx_sp->NumSupportedHardwareWatchpoints(); - return 0; -} - -uint32_t -POSIXThread::FindVacantWatchpointIndex() -{ - uint32_t hw_index = LLDB_INVALID_INDEX32; - uint32_t num_hw_wps = NumSupportedHardwareWatchpoints(); - uint32_t wp_idx; - POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); - if (reg_ctx) - { - for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) - { - if (reg_ctx->IsWatchpointVacant(wp_idx)) - { - hw_index = wp_idx; - break; - } - } - } - return hw_index; -} - -void -POSIXThread::BreakNotify(const ProcessMessage &message) -{ - bool status; - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - - assert(GetRegisterContext()); - status = GetPOSIXBreakpointProtocol()->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 ("POSIXThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); - lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); - - // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread, - // we create a stop reason with should_stop=false. If there is no breakpoint location, then report - // an invalid stop reason. We don't need to worry about stepping over the breakpoint here, that will - // be taken care of when the thread resumes and notices that there's a breakpoint under the pc. - if (bp_site) - { - lldb::break_id_t bp_id = bp_site->GetID(); - if (bp_site->ValidForThisThread(this)) - SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id)); - else - { - const bool should_stop = false; - SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id, should_stop)); - } - } - else - SetStopInfo(StopInfoSP()); -} - -void -POSIXThread::WatchNotify(const ProcessMessage &message) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - - lldb::addr_t halt_addr = message.GetHWAddress(); - if (log) - log->Printf ("POSIXThread::%s () Hardware Watchpoint Address = 0x%8.8" - PRIx64, __FUNCTION__, halt_addr); - - POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); - if (reg_ctx) - { - uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); - uint32_t wp_idx; - for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) - { - if (reg_ctx->IsWatchpointHit(wp_idx)) - { - // Clear the watchpoint hit here - reg_ctx->ClearWatchpointHits(); - break; - } - } - - if (wp_idx == num_hw_wps) - return; - - Target &target = GetProcess()->GetTarget(); - lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx); - const WatchpointList &wp_list = target.GetWatchpointList(); - lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr); - - assert(wp_sp.get() && "No watchpoint found"); - SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID(*this, - wp_sp->GetID())); - } -} - -void -POSIXThread::TraceNotify(const ProcessMessage &message) -{ - POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); - if (reg_ctx) - { - uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); - uint32_t wp_idx; - for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) - { - if (reg_ctx->IsWatchpointHit(wp_idx)) - { - WatchNotify(message); - return; - } - } - } - - SetStopInfo (StopInfo::CreateStopReasonToTrace(*this)); -} - -void -POSIXThread::LimboNotify(const ProcessMessage &message) -{ - SetStopInfo (lldb::StopInfoSP(new POSIXLimboStopInfo(*this))); -} - -void -POSIXThread::SignalNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo)); -} - -void -POSIXThread::SignalDeliveredNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo)); -} - -void -POSIXThread::CrashNotify(const ProcessMessage &message) -{ - // FIXME: Update stop reason as per bugzilla 14598 - int signo = message.GetSignal(); - - assert(message.GetKind() == ProcessMessage::eCrashMessage); - - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log) - log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", - __FUNCTION__, signo, message.PrintCrashReason()); - - SetStopInfo (lldb::StopInfoSP(new POSIXCrashStopInfo(*this, signo, - message.GetCrashReason(), - message.GetFaultAddress()))); -} - -void -POSIXThread::ThreadNotify(const ProcessMessage &message) -{ - SetStopInfo (lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this))); -} - -unsigned -POSIXThread::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg = LLDB_INVALID_REGNUM; - ArchSpec arch = HostInfo::GetArchitecture(); - - switch (arch.GetMachine()) - { - default: - llvm_unreachable("CPU type not supported!"); - break; - - case llvm::Triple::aarch64: - case llvm::Triple::mips64: - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - case llvm::Triple::x86: - case llvm::Triple::x86_64: - { - POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); - reg = reg_ctx->GetRegisterIndexFromOffset(offset); - } - break; - } - return reg; -} - -void -POSIXThread::ExecNotify(const ProcessMessage &message) -{ - SetStopInfo (StopInfo::CreateStopReasonWithExec(*this)); -} - -const char * -POSIXThread::GetRegisterName(unsigned reg) -{ - const char * name = nullptr; - ArchSpec arch = HostInfo::GetArchitecture(); - - switch (arch.GetMachine()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case llvm::Triple::aarch64: - case llvm::Triple::mips64: - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - case llvm::Triple::x86: - case llvm::Triple::x86_64: - name = GetRegisterContext()->GetRegisterName(reg); - break; - } - return name; -} - -const char * -POSIXThread::GetRegisterNameFromOffset(unsigned offset) -{ - return GetRegisterName(GetRegisterIndexFromOffset(offset)); -} - diff --git a/source/Plugins/Process/POSIX/POSIXThread.h b/source/Plugins/Process/POSIX/POSIXThread.h deleted file mode 100644 index 56dcccbfb0f98..0000000000000 --- a/source/Plugins/Process/POSIX/POSIXThread.h +++ /dev/null @@ -1,135 +0,0 @@ -//===-- POSIXThread.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_POSIXThread_H_ -#define liblldb_POSIXThread_H_ - -// C Includes -// C++ Includes -#include <memory> -#include <string> - -// Other libraries and framework includes -#include "lldb/Target/Thread.h" -#include "Plugins/Process/Utility/RegisterContextPOSIX.h" - -class ProcessMessage; -class ProcessMonitor; -class POSIXBreakpointProtocol; - -//------------------------------------------------------------------------------ -// @class POSIXThread -// @brief Abstraction of a POSIX thread. -class POSIXThread - : public lldb_private::Thread -{ -public: - POSIXThread(lldb_private::Process &process, lldb::tid_t tid); - - virtual ~POSIXThread(); - - void - RefreshStateAfterStop(); - - virtual void - WillResume(lldb::StateType resume_state); - - // This notifies the thread when a private stop occurs. - virtual void - DidStop (); - - const char * - GetInfo(); - - void - SetName (const char *name); - - const char * - GetName (); - - virtual lldb::RegisterContextSP - GetRegisterContext(); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - virtual lldb::addr_t - GetThreadPointer (); - - //-------------------------------------------------------------------------- - // These functions provide a mapping from the register offset - // back to the register index or name for use in debugging or log - // output. - - unsigned - GetRegisterIndexFromOffset(unsigned offset); - - const char * - GetRegisterName(unsigned reg); - - const char * - GetRegisterNameFromOffset(unsigned offset); - - //-------------------------------------------------------------------------- - // These methods form a specialized interface to POSIX threads. - // - bool Resume(); - - void Notify(const ProcessMessage &message); - - //-------------------------------------------------------------------------- - // These methods provide an interface to watchpoints - // - bool EnableHardwareWatchpoint(lldb_private::Watchpoint *wp); - - bool DisableHardwareWatchpoint(lldb_private::Watchpoint *wp); - - uint32_t NumSupportedHardwareWatchpoints(); - - uint32_t FindVacantWatchpointIndex(); - -protected: - POSIXBreakpointProtocol * - GetPOSIXBreakpointProtocol () - { - if (!m_reg_context_sp) - m_reg_context_sp = GetRegisterContext(); - return m_posix_thread; - } - - std::unique_ptr<lldb_private::StackFrame> m_frame_ap; - - lldb::BreakpointSiteSP m_breakpoint; - - bool m_thread_name_valid; - std::string m_thread_name; - POSIXBreakpointProtocol *m_posix_thread; - - ProcessMonitor & - GetMonitor(); - - virtual bool - CalculateStopInfo(); - - void BreakNotify(const ProcessMessage &message); - void WatchNotify(const ProcessMessage &message); - virtual 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); - void ThreadNotify(const ProcessMessage &message); - void ExitNotify(const ProcessMessage &message); - void ExecNotify(const ProcessMessage &message); - - lldb_private::Unwind * - GetUnwinder(); -}; - -#endif // #ifndef liblldb_POSIXThread_H_ diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp deleted file mode 100644 index 882fac75c9a0d..0000000000000 --- a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ /dev/null @@ -1,964 +0,0 @@ -//===-- ProcessPOSIX.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/lldb-python.h" - -// C Includes -#include <errno.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/Host.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/Platform.h" -#include "lldb/Target/Target.h" - -#include "ProcessPOSIX.h" -#include "ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "Plugins/Process/Linux/ProcessMonitor.h" -#include "POSIXThread.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------------ -// Static functions. -#if 0 -Process* -ProcessPOSIX::CreateInstance(Target& target, Listener &listener) -{ - return new ProcessPOSIX(target, listener); -} - - -void -ProcessPOSIX::Initialize() -{ - static bool g_initialized = false; - - if (!g_initialized) - { - g_initialized = true; - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - - Log::Callbacks log_callbacks = { - ProcessPOSIXLog::DisableLog, - ProcessPOSIXLog::EnableLog, - ProcessPOSIXLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks); - } -} -#endif - -//------------------------------------------------------------------------------ -// Constructors and destructors. - -ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener, UnixSignalsSP &unix_signals_sp) - : Process(target, listener, unix_signals_sp), - m_byte_order(lldb::endian::InlHostByteOrder()), - m_monitor(NULL), - m_module(NULL), - m_message_mutex (Mutex::eMutexTypeRecursive), - m_exit_now(false), - m_seen_initial_stop() -{ - // FIXME: Putting this code in the ctor and saving the byte order in a - // member variable is a hack to avoid const qual issues in GetByteOrder. - lldb::ModuleSP module = GetTarget().GetExecutableModule(); - if (module && module->GetObjectFile()) - m_byte_order = module->GetObjectFile()->GetByteOrder(); -} - -ProcessPOSIX::~ProcessPOSIX() -{ - delete m_monitor; -} - -//------------------------------------------------------------------------------ -// Process protocol. -void -ProcessPOSIX::Finalize() -{ - Process::Finalize(); - - if (m_monitor) - m_monitor->StopMonitor(); -} - -bool -ProcessPOSIX::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(); - // If there is no executable module, we return true since we might be preparing to attach. - return true; -} - -Error -ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid) -{ - Error error; - assert(m_monitor == NULL); - - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID()); - - m_monitor = new ProcessMonitor(this, pid, error); - - if (!error.Success()) - return error; - - PlatformSP platform_sp (m_target.GetPlatform ()); - assert (platform_sp.get()); - if (!platform_sp) - return error; // FIXME: Detatch? - - // Find out what we can about this process - ProcessInstanceInfo process_info; - platform_sp->GetProcessInfo (pid, process_info); - - // Resolve the executable module - ModuleSP exe_module_sp; - FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); - ModuleSpec exe_module_spec(process_info.GetExecutableFile(), m_target.GetArchitecture()); - error = platform_sp->ResolveExecutable(exe_module_spec, - exe_module_sp, - executable_search_paths.GetSize() ? &executable_search_paths : NULL); - if (!error.Success()) - return error; - - // Fix the target architecture if necessary - const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); - if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch)) - m_target.SetArchitecture(module_arch); - - // Initialize the target module list - m_target.SetExecutableModule (exe_module_sp, true); - - SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); - - SetID(pid); - - return error; -} - -Error -ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) -{ - return DoAttachToProcessWithID(pid); -} - -Error -ProcessPOSIX::WillLaunch(Module* module) -{ - Error error; - return error; -} - -const char * -ProcessPOSIX::GetFilePath(const lldb_private::FileAction *file_action, const char *default_path, - const char *dbg_pts_path) -{ - const char *path = NULL; - - if (file_action) - { - if (file_action->GetAction() == FileAction::eFileActionOpen) - { - path = file_action->GetPath(); - // By default the stdio paths passed in will be pseudo-terminal - // (/dev/pts). If so, convert to using a different default path - // instead to redirect I/O to the debugger console. This should - // also handle user overrides to /dev/null or a different file. - if (!path || (dbg_pts_path && - ::strncmp(path, dbg_pts_path, ::strlen(dbg_pts_path)) == 0)) - path = default_path; - } - } - return path; -} - -Error -ProcessPOSIX::DoLaunch (Module *module, - ProcessLaunchInfo &launch_info) -{ - Error error; - assert(m_monitor == NULL); - - const char* working_dir = launch_info.GetWorkingDirectory(); - if (working_dir) { - FileSpec WorkingDir(working_dir, true); - if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory) - { - error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); - return error; - } - } - - SetPrivateState(eStateLaunching); - - const lldb_private::FileAction *file_action; - - // Default of NULL will mean to use existing open file descriptors - const char *stdin_path = NULL; - const char *stdout_path = NULL; - const char *stderr_path = NULL; - - const char * dbg_pts_path = launch_info.GetPTY().GetSlaveName(NULL,0); - - file_action = launch_info.GetFileActionForFD (STDIN_FILENO); - stdin_path = GetFilePath(file_action, stdin_path, dbg_pts_path); - - file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); - stdout_path = GetFilePath(file_action, stdout_path, dbg_pts_path); - - file_action = launch_info.GetFileActionForFD (STDERR_FILENO); - stderr_path = GetFilePath(file_action, stderr_path, dbg_pts_path); - - m_monitor = new ProcessMonitor (this, - module, - launch_info.GetArguments().GetConstArgumentVector(), - launch_info.GetEnvironmentEntries().GetConstArgumentVector(), - stdin_path, - stdout_path, - stderr_path, - working_dir, - launch_info, - error); - - m_module = module; - - if (!error.Success()) - return error; - - int terminal = m_monitor->GetTerminalFD(); - if (terminal >= 0) { - // The reader thread will close the file descriptor when done, so we pass it a copy. - int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0); - if (stdio == -1) { - error.SetErrorToErrno(); - return error; - } - SetSTDIOFileDescriptor(stdio); - } - - SetID(m_monitor->GetPID()); - return error; -} - -void -ProcessPOSIX::DidLaunch() -{ -} - -Error -ProcessPOSIX::DoResume() -{ - StateType state = GetPrivateState(); - - assert(state == eStateStopped); - - SetPrivateState(eStateRunning); - - bool did_resume = false; - - Mutex::Locker lock(m_thread_list.GetMutex()); - - uint32_t thread_count = m_thread_list.GetSize(false); - for (uint32_t i = 0; i < thread_count; ++i) - { - POSIXThread *thread = static_cast<POSIXThread*>( - m_thread_list.GetThreadAtIndex(i, false).get()); - did_resume = thread->Resume() || did_resume; - } - assert(did_resume && "Process resume failed!"); - - return Error(); -} - -addr_t -ProcessPOSIX::GetImageInfoAddress() -{ - Target *target = &GetTarget(); - ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); - Address addr = obj_file->GetImageInfoAddress(target); - - if (addr.IsValid()) - return addr.GetLoadAddress(target); - return LLDB_INVALID_ADDRESS; -} - -Error -ProcessPOSIX::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 -ProcessPOSIX::DoSignal(int signal) -{ - Error error; - - if (kill(GetID(), signal)) - error.SetErrorToErrno(); - - return error; -} - -Error -ProcessPOSIX::DoDestroy() -{ - Error error; - - if (!HasExited()) - { - assert(m_monitor); - m_exit_now = true; - if (GetID() == LLDB_INVALID_PROCESS_ID) - { - error.SetErrorString("invalid process id"); - return error; - } - if (!m_monitor->Kill()) - { - error.SetErrorToErrno(); - return error; - } - - SetPrivateState(eStateExited); - } - - return error; -} - -void -ProcessPOSIX::DoDidExec() -{ - Target *target = &GetTarget(); - if (target) - { - PlatformSP platform_sp (target->GetPlatform()); - assert (platform_sp.get()); - if (platform_sp) - { - ProcessInstanceInfo process_info; - platform_sp->GetProcessInfo(GetID(), process_info); - ModuleSP exe_module_sp; - ModuleSpec exe_module_spec(process_info.GetExecutableFile(), target->GetArchitecture()); - FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); - Error error = platform_sp->ResolveExecutable(exe_module_spec, - exe_module_sp, - executable_search_paths.GetSize() ? &executable_search_paths : NULL); - if (!error.Success()) - return; - target->SetExecutableModule(exe_module_sp, true); - } - } -} - -void -ProcessPOSIX::SendMessage(const ProcessMessage &message) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); - - Mutex::Locker lock(m_message_mutex); - - Mutex::Locker thread_lock(m_thread_list.GetMutex()); - - POSIXThread *thread = static_cast<POSIXThread*>( - m_thread_list.FindThreadByID(message.GetTID(), false).get()); - - switch (message.GetKind()) - { - case ProcessMessage::eInvalidMessage: - return; - - case ProcessMessage::eAttachMessage: - SetPrivateState(eStateStopped); - return; - - case ProcessMessage::eLimboMessage: - assert(thread); - thread->SetState(eStateStopped); - if (message.GetTID() == GetID()) - { - m_exit_status = message.GetExitStatus(); - if (m_exit_now) - { - SetPrivateState(eStateExited); - m_monitor->Detach(GetID()); - } - else - { - StopAllThreads(message.GetTID()); - SetPrivateState(eStateStopped); - } - } - else - { - StopAllThreads(message.GetTID()); - SetPrivateState(eStateStopped); - } - break; - - case ProcessMessage::eExitMessage: - if (thread != nullptr) - thread->SetState(eStateExited); - else - { - if (log) - log->Warning ("ProcessPOSIX::%s eExitMessage for TID %" PRIu64 " failed to find a thread to mark as eStateExited, ignoring", __FUNCTION__, message.GetTID ()); - } - - // FIXME: I'm not sure we need to do this. - if (message.GetTID() == GetID()) - { - SetExitStatus(message.GetExitStatus(), NULL); - } - else if (!IsAThreadRunning()) - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eSignalMessage: - case ProcessMessage::eSignalDeliveredMessage: - if (message.GetSignal() == SIGSTOP && - AddThreadForInitialStopIfNeeded(message.GetTID())) - return; - // Intentional fall-through - - case ProcessMessage::eBreakpointMessage: - case ProcessMessage::eTraceMessage: - case ProcessMessage::eWatchpointMessage: - case ProcessMessage::eCrashMessage: - assert(thread); - thread->SetState(eStateStopped); - StopAllThreads(message.GetTID()); - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eNewThreadMessage: - { - lldb::tid_t new_tid = message.GetChildTID(); - if (WaitingForInitialStop(new_tid)) - { - m_monitor->WaitForInitialTIDStop(new_tid); - } - assert(thread); - thread->SetState(eStateStopped); - StopAllThreads(message.GetTID()); - SetPrivateState(eStateStopped); - break; - } - - case ProcessMessage::eExecMessage: - { - assert(thread); - thread->SetState(eStateStopped); - StopAllThreads(message.GetTID()); - SetPrivateState(eStateStopped); - break; - } - } - - - m_message_queue.push(message); -} - -void -ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid) -{ - // FIXME: Will this work the same way on FreeBSD and Linux? -} - -bool -ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) -{ - bool added_to_set = false; - ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid); - if (it == m_seen_initial_stop.end()) - { - m_seen_initial_stop.insert(stop_tid); - added_to_set = true; - } - return added_to_set; -} - -bool -ProcessPOSIX::WaitingForInitialStop(lldb::tid_t stop_tid) -{ - return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end()); -} - -POSIXThread * -ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid) -{ - return new POSIXThread(process, tid); -} - -void -ProcessPOSIX::RefreshStateAfterStop() -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size()); - - Mutex::Locker lock(m_message_mutex); - - // This method used to only handle one message. Changing it to loop allows - // it to handle the case where we hit a breakpoint while handling a different - // breakpoint. - while (!m_message_queue.empty()) - { - ProcessMessage &message = m_message_queue.front(); - - // Resolve the thread this message corresponds to and pass it along. - lldb::tid_t tid = message.GetTID(); - if (log) - log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid); - - if (message.GetKind() == ProcessMessage::eNewThreadMessage) - { - if (log) - log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID()); - lldb::tid_t child_tid = message.GetChildTID(); - ThreadSP thread_sp; - thread_sp.reset(CreateNewPOSIXThread(*this, child_tid)); - - Mutex::Locker lock(m_thread_list.GetMutex()); - - m_thread_list.AddThread(thread_sp); - } - - m_thread_list.RefreshStateAfterStop(); - - POSIXThread *thread = static_cast<POSIXThread*>( - GetThreadList().FindThreadByID(tid, false).get()); - if (thread) - thread->Notify(message); - - if (message.GetKind() == ProcessMessage::eExitMessage) - { - // FIXME: We should tell the user about this, but the limbo message is probably better for that. - if (log) - log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid); - - Mutex::Locker lock(m_thread_list.GetMutex()); - - ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); - thread_sp.reset(); - m_seen_initial_stop.erase(tid); - } - - m_message_queue.pop(); - } -} - -bool -ProcessPOSIX::IsAlive() -{ - StateType state = GetPrivateState(); - return state != eStateDetached - && state != eStateExited - && state != eStateInvalid - && state != eStateUnloaded; -} - -size_t -ProcessPOSIX::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 -ProcessPOSIX::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 -ProcessPOSIX::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 -ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr) -{ - 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%" PRIx64, addr); - - return error; -} - -size_t -ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) -{ - static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xD4 }; - static const uint8_t g_i386_opcode[] = { 0xCC }; - - ArchSpec arch = GetTarget().GetArchitecture(); - const uint8_t *opcode = NULL; - size_t opcode_size = 0; - - switch (arch.GetMachine()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case llvm::Triple::aarch64: - opcode = g_aarch64_opcode; - opcode_size = sizeof(g_aarch64_opcode); - break; - - case llvm::Triple::x86: - case llvm::Triple::x86_64: - opcode = g_i386_opcode; - opcode_size = sizeof(g_i386_opcode); - break; - } - - bp_site->SetTrapOpcode(opcode, opcode_size); - return opcode_size; -} - -Error -ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site) -{ - return EnableSoftwareBreakpoint(bp_site); -} - -Error -ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site) -{ - return DisableSoftwareBreakpoint(bp_site); -} - -Error -ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify) -{ - Error error; - if (wp) - { - user_id_t watchID = wp->GetID(); - addr_t addr = wp->GetLoadAddress(); - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); - if (log) - log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")", - watchID); - if (wp->IsEnabled()) - { - if (log) - log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 - ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", - watchID, (uint64_t)addr); - return error; - } - - // Try to find a vacant watchpoint slot in the inferiors' main thread - uint32_t wp_hw_index = LLDB_INVALID_INDEX32; - Mutex::Locker lock(m_thread_list.GetMutex()); - POSIXThread *thread = static_cast<POSIXThread*>( - m_thread_list.GetThreadAtIndex(0, false).get()); - - if (thread) - wp_hw_index = thread->FindVacantWatchpointIndex(); - - if (wp_hw_index == LLDB_INVALID_INDEX32) - { - error.SetErrorString("Setting hardware watchpoint failed."); - } - else - { - wp->SetHardwareIndex(wp_hw_index); - bool wp_enabled = true; - uint32_t thread_count = m_thread_list.GetSize(false); - for (uint32_t i = 0; i < thread_count; ++i) - { - thread = static_cast<POSIXThread*>( - m_thread_list.GetThreadAtIndex(i, false).get()); - if (thread) - wp_enabled &= thread->EnableHardwareWatchpoint(wp); - else - wp_enabled = false; - } - if (wp_enabled) - { - wp->SetEnabled(true, notify); - return error; - } - else - { - // Watchpoint enabling failed on at least one - // of the threads so roll back all of them - DisableWatchpoint(wp, false); - error.SetErrorString("Setting hardware watchpoint failed"); - } - } - } - else - error.SetErrorString("Watchpoint argument was NULL."); - return error; -} - -Error -ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify) -{ - Error error; - if (wp) - { - user_id_t watchID = wp->GetID(); - addr_t addr = wp->GetLoadAddress(); - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); - if (log) - log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")", - watchID); - if (!wp->IsEnabled()) - { - if (log) - log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 - ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", - watchID, (uint64_t)addr); - // This is needed (for now) to keep watchpoints disabled correctly - wp->SetEnabled(false, notify); - return error; - } - - if (wp->IsHardware()) - { - bool wp_disabled = true; - Mutex::Locker lock(m_thread_list.GetMutex()); - uint32_t thread_count = m_thread_list.GetSize(false); - for (uint32_t i = 0; i < thread_count; ++i) - { - POSIXThread *thread = static_cast<POSIXThread*>( - m_thread_list.GetThreadAtIndex(i, false).get()); - if (thread) - wp_disabled &= thread->DisableHardwareWatchpoint(wp); - else - wp_disabled = false; - } - if (wp_disabled) - { - wp->SetHardwareIndex(LLDB_INVALID_INDEX32); - wp->SetEnabled(false, notify); - return error; - } - else - error.SetErrorString("Disabling hardware watchpoint failed"); - } - } - else - error.SetErrorString("Watchpoint argument was NULL."); - return error; -} - -Error -ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num) -{ - Error error; - Mutex::Locker lock(m_thread_list.GetMutex()); - POSIXThread *thread = static_cast<POSIXThread*>( - m_thread_list.GetThreadAtIndex(0, false).get()); - if (thread) - num = thread->NumSupportedHardwareWatchpoints(); - else - error.SetErrorString("Process does not exist."); - return error; -} - -Error -ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after) -{ - Error error = GetWatchpointSupportInfo(num); - // Watchpoints trigger and halt the inferior after - // the corresponding instruction has been executed. - after = true; - return error; -} - -uint32_t -ProcessPOSIX::UpdateThreadListIfNeeded() -{ - Mutex::Locker lock(m_thread_list.GetMutex()); - // Do not allow recursive updates. - return m_thread_list.GetSize(false); -} - -bool -ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) -{ - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID()); - - bool has_updated = false; - // Update the process thread list with this new thread. - // FIXME: We should be using tid, not pid. - assert(m_monitor); - ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); - if (!thread_sp) { - thread_sp.reset(CreateNewPOSIXThread(*this, GetID())); - has_updated = true; - } - - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID()); - new_thread_list.AddThread(thread_sp); - - return has_updated; // the list has been updated -} - -ByteOrder -ProcessPOSIX::GetByteOrder() const -{ - // FIXME: We should be able to extract this value directly. See comment in - // ProcessPOSIX(). - return m_byte_order; -} - -size_t -ProcessPOSIX::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; -} - -//------------------------------------------------------------------------------ -// Utility functions. - -bool -ProcessPOSIX::HasExited() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateDetached: - case eStateExited: - return true; - } - - return false; -} - -bool -ProcessPOSIX::IsStopped() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateStopped: - case eStateCrashed: - case eStateSuspended: - return true; - } - - return false; -} - -bool -ProcessPOSIX::IsAThreadRunning() -{ - bool is_running = false; - Mutex::Locker lock(m_thread_list.GetMutex()); - uint32_t thread_count = m_thread_list.GetSize(false); - for (uint32_t i = 0; i < thread_count; ++i) - { - POSIXThread *thread = static_cast<POSIXThread*>( - m_thread_list.GetThreadAtIndex(i, false).get()); - StateType thread_state = thread->GetState(); - if (thread_state == eStateRunning || thread_state == eStateStepping) - { - is_running = true; - break; - } - } - return is_running; -} - -const DataBufferSP -ProcessPOSIX::GetAuxvData () -{ - // If we're the local platform, we can ask the host for auxv data. - PlatformSP platform_sp = m_target.GetPlatform (); - if (platform_sp && platform_sp->IsHost ()) - return lldb_private::Host::GetAuxvData(this); - - // Somewhat unexpected - the process is not running locally or we don't have a platform. - assert (false && "no platform or not the host - how did we get here with ProcessPOSIX?"); - return DataBufferSP (); -} diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.h b/source/Plugins/Process/POSIX/ProcessPOSIX.h deleted file mode 100644 index f152356b3093a..0000000000000 --- a/source/Plugins/Process/POSIX/ProcessPOSIX.h +++ /dev/null @@ -1,211 +0,0 @@ -//===-- ProcessPOSIX.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_ProcessPOSIX_H_ -#define liblldb_ProcessPOSIX_H_ - -// C Includes - -// C++ Includes -#include <queue> -#include <set> - -// Other libraries and framework includes -#include "lldb/Target/Process.h" -#include "ProcessMessage.h" - -class ProcessMonitor; -class POSIXThread; - -class ProcessPOSIX : - public lldb_private::Process -{ -public: - - //------------------------------------------------------------------ - // Constructors and destructors - //------------------------------------------------------------------ - ProcessPOSIX(lldb_private::Target& target, - lldb_private::Listener &listener, - lldb_private::UnixSignalsSP &unix_signals_sp); - - virtual - ~ProcessPOSIX(); - - //------------------------------------------------------------------ - // Process protocol. - //------------------------------------------------------------------ - virtual void - Finalize() override; - - virtual bool - CanDebug(lldb_private::Target &target, bool plugin_specified_by_name) override; - - virtual lldb_private::Error - WillLaunch(lldb_private::Module *module) override; - - virtual lldb_private::Error - DoAttachToProcessWithID(lldb::pid_t pid) override; - - virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override; - - virtual lldb_private::Error - DoLaunch (lldb_private::Module *exe_module, - lldb_private::ProcessLaunchInfo &launch_info) override; - - virtual void - DidLaunch() override; - - virtual lldb_private::Error - DoResume() override; - - virtual lldb_private::Error - DoHalt(bool &caused_stop) override; - - virtual lldb_private::Error - DoDetach(bool keep_stopped) override = 0; - - virtual lldb_private::Error - DoSignal(int signal) override; - - virtual lldb_private::Error - DoDestroy() override; - - virtual void - DoDidExec() override; - - virtual void - RefreshStateAfterStop() override; - - virtual bool - IsAlive() override; - - virtual size_t - DoReadMemory(lldb::addr_t vm_addr, - void *buf, - size_t size, - lldb_private::Error &error) override; - - virtual size_t - DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error) override; - - virtual lldb::addr_t - DoAllocateMemory(size_t size, uint32_t permissions, - lldb_private::Error &error) override; - - virtual lldb_private::Error - DoDeallocateMemory(lldb::addr_t ptr) override; - - virtual size_t - GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site); - - virtual lldb_private::Error - EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; - - virtual lldb_private::Error - DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; - - virtual lldb_private::Error - EnableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override; - - virtual lldb_private::Error - DisableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override; - - virtual lldb_private::Error - GetWatchpointSupportInfo(uint32_t &num) override; - - virtual lldb_private::Error - GetWatchpointSupportInfo(uint32_t &num, bool &after) override; - - virtual uint32_t - UpdateThreadListIfNeeded(); - - virtual bool - UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list) override = 0; - - virtual lldb::ByteOrder - GetByteOrder() const; - - virtual lldb::addr_t - GetImageInfoAddress() override; - - virtual size_t - PutSTDIN(const char *buf, size_t len, lldb_private::Error &error) override; - - const lldb::DataBufferSP - GetAuxvData () override; - - //-------------------------------------------------------------------------- - // ProcessPOSIX internal API. - - /// Registers the given message with this process. - virtual void - SendMessage(const ProcessMessage &message); - - ProcessMonitor & - GetMonitor() { assert(m_monitor); return *m_monitor; } - - const char *GetFilePath(const lldb_private::FileAction *file_action, const char *default_path, - const char *dbg_pts_path); - - /// Stops all threads in the process. - /// The \p stop_tid parameter indicates the thread which initiated the stop. - virtual void - StopAllThreads(lldb::tid_t stop_tid); - - /// Adds the thread to the list of threads for which we have received the initial stopping signal. - /// The \p stop_tid parameter indicates the thread which the stop happened for. - bool - AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid); - - bool - WaitingForInitialStop(lldb::tid_t stop_tid); - - virtual POSIXThread * - CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid); - -protected: - /// 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; - - /// Drive any exit events to completion. - bool m_exit_now; - - /// Returns true if the process has exited. - bool HasExited(); - - /// Returns true if the process is stopped. - bool IsStopped(); - - /// Returns true if at least one running is currently running - bool IsAThreadRunning(); - - typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap; - MMapMap m_addr_to_mmap_size; - - typedef std::set<lldb::tid_t> ThreadStopSet; - /// Every thread begins with a stop signal. This keeps track - /// of the threads for which we have received the stop signal. - ThreadStopSet m_seen_initial_stop; -}; - -#endif // liblldb_MacOSXProcess_H_ diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp index 624ca87b883a7..b259804a3a27c 100644 --- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp +++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp @@ -9,10 +9,11 @@ #include "ProcessPOSIXLog.h" +#include <mutex> + #include "lldb/Interpreter/Args.h" #include "lldb/Core/StreamFile.h" -#include "ProcessPOSIX.h" #include "ProcessPOSIXLog.h" using namespace lldb; @@ -33,6 +34,22 @@ GetLog () return g_log; } +void +ProcessPOSIXLog::Initialize(ConstString name) +{ + static std::once_flag g_once_flag; + + std::call_once(g_once_flag, [name](){ + Log::Callbacks log_callbacks = { + DisableLog, + EnableLog, + ListLogCategories + }; + + Log::RegisterLogChannel (name, log_callbacks); + RegisterPluginName(name); + }); +} Log * ProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask) diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h index a1e2e3747d217..7edd839152e67 100644 --- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h +++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h @@ -43,6 +43,12 @@ class ProcessPOSIXLog static const char *m_pluginname; public: + // --------------------------------------------------------------------- + // Public Static Methods + // --------------------------------------------------------------------- + static void + Initialize(lldb_private::ConstString name); + static void RegisterPluginName(const char *pluginName) { diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp deleted file mode 100644 index ec34d9e28161a..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ /dev/null @@ -1,318 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_arm64.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/Target/Thread.h" -#include "lldb/Core/RegisterValue.h" - -#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" -#include "ProcessPOSIX.h" -#include "RegisterContextPOSIXProcessMonitor_arm64.h" -#include "Plugins/Process/Linux/ProcessMonitor.h" - -#define REG_CONTEXT_SIZE (GetGPRSize()) - -RegisterContextPOSIXProcessMonitor_arm64::RegisterContextPOSIXProcessMonitor_arm64(lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : RegisterContextPOSIX_arm64(thread, concrete_frame_idx, register_info) -{ -} - -ProcessMonitor & -RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() -{ - lldb::ProcessSP base = CalculateProcess(); - ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); - return process->GetMonitor(); -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::ReadGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::ReadFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr); -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::WriteGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::WriteFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr); -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(const unsigned reg, - lldb_private::RegisterValue &value) -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg), - GetRegisterName(reg), - GetRegisterSize(reg), - value); -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(const unsigned reg, - const lldb_private::RegisterValue &value) -{ - unsigned reg_to_write = reg; - lldb_private::RegisterValue value_to_write = value; - - // Check if this is a subregister of a full register. - const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); - if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) - { - lldb_private::RegisterValue full_value; - uint32_t full_reg = reg_info->invalidate_regs[0]; - const lldb_private::RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); - - // Read the full register. - if (ReadRegister(full_reg_info, full_value)) - { - lldb_private::Error error; - lldb::ByteOrder byte_order = GetByteOrder(); - uint8_t dst[lldb_private::RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the full register. - const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info, - dst, - sizeof(dst), - byte_order, - error); - if (error.Success() && dest_size) - { - uint8_t src[lldb_private::RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the source data. - const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error); - if (error.Success() && src_size && (src_size < dest_size)) - { - // Copy the src bytes to the destination. - ::memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size); - // Set this full register as the value to write. - value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); - value_to_write.SetType(full_reg_info); - reg_to_write = full_reg; - } - } - } - } - - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg_to_write), - GetRegisterName(reg_to_write), - value_to_write); -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) -{ - if (!reg_info) - return false; - - const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; - - if (IsFPR(reg)) - { - if (!ReadFPR()) - return false; - } - else - { - uint32_t full_reg = reg; - bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); - - if (is_subreg) - { - // Read the full aligned 64-bit register. - full_reg = reg_info->invalidate_regs[0]; - } - return ReadRegister(full_reg, value); - } - - // Get pointer to m_fpr variable and set the data from it. - assert (reg_info->byte_offset < sizeof m_fpr); - uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset; - switch (reg_info->byte_size) - { - case 2: - value.SetUInt16(*(uint16_t *)src); - return true; - case 4: - value.SetUInt32(*(uint32_t *)src); - return true; - case 8: - value.SetUInt64(*(uint64_t *)src); - return true; - default: - assert(false && "Unhandled data size."); - return false; - } -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; - - if (IsGPR(reg)) - return WriteRegister(reg, value); - - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) -{ - bool success = false; - data_sp.reset (new lldb_private::DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && ReadGPR () && ReadFPR ()) - { - uint8_t *dst = data_sp->GetBytes(); - success = dst != 0; - - if (success) - { - ::memcpy (dst, &m_gpr_arm64, GetGPRSize()); - dst += GetGPRSize(); - ::memcpy (dst, &m_fpr, sizeof m_fpr); - } - } - return success; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) -{ - bool success = false; - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - uint8_t *src = data_sp->GetBytes(); - if (src) - { - ::memcpy (&m_gpr_arm64, src, GetGPRSize()); - if (WriteGPR()) { - src += GetGPRSize(); - ::memcpy (&m_fpr, src, sizeof m_fpr); - success = WriteFPR(); - } - } - } - return success; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, - bool read, bool write) -{ - const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); - uint32_t hw_index; - - for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) - { - if (IsWatchpointVacant(hw_index)) - return SetHardwareWatchpointWithIndex(addr, size, - read, write, - hw_index); - } - - return LLDB_INVALID_INDEX32; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::ClearHardwareWatchpoint(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::HardwareSingleStep(bool enable) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::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; -} - -unsigned -RegisterContextPOSIXProcessMonitor_arm64::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < k_num_registers_arm64; reg++) - { - if (GetRegisterInfo()[reg].byte_offset == offset) - break; - } - assert(reg < k_num_registers_arm64 && "Invalid register offset."); - return reg; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointHit(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::ClearWatchpointHits() -{ - return false; -} - -lldb::addr_t -RegisterContextPOSIXProcessMonitor_arm64::GetWatchpointAddress(uint32_t hw_index) -{ - return LLDB_INVALID_ADDRESS; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointVacant(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, - bool read, bool write, - uint32_t hw_index) -{ - return false; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_arm64::NumSupportedHardwareWatchpoints() -{ - return 0; -} diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.h deleted file mode 100644 index eb24d4852ab8d..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.h +++ /dev/null @@ -1,95 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_arm64.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_RegisterContextPOSIXProcessMonitor_arm64_H_ -#define liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_ - -#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" - -class RegisterContextPOSIXProcessMonitor_arm64: - public RegisterContextPOSIX_arm64, - public POSIXBreakpointProtocol -{ -public: - RegisterContextPOSIXProcessMonitor_arm64(lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); - -protected: - bool - ReadGPR(); - - bool - ReadFPR(); - - bool - WriteGPR(); - - bool - WriteFPR(); - - // lldb_private::RegisterContext - bool - ReadRegister(const unsigned reg, lldb_private::RegisterValue &value); - - bool - WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value); - - bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write); - - bool - ClearHardwareWatchpoint(uint32_t hw_index); - - bool - HardwareSingleStep(bool enable); - - // POSIXBreakpointProtocol - bool - UpdateAfterBreakpoint(); - - unsigned - GetRegisterIndexFromOffset(unsigned offset); - - bool - IsWatchpointHit(uint32_t hw_index); - - bool - ClearWatchpointHits(); - - lldb::addr_t - GetWatchpointAddress(uint32_t hw_index); - - bool - IsWatchpointVacant(uint32_t hw_index); - - bool - SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index); - - uint32_t - NumSupportedHardwareWatchpoints(); - -private: - ProcessMonitor & - GetMonitor(); -}; - -#endif diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp deleted file mode 100644 index 6717d20da056f..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp +++ /dev/null @@ -1,317 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_mips64.h ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===---------------------------------------------------------------------===// - -#include "lldb/Target/Thread.h" -#include "lldb/Core/RegisterValue.h" - -#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" -#include "ProcessPOSIX.h" -#include "RegisterContextPOSIXProcessMonitor_mips64.h" -#include "Plugins/Process/Linux/ProcessMonitor.h" - -using namespace lldb_private; -using namespace lldb; - -#define REG_CONTEXT_SIZE (GetGPRSize()) - -RegisterContextPOSIXProcessMonitor_mips64::RegisterContextPOSIXProcessMonitor_mips64(Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info) -{ -} - -ProcessMonitor & -RegisterContextPOSIXProcessMonitor_mips64::GetMonitor() -{ - ProcessSP base = CalculateProcess(); - ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); - return process->GetMonitor(); -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::ReadGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::ReadFPR() -{ - // XXX not yet implemented - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::WriteGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::WriteFPR() -{ - // XXX not yet implemented - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const unsigned reg, - RegisterValue &value) -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg), - GetRegisterName(reg), - GetRegisterSize(reg), - value); -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const unsigned reg, - const RegisterValue &value) -{ - unsigned reg_to_write = reg; - RegisterValue value_to_write = value; - - // Check if this is a subregister of a full register. - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); - if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) - { - RegisterValue full_value; - uint32_t full_reg = reg_info->invalidate_regs[0]; - const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); - - // Read the full register. - if (ReadRegister(full_reg_info, full_value)) - { - Error error; - ByteOrder byte_order = GetByteOrder(); - uint8_t dst[RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the full register. - const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info, - dst, - sizeof(dst), - byte_order, - error); - if (error.Success() && dest_size) - { - uint8_t src[RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the source data. - const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error); - if (error.Success() && src_size && (src_size < dest_size)) - { - // Copy the src bytes to the destination. - memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size); - // Set this full register as the value to write. - value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); - value_to_write.SetType(full_reg_info); - reg_to_write = full_reg; - } - } - } - } - - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg_to_write), - GetRegisterName(reg_to_write), - value_to_write); -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) -{ - if (!reg_info) - return false; - - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - if (IsFPR(reg)) - { - if (!ReadFPR()) - return false; - } - else - { - uint32_t full_reg = reg; - bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); - - if (is_subreg) - { - // Read the full aligned 64-bit register. - full_reg = reg_info->invalidate_regs[0]; - } - - bool success = ReadRegister(full_reg, value); - - if (success) - { - // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right. - if (is_subreg && (reg_info->byte_offset & 0x1)) - value.SetUInt64(value.GetAsUInt64() >> 8); - - // If our return byte size was greater than the return value reg size, then - // use the type specified by reg_info rather than the uint64_t default - if (value.GetByteSize() > reg_info->byte_size) - value.SetType(reg_info); - } - return success; - } - - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - if (IsGPR(reg)) - return WriteRegister(reg, value); - - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(DataBufferSP &data_sp) -{ - bool success = false; - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && ReadGPR () && ReadFPR ()) - { - uint8_t *dst = data_sp->GetBytes(); - success = dst != 0; - - if (success) - { - ::memcpy (dst, &m_gpr_mips64, GetGPRSize()); - } - } - return success; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(const DataBufferSP &data_sp) -{ - bool success = false; - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - uint8_t *src = data_sp->GetBytes(); - if (src) - { - ::memcpy (&m_gpr_mips64, src, GetGPRSize()); - - if (WriteGPR()) - { - src += GetGPRSize(); - } - } - } - return success; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(addr_t addr, size_t size, - bool read, bool write) -{ - const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); - uint32_t hw_index; - - for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) - { - if (IsWatchpointVacant(hw_index)) - return SetHardwareWatchpointWithIndex(addr, size, - read, write, - hw_index); - } - - return LLDB_INVALID_INDEX32; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(bool enable) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::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; -} - -unsigned -RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < k_num_registers_mips64; reg++) - { - if (GetRegisterInfo()[reg].byte_offset == offset) - break; - } - assert(reg < k_num_registers_mips64 && "Invalid register offset."); - return reg; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits() -{ - return false; -} - -addr_t -RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(uint32_t hw_index) -{ - return LLDB_INVALID_ADDRESS; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size, - bool read, bool write, - uint32_t hw_index) -{ - return false; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints() -{ - return 0; -} - diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h deleted file mode 100644 index 79e4468b1adf9..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h +++ /dev/null @@ -1,95 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_mips64.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_RegisterContextPOSIXProcessMonitor_mips64_H_ -#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_ - -#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" - -class RegisterContextPOSIXProcessMonitor_mips64: - public RegisterContextPOSIX_mips64, - public POSIXBreakpointProtocol -{ -public: - RegisterContextPOSIXProcessMonitor_mips64(lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); - -protected: - bool - ReadGPR(); - - bool - ReadFPR(); - - bool - WriteGPR(); - - bool - WriteFPR(); - - // lldb_private::RegisterContext - bool - ReadRegister(const unsigned reg, lldb_private::RegisterValue &value); - - bool - WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value); - - bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write); - - bool - ClearHardwareWatchpoint(uint32_t hw_index); - - bool - HardwareSingleStep(bool enable); - - // POSIXBreakpointProtocol - bool - UpdateAfterBreakpoint(); - - unsigned - GetRegisterIndexFromOffset(unsigned offset); - - bool - IsWatchpointHit(uint32_t hw_index); - - bool - ClearWatchpointHits(); - - lldb::addr_t - GetWatchpointAddress(uint32_t hw_index); - - bool - IsWatchpointVacant(uint32_t hw_index); - - bool - SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index); - - uint32_t - NumSupportedHardwareWatchpoints(); - -private: - ProcessMonitor & - GetMonitor(); -}; - -#endif diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp deleted file mode 100644 index 80e1c1984225a..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ /dev/null @@ -1,336 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_powerpc.h ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===---------------------------------------------------------------------===// - -#include "lldb/Target/Thread.h" -#include "lldb/Core/RegisterValue.h" - -#include "RegisterContextPOSIX_powerpc.h" -#include "ProcessPOSIX.h" -#include "RegisterContextPOSIXProcessMonitor_powerpc.h" -#include "ProcessMonitor.h" - -using namespace lldb_private; -using namespace lldb; - -#define REG_CONTEXT_SIZE (GetGPRSize()) - -RegisterContextPOSIXProcessMonitor_powerpc::RegisterContextPOSIXProcessMonitor_powerpc(Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info) -{ -} - -ProcessMonitor & -RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor() -{ - ProcessSP base = CalculateProcess(); - ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); - return process->GetMonitor(); -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc)); -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX() -{ - // XXX: Need a way to read/write process VMX registers with ptrace. - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc)); -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX() -{ - // XXX: Need a way to read/write process VMX registers with ptrace. - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg, - RegisterValue &value) -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg), - GetRegisterName(reg), - GetRegisterSize(reg), - value); -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const unsigned reg, - const RegisterValue &value) -{ - unsigned reg_to_write = reg; - RegisterValue value_to_write = value; - - // Check if this is a subregister of a full register. - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); - if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) - { - RegisterValue full_value; - uint32_t full_reg = reg_info->invalidate_regs[0]; - const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); - - // Read the full register. - if (ReadRegister(full_reg_info, full_value)) - { - Error error; - ByteOrder byte_order = GetByteOrder(); - uint8_t dst[RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the full register. - const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info, - dst, - sizeof(dst), - byte_order, - error); - if (error.Success() && dest_size) - { - uint8_t src[RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the source data. - const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error); - if (error.Success() && src_size && (src_size < dest_size)) - { - // Copy the src bytes to the destination. - memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size); - // Set this full register as the value to write. - value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); - value_to_write.SetType(full_reg_info); - reg_to_write = full_reg; - } - } - } - } - - ProcessMonitor &monitor = GetMonitor(); - // Account for the fact that 32-bit targets on powerpc64 really use 64-bit - // registers in ptrace, but expose here 32-bit registers with a higher - // offset. - uint64_t offset = GetRegisterOffset(reg_to_write); - offset &= ~(sizeof(uintptr_t) - 1); - return monitor.WriteRegisterValue(m_thread.GetID(), - offset, - GetRegisterName(reg_to_write), - value_to_write); -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) -{ - if (!reg_info) - return false; - - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - if (IsFPR(reg)) - { - if (!ReadFPR()) - return false; - uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset; - value.SetUInt64(*(uint64_t*)src); - } - else if (IsGPR(reg)) - { - bool success = ReadRegister(reg, value); - - if (success) - { - // If our return byte size was greater than the return value reg size, then - // use the type specified by reg_info rather than the uint64_t default - if (value.GetByteSize() > reg_info->byte_size) - value.SetType(reg_info); - } - return success; - } - - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - if (IsGPR(reg)) - { - return WriteRegister(reg, value); - } - else if (IsFPR(reg)) - { - assert (reg_info->byte_offset < sizeof(m_fpr_powerpc)); - uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset; - *(uint64_t *)dst = value.GetAsUInt64(); - return WriteFPR(); - } - - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(DataBufferSP &data_sp) -{ - bool success = false; - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && ReadGPR () && ReadFPR ()) - { - uint8_t *dst = data_sp->GetBytes(); - success = dst != 0; - - if (success) - { - ::memcpy (dst, &m_gpr_powerpc, GetGPRSize()); - dst += GetGPRSize(); - } - } - return success; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBufferSP &data_sp) -{ - bool success = false; - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - uint8_t *src = data_sp->GetBytes(); - if (src) - { - ::memcpy (&m_gpr_powerpc, src, GetGPRSize()); - - if (WriteGPR()) - { - src += GetGPRSize(); - ::memcpy (&m_fpr_powerpc, src, sizeof(m_fpr_powerpc)); - - success = WriteFPR(); - } - } - } - return success; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(addr_t addr, size_t size, - bool read, bool write) -{ - const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); - uint32_t hw_index; - - for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) - { - if (IsWatchpointVacant(hw_index)) - return SetHardwareWatchpointWithIndex(addr, size, - read, write, - hw_index); - } - - return LLDB_INVALID_INDEX32; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(bool enable) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint() -{ - lldb::addr_t pc; - - if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) - return false; - - return true; -} - -unsigned -RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < k_num_registers_powerpc; reg++) - { - if (GetRegisterInfo()[reg].byte_offset == offset) - break; - } - assert(reg < k_num_registers_powerpc && "Invalid register offset."); - return reg; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits() -{ - return false; -} - -addr_t -RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(uint32_t hw_index) -{ - return LLDB_INVALID_ADDRESS; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(addr_t addr, size_t size, - bool read, bool write, - uint32_t hw_index) -{ - return false; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints() -{ - return 0; -} - diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h deleted file mode 100644 index 5c686df4836fa..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h +++ /dev/null @@ -1,104 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_powerpc.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_RegisterContextPOSIXProcessMonitor_powerpc_H_ -#define liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_ - -#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" - -class RegisterContextPOSIXProcessMonitor_powerpc: - public RegisterContextPOSIX_powerpc, - public POSIXBreakpointProtocol -{ -public: - RegisterContextPOSIXProcessMonitor_powerpc(lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); - -protected: - bool - IsVMX(); - - bool - ReadGPR(); - - bool - ReadFPR(); - - bool - ReadVMX(); - - bool - WriteGPR(); - - bool - WriteFPR(); - - bool - WriteVMX(); - - // lldb_private::RegisterContext - bool - ReadRegister(const unsigned reg, lldb_private::RegisterValue &value); - - bool - WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value); - - bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write); - - bool - ClearHardwareWatchpoint(uint32_t hw_index); - - bool - HardwareSingleStep(bool enable); - - // POSIXBreakpointProtocol - bool - UpdateAfterBreakpoint(); - - unsigned - GetRegisterIndexFromOffset(unsigned offset); - - bool - IsWatchpointHit(uint32_t hw_index); - - bool - ClearWatchpointHits(); - - lldb::addr_t - GetWatchpointAddress(uint32_t hw_index); - - bool - IsWatchpointVacant(uint32_t hw_index); - - bool - SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index); - - uint32_t - NumSupportedHardwareWatchpoints(); - -private: - ProcessMonitor & - GetMonitor(); -}; - -#endif diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp deleted file mode 100644 index 1956e4584fa96..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp +++ /dev/null @@ -1,653 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_x86.h ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===---------------------------------------------------------------------===// - -#include "lldb/Target/Thread.h" -#include "lldb/Core/RegisterValue.h" - -#include "Plugins/Process/POSIX/ProcessPOSIX.h" -#include "RegisterContextPOSIXProcessMonitor_x86.h" -#if defined(__FreeBSD__) -#include "Plugins/Process/FreeBSD/ProcessMonitor.h" -#else -#include "Plugins/Process/Linux/ProcessMonitor.h" -#endif - -using namespace lldb_private; -using namespace lldb; - -// Support ptrace extensions even when compiled without required kernel support -#ifndef NT_X86_XSTATE - #define NT_X86_XSTATE 0x202 -#endif - -#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(FPR)) - -static uint32_t -size_and_rw_bits(size_t size, bool read, bool write) -{ - uint32_t rw; - - if (read) - rw = 0x3; // READ or READ/WRITE - else if (write) - rw = 0x1; // WRITE - else - assert(0 && "read and write cannot both be false"); - - switch (size) - { - case 1: - return rw; - case 2: - return (0x1 << 2) | rw; - case 4: - return (0x3 << 2) | rw; - case 8: - return (0x2 << 2) | rw; - default: - assert(0 && "invalid size, must be one of 1, 2, 4, or 8"); - return 0; // Unreachable. Just to silence compiler. - } -} - -RegisterContextPOSIXProcessMonitor_x86_64::RegisterContextPOSIXProcessMonitor_x86_64(Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info) - : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info) -{ -} - -ProcessMonitor & -RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor() -{ - ProcessSP base = CalculateProcess(); - ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); - return process->GetMonitor(); -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - if (GetFPRType() == eFXSAVE) - return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave)); - - if (GetFPRType() == eXSAVE) - return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE); - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize()); -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - if (GetFPRType() == eFXSAVE) - return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave)); - - if (GetFPRType() == eXSAVE) - return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE); - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const unsigned reg, - RegisterValue &value) -{ - ProcessMonitor &monitor = GetMonitor(); - -#if defined(__FreeBSD__) - if (reg >= m_reg_info.first_dr) - return monitor.ReadDebugRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg), - GetRegisterName(reg), - GetRegisterSize(reg), - value); -#endif - return monitor.ReadRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg), - GetRegisterName(reg), - GetRegisterSize(reg), - value); -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const unsigned reg, - const RegisterValue &value) -{ - unsigned reg_to_write = reg; - RegisterValue value_to_write = value; - - // Check if this is a subregister of a full register. - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); - if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) - { - RegisterValue full_value; - uint32_t full_reg = reg_info->invalidate_regs[0]; - const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); - - // Read the full register. - if (ReadRegister(full_reg_info, full_value)) - { - Error error; - ByteOrder byte_order = GetByteOrder(); - uint8_t dst[RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the full register. - const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info, - dst, - sizeof(dst), - byte_order, - error); - if (error.Success() && dest_size) - { - uint8_t src[RegisterValue::kMaxRegisterByteSize]; - - // Get the bytes for the source data. - const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error); - if (error.Success() && src_size && (src_size < dest_size)) - { - // Copy the src bytes to the destination. - memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size); - // Set this full register as the value to write. - value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); - value_to_write.SetType(full_reg_info); - reg_to_write = full_reg; - } - } - } - } - - ProcessMonitor &monitor = GetMonitor(); -#if defined(__FreeBSD__) - if (reg >= m_reg_info.first_dr) - return monitor.WriteDebugRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg_to_write), - GetRegisterName(reg_to_write), - value_to_write); -#endif - return monitor.WriteRegisterValue(m_thread.GetID(), - GetRegisterOffset(reg_to_write), - GetRegisterName(reg_to_write), - value_to_write); -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) -{ - if (!reg_info) - return false; - - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - if (IsFPR(reg, GetFPRType())) - { - if (!ReadFPR()) - return false; - } - else - { - uint32_t full_reg = reg; - bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); - - if (is_subreg) - { - // Read the full aligned 64-bit register. - full_reg = reg_info->invalidate_regs[0]; - } - - bool success = ReadRegister(full_reg, value); - - if (success) - { - // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right. - if (is_subreg && (reg_info->byte_offset & 0x1)) - value.SetUInt64(value.GetAsUInt64() >> 8); - - // If our return byte size was greater than the return value reg size, then - // use the type specified by reg_info rather than the uint64_t default - if (value.GetByteSize() > reg_info->byte_size) - value.SetType(reg_info); - } - return success; - } - - if (reg_info->encoding == eEncodingVector) - { - ByteOrder byte_order = GetByteOrder(); - - if (byte_order != ByteOrder::eByteOrderInvalid) - { - if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st) - value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order); - if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm) - value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order); - if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm) - value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order); - if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) - { - // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes - if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order)) - value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order); - else - return false; - } - return value.GetType() == RegisterValue::eTypeBytes; - } - return false; - } - - // Get pointer to m_fpr.xstate.fxsave variable and set the data from it. - assert (reg_info->byte_offset < sizeof(m_fpr)); - uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset; - switch (reg_info->byte_size) - { - case 2: - value.SetUInt16(*(uint16_t *)src); - return true; - case 4: - value.SetUInt32(*(uint32_t *)src); - return true; - case 8: - value.SetUInt64(*(uint64_t *)src); - return true; - default: - assert(false && "Unhandled data size."); - return false; - } -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - if (IsGPR(reg)) - return WriteRegister(reg, value); - - if (IsFPR(reg, GetFPRType())) - { - if (reg_info->encoding == eEncodingVector) - { - if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st) - ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, value.GetBytes(), value.GetByteSize()); - - if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm) - ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, value.GetBytes(), value.GetByteSize()); - - if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm) - ::memcpy (m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, value.GetBytes(), value.GetByteSize()); - - if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) - { - if (GetFPRType() != eXSAVE) - return false; // the target processor does not support AVX - - // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes - ::memcpy (m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, value.GetBytes(), value.GetByteSize()); - if (false == CopyYMMtoXSTATE(reg, GetByteOrder())) - return false; - } - } - else - { - // Get pointer to m_fpr.xstate.fxsave variable and set the data to it. - assert (reg_info->byte_offset < sizeof(m_fpr)); - uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset; - switch (reg_info->byte_size) - { - case 2: - *(uint16_t *)dst = value.GetAsUInt16(); - break; - case 4: - *(uint32_t *)dst = value.GetAsUInt32(); - break; - case 8: - *(uint64_t *)dst = value.GetAsUInt64(); - break; - default: - assert(false && "Unhandled data size."); - return false; - } - } - - if (WriteFPR()) - { - if (IsAVX(reg)) - return CopyYMMtoXSTATE(reg, GetByteOrder()); - return true; - } - } - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp) -{ - bool success = false; - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && ReadGPR () && ReadFPR ()) - { - uint8_t *dst = data_sp->GetBytes(); - success = dst != 0; - - if (success) - { - ::memcpy (dst, &m_gpr_x86_64, GetGPRSize()); - dst += GetGPRSize(); - if (GetFPRType() == eFXSAVE) - ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave)); - } - - if (GetFPRType() == eXSAVE) - { - ByteOrder byte_order = GetByteOrder(); - - // Assemble the YMM register content from the register halves. - for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg) - success = CopyXSTATEtoYMM(reg, byte_order); - - if (success) - { - // Copy the extended register state including the assembled ymm registers. - ::memcpy (dst, &m_fpr, sizeof(m_fpr)); - } - } - } - return success; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp) -{ - bool success = false; - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - uint8_t *src = data_sp->GetBytes(); - if (src) - { - ::memcpy (&m_gpr_x86_64, src, GetGPRSize()); - - if (WriteGPR()) - { - src += GetGPRSize(); - if (GetFPRType() == eFXSAVE) - ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave)); - if (GetFPRType() == eXSAVE) - ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave)); - - success = WriteFPR(); - if (success) - { - if (GetFPRType() == eXSAVE) - { - ByteOrder byte_order = GetByteOrder(); - - // Parse the YMM register content from the register halves. - for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg) - success = CopyYMMtoXSTATE(reg, byte_order); - } - } - } - } - } - return success; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(addr_t addr, size_t size, - bool read, bool write) -{ - const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); - uint32_t hw_index; - - for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) - { - if (IsWatchpointVacant(hw_index)) - return SetHardwareWatchpointWithIndex(addr, size, - read, write, - hw_index); - } - - return LLDB_INVALID_INDEX32; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(uint32_t hw_index) -{ - if (hw_index < NumSupportedHardwareWatchpoints()) - { - RegisterValue current_dr7_bits; - - if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) - { - uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index)); - - if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits))) - return true; - } - } - - return false; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(bool enable) -{ - enum { TRACE_BIT = 0x100 }; - uint64_t rflags; - - if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -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(m_reg_info.gpr_flags, rflags); -} - -bool -RegisterContextPOSIXProcessMonitor_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; -} - -unsigned -RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < m_reg_info.num_registers; reg++) - { - if (GetRegisterInfo()[reg].byte_offset == offset) - break; - } - assert(reg < m_reg_info.num_registers && "Invalid register offset."); - return reg; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index) -{ - bool is_hit = false; - - if (m_watchpoints_initialized == false) - { - // Reset the debug status and debug control registers - RegisterValue zero_bits = RegisterValue(uint64_t(0)); - if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits)) - assert(false && "Could not initialize watchpoint registers"); - m_watchpoints_initialized = true; - } - - if (hw_index < NumSupportedHardwareWatchpoints()) - { - RegisterValue value; - - if (ReadRegister(m_reg_info.first_dr + 6, value)) - { - uint64_t val = value.GetAsUInt64(); - is_hit = val & (1 << hw_index); - } - } - - return is_hit; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits() -{ - return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0)); -} - -addr_t -RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(uint32_t hw_index) -{ - addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS; - - if (hw_index < NumSupportedHardwareWatchpoints()) - { - if (!IsWatchpointVacant(hw_index)) - { - RegisterValue value; - - if (ReadRegister(m_reg_info.first_dr + hw_index, value)) - wp_monitor_addr = value.GetAsUInt64(); - } - } - - return wp_monitor_addr; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(uint32_t hw_index) -{ - bool is_vacant = false; - RegisterValue value; - - assert(hw_index < NumSupportedHardwareWatchpoints()); - - if (m_watchpoints_initialized == false) - { - // Reset the debug status and debug control registers - RegisterValue zero_bits = RegisterValue(uint64_t(0)); - if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits)) - assert(false && "Could not initialize watchpoint registers"); - m_watchpoints_initialized = true; - } - - if (ReadRegister(m_reg_info.first_dr + 7, value)) - { - uint64_t val = value.GetAsUInt64(); - is_vacant = (val & (3 << 2*hw_index)) == 0; - } - - return is_vacant; -} - -bool -RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size, - bool read, bool write, - uint32_t hw_index) -{ - const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); - - if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints) - return false; - - if (!(size == 1 || size == 2 || size == 4 || size == 8)) - return false; - - if (read == false && write == false) - return false; - - if (!IsWatchpointVacant(hw_index)) - return false; - - // Set both dr7 (debug control register) and dri (debug address register). - - // dr7{7-0} encodes the local/global enable bits: - // global enable --. .-- local enable - // | | - // v v - // dr0 -> bits{1-0} - // dr1 -> bits{3-2} - // dr2 -> bits{5-4} - // dr3 -> bits{7-6} - // - // dr7{31-16} encodes the rw/len bits: - // b_x+3, b_x+2, b_x+1, b_x - // where bits{x+1, x} => rw - // 0b00: execute, 0b01: write, 0b11: read-or-write, - // 0b10: io read-or-write (unused) - // and bits{x+3, x+2} => len - // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte - // - // dr0 -> bits{19-16} - // dr1 -> bits{23-20} - // dr2 -> bits{27-24} - // dr3 -> bits{31-28} - if (hw_index < num_hw_watchpoints) - { - RegisterValue current_dr7_bits; - - if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) - { - uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() | - (1 << (2*hw_index) | - size_and_rw_bits(size, read, write) << - (16+4*hw_index)); - - if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) && - WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits))) - return true; - } - } - - return false; -} - -uint32_t -RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints() -{ - // Available debug address registers: dr0, dr1, dr2, dr3 - return 4; -} - diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.h deleted file mode 100644 index 2afb195c4c365..0000000000000 --- a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.h +++ /dev/null @@ -1,95 +0,0 @@ -//===-- RegisterContextPOSIXProcessMonitor_x86.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_RegisterContextPOSIXProcessMonitor_x86_H_ -#define liblldb_RegisterContextPOSIXProcessMonitor_x86_H_ - -#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h" - -class RegisterContextPOSIXProcessMonitor_x86_64: - public RegisterContextPOSIX_x86, - public POSIXBreakpointProtocol -{ -public: - RegisterContextPOSIXProcessMonitor_x86_64(lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - lldb_private::RegisterInfoInterface *register_info); - -protected: - bool - ReadGPR(); - - bool - ReadFPR(); - - bool - WriteGPR(); - - bool - WriteFPR(); - - // lldb_private::RegisterContext - bool - ReadRegister(const unsigned reg, lldb_private::RegisterValue &value); - - bool - WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value); - - bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write); - - bool - ClearHardwareWatchpoint(uint32_t hw_index); - - bool - HardwareSingleStep(bool enable); - - // POSIXBreakpointProtocol - bool - UpdateAfterBreakpoint(); - - unsigned - GetRegisterIndexFromOffset(unsigned offset); - - bool - IsWatchpointHit(uint32_t hw_index); - - bool - ClearWatchpointHits(); - - lldb::addr_t - GetWatchpointAddress(uint32_t hw_index); - - bool - IsWatchpointVacant(uint32_t hw_index); - - bool - SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index); - - uint32_t - NumSupportedHardwareWatchpoints(); - -private: - ProcessMonitor & - GetMonitor(); -}; - -#endif |