2003-01-04  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>

	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile: New file.
This commit is contained in:
Ulrich Drepper 2003-01-05 10:55:15 +00:00
parent a7f7b879fb
commit 73e9ae887f
22 changed files with 375 additions and 114 deletions

View File

@ -1,3 +1,8 @@
2003-01-04 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/Makefile: New file.
2003-01-04 Jakub Jelinek <jakub@redhat.com> 2003-01-04 Jakub Jelinek <jakub@redhat.com>
* internals.h (LIBC_THREAD_GETMEM, LIBC_THREAD_SETMEM): Define * internals.h (LIBC_THREAD_GETMEM, LIBC_THREAD_SETMEM): Define

View File

@ -0,0 +1 @@
libpthread-routines += sysdep s_pread64 s_pwrite64

View File

@ -0,0 +1,110 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>, 2003.
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>
#ifndef __ASSEMBLER__
# include <linuxthreads/internals.h>
#endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.section ".text"; \
ENTRY (name) \
SINGLE_THREAD_P; \
bne- .Lpseudo_cancel; \
DO_CALL (SYS_ify (syscall_name)); \
PSEUDO_RET; \
.Lpseudo_cancel: \
stwu 1,-48(1); \
mflr 9; \
stw 9,52(1); \
DOCARGS_##args; /* save syscall args around CENABLE. */ \
CENABLE; \
stw 3,16(1); /* store CENABLE return value (MASK). */ \
UNDOCARGS_##args; /* restore syscall args. */ \
DO_CALL (SYS_ify (syscall_name)); \
mfcr 0; /* save CR/R3 around CDISABLE. */ \
stw 3,8(1); \
stw 0,12(1); \
lwz 3,16(1); /* pass MASK to CDISABLE. */ \
CDISABLE; \
lwz 4,52(1); \
lwz 0,12(1); /* restore CR/R3. */ \
lwz 3,8(1); \
mtlr 4; \
mtcr 0; \
addi 1,1,48;
# define DOCARGS_0
# define UNDOCARGS_0
# define DOCARGS_1 stw 3,20(1); DOCARGS_0
# define UNDOCARGS_1 lwz 3,20(1); UNDOCARGS_0
# define DOCARGS_2 stw 4,24(1); DOCARGS_1
# define UNDOCARGS_2 lwz 4,24(1); UNDOCARGS_1
# define DOCARGS_3 stw 5,28(1); DOCARGS_2
# define UNDOCARGS_3 lwz 5,28(1); UNDOCARGS_2
# define DOCARGS_4 stw 6,32(1); DOCARGS_3
# define UNDOCARGS_4 lwz 6,32(1); UNDOCARGS_3
# define DOCARGS_5 stw 7,36(1); DOCARGS_4
# define UNDOCARGS_5 lwz 7,36(1); UNDOCARGS_4
# ifdef IS_IN_libpthread
# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
# define __local_multiple_threads __pthread_multiple_threads
# else
# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
# define __local_multiple_threads __libc_multiple_threads
# endif
# ifndef __ASSEMBLER__
extern int __local_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
# else
# if !defined PIC
# define SINGLE_THREAD_P \
lis 10,__local_multiple_threads@ha; \
lwz 10,__local_multiple_threads@l(10); \
cmpwi 10,0
# else
# define SINGLE_THREAD_P \
mflr 9; \
bl _GLOBAL_OFFSET_TABLE_@local-4; \
mflr 10; \
mtlr 9; \
lwz 10,__local_multiple_threads@got(10); \
lwz 10,0(10); \
cmpwi 10,0
# endif
# endif
#elif !defined __ASSEMBLER__
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
#endif

View File

@ -1,3 +1,7 @@
2003-01-05 Ulrich Drepper <drepper@redhat.com>
* Makefile (libthread_db.so-no-z-defs): Define.
2002-09-29 Ulrich Drepper <drepper@redhat.com> 2002-09-29 Ulrich Drepper <drepper@redhat.com>
* td_thr_tsd.c (td_thr_tsd): Read correct entry from pthread_keys * td_thr_tsd.c (td_thr_tsd): Read correct entry from pthread_keys

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -38,7 +38,7 @@ _pthread_cleanup_push (buffer, routine, arg)
THREAD_SETMEM (self, cleanup, buffer); THREAD_SETMEM (self, cleanup, buffer);
} }
strong_alias (_pthread_cleanup_push, _GI_pthread_cleanup_push) strong_alias (_pthread_cleanup_push, __pthread_cleanup_push)
void void
@ -55,4 +55,4 @@ _pthread_cleanup_pop (buffer, execute)
if (execute) if (execute)
buffer->__routine (buffer->__arg); buffer->__routine (buffer->__arg);
} }
strong_alias (_pthread_cleanup_pop, _GI_pthread_cleanup_pop) strong_alias (_pthread_cleanup_pop, __pthread_cleanup_pop)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -54,7 +54,7 @@ _pthread_cleanup_push_defer (buffer, routine, arg)
THREAD_SETMEM (self, cleanup, buffer); THREAD_SETMEM (self, cleanup, buffer);
} }
strong_alias (_pthread_cleanup_push_defer, __pthread_cleanup_push_defer)
void void
_pthread_cleanup_pop_restore (buffer, execute) _pthread_cleanup_pop_restore (buffer, execute)
@ -84,3 +84,4 @@ _pthread_cleanup_pop_restore (buffer, execute)
if (execute) if (execute)
buffer->__routine (buffer->__arg); buffer->__routine (buffer->__arg);
} }
strong_alias (_pthread_cleanup_pop_restore, __pthread_cleanup_pop_restore)

View File

@ -57,9 +57,9 @@ extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
static struct pthread_functions pthread_functions = static struct pthread_functions pthread_functions =
{ {
.ptr_pthread_attr_destroy = __pthread_attr_destroy, .ptr_pthread_attr_destroy = __pthread_attr_destroy,
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) # if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
.ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0, .ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0,
#endif # endif
.ptr___pthread_attr_init_2_1 = __pthread_attr_init_2_1, .ptr___pthread_attr_init_2_1 = __pthread_attr_init_2_1,
.ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate, .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate,
.ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate, .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate,
@ -78,13 +78,13 @@ static struct pthread_functions pthread_functions =
.ptr___pthread_cond_init = __pthread_cond_init, .ptr___pthread_cond_init = __pthread_cond_init,
.ptr___pthread_cond_signal = __pthread_cond_signal, .ptr___pthread_cond_signal = __pthread_cond_signal,
.ptr___pthread_cond_wait = __pthread_cond_wait, .ptr___pthread_cond_wait = __pthread_cond_wait,
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2) # if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
.ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0, .ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0,
.ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0, .ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0,
.ptr___pthread_cond_init_2_0 = __pthread_cond_init_2_0, .ptr___pthread_cond_init_2_0 = __pthread_cond_init_2_0,
.ptr___pthread_cond_signal_2_0 = __pthread_cond_signal_2_0, .ptr___pthread_cond_signal_2_0 = __pthread_cond_signal_2_0,
.ptr___pthread_cond_wait_2_0 = __pthread_cond_wait_2_0, .ptr___pthread_cond_wait_2_0 = __pthread_cond_wait_2_0,
#endif # endif
.ptr_pthread_equal = __pthread_equal, .ptr_pthread_equal = __pthread_equal,
.ptr___pthread_exit = __pthread_exit, .ptr___pthread_exit = __pthread_exit,
.ptr_pthread_getschedparam = __pthread_getschedparam, .ptr_pthread_getschedparam = __pthread_getschedparam,
@ -95,7 +95,17 @@ static struct pthread_functions pthread_functions =
.ptr_pthread_mutex_unlock = INTUSE(__pthread_mutex_unlock), .ptr_pthread_mutex_unlock = INTUSE(__pthread_mutex_unlock),
.ptr_pthread_self = __pthread_self, .ptr_pthread_self = __pthread_self,
.ptr_pthread_setcancelstate = __pthread_setcancelstate, .ptr_pthread_setcancelstate = __pthread_setcancelstate,
.ptr_pthread_setcanceltype = __pthread_setcanceltype .ptr_pthread_setcanceltype = __pthread_setcanceltype,
.ptr___pthread_cleanup_upto = __pthread_cleanup_upto,
.ptr___pthread_once = __pthread_once_internal,
.ptr___pthread_rwlock_rdlock = __pthread_rwlock_rdlock_internal,
.ptr___pthread_rwlock_wrlock = __pthread_rwlock_wrlock_internal,
.ptr___pthread_rwlock_unlock = __pthread_rwlock_unlock_internal,
.ptr___pthread_key_create = __pthread_key_create_internal,
.ptr___pthread_getspecific = __pthread_getspecific_internal,
.ptr___pthread_setspecific = __pthread_setspecific_internal,
.ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer,
.ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore
}; };
# define ptr_pthread_functions &pthread_functions # define ptr_pthread_functions &pthread_functions
#else #else

View File

@ -22,13 +22,13 @@
#include <pthread.h> #include <pthread.h>
#include <setjmp.h> #include <setjmp.h>
#include <stdint.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include "descr.h" #include "descr.h"
#include <tls.h> #include <tls.h>
#include <lowlevellock.h> #include <lowlevellock.h>
#include <stackinfo.h> #include <stackinfo.h>
#include <internaltypes.h> #include <internaltypes.h>
#include <pthread-functions.h>
/* Internal variables. */ /* Internal variables. */
@ -67,65 +67,6 @@ extern int __pthread_debug attribute_hidden;
#define DEBUGGING_P __builtin_expect (__pthread_debug, 0) #define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
/* Compatibility type for old conditional variable interfaces. */
typedef struct
{
pthread_cond_t *cond;
} pthread_cond_2_0_t;
/* Data type shared with libc. The libc uses it to pass on calls to
the thread functions. */
struct pthread_functions
{
int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
int (*ptr___pthread_attr_init_2_0) (pthread_attr_t *);
int (*ptr___pthread_attr_init_2_1) (pthread_attr_t *);
int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,
struct sched_param *);
int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,
const struct sched_param *);
int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);
int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);
int (*ptr_pthread_condattr_init) (pthread_condattr_t *);
int (*ptr___pthread_cond_broadcast) (pthread_cond_t *);
int (*ptr___pthread_cond_destroy) (pthread_cond_t *);
int (*ptr___pthread_cond_init) (pthread_cond_t *,
const pthread_condattr_t *);
int (*ptr___pthread_cond_signal) (pthread_cond_t *);
int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_2_0_t *);
int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_2_0_t *);
int (*ptr___pthread_cond_init_2_0) (pthread_cond_2_0_t *,
const pthread_condattr_t *);
int (*ptr___pthread_cond_signal_2_0) (pthread_cond_2_0_t *);
int (*ptr___pthread_cond_wait_2_0) (pthread_cond_2_0_t *, pthread_mutex_t *);
int (*ptr_pthread_equal) (pthread_t, pthread_t);
void (*ptr___pthread_exit) (void *);
int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
int (*ptr_pthread_setschedparam) (pthread_t, int,
const struct sched_param *);
int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
const pthread_mutexattr_t *);
int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
pthread_t (*ptr_pthread_self) (void);
int (*ptr_pthread_setcancelstate) (int, int *);
int (*ptr_pthread_setcanceltype) (int, int *);
};
/* Variable in libc.so. */
extern struct pthread_functions __libc_pthread_functions attribute_hidden;
/* Cancellation test. */ /* Cancellation test. */
#define CANCELLATION_P(self) \ #define CANCELLATION_P(self) \
do { \ do { \
@ -299,10 +240,13 @@ extern int __pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
__attr); __attr);
extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_rdlock_internal (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_wrlock_internal (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
extern int __pthread_rwlock_unlock_internal (pthread_rwlock_t *__rwlock);
extern int __pthread_cond_broadcast (pthread_cond_t *cond); extern int __pthread_cond_broadcast (pthread_cond_t *cond);
extern int __pthread_cond_destroy (pthread_cond_t *cond); extern int __pthread_cond_destroy (pthread_cond_t *cond);
extern int __pthread_cond_init (pthread_cond_t *cond, extern int __pthread_cond_init (pthread_cond_t *cond,
@ -312,8 +256,13 @@ extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
extern int __pthread_condattr_destroy (pthread_condattr_t *attr); extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
extern int __pthread_condattr_init (pthread_condattr_t *attr); extern int __pthread_condattr_init (pthread_condattr_t *attr);
extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *)); extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));
extern int __pthread_key_create_internal (pthread_key_t *key,
void (*destr) (void *));
extern void *__pthread_getspecific (pthread_key_t key); extern void *__pthread_getspecific (pthread_key_t key);
extern void *__pthread_getspecific_internal (pthread_key_t key);
extern int __pthread_setspecific (pthread_key_t key, const void *value); extern int __pthread_setspecific (pthread_key_t key, const void *value);
extern int __pthread_setspecific_internal (pthread_key_t key,
const void *value);
extern int __pthread_once (pthread_once_t *once_control, extern int __pthread_once (pthread_once_t *once_control,
void (*init_routine) (void)); void (*init_routine) (void));
extern int __pthread_once_internal (pthread_once_t *once_control, extern int __pthread_once_internal (pthread_once_t *once_control,
@ -340,6 +289,8 @@ extern int __pthread_cond_timedwait_2_0 (pthread_cond_2_0_t *cond,
extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond, extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond,
pthread_mutex_t *mutex); pthread_mutex_t *mutex);
/* The two functions are in libc.so and not exported. */ /* The two functions are in libc.so and not exported. */
extern int __libc_enable_asynccancel (void) attribute_hidden; extern int __libc_enable_asynccancel (void) attribute_hidden;
extern void __libc_disable_asynccancel (int oldtype) extern void __libc_disable_asynccancel (int oldtype)
@ -347,19 +298,24 @@ extern void __libc_disable_asynccancel (int oldtype)
#ifdef IS_IN_libpthread #ifdef IS_IN_libpthread
/* Special versions which use non-exported functions. */ /* Special versions which use non-exported functions. */
extern void _GI_pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer, extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
void (*routine) (void *), void *arg) void (*routine) (void *), void *arg)
attribute_hidden; attribute_hidden;
# undef pthread_cleanup_push # undef pthread_cleanup_push
# define pthread_cleanup_push(routine,arg) \ # define pthread_cleanup_push(routine,arg) \
{ struct _pthread_cleanup_buffer _buffer; \ { struct _pthread_cleanup_buffer _buffer; \
_GI_pthread_cleanup_push (&_buffer, (routine), (arg)); __pthread_cleanup_push (&_buffer, (routine), (arg));
extern void _GI_pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer, extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
int execute) attribute_hidden; int execute) attribute_hidden;
# undef pthread_cleanup_pop # undef pthread_cleanup_pop
# define pthread_cleanup_pop(execute) \ # define pthread_cleanup_pop(execute) \
_GI_pthread_cleanup_pop (&_buffer, (execute)); } __pthread_cleanup_pop (&_buffer, (execute)); }
#endif #endif
extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
void (*routine) (void *), void *arg);
extern void __pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
int execute);
#endif /* pthreadP.h */ #endif /* pthreadP.h */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -66,3 +66,4 @@ __pthread_getspecific (key)
return result; return result;
} }
strong_alias (__pthread_getspecific, pthread_getspecific) strong_alias (__pthread_getspecific, pthread_getspecific)
strong_alias (__pthread_getspecific, __pthread_getspecific_internal)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -66,3 +66,4 @@ __pthread_key_create (key, destr)
return result; return result;
} }
strong_alias (__pthread_key_create, pthread_key_create) strong_alias (__pthread_key_create, pthread_key_create)
strong_alias (__pthread_key_create, __pthread_key_create_internal)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -89,3 +89,4 @@ __pthread_setspecific (key, value)
return 0; return 0;
} }
strong_alias (__pthread_setspecific, pthread_setspecific) strong_alias (__pthread_setspecific, pthread_setspecific)
strong_alias (__pthread_setspecific, __pthread_setspecific_internal)

View File

@ -1,5 +1,5 @@
/* libc-internal interface for mutex locks. NPTL version. /* libc-internal interface for mutex locks. NPTL version.
Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc. Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -34,6 +34,7 @@
#ifdef _LIBC #ifdef _LIBC
# include <lowlevellock.h> # include <lowlevellock.h>
# include <tls.h> # include <tls.h>
# include <pthread-functions.h>
#endif #endif
/* Mutex type. */ /* Mutex type. */
@ -144,6 +145,17 @@ typedef pthread_key_t __libc_key_t;
(FUNC != NULL ? FUNC ARGS : ELSE) (FUNC != NULL ? FUNC ARGS : ELSE)
#endif #endif
/* Call thread functions through the function pointer table. */
#if defined SHARED && !defined NOT_IN_libc
# define PTF(NAME) __libc_pthread_functions.ptr_##NAME
# define __libc_ptf_call(FUNC, ARGS, ELSE) \
(PTF(FUNC) != NULL ? PTF(FUNC) ARGS : ELSE)
#else
# define PTF(NAME) NAME
# define __libc_ptf_call(FUNC, ARGS, ELSE) \
__libc_maybe_call (FUNC, ARGS, ELSE)
#endif
/* Initialize the named lock variable, leaving it in a consistent, unlocked /* Initialize the named lock variable, leaving it in a consistent, unlocked
state. */ state. */
@ -215,9 +227,9 @@ typedef pthread_key_t __libc_key_t;
__libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0) __libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0)
#endif #endif
#define __libc_rwlock_rdlock(NAME) \ #define __libc_rwlock_rdlock(NAME) \
__libc_maybe_call (__pthread_rwlock_rdlock, (&(NAME)), 0) __libc_ptf_call (__pthread_rwlock_rdlock, (&(NAME)), 0)
#define __libc_rwlock_wrlock(NAME) \ #define __libc_rwlock_wrlock(NAME) \
__libc_maybe_call (__pthread_rwlock_wrlock, (&(NAME)), 0) __libc_ptf_call (__pthread_rwlock_wrlock, (&(NAME)), 0)
/* Lock the recursive named lock variable. */ /* Lock the recursive named lock variable. */
#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
@ -289,7 +301,7 @@ typedef pthread_key_t __libc_key_t;
__libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0) __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
#endif #endif
#define __libc_rwlock_unlock(NAME) \ #define __libc_rwlock_unlock(NAME) \
__libc_maybe_call (__pthread_rwlock_unlock, (&(NAME)), 0) __libc_ptf_call (__pthread_rwlock_unlock, (&(NAME)), 0)
/* Unlock the recursive named lock variable. */ /* Unlock the recursive named lock variable. */
#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
@ -324,8 +336,8 @@ typedef pthread_key_t __libc_key_t;
/* Call handler iff the first call. */ /* Call handler iff the first call. */
#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
do { \ do { \
if (__pthread_once != NULL) \ if (PTF(__pthread_once) != NULL) \
__pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION)); \ PTF(__pthread_once) (&(ONCE_CONTROL), INIT_FUNCTION); \
else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \ else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \
INIT_FUNCTION (); \ INIT_FUNCTION (); \
(ONCE_CONTROL) = !PTHREAD_ONCE_INIT; \ (ONCE_CONTROL) = !PTHREAD_ONCE_INIT; \
@ -336,9 +348,9 @@ typedef pthread_key_t __libc_key_t;
/* Start critical region with cleanup. */ /* Start critical region with cleanup. */
#define __libc_cleanup_region_start(DOIT, FCT, ARG) \ #define __libc_cleanup_region_start(DOIT, FCT, ARG) \
{ struct _pthread_cleanup_buffer _buffer; \ { struct _pthread_cleanup_buffer _buffer; \
int _avail = _pthread_cleanup_push_defer != NULL; \ int _avail = PTF(_pthread_cleanup_push_defer) != NULL; \
if (_avail) { \ if (_avail) { \
_pthread_cleanup_push_defer (&_buffer, (FCT), (ARG)); \ PTF(_pthread_cleanup_push_defer) (&_buffer, FCT, ARG); \
} else if (DOIT) { \ } else if (DOIT) { \
_buffer.__routine = (FCT); \ _buffer.__routine = (FCT); \
_buffer.__arg = (ARG); \ _buffer.__arg = (ARG); \
@ -347,7 +359,7 @@ typedef pthread_key_t __libc_key_t;
/* End critical region with cleanup. */ /* End critical region with cleanup. */
#define __libc_cleanup_region_end(DOIT) \ #define __libc_cleanup_region_end(DOIT) \
if (_avail) { \ if (_avail) { \
_pthread_cleanup_pop_restore (&_buffer, (DOIT)); \ PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT); \
} else if (DOIT) \ } else if (DOIT) \
_buffer.__routine (_buffer.__arg); \ _buffer.__routine (_buffer.__arg); \
} }
@ -355,21 +367,21 @@ typedef pthread_key_t __libc_key_t;
/* Sometimes we have to exit the block in the middle. */ /* Sometimes we have to exit the block in the middle. */
#define __libc_cleanup_end(DOIT) \ #define __libc_cleanup_end(DOIT) \
if (_avail) { \ if (_avail) { \
_pthread_cleanup_pop_restore (&_buffer, (DOIT)); \ PTF(_pthread_cleanup_pop_restore) (&_buffer, DOIT); \
} else if (DOIT) \ } else if (DOIT) \
_buffer.__routine (_buffer.__arg) _buffer.__routine (_buffer.__arg)
/* Create thread-specific key. */ /* Create thread-specific key. */
#define __libc_key_create(KEY, DESTRUCTOR) \ #define __libc_key_create(KEY, DESTRUCTOR) \
__libc_maybe_call (__pthread_key_create, (KEY, DESTRUCTOR), 1) __libc_ptf_call (__pthread_key_create, (KEY, DESTRUCTOR), 1)
/* Get thread-specific data. */ /* Get thread-specific data. */
#define __libc_getspecific(KEY) \ #define __libc_getspecific(KEY) \
__libc_maybe_call (__pthread_getspecific, (KEY), NULL) __libc_ptf_call (__pthread_getspecific, (KEY), NULL)
/* Set thread-specific data. */ /* Set thread-specific data. */
#define __libc_setspecific(KEY, VALUE) \ #define __libc_setspecific(KEY, VALUE) \
__libc_maybe_call (__pthread_setspecific, (KEY, VALUE), 0) __libc_ptf_call (__pthread_setspecific, (KEY, VALUE), 0)
/* Register handlers to execute before and after `fork'. Note that the /* Register handlers to execute before and after `fork'. Note that the

View File

@ -0,0 +1,91 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
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 _PTHREAD_FUNCTIONS_H
#define _PTHREAD_FUNCTIONS_H 1
#include <pthread.h>
#include <setjmp.h>
#include <internaltypes.h>
/* Data type shared with libc. The libc uses it to pass on calls to
the thread functions. */
struct pthread_functions
{
int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
int (*ptr___pthread_attr_init_2_0) (pthread_attr_t *);
int (*ptr___pthread_attr_init_2_1) (pthread_attr_t *);
int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,
struct sched_param *);
int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,
const struct sched_param *);
int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);
int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);
int (*ptr_pthread_condattr_init) (pthread_condattr_t *);
int (*ptr___pthread_cond_broadcast) (pthread_cond_t *);
int (*ptr___pthread_cond_destroy) (pthread_cond_t *);
int (*ptr___pthread_cond_init) (pthread_cond_t *,
const pthread_condattr_t *);
int (*ptr___pthread_cond_signal) (pthread_cond_t *);
int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_2_0_t *);
int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_2_0_t *);
int (*ptr___pthread_cond_init_2_0) (pthread_cond_2_0_t *,
const pthread_condattr_t *);
int (*ptr___pthread_cond_signal_2_0) (pthread_cond_2_0_t *);
int (*ptr___pthread_cond_wait_2_0) (pthread_cond_2_0_t *, pthread_mutex_t *);
int (*ptr_pthread_equal) (pthread_t, pthread_t);
void (*ptr___pthread_exit) (void *);
int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
int (*ptr_pthread_setschedparam) (pthread_t, int,
const struct sched_param *);
int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
const pthread_mutexattr_t *);
int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
pthread_t (*ptr_pthread_self) (void);
int (*ptr_pthread_setcancelstate) (int, int *);
int (*ptr_pthread_setcanceltype) (int, int *);
void (*ptr___pthread_cleanup_upto) (jmp_buf, char *);
int (*ptr___pthread_once) (pthread_once_t *, void (*) (void));
int (*ptr___pthread_rwlock_rdlock) (pthread_rwlock_t *);
int (*ptr___pthread_rwlock_wrlock) (pthread_rwlock_t *);
int (*ptr___pthread_rwlock_unlock) (pthread_rwlock_t *);
int (*ptr___pthread_key_create) (pthread_key_t *, void (*) (void *));
int (*ptr___pthread_getspecific) (pthread_key_t);
int (*ptr___pthread_setspecific) (pthread_key_t, const void *);
void (*ptr__pthread_cleanup_push_defer) (struct _pthread_cleanup_buffer *,
void (*) (void *), void *);
void (*ptr__pthread_cleanup_pop_restore) (struct _pthread_cleanup_buffer *,
int);
};
/* Variable in libc.so. */
extern struct pthread_functions __libc_pthread_functions attribute_hidden;
#endif /* pthread-functions.h */

View File

@ -136,7 +136,7 @@ __pthread_cond_wait:
movl %ebx, 8(%esp) movl %ebx, 8(%esp)
movl %eax, 4(%esp) movl %eax, 4(%esp)
movl %edx, (%esp) movl %edx, (%esp)
call _GI_pthread_cleanup_push call __pthread_cleanup_push
/* Get and store current wakeup_seq value. */ /* Get and store current wakeup_seq value. */
movl wakeup_seq(%ebx), %edi movl wakeup_seq(%ebx), %edi
@ -209,7 +209,7 @@ __pthread_cond_wait:
11: leal 12(%esp), %edx 11: leal 12(%esp), %edx
movl $0, 4(%esp) movl $0, 4(%esp)
movl %edx, (%esp) movl %edx, (%esp)
call _GI_pthread_cleanup_pop call __pthread_cleanup_pop
movl 48(%esp), %eax movl 48(%esp), %eax
movl %eax, (%esp) movl %eax, (%esp)
@ -316,7 +316,7 @@ __pthread_cond_timedwait:
movl %ebx, 8(%esp) movl %ebx, 8(%esp)
movl %eax, 4(%esp) movl %eax, 4(%esp)
movl %edx, (%esp) movl %edx, (%esp)
call _GI_pthread_cleanup_push call __pthread_cleanup_push
/* Get and store current wakeup_seq value. */ /* Get and store current wakeup_seq value. */
movl wakeup_seq(%ebx), %edi movl wakeup_seq(%ebx), %edi
@ -425,7 +425,7 @@ __pthread_cond_timedwait:
11: leal 20(%esp), %edx 11: leal 20(%esp), %edx
movl $0, 4(%esp) movl $0, 4(%esp)
movl %edx, (%esp) movl %edx, (%esp)
call _GI_pthread_cleanup_pop call __pthread_cleanup_pop
movl 60(%esp), %ecx movl 60(%esp), %ecx
movl %ecx, (%esp) movl %ecx, (%esp)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -164,6 +164,9 @@ __pthread_rwlock_rdlock:
.globl pthread_rwlock_rdlock .globl pthread_rwlock_rdlock
pthread_rwlock_rdlock = __pthread_rwlock_rdlock pthread_rwlock_rdlock = __pthread_rwlock_rdlock
.globl __pthread_rwlock_rdlock_internal
__pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock
.globl pthread_rwlock_timedrdlock .globl pthread_rwlock_timedrdlock
.type pthread_rwlock_timedrdlock,@function .type pthread_rwlock_timedrdlock,@function
@ -425,6 +428,9 @@ __pthread_rwlock_wrlock:
.globl pthread_rwlock_wrlock .globl pthread_rwlock_wrlock
pthread_rwlock_wrlock = __pthread_rwlock_wrlock pthread_rwlock_wrlock = __pthread_rwlock_wrlock
.globl __pthread_rwlock_wrlock_internal
__pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock
.globl pthread_rwlock_timedwrlock .globl pthread_rwlock_timedwrlock
.type pthread_rwlock_timedwrlock,@function .type pthread_rwlock_timedwrlock,@function
@ -643,3 +649,6 @@ __pthread_rwlock_unlock:
.globl pthread_rwlock_unlock .globl pthread_rwlock_unlock
pthread_rwlock_unlock = __pthread_rwlock_unlock pthread_rwlock_unlock = __pthread_rwlock_unlock
.globl __pthread_rwlock_unlock_internal
__pthread_rwlock_unlock_internal = __pthread_rwlock_unlock

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -103,7 +103,7 @@ __pthread_once:
pushl %ebx pushl %ebx
pushl %eax pushl %eax
pushl %edx pushl %edx
call _GI_pthread_cleanup_push /* Note: no @PLT. */ call __pthread_cleanup_push /* Note: no @PLT. */
movl 44(%esp), %eax movl 44(%esp), %eax
call *%eax call *%eax
@ -113,7 +113,7 @@ __pthread_once:
of the stack. Otherwise the first parameter would have of the stack. Otherwise the first parameter would have
to be reloaded. */ to be reloaded. */
movl $0, 4(%esp) movl $0, 4(%esp)
call _GI_pthread_cleanup_pop /* Note: no @PLT. */ call __pthread_cleanup_pop /* Note: no @PLT. */
addl $28, %esp addl $28, %esp

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -20,6 +20,8 @@
#ifndef _INTERNALTYPES_H #ifndef _INTERNALTYPES_H
#define _INTERNALTYPES_H 1 #define _INTERNALTYPES_H 1
#include <stdint.h>
struct pthread_attr struct pthread_attr
{ {
@ -127,4 +129,11 @@ struct sem
unsigned int count; unsigned int count;
}; };
/* Compatibility type for old conditional variable interfaces. */
typedef struct
{
pthread_cond_t *cond;
} pthread_cond_2_0_t;
#endif /* internaltypes.h */ #endif /* internaltypes.h */

View File

@ -1,5 +1,5 @@
/* _longjmp_unwind -- Clean up stack frames unwound by longjmp. Linux version. /* Clean up stack frames unwound by longjmp. Linux version.
Copyright (C) 1995, 1997, 2002 Free Software Foundation, Inc. Copyright (C) 1995, 1997, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -19,7 +19,7 @@
#include <setjmp.h> #include <setjmp.h>
#include <stddef.h> #include <stddef.h>
#include <pthread-functions.h>
extern void __pthread_cleanup_upto (jmp_buf env, char *targetframe); extern void __pthread_cleanup_upto (jmp_buf env, char *targetframe);
#pragma weak __pthread_cleanup_upto #pragma weak __pthread_cleanup_upto
@ -28,6 +28,12 @@ extern void __pthread_cleanup_upto (jmp_buf env, char *targetframe);
void void
_longjmp_unwind (jmp_buf env, int val) _longjmp_unwind (jmp_buf env, int val)
{ {
if (__pthread_cleanup_upto != NULL) #ifdef SHARED
__pthread_cleanup_upto (env, __builtin_frame_address (0)); # define fptr __libc_pthread_functions.ptr___pthread_cleanup_upto
#else
# define fptr __pthread_cleanup_upto
#endif
if (fptr != NULL)
fptr (env, __builtin_frame_address (0));
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -86,7 +86,7 @@ __pthread_once:
leaq clear_once_control(%rip), %rsi leaq clear_once_control(%rip), %rsi
movq %rdi, %rdx movq %rdi, %rdx
movq %rsp, %rdi movq %rsp, %rdi
call _GI_pthread_cleanup_push /* Note: no @PLT. */ call __pthread_cleanup_push /* Note: no @PLT. */
movq 48(%rsp), %rax movq 48(%rsp), %rax
call *%rax call *%rax
@ -96,7 +96,7 @@ __pthread_once:
of the stack. Otherwise the first parameter would have of the stack. Otherwise the first parameter would have
to be reloaded. */ to be reloaded. */
xorq %rdi, %rdi xorq %rdi, %rdi
call _GI_pthread_cleanup_pop /* Note: no @PLT. */ call __pthread_cleanup_pop /* Note: no @PLT. */
addq $32, %rsp addq $32, %rsp

View File

@ -1,3 +1,7 @@
2003-01-05 Ulrich Drepper <drepper@redhat.com>
* Makefile (libthread_db.so-no-z-defs): Define.
2003-01-03 Roland McGrath <roland@redhat.com> 2003-01-03 Roland McGrath <roland@redhat.com>
* td_thr_setgregs.c (td_thr_setgregs): *_BIT -> *_BITMASK * td_thr_setgregs.c (td_thr_setgregs): *_BIT -> *_BITMASK

View File

@ -12,6 +12,6 @@ oldsetrlimit EXTRA setrlimit i:ip __old_setrlimit setrlimit@GLIBC_2.0
# System calls with 64bit args # System calls with 64bit args
s_ftruncate64 ftruncate64 ftruncate64 i:iii __syscall_ftruncate64 s_ftruncate64 ftruncate64 ftruncate64 i:iii __syscall_ftruncate64
s_pread64 pread64 pread i:ibnii __syscall_pread s_pread64 pread64 pread Ci:ibnii __syscall_pread
s_pwrite64 pwrite64 pwrite i:ibnii __syscall_pwrite s_pwrite64 pwrite64 pwrite Ci:ibnii __syscall_pwrite
s_truncate64 truncate64 truncate64 i:sii __syscall_truncate64 s_truncate64 truncate64 truncate64 i:sii __syscall_truncate64

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1992,97,98,99,2000,01,02 Free Software Foundation, Inc. /* Copyright (C) 1992,97,98,99,2000,01,02,03 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -93,10 +93,50 @@
ret; \ ret; \
}) })
# define LOADARGS_0(name) \ /* Define a macro which expands inline into the wrapper code for a system
call. This use is for internal calls that do not need to handle errors
normally. It will never touch errno. This returns just what the kernel
gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set)
the negation of the return value in the kernel gets reverted. */
#undef INTERNAL_SYSCALL
# define INTERNAL_SYSCALL(name, nr, args...) \
({ \
register long r0 __asm__ ("r0"); \
register long r3 __asm__ ("r3"); \
register long r4 __asm__ ("r4"); \
register long r5 __asm__ ("r5"); \
register long r6 __asm__ ("r6"); \
register long r7 __asm__ ("r7"); \
register long r8 __asm__ ("r8"); \
register long r9 __asm__ ("r9"); \
register long r10 __asm__ ("r10"); \
register long r11 __asm__ ("r11"); \
register long r12 __asm__ ("r12"); \
LOADARGS_##nr(name, args); \
__asm__ __volatile__ \
("sc\n\t" \
"bns+ 0f\n\t" \
"neg %1,%1\n" \
"0:" \
: "=&r" (r0), \
"=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
"=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
: ASM_INPUT_##nr \
: "cr0", "ctr", "memory"); \
(int) r3; \
})
#undef INTERNAL_SYSCALL_ERROR_P
#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095U)
#undef INTERNAL_SYSCALL_ERRNO
#define INTERNAL_SYSCALL_ERRNO(val) (-(val))
# define LOADARGS_0(name, dummy) \
r0 = __NR_##name r0 = __NR_##name
# define LOADARGS_1(name, arg1) \ # define LOADARGS_1(name, arg1) \
LOADARGS_0(name); \ LOADARGS_0(name, 0); \
r3 = (long) (arg1) r3 = (long) (arg1)
# define LOADARGS_2(name, arg1, arg2) \ # define LOADARGS_2(name, arg1, arg2) \
LOADARGS_1(name, arg1); \ LOADARGS_1(name, arg1); \