about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/powerpc/powerpc32/backtrace.c17
-rw-r--r--sysdeps/powerpc/powerpc64/backtrace.c17
2 files changed, 20 insertions, 14 deletions
diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c
index b60ac329fd..394062136c 100644
--- a/sysdeps/powerpc/powerpc32/backtrace.c
+++ b/sysdeps/powerpc/powerpc32/backtrace.c
@@ -52,10 +52,10 @@ struct signal_frame_32 {
 };
 
 static inline int
-is_sigtramp_address (unsigned int nip)
+is_sigtramp_address (void *nip)
 {
 #ifdef SHARED
-  if (nip == (unsigned int)__vdso_sigtramp32)
+  if (nip == VDSO_SYMBOL (sigtramp32))
     return 1;
 #endif
   return 0;
@@ -69,10 +69,10 @@ struct rt_signal_frame_32 {
 };
 
 static inline int
-is_sigtramp_address_rt (unsigned int nip)
+is_sigtramp_address_rt (void * nip)
 {
 #ifdef SHARED
-  if (nip == (unsigned int)__vdso_sigtramp_rt32)
+  if (nip == VDSO_SYMBOL (sigtramp_rt32))
     return 1;
 #endif
   return 0;
@@ -100,20 +100,23 @@ __backtrace (void **array, int size)
 
       /* Check if the symbol is the signal trampoline and get the interrupted
        * symbol address from the trampoline saved area.  */
-      if (is_sigtramp_address ((unsigned int)current->return_address))
+      if (is_sigtramp_address (current->return_address))
 	{
 	  struct signal_frame_32 *sigframe =
 	    (struct signal_frame_32*) current;
           gregset = &sigframe->mctx.gregs;
         }
-      else if (is_sigtramp_address_rt ((unsigned int)current->return_address))
+      else if (is_sigtramp_address_rt (current->return_address))
 	{
 	  struct rt_signal_frame_32 *sigframe =
             (struct rt_signal_frame_32*) current;
           gregset = &sigframe->uc.uc_mcontext.uc_regs->gregs;
         }
       if (gregset)
-	array[++count] = (void*)((*gregset)[PT_NIP]);
+	{
+	  array[++count] = (void*)((*gregset)[PT_NIP]);
+	  current = (void*)((*gregset)[PT_R1]);
+	}
     }
 
   /* It's possible the second-last stack frame can't return
diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c
index 83b963e930..723948d78f 100644
--- a/sysdeps/powerpc/powerpc64/backtrace.c
+++ b/sysdeps/powerpc/powerpc64/backtrace.c
@@ -16,10 +16,12 @@
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, see <http://www.gnu.org/licenses/>.  */
 
-#include <execinfo.h>
 #include <stddef.h>
 #include <string.h>
 #include <signal.h>
+#include <stdint.h>
+
+#include <execinfo.h>
 #include <libc-vdso.h>
 
 /* This is the stack layout we see with every stack frame.
@@ -37,7 +39,7 @@
 struct layout
 {
   struct layout *next;
-  long condition_register;
+  long int condition_register;
   void *return_address;
 };
 
@@ -47,16 +49,16 @@ struct layout
    dummy frame to make it look like it has a caller.  */
 struct signal_frame_64 {
 #define SIGNAL_FRAMESIZE 128
-  char            dummy[SIGNAL_FRAMESIZE];
+  char dummy[SIGNAL_FRAMESIZE];
   struct ucontext uc;
   /* We don't care about the rest, since the IP value is at 'uc' field.  */
 };
 
 static inline int
-is_sigtramp_address (unsigned long nip)
+is_sigtramp_address (void *nip)
 {
 #ifdef SHARED
-  if (nip == (unsigned long)__vdso_sigtramp_rt64)
+  if (nip == VDSO_SYMBOL (sigtramp_rt64))
     return 1;
 #endif
   return 0;
@@ -82,10 +84,11 @@ __backtrace (void **array, int size)
 
       /* Check if the symbol is the signal trampoline and get the interrupted
        * symbol address from the trampoline saved area.  */
-      if (is_sigtramp_address ((unsigned long)current->return_address))
+      if (is_sigtramp_address (current->return_address))
         {
 	  struct signal_frame_64 *sigframe = (struct signal_frame_64*) current;
-          array[++count] = (void*)sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
+          array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
+	  current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1];
 	}
     }