tilegx32: fix various bugs in setcontext/getcontext/swapcontext
authorChris Metcalf <cmetcalf@tilera.com>
Wed, 16 May 2012 17:52:36 +0000 (13:52 -0400)
committerChris Metcalf <cmetcalf@tilera.com>
Thu, 17 May 2012 13:03:24 +0000 (09:03 -0400)
ChangeLog.tile
sysdeps/unix/sysv/linux/tile/getcontext.S
sysdeps/unix/sysv/linux/tile/setcontext.S
sysdeps/unix/sysv/linux/tile/swapcontext.S
sysdeps/unix/sysv/linux/tile/ucontext_i.h

index 733d49e..3bad4d3 100644 (file)
@@ -1,3 +1,13 @@
+2012-05-16  Chris Metcalf  <cmetcalf@tilera.com>
+
+       * sysdeps/unix/sysv/linux/tile/ucontext_i: Fix tilegx32 offset bug.
+       * sysdeps/unix/sysv/linux/tile/getcontext.S: Fix tilegx32 bug
+       where we accessed "uc_flags" as an 8-byte field.
+       * sysdeps/unix/sysv/linux/tile/setcontext.S: Likewise,
+       and also fix frame code not to access stack below "sp".
+       * sysdeps/unix/sysv/linux/tile/swapcontext.S: Fix frame code not
+       to access stack below "sp", and add frame unwind to error path.
+
 2012-05-15  Chris Metcalf  <cmetcalf@tilera.com>
 
        * sysdeps/tile/sotruss-lib.c: New file.
index 572780b..24163c2 100644 (file)
@@ -32,7 +32,7 @@ ENTRY (__getcontext)
           swapcontext() will assume those registers are all dead.
           Save value "1" to uc_flags to later recognize getcontext().  */
        { movei r11, 1; ADDI_PTR r10, r0, UC_FLAGS_OFFSET }
-       { ST r10, r11; addli r10, r0, UC_REG(30) }
+       { ST_PTR r10, r11; addli r10, r0, UC_REG(30) }
        { ST r10, r30; ADDI_PTR r10, r10, REGSIZE }
        { ST r10, r31; ADDI_PTR r10, r10, REGSIZE }
        { ST r10, r32; ADDI_PTR r10, r10, REGSIZE }
index 319031b..f95ad7c 100644 (file)
@@ -37,7 +37,7 @@ ENTRY (__setcontext)
 #if UC_FLAGS_OFFSET != 0
 # error "Add offset to r0 prior to load."
 #endif
-       LD r10, r0
+       LD_PTR r10, r0
        {
         BEQZ r10, .Lsigreturn
         addi r10, r10, -1  /* Confirm that it has value "1".  */
@@ -51,13 +51,13 @@ ENTRY (__setcontext)
         ADDI_PTR r11, sp, -(2 * REGSIZE)
         move r10, sp
        }
+       ADDI_PTR sp, sp, -(3 * REGSIZE)
+       cfi_def_cfa_offset (3 * REGSIZE)
        cfi_offset (lr, 0)
        {
         ST r11, r10
-        ADDI_PTR r10, sp, -REGSIZE
-        ADDI_PTR sp, sp, -(3 * REGSIZE)
+        ADDI_PTR r10, sp, (2 * REGSIZE)
        }
-       cfi_def_cfa_offset (3 * REGSIZE)
        {
         ST r10, r0
         ADDLI_PTR r1, r0, UC_SIGMASK_OFFSET
@@ -72,13 +72,13 @@ ENTRY (__setcontext)
         moveli TREG_SYSCALL_NR_NAME, __NR_rt_sigprocmask
        }
        swint1
+       ADDI_PTR r11, sp, 2 * REGSIZE  /* Restore uc_context to r11. */
        {
+        LD r11, r11
         ADDI_PTR sp, sp, 3 * REGSIZE
-        ADDI_PTR r11, sp, 2 * REGSIZE  /* Restore uc_context to r11. */
        }
        cfi_def_cfa_offset (0)
        LD lr, sp
-       LD r11, r11
        {
         ADDI_PTR r10, r11, UC_REG(0)
         BNEZ r1, .Lsyscall_error
index 6d3ad7f..e2b3d70 100644 (file)
@@ -31,17 +31,17 @@ ENTRY (__swapcontext)
         ADDI_PTR r11, sp, -(3 * REGSIZE)
         move r10, sp
        }
+       ADDI_PTR sp, sp, -(4 * REGSIZE)
+       cfi_def_cfa_offset (4 * REGSIZE)
        cfi_offset (lr, 0)
        {
         ST r11, r10
-        ADDI_PTR r10, sp, -(2 * REGSIZE)
+        ADDI_PTR r10, sp, (2 * REGSIZE)
        }
        {
         ST r10, r0
-        ADDI_PTR r10, sp, -REGSIZE
-        ADDI_PTR sp, sp, -(4 * REGSIZE)
+        ADDI_PTR r10, sp, (3 * REGSIZE)
        }
-       cfi_def_cfa_offset (4 * REGSIZE)
        ST r10, r1
 
        /* Save the current context.  */
@@ -80,6 +80,9 @@ ENTRY (__swapcontext)
        }
 
 .Lerror:
+       ADDI_PTR sp, sp, 4 * REGSIZE
+       cfi_def_cfa_offset (0)
+       LD lr, sp
        jrp lr
 END (__swapcontext)
 
index bdcfa25..f8ae9c9 100644 (file)
@@ -25,7 +25,8 @@
 #define UC_STACK_SP_OFFSET (UC_LINK_OFFSET + __SIZEOF_POINTER__)
 #define UC_STACK_FLAGS_OFFSET (UC_STACK_SP_OFFSET + __SIZEOF_POINTER__)
 #define UC_STACK_SIZE_OFFSET (UC_STACK_FLAGS_OFFSET + __SIZEOF_POINTER__)
-#define UC_STACK_MCONTEXT_OFFSET (UC_STACK_SIZE_OFFSET + __SIZEOF_POINTER__)
+#define UC_STACK_MCONTEXT_OFFSET \
+  ((UC_STACK_SIZE_OFFSET + __SIZEOF_POINTER__ + REGSIZE - 1) & -REGSIZE)
 #define UC_REG(i) (UC_STACK_MCONTEXT_OFFSET + ((i) * REGSIZE))
 #define UC_NREGS 64
 #define UC_SIGMASK_OFFSET UC_REG(UC_NREGS)