From c18b7473cb88e49d9f59ac2b1d2c68692202313d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 28 Sep 2012 10:51:01 -0700 Subject: [PATCH] alpha: Fix all users of SYSCALL_ERROR_HANDLER The fix begun in 64e65bc1 was incomplete. Fixed by adding a new SYSCALL_ERROR_FALLTHRU macro. --- ports/ChangeLog.alpha | 19 +++++- ports/sysdeps/unix/alpha/sysdep.h | 35 ++++++---- ports/sysdeps/unix/sysv/linux/alpha/clone.S | 79 ++++++++++------------ .../unix/sysv/linux/alpha/nptl/sysdep-cancel.h | 12 +--- ports/sysdeps/unix/sysv/linux/alpha/syscall.S | 11 +-- 5 files changed, 79 insertions(+), 77 deletions(-) diff --git a/ports/ChangeLog.alpha b/ports/ChangeLog.alpha index ab807f7..672ab65 100644 --- a/ports/ChangeLog.alpha +++ b/ports/ChangeLog.alpha @@ -1,4 +1,21 @@ -2012-12-13 Richard Henderson +2012-09-28 Richard Henderson + + * sysdeps/unix/alpha/sysdep.h (PSEUDO_END): Merge versions and + move $syscall_error label... + (SYSCALL_ERROR_HANDLER): ... here. + (SYSCALL_ERROR_FALLTHRU): New. + (PSEUDO_PROF): Split out of ... + (PSEUDO_PROLOGUE): ... here. + * sysdeps/unix/sysv/linux/alpha/syscall.S (__syscall): Use + SYSCALL_ERROR_LABEL and PSEUDO_END. + * sysdeps/unix/sysv/linux/alpha/clone.S (__clone): Likewise. + Use USEPV_PROF and cfi markup. + (thread_start): Use cfi markup and cfi_undefined on ra. + * sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h + (PSEUDO_PROF): Remove. + (PSEUDO): Use SYSCALL_ERROR_FALLTHRU. + +2012-09-13 Richard Henderson * sysdeps/unix/sysv/linux/alpha/setfpucw.c (__setfpucw): Rewrite with the assumption of being used at program startup only. diff --git a/ports/sysdeps/unix/alpha/sysdep.h b/ports/sysdeps/unix/alpha/sysdep.h index 4ee0746..75c06c9 100644 --- a/ports/sysdeps/unix/alpha/sysdep.h +++ b/ports/sysdeps/unix/alpha/sysdep.h @@ -52,13 +52,20 @@ #define END(sym) .end sym #ifdef PROF +# define PSEUDO_PROF \ + .set noat; \ + lda AT, _mcount; \ + jsr AT, (AT), _mcount; \ + .set at +#else +# define PSEUDO_PROF +#endif + +#ifdef PROF # define PSEUDO_PROLOGUE \ .frame sp, 0, ra; \ ldgp gp,0(pv); \ - .set noat; \ - lda AT,_mcount; \ - jsr AT,(AT),_mcount; \ - .set at; \ + PSEUDO_PROF; \ .prologue 1 #elif defined PIC # define PSEUDO_PROLOGUE \ @@ -80,16 +87,21 @@ #if RTLD_PRIVATE_ERRNO # define SYSCALL_ERROR_LABEL $syscall_error # define SYSCALL_ERROR_HANDLER \ +$syscall_error: \ stl v0, rtld_errno(gp) !gprel; \ lda v0, -1; \ ret +# define SYSCALL_ERROR_FALLTHRU #elif defined(PIC) -# define SYSCALL_ERROR_LABEL __syscall_error !samegp +# define SYSCALL_ERROR_LABEL __syscall_error !samegp # define SYSCALL_ERROR_HANDLER +# define SYSCALL_ERROR_FALLTHRU br SYSCALL_ERROR_LABEL #else -# define SYSCALL_ERROR_LABEL $syscall_error -# define SYSCALL_ERROR_HANDLER \ - jmp $31, __syscall_error +# define SYSCALL_ERROR_LABEL $syscall_error +# define SYSCALL_ERROR_HANDLER \ +$syscall_error: \ + jmp $31, __syscall_error +# define SYSCALL_ERROR_FALLTHRU #endif /* RTLD_PRIVATE_ERRNO */ /* Overridden by specific syscalls. */ @@ -108,14 +120,9 @@ __LABEL(name) \ bne a3, SYSCALL_ERROR_LABEL #undef PSEUDO_END -#if defined(PIC) && !RTLD_PRIVATE_ERRNO -# define PSEUDO_END(sym) END(sym) -#else -# define PSEUDO_END(sym) \ -$syscall_error: \ +#define PSEUDO_END(sym) \ SYSCALL_ERROR_HANDLER; \ END(sym) -#endif #define PSEUDO_NOERRNO(name, syscall_name, args) \ .globl name; \ diff --git a/ports/sysdeps/unix/sysv/linux/alpha/clone.S b/ports/sysdeps/unix/sysv/linux/alpha/clone.S index 1c6c8d6..b92b6c2 100644 --- a/ports/sysdeps/unix/sysv/linux/alpha/clone.S +++ b/ports/sysdeps/unix/sysv/linux/alpha/clone.S @@ -35,89 +35,84 @@ we don't bother checking FLAGS. */ .text -ENTRY(__clone) + .align 4 + .globl __clone + .ent __clone + .usepv __clone, USEPV_PROF + + cfi_startproc +__clone: #ifdef PROF ldgp gp,0(pv) - .set noat lda AT, _mcount jsr AT, (AT), _mcount - .set at - .prologue 1 -#else - .prologue 0 #endif /* Sanity check arguments. */ - ldiq v0,EINVAL - beq a0,$error /* no NULL function pointers */ - beq a1,$error /* no NULL stack pointers */ + ldiq v0, EINVAL + beq a0, SYSCALL_ERROR_LABEL /* no NULL function pointers */ + beq a1, SYSCALL_ERROR_LABEL /* no NULL stack pointers */ /* Save the fn ptr and arg on the new stack. */ - subq a1,32,a1 - stq a0,0(a1) - stq a3,8(a1) + subq a1, 32, a1 + stq a0, 0(a1) + stq a3, 8(a1) #ifdef RESET_PID - stq a2,16(a1) + stq a2, 16(a1) #endif /* The syscall is of the form clone(flags, usp, ptid, ctid, tls). Shift the flags, ptid, ctid, tls arguments into place; the child_stack argument is already correct. */ - mov a2,a0 - mov a4,a2 - ldq a3,0(sp) - mov a5,a4 + mov a2, a0 + mov a4, a2 + ldq a3, 0(sp) + mov a5, a4 /* Do the system call. */ - ldiq v0,__NR_clone + ldiq v0, __NR_clone call_pal PAL_callsys - bne a3,$error - beq v0,thread_start + bne a3, SYSCALL_ERROR_LABEL + beq v0, thread_start /* Successful return from the parent. */ ret - /* Something bad happened -- no child created. */ -$error: -#ifndef PROF - br gp,1f -1: ldgp gp,0(gp) -#endif - SYSCALL_ERROR_HANDLER - - END(__clone) +PSEUDO_END(__clone) + cfi_endproc /* Load up the arguments to the function. Put this block of code in its own function so that we can terminate the stack trace with our debug info. */ .ent thread_start + cfi_startproc thread_start: - .frame fp,0,fp,0 mov 0, fp - .prologue 0 + cfi_def_cfa_register(fp) + cfi_undefined(ra) #ifdef RESET_PID /* Check and see if we need to reset the PID. */ - ldq t0,16(sp) - lda t1,CLONE_THREAD - and t0,t1,t2 - beq t2,2f + ldq t0, 16(sp) + lda t1, CLONE_THREAD + and t0, t1, t2 + beq t2, 2f 1: #endif /* Load up the arguments. */ - ldq pv,0(sp) - ldq a0,8(sp) - addq sp,32,sp + ldq pv, 0(sp) + ldq a0, 8(sp) + addq sp, 32, sp /* Call the user's function. */ - jsr ra,(pv) - ldgp gp,0(ra) + jsr ra, (pv) + ldgp gp, 0(ra) /* Call _exit rather than doing it inline for breakpoint purposes. */ - mov v0,a0 + mov v0, a0 #ifdef PIC bsr ra, HIDDEN_JUMPTARGET(_exit) !samegp #else @@ -142,7 +137,7 @@ thread_start: stl v0, TID_OFFSET(s0) br 1b #endif - + cfi_endproc .end thread_start weak_alias (__clone, clone) diff --git a/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h b/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h index 04c7af4..e6795d9 100644 --- a/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +++ b/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h @@ -23,16 +23,6 @@ #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt -# ifdef PROF -# define PSEUDO_PROF \ - .set noat; \ - lda AT, _mcount; \ - jsr AT, (AT), _mcount; \ - .set at -# else -# define PSEUDO_PROF -# endif - /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END besides "ret". */ @@ -88,7 +78,7 @@ __LABEL($multi_error) \ addq sp, 64, sp; \ cfi_restore(ra); \ cfi_def_cfa_offset(0); \ -__LABEL($syscall_error) \ + SYSCALL_ERROR_FALLTHRU; \ SYSCALL_ERROR_HANDLER; \ cfi_endproc; \ .previous diff --git a/ports/sysdeps/unix/sysv/linux/alpha/syscall.S b/ports/sysdeps/unix/sysv/linux/alpha/syscall.S index 830b10a..5cec380 100644 --- a/ports/sysdeps/unix/sysv/linux/alpha/syscall.S +++ b/ports/sysdeps/unix/sysv/linux/alpha/syscall.S @@ -62,16 +62,9 @@ LEAF(__syscall, 0) ldq a5,0(sp) /* arg6 -> a5 */ call_pal PAL_callsys /* Invoke system call */ - bne a3, $error + bne a3, SYSCALL_ERROR_LABEL ret -$error: -#ifndef PROF - br gp, 2f -2: ldgp gp, 0(gp) -#endif - SYSCALL_ERROR_HANDLER - -END(__syscall) +PSEUDO_END(__syscall) weak_alias (__syscall, syscall) -- 2.7.4