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
with the assumption of being used at program startup only.

View file

@ -51,14 +51,21 @@
#undef END
#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; \

View file

@ -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)

View file

@ -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

View file

@ -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)