diff options
Diffstat (limited to 'sysdeps')
21 files changed, 183 insertions, 60 deletions
diff --git a/sysdeps/generic/errno.c b/sysdeps/generic/errno.c index 10dbabe762..03d661b717 100644 --- a/sysdeps/generic/errno.c +++ b/sysdeps/generic/errno.c @@ -22,24 +22,32 @@ #include <dl-sysdep.h> #undef errno -#if USE___THREAD +#if RTLD_PRIVATE_ERRNO + +/* Code compiled for rtld refers only to this name. */ +int rtld_errno attribute_hidden; + +#elif USE___THREAD + __thread int errno; extern __thread int __libc_errno __attribute__ ((alias ("errno"))) attribute_hidden; + #else + /* This differs from plain `int errno;' in that it doesn't create a common definition, but a plain symbol that resides in .bss, which can have an alias. */ -int errno __attribute__ ((section (".bss"))); +int errno __attribute__ ((nocommon)); strong_alias (errno, _errno) /* We declare these with compat_symbol so that they are not visible at link time. Programs must use the accessor functions. RTLD is special, since it's not exported from there at any time. */ -# if defined HAVE_ELF && defined SHARED && defined DO_VERSIONING \ - && !RTLD_PRIVATE_ERRNO +# if defined HAVE_ELF && defined SHARED && defined DO_VERSIONING # include <shlib-compat.h> compat_symbol (libc, errno, errno, GLIBC_2_0); compat_symbol (libc, _errno, _errno, GLIBC_2_0); # endif + #endif diff --git a/sysdeps/i386/bits/atomic.h b/sysdeps/i386/bits/atomic.h index d8aa448d7d..27840f9fe3 100644 --- a/sysdeps/i386/bits/atomic.h +++ b/sysdeps/i386/bits/atomic.h @@ -95,17 +95,29 @@ init_has_cmpxchg (void) \ # define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ if (__builtin_expect (has_cmpxchg, 1)) \ - __asm __volatile (LOCK_PREFIX "cmpxchgw %w2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "r" (newval), "m" (*mem), "0" (oldval)); \ + __asm __volatile (LOCK_PREFIX "cmpxchgw %w2, %1" \ + : "=a" (ret), "=m" (*mem) \ + : "r" (newval), "m" (*mem), "0" (oldval)); \ + else \ + { \ + ret = *mem; \ + if (ret == oldval) \ + *mem = (newval); \ + } \ ret; }) # define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ ({ __typeof (*mem) ret; \ if (__builtin_expect (has_cmpxchg, 1)) \ - __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1" \ - : "=a" (ret), "=m" (*mem) \ - : "r" (newval), "m" (*mem), "0" (oldval)); \ + __asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1" \ + : "=a" (ret), "=m" (*mem) \ + : "r" (newval), "m" (*mem), "0" (oldval)); \ + else \ + { \ + ret = *mem; \ + if (ret == oldval) \ + *mem = (newval); \ + } \ ret; }) /* XXX We do not really need 64-bit compare-and-exchange. At least diff --git a/sysdeps/unix/alpha/sysdep.h b/sysdeps/unix/alpha/sysdep.h index 5259c09a91..f9f1dd6e41 100644 --- a/sysdeps/unix/alpha/sysdep.h +++ b/sysdeps/unix/alpha/sysdep.h @@ -82,7 +82,7 @@ #if RTLD_PRIVATE_ERRNO # define SYSCALL_ERROR_LABEL $syscall_error # define SYSCALL_ERROR_HANDLER \ - stl v0, errno(gp) !gprel; \ + stl v0, rtld_errno(gp) !gprel; \ lda v0, -1; \ ret #elif defined(PIC) diff --git a/sysdeps/unix/i386/sysdep.S b/sysdeps/unix/i386/sysdep.S index dceb6815f4..6056cbeef2 100644 --- a/sysdeps/unix/i386/sysdep.S +++ b/sysdeps/unix/i386/sysdep.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 2000, 2002 +/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 2000, 2002, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -68,7 +68,7 @@ notb: popl %ebx movl %eax, %gs:0(%ecx) # elif RTLD_PRIVATE_ERRNO - movl %eax, C_SYMBOL_NAME(errno@GOTOFF)(%ebx) + movl %eax, C_SYMBOL_NAME(rtld_errno@GOTOFF)(%ebx) /* Pop %ebx value saved before jumping here. */ popl %ebx diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index fd089dd236..37be75e964 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -153,4 +153,5 @@ endif ifeq ($(subdir),nscd) CFLAGS-connections.c += -DHAVE_EPOLL +CFLAGS-gai.c += -DNEED_NETLINK endif diff --git a/sysdeps/unix/sysv/linux/i386/sysconf.c b/sysdeps/unix/sysv/linux/i386/sysconf.c index cb4706de73..eae849b277 100644 --- a/sysdeps/unix/sysv/linux/i386/sysconf.c +++ b/sysdeps/unix/sysv/linux/i386/sysconf.c @@ -21,7 +21,7 @@ #include <stdbool.h> #include <stdlib.h> #include <unistd.h> - +#include <hp-timing.h> static long int linux_sysconf (int name); @@ -319,16 +319,9 @@ handle_amd (int name) } -/* Get the value of the system variable NAME. */ -long int -__sysconf (int name) +static int +i386_i486_test (void) { - /* We only handle the cache information here (for now). */ - if (name < _SC_LEVEL1_ICACHE_SIZE || name > _SC_LEVEL4_CACHE_LINESIZE) - return linux_sysconf (name); - - /* Recognize i386 and compatible. These don't have any cache on - board. */ int eflags; int ac; asm volatile ("pushfl;\n\t" @@ -343,6 +336,35 @@ __sysconf (int name) "pushl %0;\n\t" "popfl" : "=r" (eflags), "=r" (ac)); + + return ac; +} + + +/* Get the value of the system variable NAME. */ +long int +__sysconf (int name) +{ + if (name == _SC_CPUTIME || name == _SC_THREAD_CPUTIME) + { +#if HP_TIMING_AVAIL + // XXX We can add here test for machines which cannot support a + // XXX usable TSC. + return 200112L; +#else + return -1; +#endif + } + + /* All the remainder, except the cache information, is handled in + the generic code. */ + if (name < _SC_LEVEL1_ICACHE_SIZE || name > _SC_LEVEL4_CACHE_LINESIZE) + return linux_sysconf (name); + + /* Recognize i386 and compatible. These don't have any cache on + board. */ + int ac = i386_i486_test (); + if (ac == 0) /* This is an i386. */ // XXX Is this true for all brands? diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h index 8845e46157..37e7459a9c 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -136,7 +136,7 @@ __i686.get_pc_thunk.reg: \ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ xorl %edx, %edx; \ subl %eax, %edx; \ - movl %edx, errno@GOTOFF(%ecx); \ + movl %edx, rtld_errno@GOTOFF(%ecx); \ orl $-1, %eax; \ jmp L(pseudo_end); diff --git a/sysdeps/unix/sysv/linux/ia64/Dist b/sysdeps/unix/sysv/linux/ia64/Dist index c9e81a3e8f..b4118bdead 100644 --- a/sysdeps/unix/sysv/linux/ia64/Dist +++ b/sysdeps/unix/sysv/linux/ia64/Dist @@ -2,6 +2,7 @@ clone.S clone2.S dl-brk.S dl-static.c +has_cpuclock.c ioperm.c ldd-rewrite.sed __start_context.S diff --git a/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c b/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c index 68e5763a8c..d2c45a560a 100644 --- a/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c +++ b/sysdeps/unix/sysv/linux/ia64/clock_getcpuclockid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2003, 2004 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 @@ -24,6 +24,9 @@ #include <fcntl.h> +#include "has_cpuclock.c" + + int clock_getcpuclockid (pid_t pid, clockid_t *clock_id) { @@ -31,30 +34,9 @@ clock_getcpuclockid (pid_t pid, clockid_t *clock_id) if (pid != 0 && pid != getpid ()) return EPERM; - static int itc_usable; int retval = ENOENT; - if (__builtin_expect (itc_usable == 0, 0)) - { - int newval = 1; - int fd = open ("/proc/sal/itc_drift", O_RDONLY); - if (__builtin_expect (fd != -1, 1)) - { - char buf[16]; - /* We expect the file to contain a single digit followed by - a newline. If the format changes we better not rely on - the file content. */ - if (read (fd, buf, sizeof buf) != 2 || buf[0] != '0' - || buf[1] != '\n') - newval = -1; - - close (fd); - } - - itc_usable = newval; - } - - if (itc_usable > 0) + if (has_cpuclock () > 0) { /* Store the number. */ *clock_id = CLOCK_PROCESS_CPUTIME_ID; diff --git a/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c b/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c new file mode 100644 index 0000000000..ee19161272 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/has_cpuclock.c @@ -0,0 +1,52 @@ +/* Copyright (C) 2000, 2001, 2003, 2004 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. */ + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> + + +static int itc_usable; + +static int +has_cpuclock (void) +{ + if (__builtin_expect (itc_usable == 0, 0)) + { + int newval = 1; + int fd = open ("/proc/sal/itc_drift", O_RDONLY); + if (__builtin_expect (fd != -1, 1)) + { + char buf[16]; + /* We expect the file to contain a single digit followed by + a newline. If the format changes we better not rely on + the file content. */ + if (read (fd, buf, sizeof buf) != 2 || buf[0] != '0' + || buf[1] != '\n') + newval = -1; + + close (fd); + } + + itc_usable = newval; + } + + return itc_usable; +} diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf.c b/sysdeps/unix/sysv/linux/ia64/sysconf.c new file mode 100644 index 0000000000..4b5d1ce2cd --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/sysconf.c @@ -0,0 +1,45 @@ +/* Get file-specific information about a file. Linux version. + Copyright (C) 2003, 2004 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. */ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> + + +#include "has_cpuclock.c" + +static long int linux_sysconf (int name); + + +/* Get the value of the system variable NAME. */ +long int +__sysconf (int name) +{ + if (name == _SC_CPUTIME || name == _SC_THREAD_CPUTIME) + return has_cpuclock () ? 200112L : -1; + + /* Everything else is handled by the more general code. */ + return linux_sysconf (name); +} + +/* Now the generic Linux version. */ +#undef __sysconf +#define __sysconf static linux_sysconf +#include "../sysconf.c" diff --git a/sysdeps/unix/sysv/linux/ia64/sysdep.S b/sysdeps/unix/sysv/linux/ia64/sysdep.S index 3b4b600b42..3633dd4b78 100644 --- a/sysdeps/unix/sysv/linux/ia64/sysdep.S +++ b/sysdeps/unix/sysv/linux/ia64/sysdep.S @@ -30,7 +30,7 @@ ENTRY(__syscall_error) * be fine. Otherwise, we would have to first load the global * pointer register from __gp. */ - addl r2=@gprel(errno),gp + addl r2=@gprel(rtld_errno),gp ;; st4 [r2]=r8 mov r8=-1 diff --git a/sysdeps/unix/sysv/linux/m68k/sysdep.h b/sysdeps/unix/sysv/linux/m68k/sysdep.h index 234ce32f4f..091dfc9c7d 100644 --- a/sysdeps/unix/sysv/linux/m68k/sysdep.h +++ b/sysdeps/unix/sysv/linux/m68k/sysdep.h @@ -98,7 +98,7 @@ # if RTLD_PRIVATE_ERRNO # define SYSCALL_ERROR_HANDLER \ SYSCALL_ERROR_LABEL: \ - lea (errno, %pc), %a0; \ + lea (rtld_errno, %pc), %a0; \ neg.l %d0; \ move.l %d0, (%a0); \ move.l &-1, %d0; \ diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S index 1aad4ab164..2a1dad0695 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S +++ b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S @@ -82,7 +82,7 @@ ENTRY(__syscall_error) st %r2,0(%r1) lhi %r2,-1 br %r14 -1: .long errno - 0b +1: .long rtld_errno - 0b # elif USE___THREAD # ifndef NOT_IN_libc # define SYSCALL_ERROR_ERRNO __libc_errno diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h index 55a2cd7443..ad3cde6a66 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h @@ -97,7 +97,7 @@ st %r2,0(%r1); \ lhi %r2,-1; \ br %r14; \ -2: .long errno-1b +2: .long rtld_errno-1b # elif defined _LIBC_REENTRANT # if USE___THREAD # ifndef NOT_IN_libc diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S index 4299257afa..bb61e894f1 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S @@ -74,7 +74,7 @@ ENTRY(__syscall_error) #endif #else # if RTLD_PRIVATE_ERRNO - larl %r1,errno + larl %r1,rtld_errno lcr %r2,%r2 st %r2,0(%r1) lghi %r2,-1 @@ -100,7 +100,7 @@ ENTRY(__syscall_error) lcr %r2,%r2 st %r2,0(%r1) lghi %r2,-1 - br %r14 + br %r14 # else stmg %r13,%r15,104(%r15) cfi_offset (%r15,-40) diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h index c7f3a03f26..45e701e7a4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h @@ -101,7 +101,7 @@ # if RTLD_PRIVATE_ERRNO # define SYSCALL_ERROR_LABEL 0f # define SYSCALL_ERROR_HANDLER \ -0: larl %r1,errno; \ +0: larl %r1,rtld_errno; \ lcr %r2,%r2; \ st %r2,0(%r1); \ lghi %r2,-1; \ diff --git a/sysdeps/unix/sysv/linux/sh/sysdep.h b/sysdeps/unix/sysv/linux/sh/sysdep.h index aeec279de0..d56ec454f9 100644 --- a/sysdeps/unix/sysv/linux/sh/sysdep.h +++ b/sysdeps/unix/sysv/linux/sh/sysdep.h @@ -1,5 +1,5 @@ -/* Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2002, - 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1992,1993,1995,1996,1997,1998,1999,2000,2002,2003,2004 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995. Changed by Kaz Kojima, <kkojima@rr.iij4u.or.jp>. @@ -109,7 +109,7 @@ mov _IMM1,r0; \ .align 2; \ 0: .long _GLOBAL_OFFSET_TABLE_; \ - 1: .long errno@GOTOFF + 1: .long rtld_errno@GOTOFF # elif defined _LIBC_REENTRANT diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h index 67cb32645b..29c5158b9f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h @@ -83,7 +83,7 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler) \ sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \ call __sparc_get_pic_l7; \ add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \ - ld [%l7 + errno], %l0; \ + ld [%l7 + rtld_errno], %l0; \ st %i0, [%l0]; \ jmpl %i7+8, %g0; \ restore %g0, -1, %o0; \ diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 56e4422a73..fd92d7ae16 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -118,7 +118,7 @@ #elif RTLD_PRIVATE_ERRNO # define SYSCALL_ERROR_HANDLER \ 0: \ - leaq errno(%rip), %rcx; \ + leaq rtld_errno(%rip), %rcx; \ xorq %rdx, %rdx; \ subq %rax, %rdx; \ movl %edx, (%rcx); \ diff --git a/sysdeps/unix/x86_64/sysdep.S b/sysdeps/unix/x86_64/sysdep.S index d2c3d0916c..0d0d715052 100644 --- a/sysdeps/unix/x86_64/sysdep.S +++ b/sysdeps/unix/x86_64/sysdep.S @@ -67,7 +67,7 @@ notb: # endif #else # if RTLD_PRIVATE_ERRNO - leaq errno(%rip), %rcx + leaq rtld_errno(%rip), %rcx movl %eax, (%rcx) # elif !defined _LIBC_REENTRANT movq C_SYMBOL_NAME(errno)@GOTPCREL(%rip), %rcx |