Author: emaste Date: Thu Oct 10 14:14:55 2013 New Revision: 192387 URL: http://llvm.org/viewvc/llvm-project?rev=192387&view=rev Log: Initial FreeBSD mips64 ProcessMonitor support
Committing early to ease tracking other ongoing POSIX changes. Review: http://llvm-reviews.chandlerc.com/D1886 Added: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h Modified: lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h Modified: lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt?rev=192387&r1=192386&r2=192387&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt (original) +++ lldb/trunk/source/Plugins/Process/POSIX/CMakeLists.txt Thu Oct 10 14:14:55 2013 @@ -12,6 +12,7 @@ add_lldb_library(lldbPluginProcessPOSIX ProcessPOSIXLog.cpp RegisterContextPOSIX_mips64.cpp RegisterContextPOSIX_x86.cpp + RegisterContextPOSIXProcessMonitor_mips64.cpp RegisterContextPOSIXProcessMonitor_x86.cpp RegisterContextFreeBSD_i386.cpp RegisterContextFreeBSD_mips64.cpp Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=192387&r1=192386&r2=192387&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp (original) +++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp Thu Oct 10 14:14:55 2013 @@ -29,10 +29,12 @@ #include "ProcessPOSIX.h" #include "ProcessPOSIXLog.h" #include "ProcessMonitor.h" +#include "RegisterContextPOSIXProcessMonitor_mips64.h" #include "RegisterContextPOSIXProcessMonitor_x86.h" #include "RegisterContextLinux_i386.h" #include "RegisterContextLinux_x86_64.h" #include "RegisterContextFreeBSD_i386.h" +#include "RegisterContextFreeBSD_mips64.h" #include "RegisterContextFreeBSD_x86_64.h" #include "UnwindLLDB.h" @@ -144,25 +146,62 @@ POSIXThread::GetRegisterContext() RegisterInfoInterface *reg_interface = NULL; const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture(); - switch (target_arch.GetTriple().getOS()) + switch (target_arch.GetCore()) { - case llvm::Triple::FreeBSD: - reg_interface = new RegisterContextFreeBSD_x86_64(target_arch); + case ArchSpec::eCore_mips64: + { + RegisterInfoInterface *reg_interface = NULL; + + switch (target_arch.GetTriple().getOS()) + { + case llvm::Triple::FreeBSD: + reg_interface = new RegisterContextFreeBSD_mips64(target_arch); + break; + default: + assert(false && "OS not supported"); + break; + } + + if (reg_interface) + { + 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::Linux: - reg_interface = new RegisterContextLinux_x86_64(target_arch); + } + + case ArchSpec::eCore_x86_32_i386: + case ArchSpec::eCore_x86_32_i486: + case ArchSpec::eCore_x86_32_i486sx: + case ArchSpec::eCore_x86_64_x86_64: + { + switch (target_arch.GetTriple().getOS()) + { + case llvm::Triple::FreeBSD: + reg_interface = new RegisterContextFreeBSD_x86_64(target_arch); + break; + case llvm::Triple::Linux: + reg_interface = new RegisterContextLinux_x86_64(target_arch); + break; + default: + assert(false && "OS not supported"); + break; + } + + if (reg_interface) + { + 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: - assert(false && "OS not supported"); + assert(false && "CPU type not supported!"); break; } - - if (reg_interface) - { - 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); - } } return m_reg_context_sp; } @@ -523,6 +562,7 @@ POSIXThread::GetRegisterIndexFromOffset( llvm_unreachable("CPU type not supported!"); break; + case ArchSpec::eCore_mips64: case ArchSpec::eCore_x86_32_i386: case ArchSpec::eCore_x86_32_i486: case ArchSpec::eCore_x86_32_i486sx: @@ -554,6 +594,7 @@ POSIXThread::GetRegisterName(unsigned re assert(false && "CPU type not supported!"); break; + case ArchSpec::eCore_mips64: case ArchSpec::eCore_x86_32_i386: case ArchSpec::eCore_x86_32_i486: case ArchSpec::eCore_x86_32_i486sx: Added: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp?rev=192387&view=auto ============================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp (added) +++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp Thu Oct 10 14:14:55 2013 @@ -0,0 +1,318 @@ +//===-- 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 "RegisterContextPOSIX_mips64.h" +#include "ProcessPOSIX.h" +#include "RegisterContextPOSIXProcessMonitor_mips64.h" +#include "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, + 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()); + dst += 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; +} + Added: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h?rev=192387&view=auto ============================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h (added) +++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h Thu Oct 10 14:14:55 2013 @@ -0,0 +1,95 @@ +//===-- 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/POSIX/RegisterContextPOSIX_mips64.h" + +class RegisterContextPOSIXProcessMonitor_mips64: + public RegisterContextPOSIX_mips64, + public POSIXBreakpointProtocol +{ +public: + RegisterContextPOSIXProcessMonitor_mips64(lldb_private::Thread &thread, + uint32_t concrete_frame_idx, + 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 Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h?rev=192387&r1=192386&r2=192387&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h (original) +++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h Thu Oct 10 14:14:55 2013 @@ -111,7 +111,7 @@ public: ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num); protected: - uint64_t m_gpr[k_num_gpr_registers_mips64]; // general purpose registers. + uint64_t m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers. std::unique_ptr<RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux) // Determines if an extended register set is supported on the processor running the inferior process. _______________________________________________ lldb-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
