2002-12-28  Ulrich Drepper  <drepper@redhat.com>

	* descr.h (struct pthread): Move header.data.list to the back of the
	struct.
	* sysdeps/i386/tls.h (tcbhead_t): Move list to the back of the struct.
	(MULTIPLE_THREADS_OFFSET): Adjust offset.
	(SYSINFO_OFFSEET): Likewise.

2002-12-27  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h (USE_DL_SYSINFO):
	Define.
	(DL_SYSINFO_DEFAULT): Cast to uintptr_t to avoid warnings.
	* sysdeps/unix/sysv/linux/i386/dl-sysdep.h (NEED_DL_SYSINFO,
	DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): Define.
	(USE_DL_SYSINFO): Undef.

2002-12-22  Jakub Jelinek  <jakub@redhat.com>

	* Makefile (tests-reverse): Use $(objpfx)../libc.so instead of
	$(common-objpfx)libc.so.
	* tst-cancel4.c (tf_write, tf_writev): Increase buf sizes so that
	it is bigger than pipe buffer size even on arches with bigger
	page size.
	(tf_usleep): Cast usleep argument to useconds_t to avoid warnings.
This commit is contained in:
Ulrich Drepper 2002-12-28 09:27:26 +00:00
parent ca78735936
commit 131fd126cd
36 changed files with 907 additions and 110 deletions

View File

@ -1150,6 +1150,10 @@ of this helper program; chances are you did not intend to run this program.\n\
/* Assign a module ID. */
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
# ifndef TLS_INIT_TP_EXPENSIVE
# define TLS_INIT_TP_EXPENSIVE 0
# endif
/* We do not initialize any of the TLS functionality unless any of the
initial modules uses TLS. This makes dynamic loading of modules with
TLS impossible, but to support it requires either eagerly doing setup
@ -1157,7 +1161,7 @@ of this helper program; chances are you did not intend to run this program.\n\
an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
used. Trying to do it lazily is too hairy to try when there could be
multiple threads (from a non-TLS-using libpthread). */
if (GL(dl_tls_max_dtv_idx) > 0)
if (GL(dl_tls_max_dtv_idx) > 0 || !TLS_INIT_TP_EXPENSIVE)
{
struct link_map *l;
size_t nelem;
@ -1565,8 +1569,12 @@ cannot allocate TLS data structures for initial thread");
we need it in the memory handling later. */
GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
#ifndef NONTLS_INIT_TP
# define NONTLS_INIT_TP do { } while (0)
#endif
#ifdef USE_TLS
if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD)
if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD || !TLS_INIT_TP_EXPENSIVE)
{
/* Now that we have completed relocation, the initializer data
for the TLS blocks has its final values and we can copy them
@ -1579,7 +1587,9 @@ cannot allocate TLS data structures for initial thread");
if (__builtin_expect (lossage != NULL, 0))
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
}
else
#endif
NONTLS_INIT_TP;
{
/* Initialize _r_debug. */

View File

@ -74,8 +74,12 @@ endif
librt-tests = ex10 ex11
tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 $(librt-tests) ex12 ex13 joinrace \
tststack $(tests-nodelete-$(have-z-nodelete)) ecmutex ex14 ex15 ex16 \
ex17 ex18 tst-cancel tst-context bug-sleep
ex17 ex18 tst-cancel tst-context bug-sleep \
tst-cancel1 tst-cancel2 tst-cancel3 tst-cancel4 tst-cancel5 \
tst-cancel6
test-srcs = tst-signal
# These tests are linked with libc before libpthread
tests-reverse += tst-cancel5
ifeq ($(build-static),yes)
tests += tststatic tst-static-locale
@ -149,8 +153,12 @@ $(objpfx)libpthread.so: $(libc-link.so) $(common-objpfx)libc_nonshared.a
# Make sure we link with the thread library.
ifeq ($(build-shared),yes)
$(addprefix $(objpfx), \
$(filter-out $(tests-static) unload, \
$(filter-out $(tests-static) $(tests-reverse) unload, \
$(tests) $(test-srcs))): $(objpfx)libpthread.so
# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
# since otherwise libpthread.so comes before libc.so when linking.
$(addprefix $(objpfx), $(tests-reverse)): \
$(objpfx)../libc.so $(objpfx)libpthread.so
$(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.so
$(objpfx)unload: $(common-objpfx)dlfcn/libdl.so
$(objpfx)unload.out: $(objpfx)libpthread.so

View File

@ -20,6 +20,7 @@
#include <sched.h>
#include <setjmp.h>
#include <signal.h>
#include <stdint.h>
#include <sys/types.h>
#include <hp-timing.h>
#include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */
@ -107,6 +108,9 @@ struct _pthread_descr_struct {
union dtv *dtvp;
pthread_descr self; /* Pointer to this structure */
int multiple_threads;
#ifdef NEED_DL_SYSINFO
uintptr_t sysinfo;
#endif
} data;
void *__padding[16];
} p_header;

View File

@ -17,9 +17,10 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <tls.h>
#include <locale.h>
#include "internals.h"
#include <sysdep-cancel.h>

View File

@ -20,10 +20,12 @@
#ifndef _TLS_H
#define _TLS_H
# include <dl-sysdep.h>
# include <pt-machine.h>
#ifndef __ASSEMBLER__
# include <stddef.h>
# include <stdint.h>
/* Type for the dtv. */
typedef union dtv
@ -39,9 +41,17 @@ typedef struct
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
#ifdef NEED_DL_SYSINFO
uintptr_t sysinfo;
#endif
} tcbhead_t;
#endif
#ifdef NEED_DL_SYSINFO
/* Offset of the SYSINFO element in tcbhead_t. */
# define SYSINFO_OFFSET 24
#endif
/* We can support TLS only if the floating-stack support is available.
However, we want to compile in the support and test at runtime whether
@ -174,6 +184,12 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK( \
TLS_DO_MODIFY_LDT ((descr), 0)
# endif
#if defined NEED_DL_SYSINFO && defined SHARED
# define INIT_SYSINFO \
head->sysinfo = GL(dl_sysinfo)
#else
# define INIT_SYSINFO
#endif
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
@ -189,9 +205,14 @@ TLS_DO_MODIFY_LDT_KERNEL_CHECK( \
/* For now the thread descriptor is at the same address. */ \
head->self = _descr; \
\
INIT_SYSINFO; \
TLS_SETUP_GS_SEGMENT (_descr, secondcall); \
})
/* Indicate that dynamic linker shouldn't try to initialize TLS even
when no PT_TLS segments are found in the program and libraries
it is linked against. */
# define TLS_INIT_TP_EXPENSIVE 1
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \

View File

@ -0,0 +1,64 @@
/* Definitions for thread-local data handling. linuxthreads/IA-64 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;
/* FIXME: Only temporary. When TLS is supported on IA-64,
pthread_descr struct needs to be immediately below r13 and
at r13 a struct { dtv_t *dtv; void *private; }. */
typedef struct
{
void *tcb; /* Pointer to the TCB. Not necessary the
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
} tcbhead_t;
#endif /* __ASSEMBLER__ */
#undef USE_TLS
#if USE_TLS
#else
#define NONTLS_INIT_TP \
do { \
static const tcbhead_t nontls_init_tp \
= { .multiple_threads = 0 }; \
__thread_self = (__typeof (__thread_self)) &nontls_init_tp; \
} while (0)
#endif /* USE_TLS */
#endif /* tls.h */

View File

@ -97,7 +97,7 @@ typedef pthread_key_t __libc_key_t;
#if defined _LIBC && defined IS_IN_libpthread
# define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS
#else
# ifdef __PIC__
# if defined __PIC__ || (defined _LIBC && defined SHARED)
# define __libc_maybe_call(FUNC, ARGS, ELSE) \
(__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
_fn != NULL ? (*_fn) ARGS : ELSE; }))
@ -106,7 +106,7 @@ typedef pthread_key_t __libc_key_t;
(FUNC != NULL ? FUNC ARGS : ELSE)
# endif
#endif
#if defined _LIBC && !defined NOT_IN_libc && defined __PIC__
#if defined _LIBC && !defined NOT_IN_libc && defined SHARED
# define __libc_maybe_call2(FUNC, ARGS, ELSE) \
({__libc_pthread_functions.ptr_##FUNC != NULL \
? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; })

View File

@ -0,0 +1,61 @@
/* Definitions for thread-local data handling. linuxthreads/sparc32 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
{
void *tcb; /* Pointer to the TCB. Not necessary the
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
} tcbhead_t;
#endif /* __ASSEMBLER__ */
#undef USE_TLS
#if USE_TLS
#else
#define NONTLS_INIT_TP \
do { \
static const tcbhead_t nontls_init_tp \
= { .multiple_threads = 0 }; \
__thread_self = (__typeof (__thread_self)) &nontls_init_tp; \
} while (0)
#endif /* USE_TLS */
#endif /* tls.h */

View File

@ -0,0 +1,61 @@
/* Definitions for thread-local data handling. linuxthreads/sparc64 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
{
void *tcb; /* Pointer to the TCB. Not necessary the
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
} tcbhead_t;
#endif /* __ASSEMBLER__ */
#undef USE_TLS
#if USE_TLS
#else
#define NONTLS_INIT_TP \
do { \
static const tcbhead_t nontls_init_tp \
= { .multiple_threads = 0 }; \
__thread_self = (__typeof (__thread_self)) &nontls_init_tp; \
} while (0)
#endif /* USE_TLS */
#endif /* tls.h */

View File

@ -0,0 +1,60 @@
/* System-specific settings for dynamic linker code. IA-32 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 _DL_SYSDEP_H
#define _DL_SYSDEP_H 1
/* This macro must be defined to either 0 or 1.
If 1, then an errno global variable hidden in ld.so will work right with
all the errno-using libc code compiled for ld.so, and there is never a
need to share the errno location with libc. This is appropriate only if
all the libc functions that ld.so uses are called without PLT and always
get the versions linked into ld.so rather than the libc ones. */
#ifdef IS_IN_rtld
# define RTLD_PRIVATE_ERRNO 1
#else
# define RTLD_PRIVATE_ERRNO 0
#endif
/* Traditionally system calls have been made using int $0x80. A
second method was introduced which, if possible, will use the
sysenter/syscall instructions. To signal the presence and where to
find the code the kernel passes an AT_SYSINFO value in the
auxiliary vector to the application.
sysenter/syscall is not useful on i386 through i586, but the dynamic
linker and dl code in libc.a has to be able to load i686 compiled
libraries. */
#define NEED_DL_SYSINFO 1
#undef USE_DL_SYSINFO
#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
extern void _dl_sysinfo_int80 (void) attribute_hidden;
# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
# define DL_SYSINFO_IMPLEMENTATION \
asm (".type _dl_sysinfo_int80,@function\n\t" \
".hidden _dl_sysinfo_int80\n" \
"_dl_sysinfo_int80:\n\t" \
"int $0x80;\n\t" \
"ret;\n\t" \
".size _dl_sysinfo_int80,.-_dl_sysinfo_int80");
#endif
#endif /* dl-sysdep.h */

View File

@ -25,7 +25,7 @@
#endif
#if defined FLOATING_STACKS && USE___THREAD
# define MULTIPLE_THREADS_OFFSET 12
# define MULTIPLE_THREADS_OFFSET 20
#endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread

View File

@ -0,0 +1,3 @@
ifeq ($(subdir),linuxthreads)
libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask
endif

View File

@ -0,0 +1,118 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
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. */
#include <sysdep.h>
#include <tls.h>
#ifndef ASSEMBLER
# include <linuxthreads/internals.h>
#endif
#define MULTIPLE_THREADS_OFFSET 40
#if !defined NOT_IN_libc || defined IS_IN_libpthread
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
adds r14 = MULTIPLE_THREADS_OFFSET, r13;; \
ld4 r14 = [r14]; \
mov r15 = SYS_ify(syscall_name);; \
cmp4.ne p6, p7 = 0, r14; \
(p6) br.cond.spnt .Lpseudo_cancel;; \
break __BREAK_SYSCALL;; \
cmp.eq p6,p0=-1,r10; \
(p6) br.cond.spnt.few __syscall_error; \
ret;; \
.Lpseudo_cancel: \
.prologue; \
.regstk args, 5, args, 0; \
.save ar.pfs, loc0; \
alloc loc0 = ar.pfs, args, 5, args, 0; \
.save rp, loc1; \
mov loc1 = rp;; \
.body; \
CENABLE;; \
mov loc2 = r8; \
COPY_ARGS_##args \
mov r15 = SYS_ify(syscall_name); \
break __BREAK_SYSCALL;; \
mov loc3 = r8; \
mov loc4 = r10; \
mov out0 = loc2; \
CDISABLE;; \
cmp.eq p6,p0=-1,loc4; \
(p6) br.cond.spnt.few __syscall_error_##args; \
mov r8 = loc3; \
mov rp = loc1; \
mov ar.pfs = loc0; \
.Lpseudo_end: \
ret; \
.endp name; \
.section .gnu.linkonce.t.__syscall_error_##args, "ax"; \
.align 32; \
.proc __syscall_error_##args; \
.global __syscall_error_##args; \
.hidden __syscall_error_##args; \
__syscall_error_##args: \
.prologue; \
.regstk args, 5, args, 0; \
.save ar.pfs, loc0; \
.save rp, loc1; \
.body; \
mov loc4 = r1;; \
br.call.sptk.many b0 = __errno_location;; \
st4 [r8] = loc3; \
mov r1 = loc4; \
mov rp = loc1; \
mov r8 = -1; \
mov ar.pfs = loc0
# ifdef IS_IN_libpthread
# define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel
# define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel
# else
# define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel
# define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel
# endif
#define COPY_ARGS_0 /* Nothing */
#define COPY_ARGS_1 COPY_ARGS_0 mov out0 = in0;
#define COPY_ARGS_2 COPY_ARGS_1 mov out1 = in1;
#define COPY_ARGS_3 COPY_ARGS_2 mov out2 = in2;
#define COPY_ARGS_4 COPY_ARGS_3 mov out3 = in3;
#define COPY_ARGS_5 COPY_ARGS_4 mov out4 = in4;
#define COPY_ARGS_6 COPY_ARGS_5 mov out5 = in5;
#define COPY_ARGS_7 COPY_ARGS_6 mov out6 = in6;
# ifndef ASSEMBLER
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
p_header.data.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P \
adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14 ;;
# endif
#elif !defined ASSEMBLER
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
#endif

View File

@ -0,0 +1,99 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
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. */
#include <sysdep.h>
#include <tls.h>
#ifndef ASSEMBLER
# include <linuxthreads/internals.h>
#endif
#define MULTIPLE_THREADS_OFFSET 20
#if !defined NOT_IN_libc || defined IS_IN_libpthread
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY(name) \
ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1; \
cmp %g1, 0; \
bne 1f; \
mov SYS_ify(syscall_name), %g1; \
ta 0x10; \
bcs __syscall_error_handler; \
nop; \
.subsection 2; \
1: save %sp, -96, %sp; \
CENABLE; \
nop; \
mov %o0, %l0; \
COPY_ARGS_##args \
mov SYS_ify(syscall_name), %g1; \
ta 0x10; \
bcs __syscall_error_handler2; \
mov %o0, %l1; \
CDISABLE; \
mov %l0, %o0; \
jmpl %i7 + 8, %g0; \
restore %g0, %l1, %o0; \
.previous; \
SYSCALL_ERROR_HANDLER \
SYSCALL_ERROR_HANDLER2
#define SYSCALL_ERROR_HANDLER2 \
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2) \
.global __errno_location; \
.type __errno_location,@function; \
call __errno_location; \
nop; \
st %l1, [%o0]; \
jmpl %i7 + 8, %g0; \
restore %g0, -1, %o0; \
.previous;
# ifdef IS_IN_libpthread
# define CENABLE call __pthread_enable_asynccancel
# define CDISABLE call __pthread_disable_asynccancel
# else
# define CENABLE call __libc_enable_asynccancel
# define CDISABLE call __libc_disable_asynccancel
# endif
#define COPY_ARGS_0 /* Nothing */
#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0;
#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1;
#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2;
#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3;
#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4;
#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5;
# ifndef ASSEMBLER
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
p_header.data.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1
# endif
#elif !defined ASSEMBLER
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
#endif

View File

@ -0,0 +1,98 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
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. */
#include <sysdep.h>
#include <tls.h>
#ifndef ASSEMBLER
# include <linuxthreads/internals.h>
#endif
#define MULTIPLE_THREADS_OFFSET 40
#if !defined NOT_IN_libc || defined IS_IN_libpthread
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY(name) \
ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1; \
brz,pn %g1, 1f; \
mov SYS_ify(syscall_name), %g1; \
ta 0x6d; \
bcs,pn %xcc, __syscall_error_handler; \
nop; \
.subsection 2; \
1: save %sp, -192, %sp; \
CENABLE; \
nop; \
mov %o0, %l0; \
COPY_ARGS_##args \
mov SYS_ify(syscall_name), %g1; \
ta 0x6d; \
bcs,pn %xcc, __syscall_error_handler2; \
mov %o0, %l1; \
CDISABLE; \
mov %l0, %o0; \
jmpl %i7 + 8, %g0; \
restore %g0, %l1, %o0; \
.previous; \
SYSCALL_ERROR_HANDLER \
SYSCALL_ERROR_HANDLER2
#define SYSCALL_ERROR_HANDLER2 \
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2) \
.global __errno_location; \
.type __errno_location,@function; \
call __errno_location; \
nop; \
st %l1, [%o0]; \
jmpl %i7 + 8, %g0; \
restore %g0, -1, %o0; \
.previous;
# ifdef IS_IN_libpthread
# define CENABLE call __pthread_enable_asynccancel
# define CDISABLE call __pthread_disable_asynccancel
# else
# define CENABLE call __libc_enable_asynccancel
# define CDISABLE call __libc_disable_asynccancel
# endif
#define COPY_ARGS_0 /* Nothing */
#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0;
#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1;
#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2;
#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3;
#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4;
#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5;
# ifndef ASSEMBLER
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
p_header.data.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P ld [%g6 + MULTIPLE_THREADS_OFFSET], %g1
# endif
#elif !defined ASSEMBLER
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
#endif

View File

@ -109,6 +109,11 @@ typedef struct
_result ? "cannot set %fs base address for thread-local storage" : 0; \
})
/* Indicate that dynamic linker shouldn't try to initialize TLS even
when no PT_TLS segments are found in the program and libraries
it is linked against. */
# define TLS_INIT_TP_EXPENSIVE 1
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \
({ struct _pthread_descr_struct *__descr; \

View File

@ -1,3 +1,29 @@
2002-12-28 Ulrich Drepper <drepper@redhat.com>
* descr.h (struct pthread): Move header.data.list to the back of the
struct.
* sysdeps/i386/tls.h (tcbhead_t): Move list to the back of the struct.
(MULTIPLE_THREADS_OFFSET): Adjust offset.
(SYSINFO_OFFSEET): Likewise.
2002-12-27 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h (USE_DL_SYSINFO):
Define.
(DL_SYSINFO_DEFAULT): Cast to uintptr_t to avoid warnings.
* sysdeps/unix/sysv/linux/i386/dl-sysdep.h (NEED_DL_SYSINFO,
DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): Define.
(USE_DL_SYSINFO): Undef.
2002-12-22 Jakub Jelinek <jakub@redhat.com>
* Makefile (tests-reverse): Use $(objpfx)../libc.so instead of
$(common-objpfx)libc.so.
* tst-cancel4.c (tf_write, tf_writev): Increase buf sizes so that
it is bigger than pipe buffer size even on arches with bigger
page size.
(tf_usleep): Cast usleep argument to useconds_t to avoid warnings.
2002-12-25 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/i486/lowlevelsem.S: Implement

View File

@ -217,8 +217,10 @@ $(addprefix $(objpfx), \
$(tests) $(test-srcs))): $(objpfx)libpthread.so \
$(objpfx)libpthread_nonshared.a
$(objpfx)tst-unload: $(common-objpfx)dlfcn/libdl.so
# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
# since otherwise libpthread.so comes before libc.so when linking.
$(addprefix $(objpfx), $(tests-reverse)): \
$(common-objpfx)libc.so $(objpfx)libpthread.so \
$(objpfx)../libc.so $(objpfx)libpthread.so \
$(objpfx)libpthread_nonshared.a
$(addprefix $(objpfx),$(tests-static)): $(objpfx)libpthread.a
else

View File

@ -66,11 +66,11 @@ struct pthread
the address of this thread descriptor. */
union dtv *dtvp;
struct pthread *self; /* Pointer to this structure */
list_t list;
int multiple_threads;
#ifdef NEED_DL_SYSINFO
uintptr_t sysinfo;
#endif
list_t list;
} data;
void *__padding[16];
} header;

View File

@ -42,9 +42,9 @@ typedef struct
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
list_t list;
int multiple_threads;
uintptr_t sysinfo;
list_t list;
} tcbhead_t;
#endif
@ -62,11 +62,11 @@ typedef struct
#define STACK_ALIGN 16
/* Offset of the MULTIPLE_THREADS element in tcbhead_t. */
#define MULTIPLE_THREADS_OFFSET 20
#define MULTIPLE_THREADS_OFFSET 12
#ifdef NEED_DL_SYSINFO
/* Offset of the SYSINFO element in tcbhead_t. */
# define SYSINFO_OFFSET 24
# define SYSINFO_OFFSET 16
#endif

View File

@ -1,4 +1,4 @@
/* System-specific settings for dynamic linker code. Generic version.
/* System-specific settings for dynamic linker code. IA-32 version.
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@ -42,4 +42,28 @@
#define RTLD_CORRECT_DYNAMIC_WEAK 1
/* Traditionally system calls have been made using int $0x80. A
second method was introduced which, if possible, will use the
sysenter/syscall instructions. To signal the presence and where to
find the code the kernel passes an AT_SYSINFO value in the
auxiliary vector to the application.
sysenter/syscall is not useful on i386 through i586, but the dynamic
linker and dl code in libc.a has to be able to load i686 compiled
libraries. */
#define NEED_DL_SYSINFO 1
#undef USE_DL_SYSINFO
#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
extern void _dl_sysinfo_int80 (void) attribute_hidden;
# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
# define DL_SYSINFO_IMPLEMENTATION \
asm (".type _dl_sysinfo_int80,@function\n\t" \
".hidden _dl_sysinfo_int80\n" \
"_dl_sysinfo_int80:\n\t" \
"int $0x80;\n\t" \
"ret;\n\t" \
".size _dl_sysinfo_int80,.-_dl_sysinfo_int80");
#endif
#endif /* dl-sysdep.h */

View File

@ -1,4 +1,4 @@
/* System-specific settings for dynamic linker code. Generic version.
/* System-specific settings for dynamic linker code. IA-32 version.
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@ -49,10 +49,11 @@
find the code the kernel passes an AT_SYSINFO value in the
auxiliary vector to the application. */
#define NEED_DL_SYSINFO 1
#define USE_DL_SYSINFO 1
#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
extern void _dl_sysinfo_int80 (void) attribute_hidden;
# define DL_SYSINFO_DEFAULT _dl_sysinfo_int80
# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
# define DL_SYSINFO_IMPLEMENTATION \
asm (".type _dl_sysinfo_int80,@function\n\t" \
".hidden _dl_sysinfo_int80\n" \

View File

@ -113,7 +113,7 @@ tf_write (void *arg)
exit (1);
}
char buf[10000];
char buf[100000];
memset (buf, '\0', sizeof (buf));
ssize_t s = write (fds[1], buf, sizeof (buf));
@ -133,7 +133,7 @@ tf_writev (void *arg)
exit (1);
}
char buf[10000];
char buf[100000];
memset (buf, '\0', sizeof (buf));
struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
ssize_t s = writev (fds[1], iov, 1);
@ -172,7 +172,7 @@ tf_usleep (void *arg)
exit (1);
}
usleep (ULONG_MAX);
usleep ((useconds_t) ULONG_MAX);
printf ("%s: usleep returns\n", __FUNCTION__);

View File

@ -32,7 +32,7 @@ extern void *__libc_stack_end;
#ifndef SHARED
# include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void)
# if !(USE_TLS - 0)
# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
__attribute__ ((weak))
# endif
;
@ -97,7 +97,7 @@ BP_SYM (__libc_start_main) (int (*main) (int, char **, char **),
we need to setup errno. If there is no thread library and we
handle TLS the function is defined in the libc to initialized the
TLS handling. */
# if !(USE_TLS - 0)
# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
if (__pthread_initialize_minimal)
# endif
__pthread_initialize_minimal ();

View File

@ -135,8 +135,13 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
}
if (memsz == 0 && tcbsize <= TLS_INIT_TCB_SIZE)
/* We do not need a TLS block and no thread descriptor. */
return;
{
/* We do not need a TLS block and no thread descriptor. */
#ifdef NONTLS_INIT_TP
NONTLS_INIT_TP;
#endif
return;
}
/* We have to set up the TCB block which also (possibly) contains
@ -249,4 +254,16 @@ __pthread_initialize_minimal (void)
{
__libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
}
#elif defined NONTLS_INIT_TP
/* This is the minimal initialization function used when libpthread is
not used. */
void
__attribute__ ((weak))
__pthread_initialize_minimal (void)
{
NONTLS_INIT_TP;
}
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1996, 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
@ -18,7 +18,7 @@
#include <signal.h>
#include <unistd.h>
#include <sysdep-cancel.h>
/* Suspend the process until a signal arrives.
This always returns -1 and sets errno to EINTR. */
@ -26,6 +26,12 @@
int
__libc_pause (void)
{
return __sigpause (__sigblock (0), 0);
if (SINGLE_THREAD_P)
return __sigpause (__sigblock (0), 0);
int oldtype = LIBC_CANCEL_ASYNC ();
int result = __sigpause (__sigblock (0), 0);
LIBC_CANCEL_RESET (oldtype);
return result;
}
weak_alias (__libc_pause, pause)

View File

@ -24,7 +24,7 @@
#include <sysdeps/unix/i386/sysdep.h>
#include <bp-sym.h>
#include <bp-asm.h>
/* Defines RTLD_PRIVATE_ERRNO and NEED_DL_SYSINFO. */
/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
#include <dl-sysdep.h>
#include <tls.h>
@ -36,7 +36,8 @@
#undef SYS_ify
#define SYS_ify(syscall_name) __NR_##syscall_name
#if defined NEED_DL_SYSINFO && !defined IS_IN_rtld
#if defined USE_DL_SYSINFO \
&& (!defined NOT_IN_libc || defined IS_IN_libpthread)
# define I386_USE_SYSENTER 1
#else
# undef I386_USE_SYSENTER

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
Based on code originally written by David Mosberger-Tang
@ -83,7 +83,7 @@
#define PSEUDO(name, syscall_name, args) \
ENTRY(name) \
DO_CALL (SYS_ify(syscall_name)); \
cmp.eq p6,p0=-1,r10;; \
cmp.eq p6,p0=-1,r10; \
(p6) br.cond.spnt.few __syscall_error;
#define DO_CALL(num) \
@ -102,11 +102,98 @@
#else /* not __ASSEMBLER__ */
/* Define a macro which expands into the inline wrapper code for a system
call. */
#if 0
/* On IA-64 we have stacked registers for passing arguments. The
"out" registers end up being the called function's "in"
registers.
Also, since we have plenty of registers we have two return values
from a syscall. r10 is set to -1 on error, whilst r8 contains the
(non-negative) errno on error or the return value on success.
*/
#undef INLINE_SYSCALL
#define INLINE_SYSCALL(name, nr, args...) __##name (args)
#endif
#define INLINE_SYSCALL(name, nr, args...) \
({ \
register long _r8 asm ("r8"); \
register long _r10 asm ("r10"); \
register long _r15 asm ("r15") = __NR_##name; \
long _retval; \
LOAD_ARGS_##nr (args); \
__asm __volatile ("break %3;;\n\t" \
: "=r" (_r8), "=r" (_r10), "=r" (_r15) \
: "i" (__BREAK_SYSCALL), "2" (_r15) \
ASM_ARGS_##nr \
: "memory" ASM_CLOBBERS_##nr); \
_retval = _r8; \
if (_r10 == -1) \
{ \
__set_errno (_retval); \
_retval = -1; \
} \
_retval; })
#undef INTERNAL_SYSCALL
#define INTERNAL_SYSCALL(name, nr, args...) \
({ \
register long _r8 asm ("r8"); \
register long _r10 asm ("r10"); \
register long _r15 asm ("r15") = __NR_##name; \
long _retval; \
LOAD_ARGS_##nr (args); \
__asm __volatile ("break %3;;\n\t" \
: "=r" (_r8), "=r" (_r10), "=r" (_r15) \
: "i" (__BREAK_SYSCALL), "2" (_r15) \
ASM_ARGS_##nr \
: "memory" ASM_CLOBBERS_##nr); \
_retval = _r8; \
if (_r10 == -1) \
_retval = -_retval; \
_retval; })
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095UL)
#undef INTERNAL_SYSCALL_ERRNO
#define INTERNAL_SYSCALL_ERRNO(val) (-(val))
#define LOAD_ARGS_0() do { } while (0)
#define LOAD_ARGS_1(out0) \
register long _out0 asm ("out0") = (long) (out0); \
LOAD_ARGS_0 ()
#define LOAD_ARGS_2(out0, out1) \
register long _out1 asm ("out1") = (long) (out1); \
LOAD_ARGS_1 (out0)
#define LOAD_ARGS_3(out0, out1, out2) \
register long _out2 asm ("out2") = (long) (out2); \
LOAD_ARGS_2 (out0, out1)
#define LOAD_ARGS_4(out0, out1, out2, out3) \
register long _out3 asm ("out3") = (long) (out3); \
LOAD_ARGS_3 (out0, out1, out2)
#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \
register long _out4 asm ("out4") = (long) (out4); \
LOAD_ARGS_4 (out0, out1, out2, out3)
#define ASM_ARGS_0
#define ASM_ARGS_1 ASM_ARGS_0, "r" (_out0)
#define ASM_ARGS_2 ASM_ARGS_1, "r" (_out1)
#define ASM_ARGS_3 ASM_ARGS_2, "r" (_out2)
#define ASM_ARGS_4 ASM_ARGS_3, "r" (_out3)
#define ASM_ARGS_5 ASM_ARGS_4, "r" (_out4)
#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0"
#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1"
#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2"
#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3"
#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4"
#define ASM_CLOBBERS_5 , "out5", "out6", "out7", \
/* Non-stacked integer registers, minus r8, r10, r15. */ \
"r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \
"r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
"r28", "r29", "r30", "r31", \
/* Predicate registers. */ \
"p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \
/* Non-rotating fp registers. */ \
"f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
/* Branch registers. */ \
"b6", "b7"
#endif /* not __ASSEMBLER__ */

View File

@ -18,19 +18,19 @@
02111-1307 USA. */
#include <sysdep.h>
.globl __libc_pipe
ENTRY (__libc_pipe)
mov %o0, %o2 /* Save PIPEDES. */
mov SYS_ify(pipe),%g1
ta 0x10
bcc,a 2f
nop
SYSCALL_ERROR_HANDLER
2:
bcs __syscall_error_handler
nop
st %o0, [%o2] /* PIPEDES[0] = %o0; */
st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
retl
clr %o0
clr %o0
SYSCALL_ERROR_HANDLER
PSEUDO_END (__libc_pipe)
weak_alias (__libc_pipe, __pipe)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
/* Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
@ -67,13 +67,12 @@ ENTRY (__socket)
add %sp, 68, %o1 /* arg 2: parameter block */
LOADSYSCALL(socketcall)
t 0x10
bcs,a 1f
bcs __syscall_error_handler
nop
retl
nop
1: SYSCALL_ERROR_HANDLER
SYSCALL_ERROR_HANDLER
END (__socket)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1992, 1997, 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
@ -19,23 +19,17 @@
#include <sysdep.h>
.text
ENTRY (syscall)
or %o0,%g0,%g1
or %o1,%g0,%o0
or %o2,%g0,%o1
or %o3,%g0,%o2
or %o4,%g0,%o3
or %o5,%g0,%o4
mov %o0, %g1
mov %o1, %o0
mov %o2, %o1
mov %o3, %o2
mov %o4, %o3
mov %o5, %o4
ta 0x10
bcc 1f
nop
save %sp, -96, %sp
call __errno_location
nop
st %i0,[%o0]
restore
bcs __syscall_error_handler
nop
retl
mov -1, %o0
1:
ret
nop
SYSCALL_ERROR_HANDLER
PSEUDO_END (syscall)

View File

@ -31,11 +31,7 @@
#ifdef __ASSEMBLER__
#ifdef DONT_LOAD_G1
# define LOADSYSCALL(x)
#else
# define LOADSYSCALL(x) mov __NR_##x, %g1
#endif
#define LOADSYSCALL(x) mov __NR_##x, %g1
/* Linux/SPARC uses a different trap number */
#undef PSEUDO
@ -54,6 +50,21 @@
#define LOC(name) .L##name
#ifdef LINKER_HANDLES_R_SPARC_WDISP22
/* Unfortunately, we cannot do this yet. Linker doesn't seem to
handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly . */
# define SYSCALL_ERROR_HANDLER_ENTRY(handler) \
.section .gnu.linkonce.t.handler,"ax",@progbits; \
.globl handler; \
.hidden handler; \
.type handler,@function; \
handler:
#else
# define SYSCALL_ERROR_HANDLER_ENTRY(handler) \
.subsection 3; \
handler:
#endif
#if RTLD_PRIVATE_ERRNO
# define SYSCALL_ERROR_HANDLER \
.section .gnu.linkonce.t.__sparc.get_pic.l7,"ax",@progbits; \
@ -64,6 +75,7 @@ __sparc.get_pic.l7: \
retl; \
add %o7, %l7, %l7; \
.previous; \
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
save %sp,-96,%sp; \
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \
call __sparc.get_pic.l7; \
@ -71,17 +83,20 @@ __sparc.get_pic.l7: \
ld [%l7 + errno], %l0; \
st %i0, [%l0]; \
jmpl %i7+8, %g0; \
restore %g0, -1, %o0;
restore %g0, -1, %o0; \
.previous;
#else
# define SYSCALL_ERROR_HANDLER \
.global __errno_location; \
.type __errno_location,@function; \
save %sp, -96, %sp; \
call __errno_location; \
nop; \
st %i0, [%o0]; \
jmpl %i7+8, %g0; \
restore %g0, -1, %o0;
# define SYSCALL_ERROR_HANDLER \
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
.global __errno_location; \
.type __errno_location,@function; \
save %sp, -96, %sp; \
call __errno_location; \
nop; \
st %i0, [%o0]; \
jmpl %i7+8, %g0; \
restore %g0, -1, %o0; \
.previous;
#endif
#define PSEUDO(name, syscall_name, args) \
@ -89,10 +104,9 @@ __sparc.get_pic.l7: \
ENTRY(name); \
LOADSYSCALL(syscall_name); \
ta 0x10; \
bcc,a 9000f; \
nop; \
SYSCALL_ERROR_HANDLER; \
9000:;
bcs __syscall_error_handler; \
nop; \
SYSCALL_ERROR_HANDLER
#else /* __ASSEMBLER__ */

View File

@ -23,14 +23,13 @@ ENTRY (__libc_pipe)
mov %o0, %o2 /* Save PIPEDES. */
LOADSYSCALL(pipe)
ta 0x6d
bcc,pt %xcc, 2f
bcs,pn %xcc, __syscall_error_handler
nop
SYSCALL_ERROR_HANDLER
2: st %o0, [%o2] /* PIPEDES[0] = %o0; */
st %o0, [%o2] /* PIPEDES[0] = %o0; */
st %o1, [%o2 + 4] /* PIPEDES[1] = %o1; */
retl
clr %o0
SYSCALL_ERROR_HANDLER
PSEUDO_END (__libc_pipe)
weak_alias (__libc_pipe, __pipe)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
/* Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997.
@ -68,12 +68,12 @@ ENTRY (__socket)
LOADSYSCALL(socketcall)
ta 0x6d
bcs,pn %xcc, 1f
bcs,pn %xcc, __syscall_error_handler
nop
retl
nop
1: SYSCALL_ERROR_HANDLER
SYSCALL_ERROR_HANDLER
END (__socket)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
/* Copyright (C) 1997, 1999, 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
@ -30,11 +30,11 @@ ENTRY (syscall)
ta 0x6d
bcc,pt %xcc,1f
bcs,pn %xcc,__syscall_error_handler
nop
retl
nop
SYSCALL_ERROR_HANDLER
1: retl
nop
PSEUDO_END (syscall)

View File

@ -31,11 +31,7 @@
#ifdef __ASSEMBLER__
#ifdef DONT_LOAD_G1
# define LOADSYSCALL(x)
#else
# define LOADSYSCALL(x) mov __NR_##x, %g1
#endif
#define LOADSYSCALL(x) mov __NR_##x, %g1
/* Linux/SPARC uses a different trap number */
#undef PSEUDO
@ -47,6 +43,21 @@
C_LABEL(name); \
.type name,@function;
#ifdef LINKER_HANDLES_R_SPARC_WDISP22
/* Unfortunately, we cannot do this yet. Linker doesn't seem to
handle R_SPARC_WDISP22 against non-STB_LOCAL symbols properly . */
# define SYSCALL_ERROR_HANDLER_ENTRY(handler) \
.section .gnu.linkonce.t.handler,"ax",@progbits; \
.globl handler; \
.hidden handler; \
.type handler,@function; \
handler:
#else
# define SYSCALL_ERROR_HANDLER_ENTRY(handler) \
.subsection 3; \
handler:
#endif
#if RTLD_PRIVATE_ERRNO
# define SYSCALL_ERROR_HANDLER \
.section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits; \
@ -57,6 +68,7 @@ __sparc64.get_pic.l7: \
retl; \
add %o7, %l7, %l7; \
.previous; \
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
save %sp, -192, %sp; \
sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \
call __sparc64.get_pic.l7; \
@ -64,17 +76,20 @@ __sparc64.get_pic.l7: \
ldx [%l7 + errno], %l0; \
st %i0, [%l0]; \
jmpl %i7+8, %g0; \
restore %g0, -1, %o0;
restore %g0, -1, %o0; \
.previous;
#else
# define SYSCALL_ERROR_HANDLER \
.global __errno_location; \
.type __errno_location,@function; \
save %sp, -192, %sp; \
call __errno_location; \
nop; \
st %i0, [%o0]; \
jmpl %i7+8, %g0; \
restore %g0, -1, %o0;
# define SYSCALL_ERROR_HANDLER \
SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \
.global __errno_location; \
.type __errno_location,@function; \
save %sp, -192, %sp; \
call __errno_location; \
nop; \
st %i0, [%o0]; \
jmpl %i7+8, %g0; \
restore %g0, -1, %o0; \
.previous;
#endif
#define PSEUDO(name, syscall_name, args) \
@ -82,10 +97,9 @@ __sparc64.get_pic.l7: \
ENTRY(name); \
LOADSYSCALL(syscall_name); \
ta 0x6d; \
bcc,pt %xcc, 1f; \
bcs,pn %xcc, __syscall_error_handler; \
nop; \
SYSCALL_ERROR_HANDLER; \
1:
SYSCALL_ERROR_HANDLER
#undef PSEUDO_END
#define PSEUDO_END(name) \