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])
|
AC_DEFINE([BACKTRACE_METHOD_TEXT],["x86 custom backtrace"],[Define backtrace type])
|
||||||
have_backtrace=yes
|
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
|
esac
|
||||||
|
|
||||||
# Do we have a libdl with dladdr?
|
# 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;
|
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
|
#else
|
||||||
|
|
||||||
#warning Undefined BACKTRACE_METHOD_*
|
#warning Undefined BACKTRACE_METHOD_*
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ bool GetThreadBacktraceContext( uint64_t ThreadID, BacktraceContext *ctx )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CPU_X86_64) || defined(CPU_X86)
|
||||||
user_regs_struct regs;
|
user_regs_struct regs;
|
||||||
if( ptrace( PTRACE_GETREGS, pid_t(ThreadID), NULL, ®s ) == -1 )
|
if( ptrace( PTRACE_GETREGS, pid_t(ThreadID), NULL, ®s ) == -1 )
|
||||||
return false;
|
return false;
|
||||||
@@ -224,10 +225,19 @@ bool GetThreadBacktraceContext( uint64_t ThreadID, BacktraceContext *ctx )
|
|||||||
ctx->ip = (void *) regs.rip;
|
ctx->ip = (void *) regs.rip;
|
||||||
ctx->bp = (void *) regs.rbp;
|
ctx->bp = (void *) regs.rbp;
|
||||||
ctx->sp = (void *) regs.rsp;
|
ctx->sp = (void *) regs.rsp;
|
||||||
#elif defined(CPU_X86)
|
#else
|
||||||
ctx->ip = (void *) regs.eip;
|
ctx->ip = (void *) regs.eip;
|
||||||
ctx->bp = (void *) regs.ebp;
|
ctx->bp = (void *) regs.ebp;
|
||||||
ctx->sp = (void *) regs.esp;
|
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
|
#else
|
||||||
#error GetThreadBacktraceContext: which arch?
|
#error GetThreadBacktraceContext: which arch?
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user