This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: fix bug in SPU sbrk


The Cell SPU ABI defines using word element 1 of the stack pointer
register to keep track of the number of available stack bytes.
malloc/sbrk is meant to update this (see patch) so that GCC's stack
check instrumentation can detect stack/heap collisions.

Okay to commit?

Ben

2007-03-01  Ben Elliston  <bje@au.ibm.com>

        * spu/sbrk.c (sbrk): Adjust the stack pointer vector correctly so
        that GCC runtime stack checking works.  Handle the backchain, too.

Index: spu/sbrk.c
===================================================================
RCS file: /cvs/src/src/libgloss/spu/sbrk.c,v
retrieving revision 1.1
diff -u -p -r1.1 sbrk.c
--- spu/sbrk.c  16 Aug 2006 21:15:03 -0000      1.1
+++ spu/sbrk.c  1 Mar 2007 04:22:32 -0000
@@ -32,6 +32,7 @@ Author: Andreas Neukoetter (ti95neuk@de.
 
 #include <sys/types.h>
 #include <errno.h>
+#include <spu_intrinsics.h>
 
 extern int errno;
 
@@ -44,20 +45,39 @@ sbrk (ptrdiff_t increment)
 {
        static caddr_t heap_ptr = NULL;
        caddr_t base;
+       vector unsigned int sp_reg, sp_delta;
+       vector unsigned int *sp_ptr;
 
+       /* The stack pointer register.  */
+       volatile register vector unsigned int sp_r1 __asm__("1");
+
        if (heap_ptr == NULL)
-         {
-                 heap_ptr = (caddr_t) & _end;
-         }
+         heap_ptr = (caddr_t) & _end;
+
        if (((RAMSIZE - STACKSIZE) - (int) heap_ptr) >= increment)
          {
-                 base = heap_ptr;
-                 heap_ptr += increment;
-                 return (base);
+           base = heap_ptr;
+           heap_ptr += increment;
+           
+           sp_delta = (vector unsigned int) spu_insert (increment, spu_splats (0), 1);
+
+           /* Subtract sp_delta from the SP limit (word 1).  */
+           sp_r1 = spu_sub (sp_r1, sp_delta);
+           
+           /* Fix-up backchain.  */
+           sp_ptr = (vector unsigned int *) spu_extract (sp_r1, 0);
+           do
+             {
+               sp_reg = *sp_ptr;
+               *sp_ptr = (vector unsigned int) spu_sub (sp_reg, sp_delta);
+             }
+           while ((sp_ptr = (vector unsigned int *) spu_extract (sp_reg, 0)));
+
+           return (base);
          }
        else
          {
-                 errno = ENOMEM;
-                 return ((void *) -1);
+           errno = ENOMEM;
+           return ((void *) -1);
          }
 }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]