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>
* 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 \
$(addprefix install-, no-libc.a bin lib data headers others)
headers := errno.h sys/errno.h bits/errno.h limits.h values.h \
features.h gnu-versions.h bits/libc-lock.h bits/xopen_lim.h \
gnu/libc-version.h
headers := limits.h values.h features.h gnu-versions.h bits/libc-lock.h \
bits/xopen_lim.h gnu/libc-version.h
echo-headers: subdir_echo-headers

View File

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

View File

@ -94,6 +94,9 @@
/* Define if the compiler supports __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
(gcc on ix86 only). */
#undef USE_REGPARMS

45
configure vendored
View File

@ -3540,8 +3540,33 @@ EOF
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 "configure:3545: checking for libgd" >&5
echo "configure:3570: checking for libgd" >&5
if test "$with_gd" != "no"; then
old_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $libgd_include"
@ -3550,14 +3575,14 @@ if test "$with_gd" != "no"; then
old_LIBS="$LIBS"
LIBS="$LIBS -lgd -lpng -lz -lm"
cat > conftest.$ac_ext <<EOF
#line 3554 "configure"
#line 3579 "configure"
#include "confdefs.h"
#include <gd.h>
int main() {
gdImagePng (0, 0)
; return 0; }
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*
LIBGD=yes
else
@ -3577,7 +3602,7 @@ echo "$ac_t""$LIBGD" 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
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -3585,7 +3610,7 @@ else
ac_cv_sizeof_long_double=0
else
cat > conftest.$ac_ext <<EOF
#line 3589 "configure"
#line 3614 "configure"
#include "confdefs.h"
#include <stdio.h>
int main()
@ -3596,7 +3621,7 @@ int main()
return(0);
}
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
ac_cv_sizeof_long_double=`cat conftestval`
else
@ -3674,7 +3699,7 @@ if test "$uname" = "sysdeps/generic"; then
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -3696,7 +3721,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
uname_release="$libc_cv_uname_release"
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
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -3725,7 +3750,7 @@ EOF
# Test for old glibc 2.0.x headers so that they can be removed properly
# Search only in includedir.
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"
then
old_glibc_headers=yes
@ -3786,7 +3811,7 @@ if test $shared = default; then
fi
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
echo $ac_n "(cached) $ac_c" 1>&6
else

View File

@ -1513,6 +1513,22 @@ if test "$libc_cv_gcc_subtract_local_labels" = yes; then
AC_DEFINE(HAVE_SUBTRACT_LOCAL_LABELS)
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.
AC_MSG_CHECKING(for libgd)
if test "$with_gd" != "no"; then

View File

@ -20,6 +20,7 @@
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <tls.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/param.h>
@ -354,8 +355,12 @@ const char INTUSE(_itoa_lower_digits)[16] attribute_hidden
= "0123456789abcdef";
#undef errno
/* 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;
int *
@ -363,3 +368,4 @@ __errno_location (void)
{
return &errno;
}
#endif

View File

@ -130,9 +130,14 @@ _dl_start (void *arg)
{
struct link_map bootstrap_map;
hp_timing_t start_time;
#ifndef HAVE_BUILTIN_MEMSET
#if !defined HAVE_BUILTIN_MEMSET || defined USE_TLS
size_t cnt;
#endif
#ifdef USE_TLS
ElfW(Ehdr) *ehdr;
ElfW(Phdr) *phdr;
dtv_t initdtv[3];
#endif
/* This #define produces dynamic linking inline functions for
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 ();
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
ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
#endif
@ -220,12 +316,6 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
ElfW(Addr) *start_addr = alloca (sizeof (ElfW(Addr)));
extern char _begin[] 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)
{
@ -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_map_start = (ElfW(Addr)) _begin;
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
HP_TIMING_NOW (GL(dl_cpuclock_offset));
#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
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

View File

@ -1,73 +1,13 @@
/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
This file is part of the GNU C Library.
#include <stdlib/errno.h>
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.
#ifdef _ERRNO_H
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>
#if USE_TLS && HAVE___THREAD
# undef errno
extern __thread int errno;
# define __set_errno(val) (errno = (val))
#else
# define __set_errno(val) (*__errno_location ()) = (val)
#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

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>
* sysdeps/mips/pspinlock.c: Don't include <sgidefs.h>. Always

View File

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

View File

@ -27,6 +27,7 @@
#endif
#include "kernel-features.h"
#ifndef ASSEMBLER
extern long int testandset (int *spinlock);
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");
return ret;
}
#endif
#if __ASSUME_LDT_WORKS > 0
#include "../useldt.h"

View File

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

View File

@ -20,9 +20,10 @@
#ifndef _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. */
typedef union dtv
@ -39,56 +40,58 @@ typedef struct
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
} tcbhead_t;
#endif
/* We can support TLS only if the floating-stack support is available. */
#if defined FLOATING_STACKS && defined HAVE_TLS_SUPPORT
/* Get system call information. */
# include <sysdep.h>
/* Signal that TLS support is available. */
# define USE_TLS 1
# ifndef ASSEMBLER
/* Get system call information. */
# include <sysdep.h>
/* Get the thread descriptor definition. */
# include <linuxthreads/descr.h>
# include <linuxthreads/descr.h>
/* 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. */
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
/* 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. */
# 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
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
index -1 which contain the length. */
# define INSTALL_DTV(descr, dtvp) \
# define INSTALL_DTV(descr, dtvp) \
((tcbhead_t *) descr)->dtv = dtvp + 1
/* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtv) \
# define INSTALL_NEW_DTV(dtv) \
({ struct _pthread_descr_struct *__descr; \
THREAD_SETMEM (__descr, p_header.data.dtvp, dtv); })
/* Return dtv of given thread descriptor. */
# define GET_DTV(descr) \
# define GET_DTV(descr) \
(((tcbhead_t *) descr)->dtv)
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(descr) \
# define TLS_INIT_TP(descr) \
do { \
void *_descr = (descr); \
struct modify_ldt_ldt_s ldt_entry = \
@ -116,10 +119,11 @@ typedef struct
/* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \
# define THREAD_DTV() \
({ struct _pthread_descr_struct *__descr; \
THREAD_GETMEM (__descr, p_header.data.dtvp); })
#endif /* FLOATING_STACKS && HAVE_TLS_SUPPORT */
# endif /* FLOATING_STACKS && HAVE_TLS_SUPPORT */
#endif /* __ASSEMBLER__ */
#endif /* tls.h */

View File

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

View File

@ -22,7 +22,8 @@
subdir := stdlib
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 := \
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
...
#endif
#define __set_errno(val) errno = (val)

View File

@ -1,6 +1,6 @@
/* MT support function to get address of `errno' variable, non-threaded
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.
The GNU C Library is free software; you can redistribute it and/or
@ -19,8 +19,15 @@
02111-1307 USA. */
#include <errno.h>
#include <tls.h>
#undef errno
#if USE_TLS && HAVE___THREAD
extern __thread int errno;
#else
extern int errno;
#endif
int *
weak_const_function
__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:
/* The offset is positive, backward from the thread pointer. */
# 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
/* We know the offset of object the symbol is contained in.
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__));
#define errno (*__errno_location ())
#define __set_errno(val) (errno = (val))
#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:
/* The offset is positive, afterward from the thread pointer. */
# 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
/* We know the offset of object the symbol is contained in.
It is a positive value which will be added to the thread

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -32,17 +32,9 @@
# define ECANCELED 125
# ifndef __ASSEMBLER__
/* We now need a declaration of the `errno' variable. */
extern int errno;
/* Function to get address of global `errno' variable. */
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
/* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ())

View File

@ -1,5 +1,5 @@
/* 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.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -64,7 +64,6 @@ static int have_new_dcache = 1;
char *
__getcwd (char *buf, size_t size)
{
int save_errno;
char *path;
int n;
char *result;
@ -93,8 +92,6 @@ __getcwd (char *buf, size_t size)
return NULL;
}
save_errno = errno;
#if defined __NR_getcwd || __LINUX_GETCWD_SYSCALL > 0
if (!no_syscall_getcwd)
{
@ -137,8 +134,6 @@ __getcwd (char *buf, size_t size)
free (path);
return NULL;
}
__set_errno (save_errno);
# endif
}
#endif
@ -179,10 +174,6 @@ __getcwd (char *buf, size_t size)
have_new_dcache = 0;
#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. */
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.
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)
return -1;
__set_errno (save_errno);
/* If the filedescriptor is no TTY, grantpt has to set errno
to EINVAL. */
if (errno == ENOTTY)
if (save_errno == ENOTTY)
__set_errno (EINVAL);
else
__set_errno (save_errno);
return -1;
}

View File

@ -29,17 +29,9 @@
# define ECANCELED 125
# ifndef __ASSEMBLER__
/* We now need a declaration of the `errno' variable. */
extern int errno;
/* Function to get address of global `errno' variable. */
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
/* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ())

View File

@ -30,32 +30,44 @@
#ifdef PIC
# undef SYSCALL_ERROR_HANDLER
/* Store (- %eax) into errno through the GOT. */
# ifdef _LIBC_REENTRANT
# ifndef HAVE_HIDDEN
# define SETUP_PIC_REG \
# undef SETUP_PIC_REG
# ifndef HAVE_HIDDEN
# define SETUP_PIC_REG(reg) \
call 1f; \
.subsection 1; \
1:movl (%esp), %ebx; \
1:movl (%esp), %e##reg; \
ret; \
.previous
# else
# define SETUP_PIC_REG \
.section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits; \
.globl __i686.get_pc_thunk.bx; \
.hidden __i686.get_pc_thunk.bx; \
.type __i686.get_pc_thunk.bx,@function; \
__i686.get_pc_thunk.bx: \
movl (%esp), %ebx; \
# else
# define SETUP_PIC_REG(reg) \
.section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits; \
.globl __i686.get_pc_thunk.reg; \
.hidden __i686.get_pc_thunk.reg; \
.type __i686.get_pc_thunk.reg,@function; \
__i686.get_pc_thunk.reg: \
movl (%esp), %e##reg; \
ret; \
.previous; \
call __i686.get_pc_thunk.bx
# endif
call __i686.get_pc_thunk.reg
# 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; \
SETUP_PIC_REG; \
SETUP_PIC_REG(bx); \
addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
xorl %edx, %edx; \
subl %eax, %edx; \
@ -70,30 +82,10 @@ __i686.get_pc_thunk.bx: \
jmp L(pseudo_end);
/* A quick note: it is assumed that the call to `__errno_location' does
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
# else
# define SYSCALL_ERROR_HANDLER \
0:SETUP_PIC_REG; \
0:SETUP_PIC_REG(cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
xorl %edx, %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.
The GNU C Library is free software; you can redistribute it and/or
@ -17,6 +17,7 @@
02111-1307 USA. */
#include <sysdep.h>
#include <tls.h>
/* 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
@ -25,13 +26,21 @@
it somewhere else.
...and this place is here. */
#if USE_TLS && HAVE___THREAD
.section .tbss
#else
.bss
#endif
.globl errno
.type errno,@object
.size errno,4
.globl _errno
.type _errno,@object
.size _errno,4
.align 4
errno:
_errno:
.space 4
weak_alias (errno, _errno)
/* The following code is only used in the shared library when we
compile the reentrant version. Otherwise each system call defines

View File

@ -24,6 +24,7 @@
#include <sysdeps/unix/i386/sysdep.h>
#include <bp-sym.h>
#include <bp-asm.h>
#include <tls.h>
/* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h
@ -72,34 +73,47 @@
END (name)
#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
/* Store (- %eax) into errno through the GOT. */
#ifdef _LIBC_REENTRANT
# ifndef HAVE_HIDDEN
# define SETUP_PIC_REG \
# define SETUP_PIC_REG(reg) \
call 1f; \
.subsection 1; \
1:movl (%esp), %ebx; \
1:movl (%esp), %e##reg; \
ret; \
.previous
# else
# define SETUP_PIC_REG \
.section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits; \
.globl __i686.get_pc_thunk.bx; \
.hidden __i686.get_pc_thunk.bx; \
.type __i686.get_pc_thunk.bx,@function; \
__i686.get_pc_thunk.bx: \
movl (%esp), %ebx; \
# define SETUP_PIC_REG(reg) \
.section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits; \
.globl __i686.get_pc_thunk.reg; \
.hidden __i686.get_pc_thunk.reg; \
.type __i686.get_pc_thunk.reg,@function; \
__i686.get_pc_thunk.reg: \
movl (%esp), %e##reg; \
ret; \
.previous; \
call __i686.get_pc_thunk.bx
call __i686.get_pc_thunk.reg
# 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; \
SETUP_PIC_REG; \
SETUP_PIC_REG (bx); \
addl $_GLOBAL_OFFSET_TABLE_, %ebx; \
xorl %edx, %edx; \
subl %eax, %edx; \
@ -114,30 +128,10 @@ __i686.get_pc_thunk.bx: \
jmp L(pseudo_end);
/* A quick note: it is assumed that the call to `__errno_location' does
not modify the stack! */
#else
# ifndef HAVE_HIDDEN
# define SETUP_PIC_REG \
call 1f; \
.subsection 1; \
1:movl (%esp), %ecx; \
ret; \
.previous
# endif
# 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
#define SYSCALL_ERROR_HANDLER \
0:define SETUP_PIC_REG; \
# define SYSCALL_ERROR_HANDLER \
0:define SETUP_PIC_REG(cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
xorl %edx, %edx; \
subl %eax, %edx; \
@ -145,7 +139,7 @@ __i686.get_pc_thunk.cx: \
movl %edx, (%ecx); \
orl $-1, %eax; \
jmp L(pseudo_end);
#endif /* _LIBC_REENTRANT */
# endif /* _LIBC_REENTRANT */
#endif /* PIC */
/* 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.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -53,7 +53,6 @@
buf->f_flag = 0;
if (STAT (&st) >= 0)
{
int save_errno = errno;
struct mntent mntbuf;
FILE *mtab;
@ -104,6 +103,4 @@
/* Close the file. */
__endmntent (mtab);
}
__set_errno (save_errno);
}

View File

@ -28,17 +28,9 @@
# define ENOTSUP EOPNOTSUPP
# ifndef __ASSEMBLER__
/* We now need a declaration of the `errno' variable. */
extern int errno;
/* Function to get address of global `errno' variable. */
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
/* When using threads, errno is a per-thread value. */
# 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.
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;
/* 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)
return result;
__set_errno(save_errno);
if (cmd == IPC_SET)
{
old.msg_perm.uid = buf->msg_perm.uid;

View File

@ -1,5 +1,5 @@
/* 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.
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;
int count;
{
int errno_saved = errno;
ssize_t bytes_read;
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)
return bytes_read;
/* Restore the old error value as if nothing happened. */
__set_errno (errno_saved);
return __atomic_readv_replacement (fd, vector, count);
}
weak_alias (__readv, readv)

View File

@ -1,5 +1,5 @@
/* 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.
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;
int count;
{
int errno_saved = errno;
ssize_t bytes_written;
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)
return bytes_written;
/* Restore the old error value as if nothing happened. */
__set_errno (errno_saved);
return __atomic_writev_replacement (fd, vector, count);
}
weak_alias (__writev, writev)

View File

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