forked from OSchip/llvm-project
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:
parent
1e2cf0dd4b
commit
6256a0ea8f
|
@ -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 \
|
||||
|
|
|
@ -80,6 +80,8 @@ set( LLDB_USED_LIBS
|
|||
lldbPluginABIMacOSX_i386
|
||||
lldbPluginABISysV_x86_64
|
||||
lldbPluginABISysV_hexagon
|
||||
lldbPluginABISysV_ppc
|
||||
lldbPluginABISysV_ppc64
|
||||
lldbPluginInstructionARM
|
||||
lldbPluginInstructionARM64
|
||||
lldbPluginObjectFilePECOFF
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
@ -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_
|
|
@ -0,0 +1,5 @@
|
|||
set(LLVM_NO_RTTI 1)
|
||||
|
||||
add_lldb_library(lldbPluginABISysV_ppc
|
||||
ABISysV_ppc.cpp
|
||||
)
|
|
@ -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
|
@ -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_
|
|
@ -0,0 +1,5 @@
|
|||
set(LLVM_NO_RTTI 1)
|
||||
|
||||
add_lldb_library(lldbPluginABISysV_ppc64
|
||||
ABISysV_ppc64.cpp
|
||||
)
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -12,5 +12,6 @@ add_lldb_library(lldbPluginProcessPOSIX
|
|||
ProcessPOSIXLog.cpp
|
||||
RegisterContextPOSIXProcessMonitor_arm64.cpp
|
||||
RegisterContextPOSIXProcessMonitor_mips64.cpp
|
||||
RegisterContextPOSIXProcessMonitor_powerpc.cpp
|
||||
RegisterContextPOSIXProcessMonitor_x86.cpp
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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]));
|
||||
}
|
|
@ -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
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_
|
|
@ -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_
|
|
@ -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
|
||||
|
|
@ -6,5 +6,6 @@ add_lldb_library(lldbPluginProcessElfCore
|
|||
ProcessElfCore.cpp
|
||||
ThreadElfCore.cpp
|
||||
RegisterContextPOSIXCore_mips64.cpp
|
||||
RegisterContextPOSIXCore_powerpc.cpp
|
||||
RegisterContextPOSIXCore_x86_64.cpp
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue