Initial linux ppc backtrace implementation.

This commit is contained in:
Steve Checkoway
2006-04-05 00:49:56 +00:00
parent 79a9377506
commit e13fc56198
3 changed files with 61 additions and 1 deletions
+5
View File
@@ -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, &regs ) == -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