Initial linux ppc backtrace implementation.
This commit is contained in:
@@ -56,6 +56,11 @@ AC_DEFUN([SM_CHECK_CRASH_HANDLER],
|
||||
AC_DEFINE([BACKTRACE_METHOD_TEXT],["x86 custom backtrace"],[Define backtrace type])
|
||||
have_backtrace=yes
|
||||
;;
|
||||
powerpc-*-linux* )
|
||||
AC_DEFINE([BACKTRACE_METHOD_PPC_LINUX],[1],[Define backtrace type])
|
||||
AC_DEFINE([BACKTRACE_METHOD_TEXT],["ppc custom backtrace"],[Define backtrace type])
|
||||
have_backtrace=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
# Do we have a libdl with dladdr?
|
||||
|
||||
@@ -466,6 +466,51 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
|
||||
buf[i] = NULL;
|
||||
}
|
||||
|
||||
#elif defined(BACKTRACE_METHOD_PPC_LINUX)
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
struct Frame
|
||||
{
|
||||
Frame *stackPointer;
|
||||
void *linkReg;
|
||||
};
|
||||
|
||||
void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc )
|
||||
{
|
||||
// Wow, this is an ugly structure...
|
||||
ctx->PC = (void *)uc->uc_mcontext.uc_regs->gregs[PT_NIP];
|
||||
ctx->FramePtr = (const Frame *)uc->uc_mcontext.uc_regs->gregs[PT_R1];
|
||||
}
|
||||
|
||||
void InitializeBacktrace() { }
|
||||
|
||||
void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
|
||||
{
|
||||
BacktraceContext CurrentCtx;
|
||||
|
||||
if( ctx == NULL )
|
||||
{
|
||||
ctx = &CurrentCtx;
|
||||
|
||||
register void *r1 __asm__("1");
|
||||
CurrentCtx.FramePtr = (const Frame *)r1;
|
||||
CurrentCtx.PC = NULL;
|
||||
}
|
||||
|
||||
const Frame *frame = (const Frame *)ctx->FramePtr;
|
||||
unsigned i = 0;
|
||||
|
||||
if( ctx->PC && i < size-1 )
|
||||
buf[i++] = ctx->PC;
|
||||
|
||||
while( frame && i < size-1 )
|
||||
{
|
||||
if( frame->linkReg )
|
||||
buf[i++] = frame->linkReg;
|
||||
}
|
||||
buf[i] = NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#warning Undefined BACKTRACE_METHOD_*
|
||||
|
||||
@@ -215,6 +215,7 @@ bool GetThreadBacktraceContext( uint64_t ThreadID, BacktraceContext *ctx )
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(CPU_X86_64) || defined(CPU_X86)
|
||||
user_regs_struct regs;
|
||||
if( ptrace( PTRACE_GETREGS, pid_t(ThreadID), NULL, ®s ) == -1 )
|
||||
return false;
|
||||
@@ -224,10 +225,19 @@ bool GetThreadBacktraceContext( uint64_t ThreadID, BacktraceContext *ctx )
|
||||
ctx->ip = (void *) regs.rip;
|
||||
ctx->bp = (void *) regs.rbp;
|
||||
ctx->sp = (void *) regs.rsp;
|
||||
#elif defined(CPU_X86)
|
||||
#else
|
||||
ctx->ip = (void *) regs.eip;
|
||||
ctx->bp = (void *) regs.ebp;
|
||||
ctx->sp = (void *) regs.esp;
|
||||
#endif
|
||||
#elif defined(CPU_PPC)
|
||||
errno = 0;
|
||||
ctx->FramePtr = (const Frame *)ptrace( PTRACE_PEEKUSER, pid_t(ThreadID), (void *)(PT_R1<<2), 0 );
|
||||
if( errno )
|
||||
return false;
|
||||
ctx->PC = (void *)ptrace( PTRACE_PEEKUSER, pid_t(ThreadID), (void *)(PT_NIP<<2), 0 );
|
||||
if( errno )
|
||||
return false;
|
||||
#else
|
||||
#error GetThreadBacktraceContext: which arch?
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user