summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-11-08 02:20:41 +0000
committerRoland McGrath <roland@gnu.org>2002-11-08 02:20:41 +0000
commitc6481412ff19d5c551aba9330082a19a4a93260f (patch)
tree335acb22df9e06295318ebe74d3dc8d6dac03968
parentdfe4c900cb1d03533702c453c3a9abe6d41e545d (diff)
* 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.
-rw-r--r--ChangeLog38
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure43
-rw-r--r--configure.in20
-rw-r--r--elf/tls-macros.h27
-rw-r--r--linuxthreads/sysdeps/alpha/tls.h111
-rw-r--r--sysdeps/alpha/dl-machine.h57
-rw-r--r--sysdeps/alpha/dl-tls.h29
-rw-r--r--sysdeps/alpha/fpu/e_sqrt.c2
-rw-r--r--sysdeps/unix/alpha/sysdep.S58
-rw-r--r--sysdeps/unix/alpha/sysdep.h100
-rw-r--r--sysdeps/unix/sysv/linux/alpha/brk.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/clone.S23
-rw-r--r--sysdeps/unix/sysv/linux/alpha/getitimer.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/getrusage.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/gettimeofday.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/rt_sigaction.S4
-rw-r--r--sysdeps/unix/sysv/linux/alpha/select.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/setitimer.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/settimeofday.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/sigsuspend.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/syscall.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/sysdep.h202
-rw-r--r--sysdeps/unix/sysv/linux/alpha/utimes.S2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/wait4.S2
27 files changed, 495 insertions, 248 deletions
diff --git a/ChangeLog b/ChangeLog
index c99038a9f0..e3cddf07a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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]
diff --git a/config.h.in b/config.h.in
index bfcac4b40e..0b0a828151 100644
--- a/config.h.in
+++ b/config.h.in
@@ -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
diff --git a/configure b/configure
index dc8307a46a..d149b94da9 100755
--- a/configure
+++ b/configure
@@ -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 };
diff --git a/configure.in b/configure.in
index 95d7bf377d..9dc94f50e6 100644
--- a/configure.in
+++ b/configure.in
@@ -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.
diff --git a/elf/tls-macros.h b/elf/tls-macros.h
index e8ed56c996..b57e4ac1d3 100644
--- a/elf/tls-macros.h
+++ b/elf/tls-macros.h
@@ -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
diff --git a/linuxthreads/sysdeps/alpha/tls.h b/linuxthreads/sysdeps/alpha/tls.h
new file mode 100644
index 0000000000..c5cdc0a5b0
--- /dev/null
+++ b/linuxthreads/sysdeps/alpha/tls.h
@@ -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 */
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 05d988274b..711bf10fdd 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -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);
}
diff --git a/sysdeps/alpha/dl-tls.h b/sysdeps/alpha/dl-tls.h
new file mode 100644
index 0000000000..f81f95d75e
--- /dev/null
+++ b/sysdeps/alpha/dl-tls.h
@@ -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);
diff --git a/sysdeps/alpha/fpu/e_sqrt.c b/sysdeps/alpha/fpu/e_sqrt.c
index c6262c8f69..a371896765 100644
--- a/sysdeps/alpha/fpu/e_sqrt.c
+++ b/sysdeps/alpha/fpu/e_sqrt.c
@@ -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");
diff --git a/sysdeps/unix/alpha/sysdep.S b/sysdeps/unix/alpha/sysdep.S
index 05c00918e6..50c84c1166 100644
--- a/sysdeps/unix/alpha/sysdep.S
+++ b/sysdeps/unix/alpha/sysdep.S
@@ -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
+#else
+ LOADGP
+ PROLOGUE
stl v0, errno
lda v0, -1
ret
- END(__syscall_error)
-#endif /* _LIBC_REENTRANT */
+#endif
+
+ .end __syscall_error
diff --git a/sysdeps/unix/alpha/sysdep.h b/sysdeps/unix/alpha/sysdep.h
index 46b5214987..f9aba3ffa2 100644
--- a/sysdeps/unix/alpha/sysdep.h
+++ b/sysdeps/unix/alpha/sysdep.h
@@ -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; \
+# 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_PROLOGUE \
+ .frame sp, 0, ra; \
+ .prologue 0
+# define PSEUDO_LOADGP \
+ br gp, 2f; \
+2: ldgp gp, 0(gp)
+#endif /* PROF */
+
+#if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER \
+ stl v0, errno(gp) !gprel; \
+ lda v0, -1; \
+ ret
+#else
+# 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) \
- .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; \
+ 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 3; \
- .ent name,0; \
+# define PSEUDO(name, syscall_name, args) \
+ .globl name; \
+ .align 4; \
+ .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; \
+ lda v0, SYS_ify(syscall_name); \
+ call_pal PAL_callsys; \
+ bne a3, 1996f; \
3:
-#endif
-#undef PSEUDO_END
-#ifdef PROF
-#define PSEUDO_END(sym) \
+# undef PSEUDO_END
+# define PSEUDO_END(sym) \
1996: \
- jmp zero, __syscall_error; \
- END(sym)
-#else
-#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
diff --git a/sysdeps/unix/sysv/linux/alpha/brk.S b/sysdeps/unix/sysv/linux/alpha/brk.S
index 3cd1ae0fbd..e01abebe0e 100644
--- a/sysdeps/unix/sysv/linux/alpha/brk.S
+++ b/sysdeps/unix/sysv/linux/alpha/brk.S
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/alpha/clone.S b/sysdeps/unix/sysv/linux/alpha/clone.S
index f1f62146ac..42df98a9b4 100644
--- a/sysdeps/unix/sysv/linux/alpha/clone.S
+++ b/sysdeps/unix/sysv/linux/alpha/clone.S
@@ -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
diff --git a/sysdeps/unix/sysv/linux/alpha/getitimer.S b/sysdeps/unix/sysv/linux/alpha/getitimer.S
index 03ceea10f0..543256272c 100644
--- a/sysdeps/unix/sysv/linux/alpha/getitimer.S
+++ b/sysdeps/unix/sysv/linux/alpha/getitimer.S
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/alpha/getrusage.S b/sysdeps/unix/sysv/linux/alpha/getrusage.S
index 13762a87b1..dd3eced775 100644
--- a/sysdeps/unix/sysv/linux/alpha/getrusage.S
+++ b/sysdeps/unix/sysv/linux/alpha/getrusage.S
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/alpha/gettimeofday.S b/sysdeps/unix/sysv/linux/alpha/gettimeofday.S
index 60d642a125..71b8c134dc 100644
--- a/sysdeps/unix/sysv/linux/alpha/gettimeofday.S
+++ b/sysdeps/unix/sysv/linux/alpha/gettimeofday.S
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S b/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S
index 650f7c0715..89e08b3dc9 100644
--- a/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S
+++ b/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S b/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S
index 53838fe84e..dc1bbbb962 100644
--- a/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S
+++ b/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S b/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S
index e3d01af928..5f166a7094 100644
--- a/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S
+++ b/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S
@@ -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
diff --git a/sysdeps/unix/sysv/linux/alpha/select.S b/sysdeps/unix/sysv/linux/alpha/select.S
index 57030aaa4e..d3b206df6e 100644
--- a/sysdeps/unix/sysv/linux/alpha/select.S
+++ b/sysdeps/unix/sysv/linux/alpha/select.S
@@ -112,7 +112,7 @@ $do32:
.align 3
$error:
addq sp, 64, sp
- jmp zero, __syscall_error
+ SYSCALL_ERROR_HANDLER
END(SELECT)
diff --git a/sysdeps/unix/sysv/linux/alpha/setitimer.S b/sysdeps/unix/sysv/linux/alpha/setitimer.S
index 2cc126337d..fdc3d27a8c 100644
--- a/sysdeps/unix/sysv/linux/alpha/setitimer.S
+++ b/sysdeps/unix/sysv/linux/alpha/setitimer.S
@@ -113,7 +113,7 @@ $do32:
.align 3
$error:
addq sp, 48, sp
- jmp zero, __syscall_error
+ SYSCALL_ERROR_HANDLER
END(SETITIMER)
diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.S b/sysdeps/unix/sysv/linux/alpha/settimeofday.S
index 03e9206d48..339913ff51 100644
--- a/sysdeps/unix/sysv/linux/alpha/settimeofday.S
+++ b/sysdeps/unix/sysv/linux/alpha/settimeofday.S
@@ -94,7 +94,7 @@ $do32:
.align 3
$error:
addq sp, 16, sp
- jmp zero, __syscall_error
+ SYSCALL_ERROR_HANDLER
END(SETTIMEOFDAY)
diff --git a/sysdeps/unix/sysv/linux/alpha/sigsuspend.S b/sysdeps/unix/sysv/linux/alpha/sigsuspend.S
index d6a17851ca..955d82ecc8 100644
--- a/sysdeps/unix/sysv/linux/alpha/sigsuspend.S
+++ b/sysdeps/unix/sysv/linux/alpha/sigsuspend.S
@@ -47,7 +47,7 @@ error:
br gp, 1f
1: ldgp gp, 0(gp)
#endif
- jmp zero, __syscall_error
+ SYSCALL_ERROR_HANDLER
END(__sigsuspend)
diff --git a/sysdeps/unix/sysv/linux/alpha/syscall.S b/sysdeps/unix/sysv/linux/alpha/syscall.S
index c354bb6161..10a32d5dc8 100644
--- a/sysdeps/unix/sysv/linux/alpha/syscall.S
+++ b/sysdeps/unix/sysv/linux/alpha/syscall.S
@@ -70,7 +70,7 @@ $error:
br gp, 2f
2: ldgp gp, 0(gp)
#endif
- jmp zero, __syscall_error
+ SYSCALL_ERROR_HANDLER
END(__syscall)
diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.h b/sysdeps/unix/sysv/linux/alpha/sysdep.h
index e56adca8ed..3bf25e6fd2 100644
--- a/sysdeps/unix/sysv/linux/alpha/sysdep.h
+++ b/sysdeps/unix/sysv/linux/alpha/sysdep.h
@@ -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 */
diff --git a/sysdeps/unix/sysv/linux/alpha/utimes.S b/sysdeps/unix/sysv/linux/alpha/utimes.S
index e9c16db39d..a939255d27 100644
--- a/sysdeps/unix/sysv/linux/alpha/utimes.S
+++ b/sysdeps/unix/sysv/linux/alpha/utimes.S
@@ -99,7 +99,7 @@ $do32:
.align 3
$error:
addq sp, 16, sp
- jmp zero, __syscall_error
+ SYSCALL_ERROR_HANDLER
END(UTIMES)
diff --git a/sysdeps/unix/sysv/linux/alpha/wait4.S b/sysdeps/unix/sysv/linux/alpha/wait4.S
index b695047890..17c5a97952 100644
--- a/sysdeps/unix/sysv/linux/alpha/wait4.S
+++ b/sysdeps/unix/sysv/linux/alpha/wait4.S
@@ -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)