alpha: Fix all users of SYSCALL_ERROR_HANDLER

The fix begun in 64e65bc1 was incomplete.  Fixed by adding
a new SYSCALL_ERROR_FALLTHRU macro.
This commit is contained in:
Richard Henderson 2012-09-28 10:51:01 -07:00
parent b31606c0e1
commit c18b7473cb
5 changed files with 79 additions and 77 deletions

View File

@ -1,4 +1,21 @@
2012-12-13 Richard Henderson <rth@redhat.com> 2012-09-28 Richard Henderson <rth@redhat.com>
* 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 <rth@redhat.com>
* sysdeps/unix/sysv/linux/alpha/setfpucw.c (__setfpucw): Rewrite * sysdeps/unix/sysv/linux/alpha/setfpucw.c (__setfpucw): Rewrite
with the assumption of being used at program startup only. with the assumption of being used at program startup only.

View File

@ -51,14 +51,21 @@
#undef END #undef END
#define END(sym) .end sym #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 #ifdef PROF
# define PSEUDO_PROLOGUE \ # define PSEUDO_PROLOGUE \
.frame sp, 0, ra; \ .frame sp, 0, ra; \
ldgp gp,0(pv); \ ldgp gp,0(pv); \
.set noat; \ PSEUDO_PROF; \
lda AT,_mcount; \
jsr AT,(AT),_mcount; \
.set at; \
.prologue 1 .prologue 1
#elif defined PIC #elif defined PIC
# define PSEUDO_PROLOGUE \ # define PSEUDO_PROLOGUE \
@ -80,16 +87,21 @@
#if RTLD_PRIVATE_ERRNO #if RTLD_PRIVATE_ERRNO
# define SYSCALL_ERROR_LABEL $syscall_error # define SYSCALL_ERROR_LABEL $syscall_error
# define SYSCALL_ERROR_HANDLER \ # define SYSCALL_ERROR_HANDLER \
$syscall_error: \
stl v0, rtld_errno(gp) !gprel; \ stl v0, rtld_errno(gp) !gprel; \
lda v0, -1; \ lda v0, -1; \
ret ret
# define SYSCALL_ERROR_FALLTHRU
#elif defined(PIC) #elif defined(PIC)
# define SYSCALL_ERROR_LABEL __syscall_error !samegp # define SYSCALL_ERROR_LABEL __syscall_error !samegp
# define SYSCALL_ERROR_HANDLER # define SYSCALL_ERROR_HANDLER
# define SYSCALL_ERROR_FALLTHRU br SYSCALL_ERROR_LABEL
#else #else
# define SYSCALL_ERROR_LABEL $syscall_error # define SYSCALL_ERROR_LABEL $syscall_error
# define SYSCALL_ERROR_HANDLER \ # define SYSCALL_ERROR_HANDLER \
jmp $31, __syscall_error $syscall_error: \
jmp $31, __syscall_error
# define SYSCALL_ERROR_FALLTHRU
#endif /* RTLD_PRIVATE_ERRNO */ #endif /* RTLD_PRIVATE_ERRNO */
/* Overridden by specific syscalls. */ /* Overridden by specific syscalls. */
@ -108,14 +120,9 @@ __LABEL(name) \
bne a3, SYSCALL_ERROR_LABEL bne a3, SYSCALL_ERROR_LABEL
#undef PSEUDO_END #undef PSEUDO_END
#if defined(PIC) && !RTLD_PRIVATE_ERRNO #define PSEUDO_END(sym) \
# define PSEUDO_END(sym) END(sym)
#else
# define PSEUDO_END(sym) \
$syscall_error: \
SYSCALL_ERROR_HANDLER; \ SYSCALL_ERROR_HANDLER; \
END(sym) END(sym)
#endif
#define PSEUDO_NOERRNO(name, syscall_name, args) \ #define PSEUDO_NOERRNO(name, syscall_name, args) \
.globl name; \ .globl name; \

View File

@ -35,89 +35,84 @@
we don't bother checking FLAGS. */ we don't bother checking FLAGS. */
.text .text
ENTRY(__clone) .align 4
.globl __clone
.ent __clone
.usepv __clone, USEPV_PROF
cfi_startproc
__clone:
#ifdef PROF #ifdef PROF
ldgp gp,0(pv) ldgp gp,0(pv)
.set noat
lda AT, _mcount lda AT, _mcount
jsr AT, (AT), _mcount jsr AT, (AT), _mcount
.set at
.prologue 1
#else
.prologue 0
#endif #endif
/* Sanity check arguments. */ /* Sanity check arguments. */
ldiq v0,EINVAL ldiq v0, EINVAL
beq a0,$error /* no NULL function pointers */ beq a0, SYSCALL_ERROR_LABEL /* no NULL function pointers */
beq a1,$error /* no NULL stack pointers */ beq a1, SYSCALL_ERROR_LABEL /* no NULL stack pointers */
/* Save the fn ptr and arg on the new stack. */ /* Save the fn ptr and arg on the new stack. */
subq a1,32,a1 subq a1, 32, a1
stq a0,0(a1) stq a0, 0(a1)
stq a3,8(a1) stq a3, 8(a1)
#ifdef RESET_PID #ifdef RESET_PID
stq a2,16(a1) stq a2, 16(a1)
#endif #endif
/* The syscall is of the form clone(flags, usp, ptid, ctid, tls). /* The syscall is of the form clone(flags, usp, ptid, ctid, tls).
Shift the flags, ptid, ctid, tls arguments into place; the Shift the flags, ptid, ctid, tls arguments into place; the
child_stack argument is already correct. */ child_stack argument is already correct. */
mov a2,a0 mov a2, a0
mov a4,a2 mov a4, a2
ldq a3,0(sp) ldq a3, 0(sp)
mov a5,a4 mov a5, a4
/* Do the system call. */ /* Do the system call. */
ldiq v0,__NR_clone ldiq v0, __NR_clone
call_pal PAL_callsys call_pal PAL_callsys
bne a3,$error bne a3, SYSCALL_ERROR_LABEL
beq v0,thread_start beq v0, thread_start
/* Successful return from the parent. */ /* Successful return from the parent. */
ret ret
/* Something bad happened -- no child created. */ PSEUDO_END(__clone)
$error: cfi_endproc
#ifndef PROF
br gp,1f
1: ldgp gp,0(gp)
#endif
SYSCALL_ERROR_HANDLER
END(__clone)
/* Load up the arguments to the function. Put this block of code in /* 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 its own function so that we can terminate the stack trace with our
debug info. */ debug info. */
.ent thread_start .ent thread_start
cfi_startproc
thread_start: thread_start:
.frame fp,0,fp,0
mov 0, fp mov 0, fp
.prologue 0 cfi_def_cfa_register(fp)
cfi_undefined(ra)
#ifdef RESET_PID #ifdef RESET_PID
/* Check and see if we need to reset the PID. */ /* Check and see if we need to reset the PID. */
ldq t0,16(sp) ldq t0, 16(sp)
lda t1,CLONE_THREAD lda t1, CLONE_THREAD
and t0,t1,t2 and t0, t1, t2
beq t2,2f beq t2, 2f
1: 1:
#endif #endif
/* Load up the arguments. */ /* Load up the arguments. */
ldq pv,0(sp) ldq pv, 0(sp)
ldq a0,8(sp) ldq a0, 8(sp)
addq sp,32,sp addq sp, 32, sp
/* Call the user's function. */ /* Call the user's function. */
jsr ra,(pv) jsr ra, (pv)
ldgp gp,0(ra) ldgp gp, 0(ra)
/* Call _exit rather than doing it inline for breakpoint purposes. */ /* Call _exit rather than doing it inline for breakpoint purposes. */
mov v0,a0 mov v0, a0
#ifdef PIC #ifdef PIC
bsr ra, HIDDEN_JUMPTARGET(_exit) !samegp bsr ra, HIDDEN_JUMPTARGET(_exit) !samegp
#else #else
@ -142,7 +137,7 @@ thread_start:
stl v0, TID_OFFSET(s0) stl v0, TID_OFFSET(s0)
br 1b br 1b
#endif #endif
cfi_endproc
.end thread_start .end thread_start
weak_alias (__clone, clone) weak_alias (__clone, clone)

View File

@ -23,16 +23,6 @@
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt #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 /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
besides "ret". */ besides "ret". */
@ -88,7 +78,7 @@ __LABEL($multi_error) \
addq sp, 64, sp; \ addq sp, 64, sp; \
cfi_restore(ra); \ cfi_restore(ra); \
cfi_def_cfa_offset(0); \ cfi_def_cfa_offset(0); \
__LABEL($syscall_error) \ SYSCALL_ERROR_FALLTHRU; \
SYSCALL_ERROR_HANDLER; \ SYSCALL_ERROR_HANDLER; \
cfi_endproc; \ cfi_endproc; \
.previous .previous

View File

@ -62,16 +62,9 @@ LEAF(__syscall, 0)
ldq a5,0(sp) /* arg6 -> a5 */ ldq a5,0(sp) /* arg6 -> a5 */
call_pal PAL_callsys /* Invoke system call */ call_pal PAL_callsys /* Invoke system call */
bne a3, $error bne a3, SYSCALL_ERROR_LABEL
ret ret
$error: PSEUDO_END(__syscall)
#ifndef PROF
br gp, 2f
2: ldgp gp, 0(gp)
#endif
SYSCALL_ERROR_HANDLER
END(__syscall)
weak_alias (__syscall, syscall) weak_alias (__syscall, syscall)