First cut of PowerPC(64) support in LLDB.

Summary:
This adds preliminary support for PowerPC/PowerPC64, for FreeBSD.  There are
some issues still:

 * Breakpoints don't work well on powerpc64.
 * Shared libraries don't yet get loaded for a 32-bit process on powerpc64 host.
 * Backtraces don't work.  This is due to PowerPC ABI using a backchain pointer
   in memory, instead of a dedicated frame pointer register for the backchain.
 * Breakpoints on functions without debug info may not work correctly for 32-bit
   powerpc.

Reviewers: emaste, tfiala, jingham, clayborg

Reviewed By: clayborg

Subscribers: emaste, lldb-commits

Differential Revision: http://reviews.llvm.org/D5988

llvm-svn: 220944
This commit is contained in:
Justin Hibbits 2014-10-31 02:34:28 +00:00
parent 1e2cf0dd4b
commit 6256a0ea8f
38 changed files with 4260 additions and 4 deletions

View File

@ -34,6 +34,7 @@ USEDLIBS = lldbAPI.a \
lldbPluginABIMacOSX_arm.a \
lldbPluginABIMacOSX_arm64.a \
lldbPluginABIMacOSX_i386.a \
lldbPluginABISysV_ppc64.a \
lldbPluginABISysV_x86_64.a \
lldbPluginABISysV_hexagon.a \
lldbPluginDisassemblerLLVM.a \

View File

@ -80,6 +80,8 @@ set( LLDB_USED_LIBS
lldbPluginABIMacOSX_i386
lldbPluginABISysV_x86_64
lldbPluginABISysV_hexagon
lldbPluginABISysV_ppc
lldbPluginABISysV_ppc64
lldbPluginInstructionARM
lldbPluginInstructionARM64
lldbPluginObjectFilePECOFF

View File

@ -19,6 +19,7 @@
#include "llvm/Support/ELF.h"
#include "llvm/Support/Host.h"
#include "lldb/Utility/SafeMachO.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StringList.h"
#include "lldb/Host/Endian.h"
@ -84,7 +85,7 @@ static const CoreDefinition g_core_definitions[] =
{ eByteOrderBig , 8, 4, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64 , "mips64" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "powerpc" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" },
@ -98,7 +99,7 @@ static const CoreDefinition g_core_definitions[] =
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" },
{ eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" },
{ eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" },
{ eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "powerpc64" },
{ eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
{ eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },

View File

@ -286,6 +286,49 @@ Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
return false;
}
static lldb::DataBufferSP
GetAuxvData32(lldb_private::Process *process)
{
struct {
uint32_t ps_argvstr;
int ps_nargvstr;
uint32_t ps_envstr;
int ps_nenvstr;
} ps_strings;
void *ps_strings_addr, *auxv_addr;
struct privElf32_Auxinfo { int a_type; unsigned int a_val; } aux_info32[AT_COUNT];
struct ptrace_io_desc pid;
DataBufferSP buf_sp;
std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
ps_strings_addr = (void *)0xffffdff0;
pid.piod_op = PIOD_READ_D;
pid.piod_addr = &ps_strings;
pid.piod_offs = ps_strings_addr;
pid.piod_len = sizeof(ps_strings);
if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, 0)) {
perror("failed to fetch ps_strings");
buf_ap.release();
goto done;
}
auxv_addr = (void *)(ps_strings.ps_envstr + sizeof(uint32_t) * (ps_strings.ps_nenvstr + 1));
pid.piod_addr = aux_info32;
pid.piod_offs = auxv_addr;
pid.piod_len = sizeof(aux_info32);
if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, 0)) {
perror("failed to fetch aux_info");
buf_ap.release();
goto done;
}
memcpy(buf_ap->GetBytes(), aux_info32, pid.piod_len);
buf_sp.reset(buf_ap.release());
done:
return buf_sp;
}
lldb::DataBufferSP
Host::GetAuxvData(lldb_private::Process *process)
{
@ -296,6 +339,10 @@ Host::GetAuxvData(lldb_private::Process *process)
struct ps_strings ps_strings;
struct ptrace_io_desc pid;
DataBufferSP buf_sp;
if (process->GetAddressByteSize() < HostInfo::GetArchitecture().GetAddressByteSize())
return GetAuxvData32(process);
std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
if (::sysctl(mib, 2, &ps_strings_addr, &ps_strings_size, NULL, 0) == 0) {

View File

@ -1,4 +1,6 @@
add_subdirectory(SysV-hexagon)
add_subdirectory(SysV-ppc64)
add_subdirectory(SysV-ppc)
add_subdirectory(SysV-x86_64)
add_subdirectory(MacOSX-i386)
add_subdirectory(MacOSX-arm)

File diff suppressed because it is too large Load Diff

View File

@ -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_

View File

@ -0,0 +1,5 @@
set(LLVM_NO_RTTI 1)
add_lldb_library(lldbPluginABISysV_ppc
ABISysV_ppc.cpp
)

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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_

View File

@ -0,0 +1,5 @@
set(LLVM_NO_RTTI 1)
add_lldb_library(lldbPluginABISysV_ppc64
ABISysV_ppc64.cpp
)

View File

@ -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

View File

@ -558,6 +558,13 @@ DynamicLoaderPOSIXDYLD::GetEntryPoint()
return LLDB_INVALID_ADDRESS;
m_entry_point = static_cast<addr_t>(I->value);
const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
// On ppc64, the entry point is actually a descriptor. Dereference it.
if (arch.GetMachine() == llvm::Triple::ppc64)
m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
return m_entry_point;
}

View File

@ -13,7 +13,7 @@ include $(LLDB_LEVEL)/../../Makefile.config
PARALLEL_DIRS := ABI/MacOSX-arm ABI/MacOSX-arm64 ABI/MacOSX-i386 ABI/SysV-x86_64 \
ABI/SysV-hexagon \
ABI/SysV-hexagon ABI/SysV-ppc64 \
Disassembler/llvm \
ObjectContainer/BSD-Archive ObjectFile/ELF ObjectFile/PECOFF \
ObjectFile/JIT SymbolFile/DWARF SymbolFile/Symtab Process/Utility \

View File

@ -173,6 +173,12 @@ ELFHeader::GetRelocationJumpSlotType() const
default:
assert(false && "architecture not supported");
break;
case EM_PPC:
slot = R_PPC_JMP_SLOT;
break;
case EM_PPC64:
slot = R_PPC64_JMP_SLOT;
break;
case EM_386:
case EM_486:
slot = R_386_JUMP_SLOT;

View File

@ -1724,6 +1724,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
static ConstString rodata1_section_name(".rodata1");
static ConstString data2_section_name(".data1");
static ConstString bss_section_name(".bss");
static ConstString opd_section_name(".opd"); // For ppc64
//StreamFile strm(stdout, false);
unsigned i;

View File

@ -326,6 +326,13 @@ PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite
trap_opcode_size = sizeof(g_i386_opcode);
}
break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
{
static const uint8_t g_ppc_opcode[] = { 0x7f, 0xe0, 0x00, 0x08 };
trap_opcode = g_ppc_opcode;
trap_opcode_size = sizeof(g_ppc_opcode);
}
}
if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))

View File

@ -113,6 +113,7 @@ PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
log->Printf("PT_GETREGS: ax=0x%lx", r->r_rax);
}
#endif
#ifndef __powerpc__
if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
struct dbreg *r = (struct dbreg *) addr;
char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
@ -120,6 +121,7 @@ PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
for (int i = 0; i <= 7; i++)
log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
}
#endif
}
return result;

View File

@ -12,5 +12,6 @@ add_lldb_library(lldbPluginProcessPOSIX
ProcessPOSIXLog.cpp
RegisterContextPOSIXProcessMonitor_arm64.cpp
RegisterContextPOSIXProcessMonitor_mips64.cpp
RegisterContextPOSIXProcessMonitor_powerpc.cpp
RegisterContextPOSIXProcessMonitor_x86.cpp
)

View File

@ -34,12 +34,14 @@
#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"
@ -167,6 +169,14 @@ POSIXThread::GetRegisterContext()
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;
@ -229,6 +239,14 @@ POSIXThread::GetRegisterContext()
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:
{
@ -624,6 +642,8 @@ POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
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:
{
@ -655,6 +675,8 @@ POSIXThread::GetRegisterName(unsigned reg)
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);

View File

@ -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;
}

View File

@ -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

View File

@ -16,6 +16,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextDummy.cpp
RegisterContextFreeBSD_i386.cpp
RegisterContextFreeBSD_mips64.cpp
RegisterContextFreeBSD_powerpc.cpp
RegisterContextFreeBSD_x86_64.cpp
RegisterContextHistory.cpp
RegisterContextLinux_arm64.cpp
@ -29,6 +30,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextMemory.cpp
RegisterContextPOSIX_arm64.cpp
RegisterContextPOSIX_mips64.cpp
RegisterContextPOSIX_powerpc.cpp
RegisterContextPOSIX_x86.cpp
RegisterContextThreadMemory.cpp
StopInfoMachException.cpp

View File

@ -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]));
}

View File

@ -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

View File

@ -149,7 +149,8 @@ RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info,
// TOOD: need a better way to detect when "long double" types are
// the same bytes size as "double"
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && !defined(__mips__)
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && \
!defined(__mips__) && !defined(__powerpc__)
case sizeof (long double):
if (sizeof (long double) == sizeof(uint32_t))
{

View File

@ -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;
}

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -6,5 +6,6 @@ add_lldb_library(lldbPluginProcessElfCore
ProcessElfCore.cpp
ThreadElfCore.cpp
RegisterContextPOSIXCore_mips64.cpp
RegisterContextPOSIXCore_powerpc.cpp
RegisterContextPOSIXCore_x86_64.cpp
)

View File

@ -420,6 +420,7 @@ ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
{
lldb::offset_t offset = 0;
bool lp64 = (arch.GetMachine() == llvm::Triple::mips64 ||
arch.GetMachine() == llvm::Triple::ppc64 ||
arch.GetMachine() == llvm::Triple::x86_64);
int pr_version = data.GetU32(&offset);

View File

@ -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;
}

View File

@ -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_

View File

@ -19,8 +19,10 @@
#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 "RegisterContextPOSIXCore_mips64.h"
#include "RegisterContextPOSIXCore_powerpc.h"
#include "RegisterContextPOSIXCore_x86_64.h"
using namespace lldb;
@ -94,6 +96,12 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
{
switch (arch.GetMachine())
{
case llvm::Triple::ppc:
reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
break;
case llvm::Triple::ppc64:
reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
break;
case llvm::Triple::mips64:
reg_interface = new RegisterContextFreeBSD_mips64(arch);
break;
@ -138,6 +146,10 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
case llvm::Triple::mips64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data));
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));

View File

@ -2281,6 +2281,8 @@ Thread::GetUnwinder ()
case llvm::Triple::aarch64:
case llvm::Triple::thumb:
case llvm::Triple::mips64:
case llvm::Triple::ppc64:
case llvm::Triple::ppc:
case llvm::Triple::hexagon:
m_unwinder_ap.reset (new UnwindLLDB (*this));
break;

View File

@ -31,6 +31,8 @@
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
#include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
#include "Plugins/ABI/SysV-ppc/ABISysV_ppc.h"
#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
@ -132,6 +134,8 @@ lldb_private::Initialize ()
ABIMacOSX_arm::Initialize();
ABIMacOSX_arm64::Initialize();
ABISysV_x86_64::Initialize();
ABISysV_ppc::Initialize();
ABISysV_ppc64::Initialize();
DisassemblerLLVMC::Initialize();
ObjectContainerBSDArchive::Initialize();
ObjectFileELF::Initialize();
@ -225,6 +229,7 @@ lldb_private::Terminate ()
ABIMacOSX_arm::Terminate();
ABIMacOSX_arm64::Terminate();
ABISysV_x86_64::Terminate();
ABISysV_ppc64::Terminate();
DisassemblerLLVMC::Terminate();
ObjectContainerBSDArchive::Terminate();
ObjectFileELF::Terminate();