From: Chris Metcalf Date: Wed, 16 May 2012 17:52:36 +0000 (-0400) Subject: tilegx32: fix various bugs in setcontext/getcontext/swapcontext X-Git-Tag: glibc-2.16-ports-before-merge~109 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=0adc5f3892fee6fc6221691e3f269fcc3b386965;p=glibc.git tilegx32: fix various bugs in setcontext/getcontext/swapcontext --- diff --git a/ChangeLog.tile b/ChangeLog.tile index 733d49ead5..3bad4d34db 100644 --- a/ChangeLog.tile +++ b/ChangeLog.tile @@ -1,3 +1,13 @@ +2012-05-16 Chris Metcalf + + * 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 * sysdeps/tile/sotruss-lib.c: New file. diff --git a/sysdeps/unix/sysv/linux/tile/getcontext.S b/sysdeps/unix/sysv/linux/tile/getcontext.S index 572780b88c..24163c28ce 100644 --- a/sysdeps/unix/sysv/linux/tile/getcontext.S +++ b/sysdeps/unix/sysv/linux/tile/getcontext.S @@ -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 } diff --git a/sysdeps/unix/sysv/linux/tile/setcontext.S b/sysdeps/unix/sysv/linux/tile/setcontext.S index 319031b31d..f95ad7ccaa 100644 --- a/sysdeps/unix/sysv/linux/tile/setcontext.S +++ b/sysdeps/unix/sysv/linux/tile/setcontext.S @@ -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 diff --git a/sysdeps/unix/sysv/linux/tile/swapcontext.S b/sysdeps/unix/sysv/linux/tile/swapcontext.S index 6d3ad7fd1d..e2b3d70709 100644 --- a/sysdeps/unix/sysv/linux/tile/swapcontext.S +++ b/sysdeps/unix/sysv/linux/tile/swapcontext.S @@ -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) diff --git a/sysdeps/unix/sysv/linux/tile/ucontext_i.h b/sysdeps/unix/sysv/linux/tile/ucontext_i.h index bdcfa258dc..f8ae9c9f16 100644 --- a/sysdeps/unix/sysv/linux/tile/ucontext_i.h +++ b/sysdeps/unix/sysv/linux/tile/ucontext_i.h @@ -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)