diff --git a/stepmania/autoconf/m4/backtrace.m4 b/stepmania/autoconf/m4/backtrace.m4 index 582aba886b..f1f13afc8a 100644 --- a/stepmania/autoconf/m4/backtrace.m4 +++ b/stepmania/autoconf/m4/backtrace.m4 @@ -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? diff --git a/stepmania/src/archutils/Unix/Backtrace.cpp b/stepmania/src/archutils/Unix/Backtrace.cpp index 250cad36d1..c86e048abf 100644 --- a/stepmania/src/archutils/Unix/Backtrace.cpp +++ b/stepmania/src/archutils/Unix/Backtrace.cpp @@ -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 + +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_* diff --git a/stepmania/src/archutils/Unix/LinuxThreadHelpers.cpp b/stepmania/src/archutils/Unix/LinuxThreadHelpers.cpp index bce7f99840..035f6ac31a 100644 --- a/stepmania/src/archutils/Unix/LinuxThreadHelpers.cpp +++ b/stepmania/src/archutils/Unix/LinuxThreadHelpers.cpp @@ -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