| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| //===-- ABISysV_ppc.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_ABISysV_ppc_h_ | ||
| #define liblldb_ABISysV_ppc_h_ | ||
|
|
||
| // C Includes | ||
| // C++ Includes | ||
| // Other libraries and framework includes | ||
| // Project includes | ||
| #include "lldb/lldb-private.h" | ||
| #include "lldb/Target/ABI.h" | ||
|
|
||
| class ABISysV_ppc : | ||
| public lldb_private::ABI | ||
| { | ||
| public: | ||
|
|
||
| ~ABISysV_ppc() | ||
| { | ||
| } | ||
|
|
||
| virtual size_t | ||
| GetRedZoneSize () const; | ||
|
|
||
| virtual bool | ||
| PrepareTrivialCall (lldb_private::Thread &thread, | ||
| lldb::addr_t sp, | ||
| lldb::addr_t functionAddress, | ||
| lldb::addr_t returnAddress, | ||
| llvm::ArrayRef<lldb::addr_t> args) const; | ||
|
|
||
| virtual bool | ||
| GetArgumentValues (lldb_private::Thread &thread, | ||
| lldb_private::ValueList &values) const; | ||
|
|
||
| virtual lldb_private::Error | ||
| SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value); | ||
|
|
||
| protected: | ||
| lldb::ValueObjectSP | ||
| GetReturnValueObjectSimple (lldb_private::Thread &thread, | ||
| lldb_private::ClangASTType &ast_type) const; | ||
|
|
||
| public: | ||
| virtual lldb::ValueObjectSP | ||
| GetReturnValueObjectImpl (lldb_private::Thread &thread, | ||
| lldb_private::ClangASTType &type) const; | ||
|
|
||
| virtual bool | ||
| CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan); | ||
|
|
||
| virtual bool | ||
| CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan); | ||
|
|
||
| virtual bool | ||
| RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info); | ||
|
|
||
| virtual bool | ||
| StackUsesFrames () | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| // The SysV ppc ABI requires that stack frames be 16 byte aligned. | ||
| // When there is a trap handler on the stack, e.g. _sigtramp in userland | ||
| // code, we've seen that the stack pointer is often not aligned properly | ||
| // before the handler is invoked. This means that lldb will stop the unwind | ||
| // early -- before the function which caused the trap. | ||
| // | ||
| // To work around this, we relax that alignment to be just word-size (8-bytes). | ||
| // Whitelisting the trap handlers for user space would be easy (_sigtramp) but | ||
| // in other environments there can be a large number of different functions | ||
| // involved in async traps. | ||
| virtual bool | ||
| CallFrameAddressIsValid (lldb::addr_t cfa) | ||
| { | ||
| // Make sure the stack call frame addresses are 8 byte aligned | ||
| if (cfa & (8ull - 1ull)) | ||
| return false; // Not 8 byte aligned | ||
| if (cfa == 0) | ||
| return false; // Zero is not a valid stack address | ||
| return true; | ||
| } | ||
|
|
||
| virtual bool | ||
| CodeAddressIsValid (lldb::addr_t pc) | ||
| { | ||
| // We have a 64 bit address space, so anything is valid as opcodes | ||
| // aren't fixed width... | ||
| return true; | ||
| } | ||
|
|
||
| virtual bool | ||
| FunctionCallsChangeCFA () | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| virtual const lldb_private::RegisterInfo * | ||
| GetRegisterInfoArray (uint32_t &count); | ||
| //------------------------------------------------------------------ | ||
| // Static Functions | ||
| //------------------------------------------------------------------ | ||
| static void | ||
| Initialize(); | ||
|
|
||
| static void | ||
| Terminate(); | ||
|
|
||
| static lldb::ABISP | ||
| CreateInstance (const lldb_private::ArchSpec &arch); | ||
|
|
||
| static lldb_private::ConstString | ||
| GetPluginNameStatic(); | ||
|
|
||
| //------------------------------------------------------------------ | ||
| // PluginInterface protocol | ||
| //------------------------------------------------------------------ | ||
| virtual lldb_private::ConstString | ||
| GetPluginName(); | ||
|
|
||
| virtual uint32_t | ||
| GetPluginVersion(); | ||
|
|
||
| protected: | ||
| void | ||
| CreateRegisterMapIfNeeded (); | ||
|
|
||
| bool | ||
| RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info); | ||
|
|
||
| private: | ||
| ABISysV_ppc() : lldb_private::ABI() { } // Call CreateInstance instead. | ||
| }; | ||
|
|
||
| #endif // liblldb_ABI_h_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| set(LLVM_NO_RTTI 1) | ||
|
|
||
| add_lldb_library(lldbPluginABISysV_ppc | ||
| ABISysV_ppc.cpp | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| ##===- source/Plugins/ABI/SysV-hexagon/Makefile -------------*- Makefile -*-===## | ||
| # | ||
| # The LLVM Compiler Infrastructure | ||
| # | ||
| # This file is distributed under the University of Illinois Open Source | ||
| # License. See LICENSE.TXT for details. | ||
| # | ||
| ##===----------------------------------------------------------------------===## | ||
|
|
||
| LLDB_LEVEL := ../../../.. | ||
| LIBRARYNAME := lldbPluginABISysV_ppc | ||
| BUILD_ARCHIVE = 1 | ||
|
|
||
| include $(LLDB_LEVEL)/Makefile |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| //===-- ABISysV_ppc64.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_ABISysV_ppc64_h_ | ||
| #define liblldb_ABISysV_ppc64_h_ | ||
|
|
||
| // C Includes | ||
| // C++ Includes | ||
| // Other libraries and framework includes | ||
| // Project includes | ||
| #include "lldb/lldb-private.h" | ||
| #include "lldb/Target/ABI.h" | ||
|
|
||
| class ABISysV_ppc64 : | ||
| public lldb_private::ABI | ||
| { | ||
| public: | ||
|
|
||
| ~ABISysV_ppc64() | ||
| { | ||
| } | ||
|
|
||
| virtual size_t | ||
| GetRedZoneSize () const; | ||
|
|
||
| virtual bool | ||
| PrepareTrivialCall (lldb_private::Thread &thread, | ||
| lldb::addr_t sp, | ||
| lldb::addr_t functionAddress, | ||
| lldb::addr_t returnAddress, | ||
| llvm::ArrayRef<lldb::addr_t> args) const; | ||
|
|
||
| virtual bool | ||
| GetArgumentValues (lldb_private::Thread &thread, | ||
| lldb_private::ValueList &values) const; | ||
|
|
||
| virtual lldb_private::Error | ||
| SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value); | ||
|
|
||
| protected: | ||
| lldb::ValueObjectSP | ||
| GetReturnValueObjectSimple (lldb_private::Thread &thread, | ||
| lldb_private::ClangASTType &ast_type) const; | ||
|
|
||
| public: | ||
| virtual lldb::ValueObjectSP | ||
| GetReturnValueObjectImpl (lldb_private::Thread &thread, | ||
| lldb_private::ClangASTType &type) const; | ||
|
|
||
| virtual bool | ||
| CreateFunctionEntryUnwindPlan (lldb_private::UnwindPlan &unwind_plan); | ||
|
|
||
| virtual bool | ||
| CreateDefaultUnwindPlan (lldb_private::UnwindPlan &unwind_plan); | ||
|
|
||
| virtual bool | ||
| RegisterIsVolatile (const lldb_private::RegisterInfo *reg_info); | ||
|
|
||
| virtual bool | ||
| StackUsesFrames () | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| // The SysV ppc64 ABI requires that stack frames be 16 byte aligned. | ||
| // When there is a trap handler on the stack, e.g. _sigtramp in userland | ||
| // code, we've seen that the stack pointer is often not aligned properly | ||
| // before the handler is invoked. This means that lldb will stop the unwind | ||
| // early -- before the function which caused the trap. | ||
| // | ||
| // To work around this, we relax that alignment to be just word-size (8-bytes). | ||
| // Whitelisting the trap handlers for user space would be easy (_sigtramp) but | ||
| // in other environments there can be a large number of different functions | ||
| // involved in async traps. | ||
| virtual bool | ||
| CallFrameAddressIsValid (lldb::addr_t cfa) | ||
| { | ||
| // Make sure the stack call frame addresses are 8 byte aligned | ||
| if (cfa & (8ull - 1ull)) | ||
| return false; // Not 8 byte aligned | ||
| if (cfa == 0) | ||
| return false; // Zero is not a valid stack address | ||
| return true; | ||
| } | ||
|
|
||
| virtual bool | ||
| CodeAddressIsValid (lldb::addr_t pc) | ||
| { | ||
| // We have a 64 bit address space, so anything is valid as opcodes | ||
| // aren't fixed width... | ||
| return true; | ||
| } | ||
|
|
||
| virtual bool | ||
| FunctionCallsChangeCFA () | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| virtual const lldb_private::RegisterInfo * | ||
| GetRegisterInfoArray (uint32_t &count); | ||
| //------------------------------------------------------------------ | ||
| // Static Functions | ||
| //------------------------------------------------------------------ | ||
| static void | ||
| Initialize(); | ||
|
|
||
| static void | ||
| Terminate(); | ||
|
|
||
| static lldb::ABISP | ||
| CreateInstance (const lldb_private::ArchSpec &arch); | ||
|
|
||
| static lldb_private::ConstString | ||
| GetPluginNameStatic(); | ||
|
|
||
| //------------------------------------------------------------------ | ||
| // PluginInterface protocol | ||
| //------------------------------------------------------------------ | ||
| virtual lldb_private::ConstString | ||
| GetPluginName(); | ||
|
|
||
| virtual uint32_t | ||
| GetPluginVersion(); | ||
|
|
||
| protected: | ||
| void | ||
| CreateRegisterMapIfNeeded (); | ||
|
|
||
| bool | ||
| RegisterIsCalleeSaved (const lldb_private::RegisterInfo *reg_info); | ||
|
|
||
| private: | ||
| ABISysV_ppc64() : lldb_private::ABI() { } // Call CreateInstance instead. | ||
| }; | ||
|
|
||
| #endif // liblldb_ABI_h_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| set(LLVM_NO_RTTI 1) | ||
|
|
||
| add_lldb_library(lldbPluginABISysV_ppc64 | ||
| ABISysV_ppc64.cpp | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| ##===- source/Plugins/ABI/SysV-hexagon/Makefile -------------*- Makefile -*-===## | ||
| # | ||
| # The LLVM Compiler Infrastructure | ||
| # | ||
| # This file is distributed under the University of Illinois Open Source | ||
| # License. See LICENSE.TXT for details. | ||
| # | ||
| ##===----------------------------------------------------------------------===## | ||
|
|
||
| LLDB_LEVEL := ../../../.. | ||
| LIBRARYNAME := lldbPluginABISysV_ppc64 | ||
| BUILD_ARCHIVE = 1 | ||
|
|
||
| include $(LLDB_LEVEL)/Makefile |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,316 @@ | ||
| //===-- 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() | ||
| { | ||
| // XXX not yet implemented | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() | ||
| { | ||
| ProcessMonitor &monitor = GetMonitor(); | ||
| return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize()); | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() | ||
| { | ||
| // XXX not yet implemented | ||
| 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(); | ||
| return monitor.WriteRegisterValue(m_thread.GetID(), | ||
| GetRegisterOffset(reg_to_write), | ||
| 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; | ||
| } | ||
| 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_powerpc::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_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(); | ||
| } | ||
| } | ||
| } | ||
| 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; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| //===-- 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 | ||
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,227 @@ | ||
| //===-- RegisterContextFreeBSD_powerpc.cpp ----------------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===---------------------------------------------------------------------===// | ||
|
|
||
| #include <vector> | ||
| #include "RegisterContextPOSIX_powerpc.h" | ||
| #include "RegisterContextFreeBSD_powerpc.h" | ||
|
|
||
| using namespace lldb_private; | ||
| using namespace lldb; | ||
|
|
||
| // http://svnweb.freebsd.org/base/head/sys/powerpc/include/reg.h | ||
| typedef struct _GPR64 | ||
| { | ||
| uint64_t r0; | ||
| uint64_t r1; | ||
| uint64_t r2; | ||
| uint64_t r3; | ||
| uint64_t r4; | ||
| uint64_t r5; | ||
| uint64_t r6; | ||
| uint64_t r7; | ||
| uint64_t r8; | ||
| uint64_t r9; | ||
| uint64_t r10; | ||
| uint64_t r11; | ||
| uint64_t r12; | ||
| uint64_t r13; | ||
| uint64_t r14; | ||
| uint64_t r15; | ||
| uint64_t r16; | ||
| uint64_t r17; | ||
| uint64_t r18; | ||
| uint64_t r19; | ||
| uint64_t r20; | ||
| uint64_t r21; | ||
| uint64_t r22; | ||
| uint64_t r23; | ||
| uint64_t r24; | ||
| uint64_t r25; | ||
| uint64_t r26; | ||
| uint64_t r27; | ||
| uint64_t r28; | ||
| uint64_t r29; | ||
| uint64_t r30; | ||
| uint64_t r31; | ||
| uint64_t lr; | ||
| uint64_t cr; | ||
| uint64_t xer; | ||
| uint64_t ctr; | ||
| uint64_t pc; | ||
| } GPR64; | ||
|
|
||
| typedef struct _GPR32 | ||
| { | ||
| uint32_t r0; | ||
| uint32_t r1; | ||
| uint32_t r2; | ||
| uint32_t r3; | ||
| uint32_t r4; | ||
| uint32_t r5; | ||
| uint32_t r6; | ||
| uint32_t r7; | ||
| uint32_t r8; | ||
| uint32_t r9; | ||
| uint32_t r10; | ||
| uint32_t r11; | ||
| uint32_t r12; | ||
| uint32_t r13; | ||
| uint32_t r14; | ||
| uint32_t r15; | ||
| uint32_t r16; | ||
| uint32_t r17; | ||
| uint32_t r18; | ||
| uint32_t r19; | ||
| uint32_t r20; | ||
| uint32_t r21; | ||
| uint32_t r22; | ||
| uint32_t r23; | ||
| uint32_t r24; | ||
| uint32_t r25; | ||
| uint32_t r26; | ||
| uint32_t r27; | ||
| uint32_t r28; | ||
| uint32_t r29; | ||
| uint32_t r30; | ||
| uint32_t r31; | ||
| uint32_t lr; | ||
| uint32_t cr; | ||
| uint32_t xer; | ||
| uint32_t ctr; | ||
| uint32_t pc; | ||
| } GPR32; | ||
|
|
||
| typedef struct _FPR | ||
| { | ||
| uint64_t f0; | ||
| uint64_t f1; | ||
| uint64_t f2; | ||
| uint64_t f3; | ||
| uint64_t f4; | ||
| uint64_t f5; | ||
| uint64_t f6; | ||
| uint64_t f7; | ||
| uint64_t f8; | ||
| uint64_t f9; | ||
| uint64_t f10; | ||
| uint64_t f11; | ||
| uint64_t f12; | ||
| uint64_t f13; | ||
| uint64_t f14; | ||
| uint64_t f15; | ||
| uint64_t f16; | ||
| uint64_t f17; | ||
| uint64_t f18; | ||
| uint64_t f19; | ||
| uint64_t f20; | ||
| uint64_t f21; | ||
| uint64_t f22; | ||
| uint64_t f23; | ||
| uint64_t f24; | ||
| uint64_t f25; | ||
| uint64_t f26; | ||
| uint64_t f27; | ||
| uint64_t f28; | ||
| uint64_t f29; | ||
| uint64_t f30; | ||
| uint64_t f31; | ||
| uint64_t fpscr; | ||
| } FPR; | ||
|
|
||
| //--------------------------------------------------------------------------- | ||
| // Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure. | ||
| //--------------------------------------------------------------------------- | ||
| #define DECLARE_REGISTER_INFOS_POWERPC_STRUCT | ||
| #include "RegisterInfos_powerpc.h" | ||
| #undef DECLARE_REGISTER_INFOS_POWERPC_STRUCT | ||
|
|
||
| RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(const ArchSpec &target_arch) : | ||
| RegisterInfoInterface(target_arch) | ||
| { | ||
| } | ||
|
|
||
| RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() | ||
| { | ||
| } | ||
|
|
||
| size_t | ||
| RegisterContextFreeBSD_powerpc::GetGPRSize() const | ||
| { | ||
| return sizeof(GPR64); | ||
| } | ||
|
|
||
| const RegisterInfo * | ||
| RegisterContextFreeBSD_powerpc::GetRegisterInfo() const | ||
| { | ||
| //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc); | ||
| llvm_unreachable("Abstract class!"); | ||
| return NULL; | ||
| } | ||
|
|
||
| uint32_t | ||
| RegisterContextFreeBSD_powerpc::GetRegisterCount () const | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(const ArchSpec &target_arch) : | ||
| RegisterContextFreeBSD_powerpc(target_arch) | ||
| { | ||
| } | ||
|
|
||
| RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() | ||
| { | ||
| } | ||
|
|
||
| size_t | ||
| RegisterContextFreeBSD_powerpc32::GetGPRSize() const | ||
| { | ||
| return sizeof(GPR32); | ||
| } | ||
|
|
||
| const RegisterInfo * | ||
| RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const | ||
| { | ||
| //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc); | ||
| return g_register_infos_powerpc32; | ||
| } | ||
|
|
||
| uint32_t | ||
| RegisterContextFreeBSD_powerpc32::GetRegisterCount () const | ||
| { | ||
| return static_cast<uint32_t> (sizeof (g_register_infos_powerpc32) / sizeof (g_register_infos_powerpc32 [0])); | ||
| } | ||
|
|
||
| RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(const ArchSpec &target_arch) : | ||
| RegisterContextFreeBSD_powerpc(target_arch) | ||
| { | ||
| } | ||
|
|
||
| RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() | ||
| { | ||
| } | ||
|
|
||
| size_t | ||
| RegisterContextFreeBSD_powerpc64::GetGPRSize() const | ||
| { | ||
| return sizeof(GPR64); | ||
| } | ||
|
|
||
| const RegisterInfo * | ||
| RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const | ||
| { | ||
| //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc); | ||
| return g_register_infos_powerpc64; | ||
| } | ||
|
|
||
| uint32_t | ||
| RegisterContextFreeBSD_powerpc64::GetRegisterCount () const | ||
| { | ||
| return static_cast<uint32_t> (sizeof (g_register_infos_powerpc64) / sizeof (g_register_infos_powerpc64 [0])); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| //===-- RegisterContextFreeBSD_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_RegisterContextFreeBSD_powerpc_H_ | ||
| #define liblldb_RegisterContextFreeBSD_powerpc_H_ | ||
|
|
||
| #include "RegisterContextPOSIX.h" | ||
|
|
||
| class RegisterContextFreeBSD_powerpc: | ||
| public lldb_private::RegisterInfoInterface | ||
| { | ||
| public: | ||
| RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch); | ||
| virtual ~RegisterContextFreeBSD_powerpc(); | ||
|
|
||
| size_t | ||
| GetGPRSize() const override; | ||
|
|
||
| const lldb_private::RegisterInfo * | ||
| GetRegisterInfo() const override; | ||
|
|
||
| uint32_t | ||
| GetRegisterCount() const override; | ||
| }; | ||
|
|
||
| class RegisterContextFreeBSD_powerpc32: | ||
| public RegisterContextFreeBSD_powerpc | ||
| { | ||
| public: | ||
| RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch); | ||
| virtual ~RegisterContextFreeBSD_powerpc32(); | ||
|
|
||
| size_t | ||
| GetGPRSize() const override; | ||
|
|
||
| const lldb_private::RegisterInfo * | ||
| GetRegisterInfo() const override; | ||
|
|
||
| uint32_t | ||
| GetRegisterCount() const override; | ||
| }; | ||
|
|
||
| class RegisterContextFreeBSD_powerpc64: | ||
| public RegisterContextFreeBSD_powerpc | ||
| { | ||
| public: | ||
| RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch); | ||
| virtual ~RegisterContextFreeBSD_powerpc64(); | ||
|
|
||
| size_t | ||
| GetGPRSize() const override; | ||
|
|
||
| const lldb_private::RegisterInfo * | ||
| GetRegisterInfo() const override; | ||
|
|
||
| uint32_t | ||
| GetRegisterCount() const override; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,273 @@ | ||
| //===-- RegisterContextPOSIX_powerpc.cpp -------------------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include <cstring> | ||
| #include <errno.h> | ||
| #include <stdint.h> | ||
|
|
||
| #include "lldb/Core/DataBufferHeap.h" | ||
| #include "lldb/Core/DataExtractor.h" | ||
| #include "lldb/Core/RegisterValue.h" | ||
| #include "lldb/Core/Scalar.h" | ||
| #include "lldb/Target/Target.h" | ||
| #include "lldb/Target/Thread.h" | ||
| #include "lldb/Host/Endian.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
||
| #include "RegisterContextPOSIX_powerpc.h" | ||
| #include "Plugins/Process/elf-core/ProcessElfCore.h" | ||
|
|
||
| using namespace lldb_private; | ||
| using namespace lldb; | ||
|
|
||
| static const | ||
| uint32_t g_gpr_regnums[] = | ||
| { | ||
| gpr_r0_powerpc, | ||
| gpr_r1_powerpc, | ||
| gpr_r2_powerpc, | ||
| gpr_r3_powerpc, | ||
| gpr_r4_powerpc, | ||
| gpr_r5_powerpc, | ||
| gpr_r6_powerpc, | ||
| gpr_r7_powerpc, | ||
| gpr_r8_powerpc, | ||
| gpr_r9_powerpc, | ||
| gpr_r10_powerpc, | ||
| gpr_r11_powerpc, | ||
| gpr_r12_powerpc, | ||
| gpr_r13_powerpc, | ||
| gpr_r14_powerpc, | ||
| gpr_r15_powerpc, | ||
| gpr_r16_powerpc, | ||
| gpr_r17_powerpc, | ||
| gpr_r18_powerpc, | ||
| gpr_r19_powerpc, | ||
| gpr_r20_powerpc, | ||
| gpr_r21_powerpc, | ||
| gpr_r22_powerpc, | ||
| gpr_r23_powerpc, | ||
| gpr_r24_powerpc, | ||
| gpr_r25_powerpc, | ||
| gpr_r26_powerpc, | ||
| gpr_r27_powerpc, | ||
| gpr_r28_powerpc, | ||
| gpr_r29_powerpc, | ||
| gpr_r30_powerpc, | ||
| gpr_r31_powerpc, | ||
| gpr_lr_powerpc, | ||
| gpr_cr_powerpc, | ||
| gpr_xer_powerpc, | ||
| gpr_ctr_powerpc, | ||
| gpr_pc_powerpc, | ||
| }; | ||
|
|
||
| static const | ||
| uint32_t g_fpr_regnums[] = | ||
| { | ||
| fpr_f0_powerpc, | ||
| fpr_f1_powerpc, | ||
| fpr_f2_powerpc, | ||
| fpr_f3_powerpc, | ||
| fpr_f4_powerpc, | ||
| fpr_f5_powerpc, | ||
| fpr_f6_powerpc, | ||
| fpr_f7_powerpc, | ||
| fpr_f8_powerpc, | ||
| fpr_f9_powerpc, | ||
| fpr_f10_powerpc, | ||
| fpr_f11_powerpc, | ||
| fpr_f12_powerpc, | ||
| fpr_f13_powerpc, | ||
| fpr_f14_powerpc, | ||
| fpr_f15_powerpc, | ||
| fpr_f16_powerpc, | ||
| fpr_f17_powerpc, | ||
| fpr_f18_powerpc, | ||
| fpr_f19_powerpc, | ||
| fpr_f20_powerpc, | ||
| fpr_f21_powerpc, | ||
| fpr_f22_powerpc, | ||
| fpr_f23_powerpc, | ||
| fpr_f24_powerpc, | ||
| fpr_f25_powerpc, | ||
| fpr_f26_powerpc, | ||
| fpr_f27_powerpc, | ||
| fpr_f28_powerpc, | ||
| fpr_f29_powerpc, | ||
| fpr_f30_powerpc, | ||
| fpr_f31_powerpc, | ||
| fpr_fpscr_powerpc, | ||
| }; | ||
|
|
||
| // Number of register sets provided by this context. | ||
| enum | ||
| { | ||
| k_num_register_sets = 2 | ||
| }; | ||
|
|
||
| static const RegisterSet | ||
| g_reg_sets_powerpc[k_num_register_sets] = | ||
| { | ||
| { "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums }, | ||
| { "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums }, | ||
| }; | ||
|
|
||
| bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg) | ||
| { | ||
| return reg <= k_num_gpr_registers_powerpc; // GPR's come first. | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextPOSIX_powerpc::IsFPR(unsigned reg) | ||
| { | ||
| // XXX | ||
| return (reg >= k_first_fpr) && (reg <= k_last_fpr); | ||
| } | ||
|
|
||
| RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread, | ||
| uint32_t concrete_frame_idx, | ||
| RegisterInfoInterface *register_info) | ||
| : RegisterContext(thread, concrete_frame_idx) | ||
| { | ||
| m_register_info_ap.reset(register_info); | ||
|
|
||
| // elf-core yet to support ReadFPR() | ||
| ProcessSP base = CalculateProcess(); | ||
| if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) | ||
| return; | ||
| } | ||
|
|
||
| RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() | ||
| { | ||
| } | ||
|
|
||
| void | ||
| RegisterContextPOSIX_powerpc::Invalidate() | ||
| { | ||
| } | ||
|
|
||
| void | ||
| RegisterContextPOSIX_powerpc::InvalidateAllRegisters() | ||
| { | ||
| } | ||
|
|
||
| unsigned | ||
| RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg) | ||
| { | ||
| assert(reg < k_num_registers_powerpc && "Invalid register number."); | ||
| return GetRegisterInfo()[reg].byte_offset; | ||
| } | ||
|
|
||
| unsigned | ||
| RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg) | ||
| { | ||
| assert(reg < k_num_registers_powerpc && "Invalid register number."); | ||
| return GetRegisterInfo()[reg].byte_size; | ||
| } | ||
|
|
||
| size_t | ||
| RegisterContextPOSIX_powerpc::GetRegisterCount() | ||
| { | ||
| size_t num_registers = k_num_registers_powerpc; | ||
| return num_registers; | ||
| } | ||
|
|
||
| size_t | ||
| RegisterContextPOSIX_powerpc::GetGPRSize() | ||
| { | ||
| return m_register_info_ap->GetGPRSize(); | ||
| } | ||
|
|
||
| const RegisterInfo * | ||
| RegisterContextPOSIX_powerpc::GetRegisterInfo() | ||
| { | ||
| // Commonly, this method is overridden and g_register_infos is copied and specialized. | ||
| // So, use GetRegisterInfo() rather than g_register_infos in this scope. | ||
| return m_register_info_ap->GetRegisterInfo (); | ||
| } | ||
|
|
||
| const RegisterInfo * | ||
| RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg) | ||
| { | ||
| if (reg < k_num_registers_powerpc) | ||
| return &GetRegisterInfo()[reg]; | ||
| else | ||
| return NULL; | ||
| } | ||
|
|
||
| size_t | ||
| RegisterContextPOSIX_powerpc::GetRegisterSetCount() | ||
| { | ||
| size_t sets = 0; | ||
| for (size_t set = 0; set < k_num_register_sets; ++set) | ||
| { | ||
| if (IsRegisterSetAvailable(set)) | ||
| ++sets; | ||
| } | ||
|
|
||
| return sets; | ||
| } | ||
|
|
||
| const RegisterSet * | ||
| RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set) | ||
| { | ||
| if (IsRegisterSetAvailable(set)) | ||
| return &g_reg_sets_powerpc[set]; | ||
| else | ||
| return NULL; | ||
| } | ||
|
|
||
| const char * | ||
| RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) | ||
| { | ||
| assert(reg < k_num_registers_powerpc && "Invalid register offset."); | ||
| return GetRegisterInfo()[reg].name; | ||
| } | ||
|
|
||
| lldb::ByteOrder | ||
| RegisterContextPOSIX_powerpc::GetByteOrder() | ||
| { | ||
| // Get the target process whose privileged thread was used for the register read. | ||
| lldb::ByteOrder byte_order = eByteOrderInvalid; | ||
| Process *process = CalculateProcess().get(); | ||
|
|
||
| if (process) | ||
| byte_order = process->GetByteOrder(); | ||
| return byte_order; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index) | ||
| { | ||
| size_t num_sets = k_num_register_sets; | ||
|
|
||
| return (set_index < num_sets); | ||
| } | ||
|
|
||
| // Used when parsing DWARF and EH frame information and any other | ||
| // object file sections that contain register numbers in them. | ||
| uint32_t | ||
| RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, | ||
| uint32_t num) | ||
| { | ||
| const uint32_t num_regs = GetRegisterCount(); | ||
|
|
||
| assert (kind < kNumRegisterKinds); | ||
| for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) | ||
| { | ||
| const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx); | ||
|
|
||
| if (reg_info->kinds[kind] == num) | ||
| return reg_idx; | ||
| } | ||
|
|
||
| return LLDB_INVALID_REGNUM; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| //===-- RegisterContextPOSIX_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_RegisterContextPOSIX_powerpc_H_ | ||
| #define liblldb_RegisterContextPOSIX_powerpc_H_ | ||
|
|
||
| #include "lldb/Core/Log.h" | ||
| #include "RegisterContextPOSIX.h" | ||
| #include "RegisterContext_powerpc.h" | ||
|
|
||
| class ProcessMonitor; | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // Internal codes for all powerpc registers. | ||
| // --------------------------------------------------------------------------- | ||
| enum | ||
| { | ||
| k_first_gpr_powerpc, | ||
| gpr_r0_powerpc = k_first_gpr_powerpc, | ||
| gpr_r1_powerpc, | ||
| gpr_r2_powerpc, | ||
| gpr_r3_powerpc, | ||
| gpr_r4_powerpc, | ||
| gpr_r5_powerpc, | ||
| gpr_r6_powerpc, | ||
| gpr_r7_powerpc, | ||
| gpr_r8_powerpc, | ||
| gpr_r9_powerpc, | ||
| gpr_r10_powerpc, | ||
| gpr_r11_powerpc, | ||
| gpr_r12_powerpc, | ||
| gpr_r13_powerpc, | ||
| gpr_r14_powerpc, | ||
| gpr_r15_powerpc, | ||
| gpr_r16_powerpc, | ||
| gpr_r17_powerpc, | ||
| gpr_r18_powerpc, | ||
| gpr_r19_powerpc, | ||
| gpr_r20_powerpc, | ||
| gpr_r21_powerpc, | ||
| gpr_r22_powerpc, | ||
| gpr_r23_powerpc, | ||
| gpr_r24_powerpc, | ||
| gpr_r25_powerpc, | ||
| gpr_r26_powerpc, | ||
| gpr_r27_powerpc, | ||
| gpr_r28_powerpc, | ||
| gpr_r29_powerpc, | ||
| gpr_r30_powerpc, | ||
| gpr_r31_powerpc, | ||
| gpr_lr_powerpc, | ||
| gpr_cr_powerpc, | ||
| gpr_xer_powerpc, | ||
| gpr_ctr_powerpc, | ||
| gpr_pc_powerpc, | ||
| k_last_gpr_powerpc = gpr_pc_powerpc, | ||
|
|
||
| k_first_fpr, | ||
| fpr_f0_powerpc = k_first_fpr, | ||
| fpr_f1_powerpc, | ||
| fpr_f2_powerpc, | ||
| fpr_f3_powerpc, | ||
| fpr_f4_powerpc, | ||
| fpr_f5_powerpc, | ||
| fpr_f6_powerpc, | ||
| fpr_f7_powerpc, | ||
| fpr_f8_powerpc, | ||
| fpr_f9_powerpc, | ||
| fpr_f10_powerpc, | ||
| fpr_f11_powerpc, | ||
| fpr_f12_powerpc, | ||
| fpr_f13_powerpc, | ||
| fpr_f14_powerpc, | ||
| fpr_f15_powerpc, | ||
| fpr_f16_powerpc, | ||
| fpr_f17_powerpc, | ||
| fpr_f18_powerpc, | ||
| fpr_f19_powerpc, | ||
| fpr_f20_powerpc, | ||
| fpr_f21_powerpc, | ||
| fpr_f22_powerpc, | ||
| fpr_f23_powerpc, | ||
| fpr_f24_powerpc, | ||
| fpr_f25_powerpc, | ||
| fpr_f26_powerpc, | ||
| fpr_f27_powerpc, | ||
| fpr_f28_powerpc, | ||
| fpr_f29_powerpc, | ||
| fpr_f30_powerpc, | ||
| fpr_f31_powerpc, | ||
| fpr_fpscr_powerpc, | ||
| k_last_fpr = fpr_fpscr_powerpc, | ||
|
|
||
| k_num_registers_powerpc, | ||
| k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1, | ||
| k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1, | ||
| }; | ||
|
|
||
| class RegisterContextPOSIX_powerpc | ||
| : public lldb_private::RegisterContext | ||
| { | ||
| public: | ||
| RegisterContextPOSIX_powerpc (lldb_private::Thread &thread, | ||
| uint32_t concrete_frame_idx, | ||
| lldb_private::RegisterInfoInterface *register_info); | ||
|
|
||
| ~RegisterContextPOSIX_powerpc(); | ||
|
|
||
| void | ||
| Invalidate(); | ||
|
|
||
| void | ||
| InvalidateAllRegisters(); | ||
|
|
||
| size_t | ||
| GetRegisterCount(); | ||
|
|
||
| virtual size_t | ||
| GetGPRSize(); | ||
|
|
||
| virtual unsigned | ||
| GetRegisterSize(unsigned reg); | ||
|
|
||
| virtual unsigned | ||
| GetRegisterOffset(unsigned reg); | ||
|
|
||
| const lldb_private::RegisterInfo * | ||
| GetRegisterInfoAtIndex(size_t reg); | ||
|
|
||
| size_t | ||
| GetRegisterSetCount(); | ||
|
|
||
| const lldb_private::RegisterSet * | ||
| GetRegisterSet(size_t set); | ||
|
|
||
| const char * | ||
| GetRegisterName(unsigned reg); | ||
|
|
||
| uint32_t | ||
| ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num); | ||
|
|
||
| protected: | ||
| uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers. | ||
| std::unique_ptr<lldb_private::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. | ||
| virtual bool | ||
| IsRegisterSetAvailable(size_t set_index); | ||
|
|
||
| virtual const lldb_private::RegisterInfo * | ||
| GetRegisterInfo(); | ||
|
|
||
| bool | ||
| IsGPR(unsigned reg); | ||
|
|
||
| bool | ||
| IsFPR(unsigned reg); | ||
|
|
||
| lldb::ByteOrder GetByteOrder(); | ||
|
|
||
| virtual bool ReadGPR() = 0; | ||
| virtual bool ReadFPR() = 0; | ||
| virtual bool WriteGPR() = 0; | ||
| virtual bool WriteFPR() = 0; | ||
| }; | ||
|
|
||
| #endif // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| //===-- RegisterContext_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_RegisterContext_powerpc_H_ | ||
| #define liblldb_RegisterContext_powerpc_H_ | ||
|
|
||
| // GCC and DWARF Register numbers (eRegisterKindGCC & eRegisterKindDWARF) | ||
| enum | ||
| { | ||
| gcc_dwarf_r0_powerpc = 0, | ||
| gcc_dwarf_r1_powerpc, | ||
| gcc_dwarf_r2_powerpc, | ||
| gcc_dwarf_r3_powerpc, | ||
| gcc_dwarf_r4_powerpc, | ||
| gcc_dwarf_r5_powerpc, | ||
| gcc_dwarf_r6_powerpc, | ||
| gcc_dwarf_r7_powerpc, | ||
| gcc_dwarf_r8_powerpc, | ||
| gcc_dwarf_r9_powerpc, | ||
| gcc_dwarf_r10_powerpc, | ||
| gcc_dwarf_r11_powerpc, | ||
| gcc_dwarf_r12_powerpc, | ||
| gcc_dwarf_r13_powerpc, | ||
| gcc_dwarf_r14_powerpc, | ||
| gcc_dwarf_r15_powerpc, | ||
| gcc_dwarf_r16_powerpc, | ||
| gcc_dwarf_r17_powerpc, | ||
| gcc_dwarf_r18_powerpc, | ||
| gcc_dwarf_r19_powerpc, | ||
| gcc_dwarf_r20_powerpc, | ||
| gcc_dwarf_r21_powerpc, | ||
| gcc_dwarf_r22_powerpc, | ||
| gcc_dwarf_r23_powerpc, | ||
| gcc_dwarf_r24_powerpc, | ||
| gcc_dwarf_r25_powerpc, | ||
| gcc_dwarf_r26_powerpc, | ||
| gcc_dwarf_r27_powerpc, | ||
| gcc_dwarf_r28_powerpc, | ||
| gcc_dwarf_r29_powerpc, | ||
| gcc_dwarf_r30_powerpc, | ||
| gcc_dwarf_r31_powerpc, | ||
| gcc_dwarf_f0_powerpc, | ||
| gcc_dwarf_f1_powerpc, | ||
| gcc_dwarf_f2_powerpc, | ||
| gcc_dwarf_f3_powerpc, | ||
| gcc_dwarf_f4_powerpc, | ||
| gcc_dwarf_f5_powerpc, | ||
| gcc_dwarf_f6_powerpc, | ||
| gcc_dwarf_f7_powerpc, | ||
| gcc_dwarf_f8_powerpc, | ||
| gcc_dwarf_f9_powerpc, | ||
| gcc_dwarf_f10_powerpc, | ||
| gcc_dwarf_f11_powerpc, | ||
| gcc_dwarf_f12_powerpc, | ||
| gcc_dwarf_f13_powerpc, | ||
| gcc_dwarf_f14_powerpc, | ||
| gcc_dwarf_f15_powerpc, | ||
| gcc_dwarf_f16_powerpc, | ||
| gcc_dwarf_f17_powerpc, | ||
| gcc_dwarf_f18_powerpc, | ||
| gcc_dwarf_f19_powerpc, | ||
| gcc_dwarf_f20_powerpc, | ||
| gcc_dwarf_f21_powerpc, | ||
| gcc_dwarf_f22_powerpc, | ||
| gcc_dwarf_f23_powerpc, | ||
| gcc_dwarf_f24_powerpc, | ||
| gcc_dwarf_f25_powerpc, | ||
| gcc_dwarf_f26_powerpc, | ||
| gcc_dwarf_f27_powerpc, | ||
| gcc_dwarf_f28_powerpc, | ||
| gcc_dwarf_f29_powerpc, | ||
| gcc_dwarf_f30_powerpc, | ||
| gcc_dwarf_f31_powerpc, | ||
| gcc_dwarf_cr_powerpc, | ||
| gcc_dwarf_fpscr_powerpc, | ||
| gcc_dwarf_xer_powerpc = 101, | ||
| gcc_dwarf_lr_powerpc = 108, | ||
| gcc_dwarf_ctr_powerpc, | ||
| gcc_dwarf_pc_powerpc, | ||
| }; | ||
|
|
||
| // GDB Register numbers (eRegisterKindGDB) | ||
| enum | ||
| { | ||
| gdb_r0_powerpc = 0, | ||
| gdb_r1_powerpc, | ||
| gdb_r2_powerpc, | ||
| gdb_r3_powerpc, | ||
| gdb_r4_powerpc, | ||
| gdb_r5_powerpc, | ||
| gdb_r6_powerpc, | ||
| gdb_r7_powerpc, | ||
| gdb_r8_powerpc, | ||
| gdb_r9_powerpc, | ||
| gdb_r10_powerpc, | ||
| gdb_r11_powerpc, | ||
| gdb_r12_powerpc, | ||
| gdb_r13_powerpc, | ||
| gdb_r14_powerpc, | ||
| gdb_r15_powerpc, | ||
| gdb_r16_powerpc, | ||
| gdb_r17_powerpc, | ||
| gdb_r18_powerpc, | ||
| gdb_r19_powerpc, | ||
| gdb_r20_powerpc, | ||
| gdb_r21_powerpc, | ||
| gdb_r22_powerpc, | ||
| gdb_r23_powerpc, | ||
| gdb_r24_powerpc, | ||
| gdb_r25_powerpc, | ||
| gdb_r26_powerpc, | ||
| gdb_r27_powerpc, | ||
| gdb_r28_powerpc, | ||
| gdb_r29_powerpc, | ||
| gdb_r30_powerpc, | ||
| gdb_r31_powerpc, | ||
| gdb_f0_powerpc, | ||
| gdb_f1_powerpc, | ||
| gdb_f2_powerpc, | ||
| gdb_f3_powerpc, | ||
| gdb_f4_powerpc, | ||
| gdb_f5_powerpc, | ||
| gdb_f6_powerpc, | ||
| gdb_f7_powerpc, | ||
| gdb_f8_powerpc, | ||
| gdb_f9_powerpc, | ||
| gdb_f10_powerpc, | ||
| gdb_f11_powerpc, | ||
| gdb_f12_powerpc, | ||
| gdb_f13_powerpc, | ||
| gdb_f14_powerpc, | ||
| gdb_f15_powerpc, | ||
| gdb_f16_powerpc, | ||
| gdb_f17_powerpc, | ||
| gdb_f18_powerpc, | ||
| gdb_f19_powerpc, | ||
| gdb_f20_powerpc, | ||
| gdb_f21_powerpc, | ||
| gdb_f22_powerpc, | ||
| gdb_f23_powerpc, | ||
| gdb_f24_powerpc, | ||
| gdb_f25_powerpc, | ||
| gdb_f26_powerpc, | ||
| gdb_f27_powerpc, | ||
| gdb_f28_powerpc, | ||
| gdb_f29_powerpc, | ||
| gdb_f30_powerpc, | ||
| gdb_f31_powerpc, | ||
| gdb_cr_powerpc, | ||
| gdb_fpscr_powerpc, | ||
| gdb_xer_powerpc = 101, | ||
| gdb_lr_powerpc = 108, | ||
| gdb_ctr_powerpc, | ||
| gdb_pc_powerpc, | ||
| }; | ||
|
|
||
| #endif // liblldb_RegisterContext_powerpc_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| //===-- RegisterInfos_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 <stddef.h> | ||
|
|
||
| // Computes the offset of the given GPR in the user data area. | ||
| #define GPR_OFFSET(regname) \ | ||
| (offsetof(GPR, regname)) | ||
| #define FPR_OFFSET(regname) \ | ||
| (offsetof(FPR, regname)) | ||
|
|
||
| #ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT | ||
|
|
||
| // Note that the size and offset will be updated by platform-specific classes. | ||
| #define DEFINE_GPR(reg, alt, lldb_kind) \ | ||
| { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \ | ||
| eFormatHex, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, gpr_##reg##_powerpc }, NULL, NULL } | ||
| #define DEFINE_FPR(reg, lldb_kind) \ | ||
| { #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \ | ||
| eFormatFloat, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, fpr_##reg##_powerpc }, NULL, NULL } | ||
|
|
||
| // General purpose registers. GCC, DWARF, Generic, GDB | ||
| #define POWERPC_REGS \ | ||
| DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \ | ||
| DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r3, "arg1",LLDB_REGNUM_GENERIC_ARG1), \ | ||
| DEFINE_GPR(r4, "arg2",LLDB_REGNUM_GENERIC_ARG2), \ | ||
| DEFINE_GPR(r5, "arg3",LLDB_REGNUM_GENERIC_ARG3), \ | ||
| DEFINE_GPR(r6, "arg4",LLDB_REGNUM_GENERIC_ARG4), \ | ||
| DEFINE_GPR(r7, "arg5",LLDB_REGNUM_GENERIC_ARG5), \ | ||
| DEFINE_GPR(r8, "arg6",LLDB_REGNUM_GENERIC_ARG6), \ | ||
| DEFINE_GPR(r9, "arg7",LLDB_REGNUM_GENERIC_ARG7), \ | ||
| DEFINE_GPR(r10, "arg8",LLDB_REGNUM_GENERIC_ARG8), \ | ||
| DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \ | ||
| DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \ | ||
| DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \ | ||
| DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \ | ||
| DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f3, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f4, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f5, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f6, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f7, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f8, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f9, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f10, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f11, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f12, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f13, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f14, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f15, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f16, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f17, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f18, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f19, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f20, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f21, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f22, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f23, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f24, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f25, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f26, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f27, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f28, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \ | ||
| DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \ | ||
| { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL }, | ||
| //{ NULL, NULL, sizeof(((GPR*)NULL)->r0), 0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_cfa_powerpc}, NULL, NULL} | ||
| static RegisterInfo | ||
| g_register_infos_powerpc64[] = | ||
| { | ||
| #define GPR GPR64 | ||
| POWERPC_REGS | ||
| #undef GPR | ||
| }; | ||
|
|
||
| static RegisterInfo | ||
| g_register_infos_powerpc32[] = | ||
| { | ||
| #define GPR GPR32 | ||
| POWERPC_REGS | ||
| #undef GPR | ||
| }; | ||
| static_assert((sizeof(g_register_infos_powerpc32) / sizeof(g_register_infos_powerpc32[0])) == k_num_registers_powerpc, | ||
| "g_register_infos_powerpc32 has wrong number of register infos"); | ||
| static_assert((sizeof(g_register_infos_powerpc64) / sizeof(g_register_infos_powerpc64[0])) == k_num_registers_powerpc, | ||
| "g_register_infos_powerpc64 has wrong number of register infos"); | ||
|
|
||
| #undef DEFINE_FPR | ||
| #undef DEFINE_GPR | ||
|
|
||
| #endif // DECLARE_REGISTER_INFOS_POWERPC_STRUCT | ||
|
|
||
| #undef GPR_OFFSET | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| //===-- RegisterContextCorePOSIX_powerpc.cpp ---------------------*- C++ -*-===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "lldb/Core/DataExtractor.h" | ||
| #include "lldb/Core/RegisterValue.h" | ||
| #include "lldb/Target/Thread.h" | ||
| #include "RegisterContextPOSIX.h" | ||
| #include "RegisterContextPOSIXCore_powerpc.h" | ||
|
|
||
| using namespace lldb_private; | ||
|
|
||
| RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread, | ||
| RegisterInfoInterface *register_info, | ||
| const DataExtractor &gpregset, | ||
| const DataExtractor &fpregset) | ||
| : RegisterContextPOSIX_powerpc(thread, 0, register_info) | ||
| { | ||
| m_gpr_buffer.reset(new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize())); | ||
| m_gpr.SetData(m_gpr_buffer); | ||
| m_gpr.SetByteOrder(gpregset.GetByteOrder()); | ||
| m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); | ||
| m_fpr.SetData(m_fpr_buffer); | ||
| m_fpr.SetByteOrder(fpregset.GetByteOrder()); | ||
| } | ||
|
|
||
| RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() | ||
| { | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::ReadGPR() | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::ReadFPR() | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::WriteGPR() | ||
| { | ||
| assert(0); | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::WriteFPR() | ||
| { | ||
| assert(0); | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) | ||
| { | ||
| lldb::offset_t offset = reg_info->byte_offset; | ||
| if (reg_info->name[0] == 'f') { | ||
| uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size); | ||
| if (offset == reg_info->byte_offset + reg_info->byte_size) | ||
| { | ||
| value = v; | ||
| return true; | ||
| } | ||
| } else { | ||
| uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); | ||
| if (offset == reg_info->byte_offset + reg_info->byte_size) | ||
| { | ||
| if (reg_info->byte_size < sizeof(v)) | ||
| value = (uint32_t)v; | ||
| else | ||
| value = v; | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| bool | ||
| RegisterContextCorePOSIX_powerpc::HardwareSingleStep(bool enable) | ||
| { | ||
| return false; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| //===-- RegisterContextCorePOSIX_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_RegisterContextCorePOSIX_powerpc_H_ | ||
| #define liblldb_RegisterContextCorePOSIX_powerpc_H_ | ||
|
|
||
| #include "lldb/Core/DataBufferHeap.h" | ||
| #include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" | ||
|
|
||
| class RegisterContextCorePOSIX_powerpc : | ||
| public RegisterContextPOSIX_powerpc | ||
| { | ||
| public: | ||
| RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread, | ||
| lldb_private::RegisterInfoInterface *register_info, | ||
| const lldb_private::DataExtractor &gpregset, | ||
| const lldb_private::DataExtractor &fpregset); | ||
|
|
||
| ~RegisterContextCorePOSIX_powerpc(); | ||
|
|
||
| virtual bool | ||
| ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); | ||
|
|
||
| virtual 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); | ||
|
|
||
| bool | ||
| HardwareSingleStep(bool enable); | ||
|
|
||
| protected: | ||
| bool | ||
| ReadGPR(); | ||
|
|
||
| bool | ||
| ReadFPR(); | ||
|
|
||
| bool | ||
| WriteGPR(); | ||
|
|
||
| bool | ||
| WriteFPR(); | ||
|
|
||
| private: | ||
| lldb::DataBufferSP m_gpr_buffer; | ||
| lldb::DataBufferSP m_fpr_buffer; | ||
| lldb_private::DataExtractor m_gpr; | ||
| lldb_private::DataExtractor m_fpr; | ||
| }; | ||
|
|
||
| #endif // #ifndef liblldb_RegisterContextCorePOSIX_powerpc_H_ |