* configure.in (ASM_ALPHA_NG_SYMBOL_PREFIX): Remove test.

* configure: Regenerated.
	* config.h.in (ASM_ALPHA_NG_SYMBOL_PREFIX): Remove #undef.
	* sysdeps/alpha/dl-machine.h (TRAMPOLINE_TEMPLATE): Use !samegp.
	(RTLD_START): Likewise.  Access _dl_skip_args, _rtld_local, and
	_dl_fini via gp-relative relocations.
	* sysdeps/alpha/fpu/e_sqrt.c: Use !samegp.

	* elf/tls-macros.h: Add alpha versions.
	* sysdeps/alpha/dl-machine.h (elf_machine_rela): Handle TLS relocs.
	* sysdeps/unix/alpha/sysdep.S: Support USE___THREAD.
	* sysdeps/unix/alpha/sysdep.h: Likewise.  Add SYSCALL_ERROR_HANDLER.
	* sysdeps/unix/sysv/linux/alpha/brk.S: Use it.
	* sysdeps/unix/sysv/linux/alpha/clone.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/getitimer.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/getrusage.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/gettimeofday.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/rt_sigaction.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/select.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/setitimer.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/settimeofday.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/sigsuspend.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/syscall.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/utimes.S: Likewise.
	* sysdeps/unix/sysv/linux/alpha/wait4.S: Likewise.

	* sysdeps/unix/sysv/linux/alpha/sysdep.h: Re-include protect.
	Kill argument registers across the inline syscall.

	* sysdeps/unix/sysv/linux/alpha/clone.S: Add user_tid and tls args.

	* linuxthreads/sysdeps/alpha/tls.h: New file.
	* sysdeps/alpha/dl-tls.h: New file.
This commit is contained in:
Roland McGrath 2002-11-08 02:20:41 +00:00
parent dfe4c900cb
commit c6481412ff
27 changed files with 498 additions and 251 deletions

View File

@ -1,3 +1,41 @@
2002-11-07 Richard Henderson <rth@redhat.com>
* configure.in (ASM_ALPHA_NG_SYMBOL_PREFIX): Remove test.
* configure: Regenerated.
* config.h.in (ASM_ALPHA_NG_SYMBOL_PREFIX): Remove #undef.
* sysdeps/alpha/dl-machine.h (TRAMPOLINE_TEMPLATE): Use !samegp.
(RTLD_START): Likewise. Access _dl_skip_args, _rtld_local, and
_dl_fini via gp-relative relocations.
* sysdeps/alpha/fpu/e_sqrt.c: Use !samegp.
* elf/tls-macros.h: Add alpha versions.
* sysdeps/alpha/dl-machine.h (elf_machine_rela): Handle TLS relocs.
* sysdeps/unix/alpha/sysdep.S: Support USE___THREAD.
* sysdeps/unix/alpha/sysdep.h: Likewise. Add SYSCALL_ERROR_HANDLER.
* sysdeps/unix/sysv/linux/alpha/brk.S: Use it.
* sysdeps/unix/sysv/linux/alpha/clone.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/getitimer.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/getrusage.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/gettimeofday.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/rt_sigaction.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/select.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/setitimer.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/settimeofday.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/sigsuspend.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/syscall.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/utimes.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/wait4.S: Likewise.
* sysdeps/unix/sysv/linux/alpha/sysdep.h: Re-include protect.
Kill argument registers across the inline syscall.
* sysdeps/unix/sysv/linux/alpha/clone.S: Add user_tid and tls args.
* linuxthreads/sysdeps/alpha/tls.h: New file.
* sysdeps/alpha/dl-tls.h: New file.
2002-10-29 David Mosberger <davidm@hpl.hp.com>
* sysdeps/ia64/elf/initfini.c [HAVE_INITFINI_ARRAY]

View File

@ -73,9 +73,6 @@
directive. */
#undef HAVE_ASM_POPSECTION_DIRECTIVE
/* Define to the prefix Alpha/ELF GCC emits before ..ng symbols. */
#undef ASM_ALPHA_NG_SYMBOL_PREFIX
/* Define if versioning of the library is wanted. */
#undef DO_VERSIONING

43
configure vendored
View File

@ -5205,43 +5205,6 @@ if test $libc_cv_gcc_exceptions = yes; then
exceptions=-fexceptions
fi
if test "$base_machine" = alpha ; then
echo "$as_me:$LINENO: checking for function ..ng prefix" >&5
echo $ECHO_N "checking for function ..ng prefix... $ECHO_C" >&6
if test "${libc_cv_gcc_alpha_ng_prefix+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<\EOF
foo () { }
EOF
if { ac_try='${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; };
then
libc_cv_gcc_alpha_ng_prefix=yes
else
libc_cv_gcc_alpha_ng_prefix=no
fi
rm -f conftest*
fi
echo "$as_me:$LINENO: result: $libc_cv_gcc_alpha_ng_prefix" >&5
echo "${ECHO_T}$libc_cv_gcc_alpha_ng_prefix" >&6
if test $libc_cv_gcc_alpha_ng_prefix = yes ; then
cat >>confdefs.h <<\_ACEOF
#define ASM_ALPHA_NG_SYMBOL_PREFIX "$"
_ACEOF
else
cat >>confdefs.h <<\_ACEOF
#define ASM_ALPHA_NG_SYMBOL_PREFIX ""
_ACEOF
fi
fi
if test "$host_cpu" = powerpc ; then
# Check for a bug present in at least versions 2.8.x of GCC
# and versions 1.0.x of EGCS.
@ -5298,7 +5261,7 @@ if test "${libc_cv_gcc_dwarf2_unwind_info+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<EOF
#line 5301 "configure"
#line 5264 "configure"
static char *__EH_FRAME_BEGIN__;
_start ()
{
@ -5397,7 +5360,7 @@ if test "${libc_cv_gcc_builtin_expect+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<EOF
#line 5400 "configure"
#line 5363 "configure"
int foo (int a)
{
a = __builtin_expect (a, 10);
@ -5465,7 +5428,7 @@ if test "${libc_cv_gcc_subtract_local_labels+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<EOF
#line 5468 "configure"
#line 5431 "configure"
int foo (int a)
{
static const int ar[] = { &&l1 - &&l1, &&l2 - &&l1 };

View File

@ -1496,26 +1496,6 @@ if test $libc_cv_gcc_exceptions = yes; then
fi
AC_SUBST(exceptions)dnl
if test "$base_machine" = alpha ; then
AC_CACHE_CHECK(for function ..ng prefix, libc_cv_gcc_alpha_ng_prefix, [dnl
cat > conftest.c <<\EOF
foo () { }
EOF
dnl
if AC_TRY_COMMAND([${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null]);
then
libc_cv_gcc_alpha_ng_prefix=yes
else
libc_cv_gcc_alpha_ng_prefix=no
fi
rm -f conftest* ])
if test $libc_cv_gcc_alpha_ng_prefix = yes ; then
AC_DEFINE(ASM_ALPHA_NG_SYMBOL_PREFIX, "$")
else
AC_DEFINE(ASM_ALPHA_NG_SYMBOL_PREFIX, "")
fi
fi
if test "$host_cpu" = powerpc ; then
# Check for a bug present in at least versions 2.8.x of GCC
# and versions 1.0.x of EGCS.

View File

@ -211,6 +211,33 @@
"r12", "pr", "t"); \
__l; })
#elif defined __alpha__
register void *__gp __asm__("$29");
# define TLS_LE(x) \
({ int *__l; \
asm ("call_pal 158\n\tlda $0," #x "($0)\t\t!tprel" : "=v"(__l)); \
__l; })
# define TLS_IE(x) \
({ char *__tp; unsigned long __o; \
asm ("call_pal 158\n\tldq %1," #x "($gp)\t\t!gottprel" \
: "=v"(__tp), "=r"(__o) : "r"(__gp)); \
(int *)(__tp + __o); })
# define TLS_LD(x) \
({ extern void *__tls_get_addr(void *); int *__l; void *__i; \
asm ("lda %0," #x "($gp)\t\t!tlsldm" : "=r" (__i) : "r"(__gp)); \
__i = __tls_get_addr(__i); \
asm ("lda %0, " #x "(%1)\t\t!dtprel" : "=r"(__l) : "r"(__i)); \
__l; })
# define TLS_GD(x) \
({ extern void *__tls_get_addr(void *); void *__i; \
asm ("lda %0," #x "($gp)\t\t!tlsgd" : "=r" (__i) : "r"(__gp)); \
(int *) __tls_get_addr(__i); })
#else
# error "No support for this architecture so far."
#endif

View File

@ -0,0 +1,111 @@
/* Definitions for thread-local data handling. linuxthreads/Alpha version.
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _TLS_H
#define _TLS_H
#ifndef __ASSEMBLER__
# include <pt-machine.h>
# include <stddef.h>
/* Type for the dtv. */
typedef union dtv
{
size_t counter;
void *pointer;
} dtv_t;
typedef struct
{
dtv_t *dtv;
/* Reserved for the thread implementation. In the case of LinuxThreads,
this is the thread descriptor. */
void *tcb;
} tcbhead_t;
#endif
#ifdef HAVE_TLS_SUPPORT
/* Signal that TLS support is available. */
# define USE_TLS 1
# ifndef __ASSEMBLER__
/* Get system call information. */
# include <sysdep.h>
/* Get the thread descriptor definition. */
# include <linuxthreads/descr.h>
/* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
/* Alignment requirements for the initial TCB. */
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
/* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
/* Alignment requirements for the TCB. */
# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
/* The DTV is allocated at the TP; the TCB is placed elsewhere. */
# define TLS_DTV_AT_TP 1
/* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */
# define INSTALL_DTV(descr, dtvp) \
((tcbhead_t *) (descr))->dtv = (dtvp) + 1
/* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(DTV) \
(((tcbhead_t *)__builtin_thread_pointer ())->dtv = (DTV))
/* Return dtv of given thread descriptor. */
# define GET_DTV(descr) \
(((tcbhead_t *) (descr))->dtv)
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(descr, secondcall) \
({ \
register tcbhead_t *__self = (void *)(descr); \
__self->tcb = __self; \
__builtin_set_thread_pointer(__self); \
})
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \
(((tcbhead_t *)__builtin_thread_pointer ())->dtv)
/* Return the thread descriptor for the current thread. */
#undef THREAD_SELF
#define THREAD_SELF \
((pthread_descr)(((tcbhead_t *)__builtin_thread_pointer ())->tcb))
#undef INIT_THREAD_SELF
# endif /* HAVE_TLS_SUPPORT */
#endif /* __ASSEMBLER__ */
#endif /* tls.h */

View File

@ -228,7 +228,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
mov $26, $18 \n\
addq $17, $17, $17 \n\
/* Do the fixup */ \n\
bsr $26, " ASM_ALPHA_NG_SYMBOL_PREFIX #fixup_name "..ng\n\
bsr $26, " #fixup_name " !samegp \n\
/* Move the destination address into position. */ \n\
mov $0, $27 \n\
/* Restore program registers. */ \n\
@ -308,7 +308,7 @@ _start: \n\
.prologue 0 \n\
/* Pass pointer to argument block to _dl_start. */ \n\
mov $sp, $16 \n\
bsr $26, "ASM_ALPHA_NG_SYMBOL_PREFIX"_dl_start..ng \n\
bsr $26, _dl_start !samegp \n\
.end _start \n\
/* FALLTHRU */ \n\
.globl _dl_start_user \n\
@ -322,7 +322,7 @@ _dl_start_user: \n\
stq $30, __libc_stack_end \n\
/* See if we were run as a command with the executable \n\
file name as an extra leading argument. */ \n\
ldl $1, _dl_skip_args \n\
ldl $1, _dl_skip_args($gp) !gprel \n\
bne $1, $fixup_stack \n\
$fixup_stack_ret: \n\
/* The special initializer gets called with the stack \n\
@ -332,14 +332,16 @@ $fixup_stack_ret: \n\
" RTLD_START_SPECIAL_INIT " \n\
/* Call _dl_init(_dl_loaded, argc, argv, envp) to run \n\
initializers. */ \n\
ldq $16, _rtld_local \n\
ldah $16, _rtld_local($gp) !gprelhigh \n\
ldq $16, _rtld_local($16) !gprellow \n\
ldq $17, 0($sp) \n\
lda $18, 8($sp) \n\
s8addq $17, 8, $19 \n\
addq $19, $18, $19 \n\
jsr $26, _dl_init_internal \n\
bsr $26, _dl_init_internal !samegp \n\
/* Pass our finalizer function to the user in $0. */ \n\
lda $0, _dl_fini \n\
ldah $0, _dl_fini($gp) !gprelhigh \n\
lda $0, _dl_fini($0) !gprellow \n\
/* Jump to the user's entry point. */ \n\
mov $9, $27 \n\
jmp ($9) \n\
@ -541,10 +543,15 @@ elf_machine_rela (struct link_map *map,
return;
else
{
Elf64_Addr loadbase, sym_value;
Elf64_Addr sym_value;
loadbase = RESOLVE (&sym, version, r_type);
#if defined USE_TLS && !defined RTLD_BOOTSTRAP
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
sym_value = sym ? sym_map->l_addr + sym->st_value : 0;
#else
Elf64_Addr loadbase = RESOLVE (&sym, version, r_type);
sym_value = sym ? loadbase + sym->st_value : 0;
#endif
sym_value += reloc->r_addend;
if (r_type == R_ALPHA_GLOB_DAT)
@ -575,6 +582,40 @@ elf_machine_rela (struct link_map *map,
memcpy (reloc_addr_1, &sym_value, 8);
}
#endif
#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
else if (r_type == R_ALPHA_DTPMOD64)
{
#ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always index 1. */
*reloc_addr = 1;
#else
/* Get the information from the link map returned by the
resolv function. */
if (sym_map != NULL)
*reloc_addr = sym_map->l_tls_modid;
#endif
}
else if (r_type == R_ALPHA_DTPREL64)
{
#ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */
*reloc_addr = sym_value;
#endif
}
else if (r_type == R_ALPHA_TPREL64)
{
#ifdef RTLD_BOOTSTRAP
*reloc_addr = sym_value - map->l_tls_offset;
#else
if (sym_map)
{
*reloc_addr = sym_value - sym_map->l_tls_offset;
CHECK_STATIC_TLS (map, sym_map);
}
#endif
}
#endif /* USE_TLS */
else
_dl_reloc_bad_type (map, r_type, 0);
}

29
sysdeps/alpha/dl-tls.h Normal file
View File

@ -0,0 +1,29 @@
/* Thread-local storage handling in the ELF dynamic linker. Alpha version.
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Type used for the representation of TLS information in the GOT. */
typedef struct
{
unsigned long int ti_module;
unsigned long int ti_offset;
} tls_index;
extern void *__tls_get_addr (tls_index *ti);

View File

@ -153,7 +153,7 @@ __ieee754_sqrt: \n\
.align 4 \n\
$fixup: \n\
addq $sp, 16, $sp \n\
br "ASM_ALPHA_NG_SYMBOL_PREFIX"__full_ieee754_sqrt..ng \n\
br __full_ieee754_sqrt !samegp \n\
\n\
.end __ieee754_sqrt");

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1993, 1996, 1998 Free Software Foundation, Inc.
/* Copyright (C) 1993, 1996, 1998, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Brendan Kehoe (brendan@zen.org).
@ -20,24 +20,59 @@
#include <sysdep.h>
#include <features.h>
#if defined(__ELF__) && defined(PIC)
/* Put this at the end of libc's text segment so that all of
the direct branches from the syscalls are forward, and
thus predicted not taken. */
.section .text.last, "ax", @progbits
#else
.text
.align 2
#endif
#ifdef _LIBC_REENTRANT
#ifdef PIC
/* When building a shared library, we branch here without
having loaded the GP. Nor, since it was a direct branch,
have we loaded PV with our address. Do both. */
# define LOADGP br pv, 1f; 1: ldgp gp, 0(pv)
# define PROLOGUE .prologue 0
#else
# define LOADGP ldgp gp, 0(pv)
# define PROLOGUE .prologue 1
#endif
.align 4
.globl __syscall_error
.ent __syscall_error
__syscall_error:
ldgp gp, 0(pv)
#if defined(_LIBC_REENTRANT) && defined(USE___THREAD)
LOADGP
PROLOGUE
mov v0, t0
call_pal PAL_rduniq
ldq t1, __libc_errno(gp) !gottprel
addq v0, t1, v0
stl t0, 0(v0)
lda v0, -1
ret
#elif defined(_LIBC_REENTRANT)
LOADGP
lda sp, -16(sp)
.frame sp, 16, ra, 0
stq ra, 0(sp)
stq v0, 8(sp)
.mask 0x4000001, -16
.prologue 1
PROLOGUE
/* Find our per-thread errno address */
#ifdef PIC
bsr ra, __errno_location !samegp
#else
jsr ra, __errno_location
#endif
/* Store the error value. */
ldq t0, 8(sp)
@ -49,16 +84,15 @@ __syscall_error:
ldq ra, 0(sp)
lda sp, 16(sp)
ret
.end __syscall_error
#else
ENTRY(__syscall_error)
ldgp gp, 0(t12)
.prologue 1
LOADGP
PROLOGUE
stl v0, errno
lda v0, -1
ret
END(__syscall_error)
#endif /* _LIBC_REENTRANT */
#endif
.end __syscall_error

View File

@ -27,6 +27,13 @@
# include <regdef.h>
#endif
#include <tls.h> /* Defines USE___THREAD. */
#ifdef IS_IN_rtld
# include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
#endif
#ifdef __STDC__
#define __LABEL(x) x##:
#else
@ -55,54 +62,65 @@
label of that number between those two macros! */
#ifdef PROF
#define PSEUDO(name, syscall_name, args) \
.globl name; \
.align 3; \
.ent name,0; \
__LABEL(name) \
.frame sp, 0, ra; \
ldgp gp,0(pv); \
.set noat; \
lda AT,_mcount; \
jsr AT,(AT),_mcount; \
.set at; \
.prologue 1; \
ldiq v0, SYS_ify(syscall_name); \
.set noat; \
call_pal PAL_callsys; \
.set at; \
bne a3, 1996f; \
3:
# define PSEUDO_PROLOGUE \
.frame sp, 0, ra; \
ldgp gp,0(pv); \
.set noat; \
lda AT,_mcount; \
jsr AT,(AT),_mcount; \
.set at; \
.prologue 1
# define PSEUDO_LOADGP
#else
#define PSEUDO(name, syscall_name, args) \
.globl name; \
.align 3; \
.ent name,0; \
__LABEL(name) \
.frame sp, 0, ra \
.prologue 0; \
ldiq v0, SYS_ify(syscall_name); \
.set noat; \
call_pal PAL_callsys; \
.set at; \
bne a3, 1996f; \
3:
#endif
# define PSEUDO_PROLOGUE \
.frame sp, 0, ra; \
.prologue 0
# define PSEUDO_LOADGP \
br gp, 2f; \
2: ldgp gp, 0(gp)
#endif /* PROF */
#undef PSEUDO_END
#ifdef PROF
#define PSEUDO_END(sym) \
1996: \
jmp zero, __syscall_error; \
END(sym)
#if RTLD_PRIVATE_ERRNO
# define SYSCALL_ERROR_HANDLER \
stl v0, errno(gp) !gprel; \
lda v0, -1; \
ret
#else
#define PSEUDO_END(sym) \
# define SYSCALL_ERROR_HANDLER \
jmp $31, __syscall_error
#endif /* RTLD_PRIVATE_ERRNO */
#if defined(PIC) && !RTLD_PRIVATE_ERRNO
# define PSEUDO(name, syscall_name, args) \
.globl name; \
.align 4; \
.ent name,0; \
__LABEL(name) \
PSEUDO_PROLOGUE; \
lda v0, SYS_ify(syscall_name); \
call_pal PAL_callsys; \
bne a3, __syscall_error !samegp; \
3:
# undef PSEUDO_END
# define PSEUDO_END(sym) END(sym)
#else
# define PSEUDO(name, syscall_name, args) \
.globl name; \
.align 4; \
.ent name,0; \
__LABEL(name) \
lda v0, SYS_ify(syscall_name); \
call_pal PAL_callsys; \
bne a3, 1996f; \
3:
# undef PSEUDO_END
# define PSEUDO_END(sym) \
1996: \
br gp, 2f; \
2: ldgp gp, 0(gp); \
jmp zero, __syscall_error; \
END(sym)
#endif
PSEUDO_LOADGP; \
SYSCALL_ERROR_HANDLER; \
END(sym)
#endif /* PIC && !RTLD_PRIVATE_ERRNO */
#define r0 v0
#define r1 a4

View File

@ -74,7 +74,7 @@ $ok: stq a0, __curbrk
/* What a horrible way to die. */
$err0: ldi v0, ENOMEM
$err1: addq sp, 8, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(__brk)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
/* Copyright (C) 1996, 1997, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <rth@tamu.edu>, 1996.
@ -24,7 +24,9 @@
#define _ERRNO_H 1
#include <bits/errno.h>
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
pid_t *tid, void *tls);
*/
.text
ENTRY(__clone)
@ -49,24 +51,29 @@ ENTRY(__clone)
stq a0,0(a1)
stq a3,8(a1)
/* Do the system call */
/* Shift the flags, tid and tls arguments into place; the
child_stack argument is already correct. */
mov a2,a0
mov a4,a2
mov a5,a3
/* Do the system call. */
ldiq v0,__NR_clone
call_pal PAL_callsys
bne a3,$error
beq v0,thread_start
/* Successful return from the parent */
/* Successful return from the parent. */
ret
/* Something bad happened -- no child created */
/* Something bad happened -- no child created. */
$error:
#ifndef PROF
br gp,1f
1: ldgp gp,0(gp)
#endif
jmp zero,__syscall_error
SYSCALL_ERROR_HANDLER
END(__clone)
@ -85,11 +92,11 @@ thread_start:
ldq a0,8(sp)
addq sp,16,sp
/* Call the user's function */
/* Call the user's function. */
jsr ra,(pv)
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
jsr ra,_exit

View File

@ -97,7 +97,7 @@ $do32: ldi v0, SYS_ify(osf_getitimer)
.align 3
$error:
addq sp, 16, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(GETITIMER)

View File

@ -129,7 +129,7 @@ $do32: ldi v0, SYS_ify(osf_getrusage)
.align 3
$error:
addq sp, 16, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(GETRUSAGE)

View File

@ -94,7 +94,7 @@ $do32: ldi v0, SYS_ify(osf_gettimeofday)
.align 3
$error:
addq sp, 16, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(GETTIMEOFDAY)

View File

@ -53,7 +53,7 @@ $error:
1: ldgp gp, 0(gp)
#endif
lda sp, 16(sp)
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(__ieee_get_fp_control)

View File

@ -52,7 +52,7 @@ $error:
1: ldgp gp, 0(gp)
#endif
lda sp, 16(sp)
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(__ieee_set_fp_control)

View File

@ -56,7 +56,7 @@ ENTRY(__syscall_rt_sigaction)
br gp,2f
2: ldgp gp,0(gp)
#endif
jmp __syscall_error
SYSCALL_ERROR_HANDLER
END(__syscall_rt_sigaction)
@ -82,6 +82,6 @@ ENTRY(__syscall_rt_sigaction)
ldgp $29,0($27)
.prologue 1
ldi $0,ENOSYS
jmp __syscall_error
SYSCALL_ERROR_HANDLER
END(__syscall_rt_sigaction)
#endif

View File

@ -112,7 +112,7 @@ $do32:
.align 3
$error:
addq sp, 64, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(SELECT)

View File

@ -113,7 +113,7 @@ $do32:
.align 3
$error:
addq sp, 48, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(SETITIMER)

View File

@ -94,7 +94,7 @@ $do32:
.align 3
$error:
addq sp, 16, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(SETTIMEOFDAY)

View File

@ -47,7 +47,7 @@ error:
br gp, 1f
1: ldgp gp, 0(gp)
#endif
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(__sigsuspend)

View File

@ -70,7 +70,7 @@ $error:
br gp, 2f
2: ldgp gp, 0(gp)
#endif
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(__syscall)

View File

@ -17,6 +17,9 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _LINUX_ALPHA_SYSDEP_H
#define _LINUX_ALPHA_SYSDEP_H 1
#ifdef __ASSEMBLER__
#include <asm/pal.h>
@ -88,118 +91,114 @@
of the hard-register variables as much as possible. Thus we copy
in/out as close to the asm as possible. */
#define inline_syscall0(name) \
{ \
register long _sc_0 __asm__("$0"); \
register long _sc_19 __asm__("$19"); \
\
_sc_0 = __NR_##name; \
__asm__("callsys # %0 %1 <= %2" \
: "=r"(_sc_0), "=r"(_sc_19) \
: "0"(_sc_0) \
: inline_syscall_clobbers); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
}
#define inline_syscall1(name,arg1) \
{ \
register long _sc_0 __asm__("$0"); \
register long _sc_16 __asm__("$16"); \
register long _sc_19 __asm__("$19"); \
\
_sc_0 = __NR_##name; \
_sc_16 = (long) (arg1); \
__asm__("callsys # %0 %1 <= %2 %3" \
: "=r"(_sc_0), "=r"(_sc_19) \
: "0"(_sc_0), "r"(_sc_16) \
: inline_syscall_clobbers); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
}
#define inline_syscall2(name,arg1,arg2) \
#define inline_syscall0(name) \
{ \
register long _sc_0 __asm__("$0"); \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_19 __asm__("$19"); \
\
_sc_0 = __NR_##name; \
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
__asm__("callsys # %0 %1 <= %2 %3 %4" \
: "=r"(_sc_0), "=r"(_sc_19) \
: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17) \
: inline_syscall_clobbers); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
__asm__("callsys # %0 %1 <= %2" \
: "=v"(_sc_ret), "=r"(_sc_19) \
: "0"(__NR_##name) \
: inline_syscall_clobbers, \
"$16", "$17", "$18", "$20", "$21"); \
_sc_err = _sc_19; \
}
#define inline_syscall3(name,arg1,arg2,arg3) \
#define inline_syscall1(name,arg1) \
{ \
register long _sc_0 __asm__("$0"); \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_18 __asm__("$18"); \
register long _sc_19 __asm__("$19"); \
\
_sc_0 = __NR_##name; \
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
_sc_18 = (long) (arg3); \
__asm__("callsys # %0 %1 <= %2 %3 %4 %5" \
: "=r"(_sc_0), "=r"(_sc_19) \
: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
"r"(_sc_18) \
: inline_syscall_clobbers); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
__asm__("callsys # %0 %1 <= %2 %3" \
: "=v"(_sc_ret), "=r"(_sc_19), \
"=r"(_sc_16) \
: "0"(__NR_##name), "2"(_sc_16) \
: inline_syscall_clobbers, \
"$17", "$18", "$20", "$21"); \
_sc_err = _sc_19; \
}
#define inline_syscall4(name,arg1,arg2,arg3,arg4) \
{ \
register long _sc_0 __asm__("$0"); \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_18 __asm__("$18"); \
register long _sc_19 __asm__("$19"); \
\
_sc_0 = __NR_##name; \
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
_sc_18 = (long) (arg3); \
_sc_19 = (long) (arg4); \
__asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6" \
: "=r"(_sc_0), "=r"(_sc_19) \
: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
"r"(_sc_18), "1"(_sc_19) \
: inline_syscall_clobbers); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
#define inline_syscall2(name,arg1,arg2) \
{ \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_19 __asm__("$19"); \
\
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
__asm__("callsys # %0 %1 <= %2 %3 %4" \
: "=v"(_sc_ret), "=r"(_sc_19), \
"=r"(_sc_16), "=r"(_sc_17) \
: "0"(__NR_##name), "2"(_sc_16), "3"(_sc_17) \
: inline_syscall_clobbers, \
"$18", "$20", "$21"); \
_sc_err = _sc_19; \
}
#define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5) \
{ \
register long _sc_0 __asm__("$0"); \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_18 __asm__("$18"); \
register long _sc_19 __asm__("$19"); \
register long _sc_20 __asm__("$20"); \
\
_sc_0 = __NR_##name; \
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
_sc_18 = (long) (arg3); \
_sc_19 = (long) (arg4); \
_sc_20 = (long) (arg5); \
__asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7" \
: "=r"(_sc_0), "=r"(_sc_19) \
: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
"r"(_sc_18), "1"(_sc_19), "r"(_sc_20) \
: inline_syscall_clobbers); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
#define inline_syscall3(name,arg1,arg2,arg3) \
{ \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_18 __asm__("$18"); \
register long _sc_19 __asm__("$19"); \
\
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
_sc_18 = (long) (arg3); \
__asm__("callsys # %0 %1 <= %2 %3 %4 %5" \
: "=v"(_sc_ret), "=r"(_sc_19), \
"=r"(_sc_16), "=r"(_sc_17), "=r"(_sc_18) \
: "0"(__NR_##name), "2"(_sc_16), "3"(_sc_17), \
"4"(_sc_18) \
: inline_syscall_clobbers, "$20", "$21"); \
_sc_err = _sc_19; \
}
#define inline_syscall4(name,arg1,arg2,arg3,arg4) \
{ \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_18 __asm__("$18"); \
register long _sc_19 __asm__("$19"); \
\
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
_sc_18 = (long) (arg3); \
_sc_19 = (long) (arg4); \
__asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6" \
: "=v"(_sc_ret), "=r"(_sc_19), \
"=r"(_sc_16), "=r"(_sc_17), "=r"(_sc_18) \
: "0"(__NR_##name), "2"(_sc_16), "3"(_sc_17), \
"4"(_sc_18), "1"(_sc_19) \
: inline_syscall_clobbers, "$20", "$21"); \
_sc_err = _sc_19; \
}
#define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5) \
{ \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_18 __asm__("$18"); \
register long _sc_19 __asm__("$19"); \
register long _sc_20 __asm__("$20"); \
\
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
_sc_18 = (long) (arg3); \
_sc_19 = (long) (arg4); \
_sc_20 = (long) (arg5); \
__asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7" \
: "=v"(_sc_ret), "=r"(_sc_19), \
"=r"(_sc_16), "=r"(_sc_17), "=r"(_sc_18), \
"=r"(_sc_20) \
: "0"(__NR_##name), "2"(_sc_16), "3"(_sc_17), \
"4"(_sc_18), "1"(_sc_19), "5"(_sc_20) \
: inline_syscall_clobbers, "$21"); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
}
#define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6) \
{ \
register long _sc_0 __asm__("$0"); \
register long _sc_16 __asm__("$16"); \
register long _sc_17 __asm__("$17"); \
register long _sc_18 __asm__("$18"); \
@ -207,7 +206,6 @@
register long _sc_20 __asm__("$20"); \
register long _sc_21 __asm__("$21"); \
\
_sc_0 = __NR_##name; \
_sc_16 = (long) (arg1); \
_sc_17 = (long) (arg2); \
_sc_18 = (long) (arg3); \
@ -215,10 +213,14 @@
_sc_20 = (long) (arg5); \
_sc_21 = (long) (arg6); \
__asm__("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7 %8" \
: "=r"(_sc_0), "=r"(_sc_19) \
: "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
"r"(_sc_18), "1"(_sc_19), "r"(_sc_20), \
"r"(_sc_21) \
: "=v"(_sc_ret), "=r"(_sc_19) \
"=r"(_sc_16), "=r"(_sc_17), "=r"(_sc_18), \
"=r"(_sc_20), "=r"(_sc_21) \
: "0"(__NR_##name), "2"(_sc_16), "3"(_sc_17), \
"4"(_sc_18), "1"(_sc_19), "5"(_sc_20), \
"6"(_sc_21) \
: inline_syscall_clobbers); \
_sc_ret = _sc_0, _sc_err = _sc_19; \
_sc_err = _sc_19; \
}
#endif /* _LINUX_ALPHA_SYSDEP_H */

View File

@ -99,7 +99,7 @@ $do32:
.align 3
$error:
addq sp, 16, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(UTIMES)

View File

@ -132,7 +132,7 @@ $do32: ldi v0, SYS_ify(osf_wait4)
.align 3
$error:
addq sp, 32, sp
jmp zero, __syscall_error
SYSCALL_ERROR_HANDLER
END(WAIT4)