2002-07-19  Ulrich Drepper  <drepper@redhat.com>

	* configure.in: Add test for __thread support in compiler.
	* config.h.in: Add HAVE___THREAD.
	* Makefile (headers): Remove errno.h, sys/errno.h, and bits/errno.h.
	* include/sys/errno.h: Moved to...
	* stdlib/sys/errno.h: ...here.  New file.
	* stdlib/errno.h: New file.  Moved from...
	* include/errno.h: ...here.  Changed into an internal header defining
	libc-local things like __set_errno.
	* stdlib/Makefile (headers): Add errno.h, sys/errno.h, and
	bits/errno.h.
	* elf/dl-minimal.c: Include <tls.h>.  Define errno as thread-local
	variable if USE_TLS && HAVE___THREAD.  Don't define __errno_location
	either.
	* elf/rtld.c (_dl_start): Add code to initialize TLS for ld.so
	from...
	(_dl_start_final): ...here.  Add code to initialize tls elements from
	bootstrap_map.
	* sysdeps/generic/errno-loc.c: Define errno as thread-local variable
	if USE_TLS && HAVE___THREAD.
	* sysdeps/generic/bits/errno.h: Remove __set_errno definition.
	* sysdeps/mach/hurd/bits/errno.h: Likewise.
	* sysdeps/standalone/arm/bits/errno.h: Likewise.
	* sysdeps/standalone/bits/errno.h: Likewise.
	* sysdeps/unix/bsd/bsd4.4/bits/errno.h: Likewise.
	* sysdeps/unix/sysv/aix/bits/errno.h: Likewise.
	* sysdeps/unix/sysv/hpux/bits/errno.h: Likewise.
	* sysdeps/unix/sysv/linux/bits/errno.h: Likewise.
	* sysdeps/unix/sysv/linux/hppa/bits/errno.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/errno.h: Likewise.
	* sysdeps/unix/sysv/sysv4/solaris2/bits/errno.h: Likewise.
	* sysdeps/i386/dl-machine.c (elf_machine_rel) [RTLD_BOOTSTRAP]: Don't
	use GL(dl_rtld_map), use map parameter.
	* sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise.
	* sysdeps/unix/sysv/linux/i386/sysdep.S: Define errno in .tbss if
	USE_TLS && HAVE___THREAD.
	* sysdeps/unix/sysv/linux/i386/sysdep.h: Unify SETUP_PIC_REG
	definitions.  If USE_TLS && HAVE___THREAD store errooor value using
	TLS code sequence.
	* sysdeps/unix/sysv/linux/i386/i686/sysdep.h: Likewise.

	* sysdeps/unix/sysv/linux/getcwd.c: No real need to restore errno.
	* sysdeps/unix/sysv/linux/grantpt.c: Likewise.
	* sysdeps/unix/sysv/linux/internal_statvfs.c: Likewise.
	* sysdeps/unix/sysv/linux/msgctl.c: Likewise.
	* sysdeps/unix/sysv/linux/readv.c: Likewise.
	* sysdeps/unix/sysv/linux/writev.c: Likewise.
This commit is contained in:
Ulrich Drepper 2002-07-20 01:14:41 +00:00
parent 9df63767d4
commit 739d440d2a
41 changed files with 447 additions and 350 deletions

View File

@ -1,3 +1,52 @@
2002-07-19 Ulrich Drepper <drepper@redhat.com>
* configure.in: Add test for __thread support in compiler.
* config.h.in: Add HAVE___THREAD.
* Makefile (headers): Remove errno.h, sys/errno.h, and bits/errno.h.
* include/sys/errno.h: Moved to...
* stdlib/sys/errno.h: ...here. New file.
* stdlib/errno.h: New file. Moved from...
* include/errno.h: ...here. Changed into an internal header defining
libc-local things like __set_errno.
* stdlib/Makefile (headers): Add errno.h, sys/errno.h, and
bits/errno.h.
* elf/dl-minimal.c: Include <tls.h>. Define errno as thread-local
variable if USE_TLS && HAVE___THREAD. Don't define __errno_location
either.
* elf/rtld.c (_dl_start): Add code to initialize TLS for ld.so
from...
(_dl_start_final): ...here. Add code to initialize tls elements from
bootstrap_map.
* sysdeps/generic/errno-loc.c: Define errno as thread-local variable
if USE_TLS && HAVE___THREAD.
* sysdeps/generic/bits/errno.h: Remove __set_errno definition.
* sysdeps/mach/hurd/bits/errno.h: Likewise.
* sysdeps/standalone/arm/bits/errno.h: Likewise.
* sysdeps/standalone/bits/errno.h: Likewise.
* sysdeps/unix/bsd/bsd4.4/bits/errno.h: Likewise.
* sysdeps/unix/sysv/aix/bits/errno.h: Likewise.
* sysdeps/unix/sysv/hpux/bits/errno.h: Likewise.
* sysdeps/unix/sysv/linux/bits/errno.h: Likewise.
* sysdeps/unix/sysv/linux/hppa/bits/errno.h: Likewise.
* sysdeps/unix/sysv/linux/mips/bits/errno.h: Likewise.
* sysdeps/unix/sysv/sysv4/solaris2/bits/errno.h: Likewise.
* sysdeps/i386/dl-machine.c (elf_machine_rel) [RTLD_BOOTSTRAP]: Don't
use GL(dl_rtld_map), use map parameter.
* sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise.
* sysdeps/unix/sysv/linux/i386/sysdep.S: Define errno in .tbss if
USE_TLS && HAVE___THREAD.
* sysdeps/unix/sysv/linux/i386/sysdep.h: Unify SETUP_PIC_REG
definitions. If USE_TLS && HAVE___THREAD store errooor value using
TLS code sequence.
* sysdeps/unix/sysv/linux/i386/i686/sysdep.h: Likewise.
* sysdeps/unix/sysv/linux/getcwd.c: No real need to restore errno.
* sysdeps/unix/sysv/linux/grantpt.c: Likewise.
* sysdeps/unix/sysv/linux/internal_statvfs.c: Likewise.
* sysdeps/unix/sysv/linux/msgctl.c: Likewise.
* sysdeps/unix/sysv/linux/readv.c: Likewise.
* sysdeps/unix/sysv/linux/writev.c: Likewise.
2002-07-17 Ulrich Drepper <drepper@redhat.com> 2002-07-17 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/ia64/bits/mman.h: Fix MS_SYNC and * sysdeps/unix/sysv/linux/ia64/bits/mman.h: Fix MS_SYNC and

View File

@ -63,9 +63,8 @@ configure: configure.in aclocal.m4; $(autoconf-it)
subdir_testclean \ subdir_testclean \
$(addprefix install-, no-libc.a bin lib data headers others) $(addprefix install-, no-libc.a bin lib data headers others)
headers := errno.h sys/errno.h bits/errno.h limits.h values.h \ headers := limits.h values.h features.h gnu-versions.h bits/libc-lock.h \
features.h gnu-versions.h bits/libc-lock.h bits/xopen_lim.h \ bits/xopen_lim.h gnu/libc-version.h
gnu/libc-version.h
echo-headers: subdir_echo-headers echo-headers: subdir_echo-headers

View File

@ -33,5 +33,3 @@
# define Exxxx XXX # define Exxxx XXX
... ...
#endif #endif
#define __set_errno(val) errno = (val)

View File

@ -94,6 +94,9 @@
/* Define if the compiler supports __builtin_memset. */ /* Define if the compiler supports __builtin_memset. */
#undef HAVE_BUILTIN_MEMSET #undef HAVE_BUILTIN_MEMSET
/* Define if the __thread keyword is supported. */
#undef HAVE___THREAD
/* Define if the regparm attribute shall be used for local functions /* Define if the regparm attribute shall be used for local functions
(gcc on ix86 only). */ (gcc on ix86 only). */
#undef USE_REGPARMS #undef USE_REGPARMS

45
configure vendored
View File

@ -3540,8 +3540,33 @@ EOF
fi fi
echo $ac_n "checking for __thread""... $ac_c" 1>&6
echo "configure:3545: checking for __thread" >&5
if eval "test \"`echo '$''{'libc_cv_gcc___thread'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.c <<EOF
__thread int a = 42;
EOF
if { ac_try='${CC-cc} $CFLAGS -c conftest.c >&5'; { (eval echo configure:3552: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_gcc___thread=yes
else
libc_cv_gcc___thread=no
fi
rm -f conftest*
fi
echo "$ac_t""$libc_cv_gcc___thread" 1>&6
if test "$libc_cv_gcc___thread" = yes; then
cat >> confdefs.h <<\EOF
#define HAVE___THREAD 1
EOF
fi
echo $ac_n "checking for libgd""... $ac_c" 1>&6 echo $ac_n "checking for libgd""... $ac_c" 1>&6
echo "configure:3545: checking for libgd" >&5 echo "configure:3570: checking for libgd" >&5
if test "$with_gd" != "no"; then if test "$with_gd" != "no"; then
old_CFLAGS="$CFLAGS" old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $libgd_include" CFLAGS="$CFLAGS $libgd_include"
@ -3550,14 +3575,14 @@ if test "$with_gd" != "no"; then
old_LIBS="$LIBS" old_LIBS="$LIBS"
LIBS="$LIBS -lgd -lpng -lz -lm" LIBS="$LIBS -lgd -lpng -lz -lm"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3554 "configure" #line 3579 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <gd.h> #include <gd.h>
int main() { int main() {
gdImagePng (0, 0) gdImagePng (0, 0)
; return 0; } ; return 0; }
EOF EOF
if { (eval echo configure:3561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then if { (eval echo configure:3586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest* rm -rf conftest*
LIBGD=yes LIBGD=yes
else else
@ -3577,7 +3602,7 @@ echo "$ac_t""$LIBGD" 1>&6
echo $ac_n "checking size of long double""... $ac_c" 1>&6 echo $ac_n "checking size of long double""... $ac_c" 1>&6
echo "configure:3581: checking size of long double" >&5 echo "configure:3606: checking size of long double" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -3585,7 +3610,7 @@ else
ac_cv_sizeof_long_double=0 ac_cv_sizeof_long_double=0
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 3589 "configure" #line 3614 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <stdio.h> #include <stdio.h>
int main() int main()
@ -3596,7 +3621,7 @@ int main()
return(0); return(0);
} }
EOF EOF
if { (eval echo configure:3600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null if { (eval echo configure:3625: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then then
ac_cv_sizeof_long_double=`cat conftestval` ac_cv_sizeof_long_double=`cat conftestval`
else else
@ -3674,7 +3699,7 @@ if test "$uname" = "sysdeps/generic"; then
fi fi
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6 echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
echo "configure:3678: checking OS release for uname" >&5 echo "configure:3703: checking OS release for uname" >&5
if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -3696,7 +3721,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
uname_release="$libc_cv_uname_release" uname_release="$libc_cv_uname_release"
echo $ac_n "checking OS version for uname""... $ac_c" 1>&6 echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
echo "configure:3700: checking OS version for uname" >&5 echo "configure:3725: checking OS version for uname" >&5
if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -3725,7 +3750,7 @@ EOF
# Test for old glibc 2.0.x headers so that they can be removed properly # Test for old glibc 2.0.x headers so that they can be removed properly
# Search only in includedir. # Search only in includedir.
echo $ac_n "checking for old glibc 2.0.x headers""... $ac_c" 1>&6 echo $ac_n "checking for old glibc 2.0.x headers""... $ac_c" 1>&6
echo "configure:3729: checking for old glibc 2.0.x headers" >&5 echo "configure:3754: checking for old glibc 2.0.x headers" >&5
if eval test -f "${includedir}/elfclass.h" -a -f "${includedir}/fcntlbits.h" if eval test -f "${includedir}/elfclass.h" -a -f "${includedir}/fcntlbits.h"
then then
old_glibc_headers=yes old_glibc_headers=yes
@ -3786,7 +3811,7 @@ if test $shared = default; then
fi fi
echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6 echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6
echo "configure:3790: checking whether -fPIC is default" >&5 echo "configure:3815: checking whether -fPIC is default" >&5
if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else

View File

@ -1513,6 +1513,22 @@ if test "$libc_cv_gcc_subtract_local_labels" = yes; then
AC_DEFINE(HAVE_SUBTRACT_LOCAL_LABELS) AC_DEFINE(HAVE_SUBTRACT_LOCAL_LABELS)
fi fi
dnl Check whether the compiler supports the __thread keyword.
AC_CACHE_CHECK([for __thread], libc_cv_gcc___thread,
[cat > conftest.c <<EOF
__thread int a = 42;
EOF
if AC_TRY_COMMAND([${CC-cc} $CFLAGS -c conftest.c >&AC_FD_CC]); then
libc_cv_gcc___thread=yes
else
libc_cv_gcc___thread=no
fi
rm -f conftest*])
if test "$libc_cv_gcc___thread" = yes; then
AC_DEFINE(HAVE___THREAD)
fi
dnl Check whether we have the gd library available. dnl Check whether we have the gd library available.
AC_MSG_CHECKING(for libgd) AC_MSG_CHECKING(for libgd)
if test "$with_gd" != "no"; then if test "$with_gd" != "no"; then

View File

@ -20,6 +20,7 @@
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <tls.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/param.h> #include <sys/param.h>
@ -354,8 +355,12 @@ const char INTUSE(_itoa_lower_digits)[16] attribute_hidden
= "0123456789abcdef"; = "0123456789abcdef";
#undef errno #undef errno
/* The 'errno' in ld.so is not exported. */ /* The 'errno' in ld.so is not exported. */
#if USE_TLS && HAVE___THREAD
extern __thread int errno attribute_hidden;
#else
extern int errno attribute_hidden; extern int errno attribute_hidden;
int * int *
@ -363,3 +368,4 @@ __errno_location (void)
{ {
return &errno; return &errno;
} }
#endif

View File

@ -130,9 +130,14 @@ _dl_start (void *arg)
{ {
struct link_map bootstrap_map; struct link_map bootstrap_map;
hp_timing_t start_time; hp_timing_t start_time;
#ifndef HAVE_BUILTIN_MEMSET #if !defined HAVE_BUILTIN_MEMSET || defined USE_TLS
size_t cnt; size_t cnt;
#endif #endif
#ifdef USE_TLS
ElfW(Ehdr) *ehdr;
ElfW(Phdr) *phdr;
dtv_t initdtv[3];
#endif
/* This #define produces dynamic linking inline functions for /* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation. */ bootstrap relocation instead of general-purpose relocation. */
@ -166,6 +171,97 @@ _dl_start (void *arg)
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
elf_get_dynamic_info (&bootstrap_map); elf_get_dynamic_info (&bootstrap_map);
#if USE_TLS
# ifndef HAVE___THREAD
/* Signal that we have not found TLS data so far. */
bootstrap_map.l_tls_modid = 0;
# endif
/* Get the dynamic linkers program header. */
ehdr = (ElfW(Ehdr) *) bootstrap_map.l_addr;
phdr = (ElfW(Phdr) *) (bootstrap_map.l_addr + ehdr->e_phoff);
for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
if (phdr[cnt].p_type == PT_TLS)
{
void *tlsblock;
size_t max_align = MAX (TLS_INIT_TCB_ALIGN, phdr[cnt].p_align);
bootstrap_map.l_tls_blocksize = phdr[cnt].p_memsz;
bootstrap_map.l_tls_align = phdr[cnt].p_align;
assert (bootstrap_map.l_tls_blocksize != 0);
bootstrap_map.l_tls_initimage_size = phdr[cnt].p_filesz;
bootstrap_map.l_tls_initimage = (void *) (bootstrap_map.l_addr
+ phdr[cnt].p_offset);
/* We can now allocate the initial TLS block. This can happen
on the stack. We'll get the final memory later when we
know all about the various objects loaded at startup
time. */
# if TLS_TCB_AT_TP
tlsblock = alloca (roundup (bootstrap_map.l_tls_blocksize,
TLS_INIT_TCB_ALIGN)
+ TLS_INIT_TCB_SIZE
+ max_align);
# elif TLS_DTV_AT_TP
tlsblock = alloca (roundup (TLS_INIT_TCB_SIZE,
bootstrap_map.l_tls_align)
+ bootstrap_map.l_tls_blocksize
+ max_align);
# else
/* In case a model with a different layout for the TCB and DTV
is defined add another #elif here and in the following #ifs. */
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
/* Align the TLS block. */
tlsblock = (void *) (((uintptr_t) tlsblock + max_align - 1)
& ~(max_align - 1));
/* Initialize the dtv. [0] is the length, [1] the generation
counter. */
initdtv[0].counter = 1;
initdtv[1].counter = 0;
/* Initialize the TLS block. */
# if TLS_TCB_AT_TP
initdtv[2].pointer = tlsblock;
# elif TLS_DTV_AT_TP
bootstrap_map.l_tls_offset = roundup (TLS_INIT_TCB_SIZE,
bootstrap_map.l_tls_align);
initdtv[2].pointer = (char *) tlsblock + bootstrap_map.l_tls_offset;
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
memset (__mempcpy (initdtv[2].pointer, bootstrap_map.l_tls_initimage,
bootstrap_map.l_tls_initimage_size),
'\0', (bootstrap_map.l_tls_blocksize
- bootstrap_map.l_tls_initimage_size));
/* Install the pointer to the dtv. */
/* Initialize the thread pointer. */
# if TLS_TCB_AT_TP
bootstrap_map.l_tls_offset
= roundup (bootstrap_map.l_tls_blocksize, TLS_INIT_TCB_ALIGN);
INSTALL_DTV ((char *) tlsblock + bootstrap_map.l_tls_offset,
initdtv);
TLS_INIT_TP ((char *) tlsblock + bootstrap_map.l_tls_offset);
# elif TLS_DTV_AT_TP
INSTALL_DTV (tlsblock, initdtv);
TLS_INIT_TP (tlsblock);
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
/* So far this is module number one. */
bootstrap_map.l_tls_modid = 1;
/* There can only be one PT_TLS entry. */
break;
}
#endif /* use TLS */
#ifdef ELF_MACHINE_BEFORE_RTLD_RELOC #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info); ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
#endif #endif
@ -220,12 +316,6 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
ElfW(Addr) *start_addr = alloca (sizeof (ElfW(Addr))); ElfW(Addr) *start_addr = alloca (sizeof (ElfW(Addr)));
extern char _begin[] attribute_hidden; extern char _begin[] attribute_hidden;
extern char _end[] attribute_hidden; extern char _end[] attribute_hidden;
#ifdef USE_TLS
ElfW(Ehdr) *ehdr;
ElfW(Phdr) *phdr;
size_t cnt;
dtv_t initdtv[3];
#endif
if (HP_TIMING_AVAIL) if (HP_TIMING_AVAIL)
{ {
@ -247,97 +337,28 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
GL(dl_rtld_map).l_mach = bootstrap_map_p->l_mach; GL(dl_rtld_map).l_mach = bootstrap_map_p->l_mach;
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin; GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin;
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end; GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
/* Copy the TLS related data if necessary. */
#if USE_TLS
# ifdef HAVE___THREAD
assert (bootstrap_map_p->l_tls_modid != 0);
# else
if (bootstrap_map_p->l_tls_modid != 0)
# endif
{
GL(dl_rtld_map).l_tls_blocksize = bootstrap_map_p->l_tls_blocksize;
GL(dl_rtld_map).l_tls_align = bootstrap_map_p->l_tls_align;
GL(dl_rtld_map).l_tls_initimage_size
= bootstrap_map_p->l_tls_initimage_size;
GL(dl_rtld_map).l_tls_initimage = bootstrap_map_p->l_tls_initimage;
GL(dl_rtld_map).l_tls_offset = bootstrap_map_p->l_tls_offset;
GL(dl_rtld_map).l_tls_modid = 1;
}
#endif
#if HP_TIMING_AVAIL #if HP_TIMING_AVAIL
HP_TIMING_NOW (GL(dl_cpuclock_offset)); HP_TIMING_NOW (GL(dl_cpuclock_offset));
#endif #endif
#if USE_TLS
/* Get the dynamic linkers program header. */
ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start;
phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start + ehdr->e_phoff);
for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
if (phdr[cnt].p_type == PT_TLS)
{
void *tlsblock;
size_t max_align = MAX (TLS_INIT_TCB_ALIGN, phdr[cnt].p_align);
GL(dl_rtld_map).l_tls_blocksize = phdr[cnt].p_memsz;
GL(dl_rtld_map).l_tls_align = phdr[cnt].p_align;
assert (GL(dl_rtld_map).l_tls_blocksize != 0);
GL(dl_rtld_map).l_tls_initimage_size = phdr[cnt].p_filesz;
GL(dl_rtld_map).l_tls_initimage = (void *) (GL(dl_rtld_map).l_map_start
+ phdr[cnt].p_offset);
/* We can now allocate the initial TLS block. This can happen
on the stack. We'll get the final memory later when we
know all about the various objects loaded at startup
time. */
# if TLS_TCB_AT_TP
tlsblock = alloca (roundup (GL(dl_rtld_map).l_tls_blocksize,
TLS_INIT_TCB_ALIGN)
+ TLS_INIT_TCB_SIZE
+ max_align);
# elif TLS_DTV_AT_TP
tlsblock = alloca (roundup (TLS_INIT_TCB_SIZE,
GL(dl_rtld_map).l_tls_align)
+ GL(dl_rtld_map).l_tls_blocksize
+ max_align);
# else
/* In case a model with a different layout for the TCB and DTV
is defined add another #elif here and in the following #ifs. */
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
/* Align the TLS block. */
tlsblock = (void *) (((uintptr_t) tlsblock + max_align - 1)
& ~(max_align - 1));
/* Initialize the dtv. [0] is the length, [1] the generation
counter. */
initdtv[0].counter = 1;
initdtv[1].counter = 0;
/* Initialize the TLS block. */
# if TLS_TCB_AT_TP
initdtv[2].pointer = tlsblock;
# elif TLS_DTV_AT_TP
GL(dl_rtld_map).l_tls_offset = roundup (TLS_INIT_TCB_SIZE,
GL(dl_rtld_map).l_tls_align);
initdtv[2].pointer = (char *) tlsblock + GL(dl_rtld_map).l_tls_offset;
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
memset (__mempcpy (initdtv[1].pointer, GL(dl_rtld_map).l_tls_initimage,
GL(dl_rtld_map).l_tls_initimage_size),
'\0', (GL(dl_rtld_map).l_tls_blocksize
- GL(dl_rtld_map).l_tls_initimage_size));
/* Install the pointer to the dtv. */
/* Initialize the thread pointer. */
# if TLS_TCB_AT_TP
GL(dl_rtld_map).l_tls_offset
= roundup (GL(dl_rtld_map).l_tls_blocksize, TLS_INIT_TCB_ALIGN);
INSTALL_DTV ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset,
initdtv);
TLS_INIT_TP ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset);
# elif TLS_DTV_AT_TP
INSTALL_DTV (tlsblock, initdtv);
TLS_INIT_TP (tlsblock);
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
/* So far this is module number one. */
GL(dl_rtld_map).l_tls_modid = 1;
/* There can only be one PT_TLS entry. */
break;
}
#endif /* use TLS */
/* Call the OS-dependent function to set up life so we can do things like /* Call the OS-dependent function to set up life so we can do things like
file access. It will call `dl_main' (below) to do all the real work file access. It will call `dl_main' (below) to do all the real work
of the dynamic linker, and then unwind our frame and run the user of the dynamic linker, and then unwind our frame and run the user

View File

@ -1,73 +1,13 @@
/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. #include <stdlib/errno.h>
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or #ifdef _ERRNO_H
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, #if USE_TLS && HAVE___THREAD
but WITHOUT ANY WARRANTY; without even the implied warranty of # undef errno
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU extern __thread int errno;
Lesser General Public License for more details. # define __set_errno(val) (errno = (val))
#else
You should have received a copy of the GNU Lesser General Public # define __set_errno(val) (*__errno_location ()) = (val)
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. */
/*
* ISO C99 Standard: 7.5 Errors <errno.h>
*/
#ifndef _ERRNO_H
/* The includer defined __need_Emath if he wants only the definitions
of EDOM and ERANGE, and not everything else. */
#ifndef __need_Emath
#define _ERRNO_H 1
#include <features.h>
#endif #endif
__BEGIN_DECLS
/* Get the error number constants from the system-specific file.
This file will test __need_Emath and _ERRNO_H. */
#include <bits/errno.h>
#undef __need_Emath
#ifdef _ERRNO_H
/* Declare the `errno' variable, unless it's defined as a macro by
bits/errno.h. This is the case in GNU, where it is a per-thread
variable. This redeclaration using the macro still works, but it
will be a function declaration without a prototype and may trigger
a -Wstrict-prototypes warning. */
#ifndef errno
extern int errno;
#endif
#ifdef __USE_GNU
/* The full and simple forms of the name with which the program was
invoked. These variables are set up automatically at startup based on
the value of ARGV[0] (this works only if you use GNU ld). */
extern char *program_invocation_name, *program_invocation_short_name;
#endif /* __USE_GNU */
#endif /* _ERRNO_H */
__END_DECLS
#endif /* _ERRNO_H */
/* The Hurd <bits/errno.h> defines `error_t' as an enumerated type so
that printing `error_t' values in the debugger shows the names. We
might need this definition sometimes even if this file was included
before. */
#if defined __USE_GNU || defined __need_error_t
# ifndef __error_t_defined
typedef int error_t;
# define __error_t_defined 1
# endif
# undef __need_error_t
#endif #endif

View File

@ -1,3 +1,12 @@
2002-07-19 Ulrich Drepper <drepper@redhat.com>
* errno.c (__errno_location): Don't define unless !USE_TLS
|| !HAVE___THREAD.
* sysdeps/i386/pt-machine.c: Protect C code with #ifndef ASSEMBLER.
* sysdeps/i386/tls.h: Likewise.
* sysdeps/i386/useldt.h: Likewise.
* sysdeps/i386/i686/pt-machine.h: Likewise.
2002-07-02 H.J. Lu <hjl@gnu.org> 2002-07-02 H.J. Lu <hjl@gnu.org>
* sysdeps/mips/pspinlock.c: Don't include <sgidefs.h>. Always * sysdeps/mips/pspinlock.c: Don't include <sgidefs.h>. Always

View File

@ -17,14 +17,18 @@
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
#include <resolv.h> #include <resolv.h>
#include <tls.h>
#include "pthread.h" #include "pthread.h"
#include "internals.h" #include "internals.h"
#if !USE_TLS || !HAVE___THREAD
/* The definition in libc is sufficient if we use TLS. */
int * __errno_location() int * __errno_location()
{ {
pthread_descr self = thread_self(); pthread_descr self = thread_self();
return THREAD_GETMEM (self, p_errnop); return THREAD_GETMEM (self, p_errnop);
} }
#endif
int * __h_errno_location() int * __h_errno_location()
{ {

View File

@ -27,6 +27,7 @@
#endif #endif
#include "kernel-features.h" #include "kernel-features.h"
#ifndef ASSEMBLER
extern long int testandset (int *spinlock); extern long int testandset (int *spinlock);
extern int __compare_and_swap (long int *p, long int oldval, long int newval); extern int __compare_and_swap (long int *p, long int oldval, long int newval);
@ -66,6 +67,7 @@ __compare_and_swap (long int *p, long int oldval, long int newval)
: "memory"); : "memory");
return ret; return ret;
} }
#endif
#if __ASSUME_LDT_WORKS > 0 #if __ASSUME_LDT_WORKS > 0
#include "../useldt.h" #include "../useldt.h"

View File

@ -22,6 +22,7 @@
#ifndef _PT_MACHINE_H #ifndef _PT_MACHINE_H
#define _PT_MACHINE_H 1 #define _PT_MACHINE_H 1
#ifndef ASSEMBLER
#ifndef PT_EI #ifndef PT_EI
# define PT_EI extern inline # define PT_EI extern inline
#endif #endif
@ -102,5 +103,6 @@ compare_and_swap_is_available (void)
Otherwise, it's a 486 or above and it has cmpxchg. */ Otherwise, it's a 486 or above and it has cmpxchg. */
return changed != 0; return changed != 0;
} }
#endif /* ASSEMBLER */
#endif /* pt-machine.h */ #endif /* pt-machine.h */

View File

@ -20,9 +20,10 @@
#ifndef _TLS_H #ifndef _TLS_H
#define _TLS_H #define _TLS_H
#include <stddef.h> # include <pt-machine.h>
#include <pt-machine.h> #ifndef ASSEMBLER
# include <stddef.h>
/* Type for the dtv. */ /* Type for the dtv. */
typedef union dtv typedef union dtv
@ -39,56 +40,58 @@ typedef struct
dtv_t *dtv; dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */ void *self; /* Pointer to the thread descriptor. */
} tcbhead_t; } tcbhead_t;
#endif
/* We can support TLS only if the floating-stack support is available. */ /* We can support TLS only if the floating-stack support is available. */
#if defined FLOATING_STACKS && defined HAVE_TLS_SUPPORT #if defined FLOATING_STACKS && defined HAVE_TLS_SUPPORT
/* Get system call information. */
# include <sysdep.h>
/* Signal that TLS support is available. */ /* Signal that TLS support is available. */
# define USE_TLS 1 # define USE_TLS 1
# ifndef ASSEMBLER
/* Get system call information. */
# include <sysdep.h>
/* Get the thread descriptor definition. */ /* Get the thread descriptor definition. */
# include <linuxthreads/descr.h> # include <linuxthreads/descr.h>
/* This is the size of the initial TCB. */ /* This is the size of the initial TCB. */
# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
/* Alignment requirements for the initial TCB. */ /* Alignment requirements for the initial TCB. */
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) # define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
/* This is the size of the TCB. */ /* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct) # define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
/* Alignment requirements for the TCB. */ /* Alignment requirements for the TCB. */
# define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct) # define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
/* The TCB can have any size and the memory following the address the /* The TCB can have any size and the memory following the address the
thread pointer points to is unspecified. Allocate the TCB there. */ thread pointer points to is unspecified. Allocate the TCB there. */
# define TLS_TCB_AT_TP 1 # define TLS_TCB_AT_TP 1
/* Install the dtv pointer. The pointer passed is to the element with /* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */ index -1 which contain the length. */
# define INSTALL_DTV(descr, dtvp) \ # define INSTALL_DTV(descr, dtvp) \
((tcbhead_t *) descr)->dtv = dtvp + 1 ((tcbhead_t *) descr)->dtv = dtvp + 1
/* Install new dtv for current thread. */ /* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtv) \ # define INSTALL_NEW_DTV(dtv) \
({ struct _pthread_descr_struct *__descr; \ ({ struct _pthread_descr_struct *__descr; \
THREAD_SETMEM (__descr, p_header.data.dtvp, dtv); }) THREAD_SETMEM (__descr, p_header.data.dtvp, dtv); })
/* Return dtv of given thread descriptor. */ /* Return dtv of given thread descriptor. */
# define GET_DTV(descr) \ # define GET_DTV(descr) \
(((tcbhead_t *) descr)->dtv) (((tcbhead_t *) descr)->dtv)
/* Code to initially initialize the thread pointer. This might need /* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */ operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(descr) \ # define TLS_INIT_TP(descr) \
do { \ do { \
void *_descr = (descr); \ void *_descr = (descr); \
struct modify_ldt_ldt_s ldt_entry = \ struct modify_ldt_ldt_s ldt_entry = \
@ -116,10 +119,11 @@ typedef struct
/* Return the address of the dtv for the current thread. */ /* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \ # define THREAD_DTV() \
({ struct _pthread_descr_struct *__descr; \ ({ struct _pthread_descr_struct *__descr; \
THREAD_GETMEM (__descr, p_header.data.dtvp); }) THREAD_GETMEM (__descr, p_header.data.dtvp); })
#endif /* FLOATING_STACKS && HAVE_TLS_SUPPORT */ # endif /* FLOATING_STACKS && HAVE_TLS_SUPPORT */
#endif /* __ASSEMBLER__ */
#endif /* tls.h */ #endif /* tls.h */

View File

@ -1,6 +1,6 @@
/* Special definitions for ix86 machine using segment register based /* Special definitions for ix86 machine using segment register based
thread descriptor. thread descriptor.
Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1998, 2000, 2001, 2002 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@cygnus.com>. Contributed by Ulrich Drepper <drepper@cygnus.com>.
@ -19,6 +19,7 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
#ifndef ASSEMBLER
#include <stddef.h> /* For offsetof. */ #include <stddef.h> /* For offsetof. */
#include <stdlib.h> /* For abort(). */ #include <stdlib.h> /* For abort(). */
@ -198,6 +199,7 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
member))); \ member))); \
} \ } \
}) })
#endif
/* We want the OS to assign stack addresses. */ /* We want the OS to assign stack addresses. */
#define FLOATING_STACKS 1 #define FLOATING_STACKS 1

View File

@ -22,7 +22,8 @@
subdir := stdlib subdir := stdlib
headers := stdlib.h alloca.h monetary.h fmtmsg.h ucontext.h sys/ucontext.h \ headers := stdlib.h alloca.h monetary.h fmtmsg.h ucontext.h sys/ucontext.h \
inttypes.h stdint.h bits/wordsize.h bits/wchar.h inttypes.h stdint.h bits/wordsize.h bits/wchar.h \
errno.h sys/errno.h bits/errno.h
routines := \ routines := \
atof atoi atol atoll \ atof atoi atol atoll \

73
stdlib/errno.h Normal file
View File

@ -0,0 +1,73 @@
/* Copyright (C) 1991,92,93,94,95,96,97,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. */
/*
* ISO C99 Standard: 7.5 Errors <errno.h>
*/
#ifndef _ERRNO_H
/* The includer defined __need_Emath if he wants only the definitions
of EDOM and ERANGE, and not everything else. */
#ifndef __need_Emath
# define _ERRNO_H 1
# include <features.h>
#endif
__BEGIN_DECLS
/* Get the error number constants from the system-specific file.
This file will test __need_Emath and _ERRNO_H. */
#include <bits/errno.h>
#undef __need_Emath
#ifdef _ERRNO_H
/* Declare the `errno' variable, unless it's defined as a macro by
bits/errno.h. This is the case in GNU, where it is a per-thread
variable. This redeclaration using the macro still works, but it
will be a function declaration without a prototype and may trigger
a -Wstrict-prototypes warning. */
#ifndef errno
extern int errno;
#endif
#ifdef __USE_GNU
/* The full and simple forms of the name with which the program was
invoked. These variables are set up automatically at startup based on
the value of ARGV[0] (this works only if you use GNU ld). */
extern char *program_invocation_name, *program_invocation_short_name;
#endif /* __USE_GNU */
#endif /* _ERRNO_H */
__END_DECLS
#endif /* _ERRNO_H */
/* The Hurd <bits/errno.h> defines `error_t' as an enumerated type so
that printing `error_t' values in the debugger shows the names. We
might need this definition sometimes even if this file was included
before. */
#if defined __USE_GNU || defined __need_error_t
# ifndef __error_t_defined
typedef int error_t;
# define __error_t_defined 1
# endif
# undef __need_error_t
#endif

1
stdlib/sys/errno.h Normal file
View File

@ -0,0 +1 @@
#include <errno.h>

View File

@ -33,5 +33,3 @@
# define Exxxx XXX # define Exxxx XXX
... ...
#endif #endif
#define __set_errno(val) errno = (val)

View File

@ -1,6 +1,6 @@
/* MT support function to get address of `errno' variable, non-threaded /* MT support function to get address of `errno' variable, non-threaded
version. version.
Copyright (C) 1996, 1998 Free Software Foundation, Inc. Copyright (C) 1996, 1998, 2002 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,8 +19,15 @@
02111-1307 USA. */ 02111-1307 USA. */
#include <errno.h> #include <errno.h>
#include <tls.h>
#undef errno #undef errno
#if USE_TLS && HAVE___THREAD
extern __thread int errno;
#else
extern int errno;
#endif
int * int *
weak_const_function weak_const_function
__errno_location (void) __errno_location (void)

View File

@ -399,7 +399,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
case R_386_TLS_TPOFF32: case R_386_TLS_TPOFF32:
/* The offset is positive, backward from the thread pointer. */ /* The offset is positive, backward from the thread pointer. */
# ifdef RTLD_BOOTSTRAP # ifdef RTLD_BOOTSTRAP
*reloc_addr = GL(dl_rtld_map).l_tls_offset - sym->st_value; *reloc_addr = map->l_tls_offset - sym->st_value;
# else # else
/* We know the offset of object the symbol is contained in. /* We know the offset of object the symbol is contained in.
It is a positive value which will be subtracted from the It is a positive value which will be subtracted from the

View File

@ -310,7 +310,6 @@ typedef enum __error_t_codes error_t;
extern int *__errno_location (void) __THROW __attribute__ ((__const__)); extern int *__errno_location (void) __THROW __attribute__ ((__const__));
#define errno (*__errno_location ()) #define errno (*__errno_location ())
#define __set_errno(val) (errno = (val))
#endif /* <errno.h> included. */ #endif /* <errno.h> included. */

View File

@ -573,7 +573,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
case R_SH_TLS_TPOFF32: case R_SH_TLS_TPOFF32:
/* The offset is positive, afterward from the thread pointer. */ /* The offset is positive, afterward from the thread pointer. */
# ifdef RTLD_BOOTSTRAP # ifdef RTLD_BOOTSTRAP
*reloc_addr = GL(dl_rtld_map).l_tls_offset + sym->st_value; *reloc_addr = map->l_tls_offset + sym->st_value;
# else # else
/* We know the offset of object the symbol is contained in. /* We know the offset of object the symbol is contained in.
It is a positive value which will be added to the thread It is a positive value which will be added to the thread

View File

@ -60,7 +60,6 @@
# define EOVERFLOW 32 # define EOVERFLOW 32
#endif #endif
#define __set_errno(val) errno = (val)
/* Function to get address of global `errno' variable. */ /* Function to get address of global `errno' variable. */
extern int *__errno_location __P ((void)) __attribute__ ((__const__)); extern int *__errno_location __P ((void)) __attribute__ ((__const__));

View File

@ -57,5 +57,3 @@
# define ENOSPC 31 # define ENOSPC 31
# define EBUSY 32 # define EBUSY 32
#endif #endif
#define __set_errno(val) errno = (val)

View File

@ -161,6 +161,4 @@
#endif /* __USE_BSD */ #endif /* __USE_BSD */
#define __set_errno(val) errno = (val)
#endif /* <errno.h> included. */ #endif /* <errno.h> included. */

View File

@ -144,10 +144,6 @@
# define EMULTIHOP 125 /* Multihop is not allowed. */ # define EMULTIHOP 125 /* Multihop is not allowed. */
# define ENOLINK 126 /* The link has been severed. */ # define ENOLINK 126 /* The link has been severed. */
# define EOVERFLOW 127 /* Value too large to be stored in data type.*/ # define EOVERFLOW 127 /* Value too large to be stored in data type.*/
# ifdef _LIBC
# define __set_errno(val) errno = (val)
# endif
#endif #endif
#if !defined _ERRNO_H && defined __need_Emath #if !defined _ERRNO_H && defined __need_Emath

View File

@ -32,5 +32,3 @@
#define ENOMSG 35 #define ENOMSG 35
#define ENOSYS 251 #define ENOSYS 251
#endif #endif
#define __set_errno(val) errno = (val)

View File

@ -32,17 +32,9 @@
# define ECANCELED 125 # define ECANCELED 125
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
/* We now need a declaration of the `errno' variable. */
extern int errno;
/* Function to get address of global `errno' variable. */ /* Function to get address of global `errno' variable. */
extern int *__errno_location (void) __THROW __attribute__ ((__const__)); extern int *__errno_location (void) __THROW __attribute__ ((__const__));
# if defined _LIBC
/* We wouldn't need a special macro anymore but it is history. */
# define __set_errno(val) (*__errno_location ()) = (val)
# endif /* _LIBC */
# if !defined _LIBC || defined _LIBC_REENTRANT # if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */ /* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ()) # define errno (*__errno_location ())

View File

@ -1,5 +1,5 @@
/* Determine current working directory. Linux version. /* Determine current working directory. Linux version.
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. Copyright (C) 1997, 1998, 1999, 2000, 2002 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@cygnus.com>, 1997. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -64,7 +64,6 @@ static int have_new_dcache = 1;
char * char *
__getcwd (char *buf, size_t size) __getcwd (char *buf, size_t size)
{ {
int save_errno;
char *path; char *path;
int n; int n;
char *result; char *result;
@ -93,8 +92,6 @@ __getcwd (char *buf, size_t size)
return NULL; return NULL;
} }
save_errno = errno;
#if defined __NR_getcwd || __LINUX_GETCWD_SYSCALL > 0 #if defined __NR_getcwd || __LINUX_GETCWD_SYSCALL > 0
if (!no_syscall_getcwd) if (!no_syscall_getcwd)
{ {
@ -137,8 +134,6 @@ __getcwd (char *buf, size_t size)
free (path); free (path);
return NULL; return NULL;
} }
__set_errno (save_errno);
# endif # endif
} }
#endif #endif
@ -179,10 +174,6 @@ __getcwd (char *buf, size_t size)
have_new_dcache = 0; have_new_dcache = 0;
#endif #endif
/* Something went wrong. Restore the error number and use the generic
version. */
__set_errno (save_errno);
/* Don't put restrictions on the length of the path unless the user does. */ /* Don't put restrictions on the length of the path unless the user does. */
if (size == 0) if (size == 0)
{ {

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. /* Copyright (C) 1998, 1999, 2001, 2002 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
@ -56,12 +56,13 @@ grantpt (int fd)
if (__libc_fcntl (fd, F_GETFD) == -1 && errno == EBADF) if (__libc_fcntl (fd, F_GETFD) == -1 && errno == EBADF)
return -1; return -1;
__set_errno (save_errno);
/* If the filedescriptor is no TTY, grantpt has to set errno /* If the filedescriptor is no TTY, grantpt has to set errno
to EINVAL. */ to EINVAL. */
if (errno == ENOTTY) if (save_errno == ENOTTY)
__set_errno (EINVAL); __set_errno (EINVAL);
else
__set_errno (save_errno);
return -1; return -1;
} }

View File

@ -29,17 +29,9 @@
# define ECANCELED 125 # define ECANCELED 125
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
/* We now need a declaration of the `errno' variable. */
extern int errno;
/* Function to get address of global `errno' variable. */ /* Function to get address of global `errno' variable. */
extern int *__errno_location (void) __THROW __attribute__ ((__const__)); extern int *__errno_location (void) __THROW __attribute__ ((__const__));
# if defined _LIBC
/* We wouldn't need a special macro anymore but it is history. */
# define __set_errno(val) (*__errno_location ()) = (val)
# endif /* _LIBC */
# if !defined _LIBC || defined _LIBC_REENTRANT # if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */ /* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ()) # define errno (*__errno_location ())

View File

@ -30,32 +30,44 @@
#ifdef PIC #ifdef PIC
# undef SYSCALL_ERROR_HANDLER # undef SYSCALL_ERROR_HANDLER
/* Store (- %eax) into errno through the GOT. */ # undef SETUP_PIC_REG
# ifdef _LIBC_REENTRANT # ifndef HAVE_HIDDEN
# define SETUP_PIC_REG(reg) \
# ifndef HAVE_HIDDEN
# define SETUP_PIC_REG \
call 1f; \ call 1f; \
.subsection 1; \ .subsection 1; \
1:movl (%esp), %ebx; \ 1:movl (%esp), %e##reg; \
ret; \ ret; \
.previous .previous
# else # else
# define SETUP_PIC_REG \ # define SETUP_PIC_REG(reg) \
.section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits; \ .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits; \
.globl __i686.get_pc_thunk.bx; \ .globl __i686.get_pc_thunk.reg; \
.hidden __i686.get_pc_thunk.bx; \ .hidden __i686.get_pc_thunk.reg; \
.type __i686.get_pc_thunk.bx,@function; \ .type __i686.get_pc_thunk.reg,@function; \
__i686.get_pc_thunk.bx: \ __i686.get_pc_thunk.reg: \
movl (%esp), %ebx; \ movl (%esp), %e##reg; \
ret; \ ret; \
.previous; \ .previous; \
call __i686.get_pc_thunk.bx call __i686.get_pc_thunk.reg
# endif # endif
# define SYSCALL_ERROR_HANDLER \ /* Store (- %eax) into errno through the GOT. */
# ifdef _LIBC_REENTRANT
# if USE_TLS && HAVE___THREAD
# define SYSCALL_ERROR_HANDLER \
0:SETUP_PIC_REG (cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
xorl %edx, %edx; \
subl %eax, %edx; \
movl %gs:0, %eax; \
subl errno@gottpoff(%ecx), %eax; \
movl %edx, (%eax); \
orl $-1, %eax; \
jmp L(pseudo_end);
# else
# define SYSCALL_ERROR_HANDLER \
0:pushl %ebx; \ 0:pushl %ebx; \
SETUP_PIC_REG; \ SETUP_PIC_REG(bx); \
addl $_GLOBAL_OFFSET_TABLE_, %ebx; \ addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
xorl %edx, %edx; \ xorl %edx, %edx; \
subl %eax, %edx; \ subl %eax, %edx; \
@ -70,30 +82,10 @@ __i686.get_pc_thunk.bx: \
jmp L(pseudo_end); jmp L(pseudo_end);
/* A quick note: it is assumed that the call to `__errno_location' does /* A quick note: it is assumed that the call to `__errno_location' does
not modify the stack! */ not modify the stack! */
# else
# ifndef HAVE_HIDDEN
# define SETUP_PIC_REG \
call 1f; \
.subsection 1; \
1:movl (%esp), %ecx; \
ret; \
.previous
# else
# define SETUP_PIC_REG \
.section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits; \
.globl __i686.get_pc_thunk.cx; \
.hidden __i686.get_pc_thunk.cx; \
.type __i686.get_pc_thunk.cx,@function; \
__i686.get_pc_thunk.cx: \
movl (%esp), %ecx; \
ret; \
.previous; \
call __i686.get_pc_thunk.cx
# endif # endif
# else
# define SYSCALL_ERROR_HANDLER \ # define SYSCALL_ERROR_HANDLER \
0:SETUP_PIC_REG; \ 0:SETUP_PIC_REG(cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
xorl %edx, %edx; \ xorl %edx, %edx; \
subl %eax, %edx; \ subl %eax, %edx; \

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. /* Copyright (C) 1995, 1996, 1997, 1998, 2002 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
@ -17,6 +17,7 @@
02111-1307 USA. */ 02111-1307 USA. */
#include <sysdep.h> #include <sysdep.h>
#include <tls.h>
/* Because the Linux version is in fact i386/ELF and the start.? file /* Because the Linux version is in fact i386/ELF and the start.? file
for this system (sysdeps/i386/elf/start.S) is also used by The Hurd for this system (sysdeps/i386/elf/start.S) is also used by The Hurd
@ -25,13 +26,21 @@
it somewhere else. it somewhere else.
...and this place is here. */ ...and this place is here. */
#if USE_TLS && HAVE___THREAD
.section .tbss
#else
.bss .bss
#endif
.globl errno .globl errno
.type errno,@object .type errno,@object
.size errno,4 .size errno,4
.globl _errno
.type _errno,@object
.size _errno,4
.align 4
errno: errno:
_errno:
.space 4 .space 4
weak_alias (errno, _errno)
/* The following code is only used in the shared library when we /* The following code is only used in the shared library when we
compile the reentrant version. Otherwise each system call defines compile the reentrant version. Otherwise each system call defines

View File

@ -24,6 +24,7 @@
#include <sysdeps/unix/i386/sysdep.h> #include <sysdeps/unix/i386/sysdep.h>
#include <bp-sym.h> #include <bp-sym.h>
#include <bp-asm.h> #include <bp-asm.h>
#include <tls.h>
/* For Linux we can use the system call table in the header file /* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h /usr/include/asm/unistd.h
@ -72,34 +73,47 @@
END (name) END (name)
#ifndef PIC #ifndef PIC
#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ # define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
#else #else
/* Store (- %eax) into errno through the GOT. */
#ifdef _LIBC_REENTRANT
# ifndef HAVE_HIDDEN # ifndef HAVE_HIDDEN
# define SETUP_PIC_REG \ # define SETUP_PIC_REG(reg) \
call 1f; \ call 1f; \
.subsection 1; \ .subsection 1; \
1:movl (%esp), %ebx; \ 1:movl (%esp), %e##reg; \
ret; \ ret; \
.previous .previous
# else # else
# define SETUP_PIC_REG \ # define SETUP_PIC_REG(reg) \
.section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits; \ .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits; \
.globl __i686.get_pc_thunk.bx; \ .globl __i686.get_pc_thunk.reg; \
.hidden __i686.get_pc_thunk.bx; \ .hidden __i686.get_pc_thunk.reg; \
.type __i686.get_pc_thunk.bx,@function; \ .type __i686.get_pc_thunk.reg,@function; \
__i686.get_pc_thunk.bx: \ __i686.get_pc_thunk.reg: \
movl (%esp), %ebx; \ movl (%esp), %e##reg; \
ret; \ ret; \
.previous; \ .previous; \
call __i686.get_pc_thunk.bx call __i686.get_pc_thunk.reg
# endif # endif
#define SYSCALL_ERROR_HANDLER \ /* Store (- %eax) into errno through the GOT. */
# ifdef _LIBC_REENTRANT
# if USE_TLS && HAVE___THREAD
# define SYSCALL_ERROR_HANDLER \
0:SETUP_PIC_REG (cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
xorl %edx, %edx; \
subl %eax, %edx; \
movl %gs:0, %eax; \
subl errno@gottpoff(%ecx), %eax; \
movl %edx, (%eax); \
orl $-1, %eax; \
jmp L(pseudo_end);
# else
# define SYSCALL_ERROR_HANDLER \
0:pushl %ebx; \ 0:pushl %ebx; \
SETUP_PIC_REG; \ SETUP_PIC_REG (bx); \
addl $_GLOBAL_OFFSET_TABLE_, %ebx; \ addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
xorl %edx, %edx; \ xorl %edx, %edx; \
subl %eax, %edx; \ subl %eax, %edx; \
@ -114,30 +128,10 @@ __i686.get_pc_thunk.bx: \
jmp L(pseudo_end); jmp L(pseudo_end);
/* A quick note: it is assumed that the call to `__errno_location' does /* A quick note: it is assumed that the call to `__errno_location' does
not modify the stack! */ not modify the stack! */
#else # endif
# ifndef HAVE_HIDDEN
# define SETUP_PIC_REG \
call 1f; \
.subsection 1; \
1:movl (%esp), %ecx; \
ret; \
.previous
# else # else
# define SETUP_PIC_REG \ # define SYSCALL_ERROR_HANDLER \
.section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits; \ 0:define SETUP_PIC_REG(cx); \
.globl __i686.get_pc_thunk.cx; \
.hidden __i686.get_pc_thunk.cx; \
.type __i686.get_pc_thunk.cx,@function; \
__i686.get_pc_thunk.cx: \
movl (%esp), %ecx; \
ret; \
.previous; \
call __i686.get_pc_thunk.cx
# endif
#define SYSCALL_ERROR_HANDLER \
0:define SETUP_PIC_REG; \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
xorl %edx, %edx; \ xorl %edx, %edx; \
subl %eax, %edx; \ subl %eax, %edx; \
@ -145,7 +139,7 @@ __i686.get_pc_thunk.cx: \
movl %edx, (%ecx); \ movl %edx, (%ecx); \
orl $-1, %eax; \ orl $-1, %eax; \
jmp L(pseudo_end); jmp L(pseudo_end);
#endif /* _LIBC_REENTRANT */ # endif /* _LIBC_REENTRANT */
#endif /* PIC */ #endif /* PIC */
/* Linux takes system call arguments in registers: /* Linux takes system call arguments in registers:

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. /* Copyright (C) 1998, 1999, 2000, 2001, 2002 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@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -53,7 +53,6 @@
buf->f_flag = 0; buf->f_flag = 0;
if (STAT (&st) >= 0) if (STAT (&st) >= 0)
{ {
int save_errno = errno;
struct mntent mntbuf; struct mntent mntbuf;
FILE *mtab; FILE *mtab;
@ -104,6 +103,4 @@
/* Close the file. */ /* Close the file. */
__endmntent (mtab); __endmntent (mtab);
} }
__set_errno (save_errno);
} }

View File

@ -28,17 +28,9 @@
# define ENOTSUP EOPNOTSUPP # define ENOTSUP EOPNOTSUPP
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
/* We now need a declaration of the `errno' variable. */
extern int errno;
/* Function to get address of global `errno' variable. */ /* Function to get address of global `errno' variable. */
extern int *__errno_location (void) __THROW __attribute__ ((__const__)); extern int *__errno_location (void) __THROW __attribute__ ((__const__));
# if defined _LIBC
/* We wouldn't need a special macro anymore but it is history. */
# define __set_errno(val) (*__errno_location ()) = (val)
# endif /* _LIBC */
# if !defined _LIBC || defined _LIBC_REENTRANT # if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */ /* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ()) # define errno (*__errno_location ())

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc. /* Copyright (C) 1995, 1997, 1998, 2000, 2002 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@gnu.ai.mit.edu>, August 1995. Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
@ -80,7 +80,7 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
} }
{ {
int save_errno = errno, result; int result;
struct __old_msqid_ds old; struct __old_msqid_ds old;
/* Unfortunately there is no way how to find out for sure whether /* Unfortunately there is no way how to find out for sure whether
@ -90,7 +90,6 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
if (result != -1 || errno != EINVAL) if (result != -1 || errno != EINVAL)
return result; return result;
__set_errno(save_errno);
if (cmd == IPC_SET) if (cmd == IPC_SET)
{ {
old.msg_perm.uid = buf->msg_perm.uid; old.msg_perm.uid = buf->msg_perm.uid;

View File

@ -1,5 +1,5 @@
/* readv supports all Linux kernels >= 2.0. /* readv supports all Linux kernels >= 2.0.
Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc. Copyright (C) 1997, 1998, 2000, 2002 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
@ -45,7 +45,6 @@ __readv (fd, vector, count)
const struct iovec *vector; const struct iovec *vector;
int count; int count;
{ {
int errno_saved = errno;
ssize_t bytes_read; ssize_t bytes_read;
bytes_read = INLINE_SYSCALL (readv, 3, fd, CHECK_N (vector, count), count); bytes_read = INLINE_SYSCALL (readv, 3, fd, CHECK_N (vector, count), count);
@ -53,9 +52,6 @@ __readv (fd, vector, count)
if (bytes_read >= 0 || errno != EINVAL || count <= UIO_FASTIOV) if (bytes_read >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
return bytes_read; return bytes_read;
/* Restore the old error value as if nothing happened. */
__set_errno (errno_saved);
return __atomic_readv_replacement (fd, vector, count); return __atomic_readv_replacement (fd, vector, count);
} }
weak_alias (__readv, readv) weak_alias (__readv, readv)

View File

@ -1,5 +1,5 @@
/* writev supports all Linux kernels >= 2.0. /* writev supports all Linux kernels >= 2.0.
Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc. Copyright (C) 1997, 1998, 2000, 2002 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
@ -45,7 +45,6 @@ __writev (fd, vector, count)
const struct iovec *vector; const struct iovec *vector;
int count; int count;
{ {
int errno_saved = errno;
ssize_t bytes_written; ssize_t bytes_written;
bytes_written = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vector, count), count); bytes_written = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vector, count), count);
@ -53,9 +52,6 @@ __writev (fd, vector, count)
if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV) if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
return bytes_written; return bytes_written;
/* Restore the old error value as if nothing happened. */
__set_errno (errno_saved);
return __atomic_writev_replacement (fd, vector, count); return __atomic_writev_replacement (fd, vector, count);
} }
weak_alias (__writev, writev) weak_alias (__writev, writev)

View File

@ -166,5 +166,3 @@
# define ESTALE 151 /* Stale NFS file handle. */ # define ESTALE 151 /* Stale NFS file handle. */
#endif #endif
#define __set_errno(val) errno = (val)