diff options
| author | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
|---|---|---|
| committer | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
| commit | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch) | |
| tree | 2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /csu | |
| parent | 7d58530341304d403a6626d7f7a1913165fe2f32 (diff) | |
| download | glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.xz glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip | |
2.5-18.1
Diffstat (limited to 'csu')
| -rw-r--r-- | csu/Makefile | 30 | ||||
| -rw-r--r-- | csu/check_fds.c | 102 | ||||
| -rw-r--r-- | csu/dso_handle.c | 5 | ||||
| -rw-r--r-- | csu/elf-init.c | 59 | ||||
| -rw-r--r-- | csu/errno-loc.c (renamed from csu/munch-tmpl.c) | 33 | ||||
| -rw-r--r-- | csu/errno.c | 53 | ||||
| -rw-r--r-- | csu/init-first.c | 59 | ||||
| -rw-r--r-- | csu/libc-start.c | 263 | ||||
| -rw-r--r-- | csu/libc-tls.c | 263 | ||||
| -rw-r--r-- | csu/munch.awk | 11 | ||||
| -rw-r--r-- | csu/start.c | 13 | ||||
| -rw-r--r-- | csu/sysdep.c | 2 | ||||
| -rw-r--r-- | csu/version.c | 4 |
13 files changed, 824 insertions, 73 deletions
diff --git a/csu/Makefile b/csu/Makefile index fbbfe0050a..0e2ae07cf7 100644 --- a/csu/Makefile +++ b/csu/Makefile @@ -1,5 +1,5 @@ # Makefile for csu code for GNU C library. -# Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1995-2004, 2005, 2006 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 @@ -39,8 +39,8 @@ omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \ b$(start-installed-name) $(csu-dummies) \ S$(start-installed-name)) install-lib = $(start-installed-name) g$(start-installed-name) $(csu-dummies) -distribute = initfini.c gmon-start.c start.c defs.awk munch.awk \ - abi-note.S init.c munch-tmpl.c not-cancel.h +distribute = initfini.c gmon-start.c start.c defs.awk \ + abi-note.S init.c c not-cancel.h generated = version-info.h before-compile = $(objpfx)version-info.h @@ -54,11 +54,13 @@ include ../Makeconfig ifeq (yes,$(build-shared)) extra-objs += S$(start-installed-name) install-lib += S$(start-installed-name) +generated += start.os endif ifeq (yes,$(build-bounded)) extra-objs += b$(start-installed-name) install-lib += b$(start-installed-name) +generated += start.ob endif ifneq ($(start-installed-name),$(static-start-installed-name)) @@ -73,19 +75,6 @@ before-compile += $(objpfx)abi-tag.h generated += abi-tag.h endif -ifneq (yes,$(gnu-ld)) -libc-init = munch-init -$(objpfx)munch-init.c: munch.awk munch-tmpl.c $(+subdir_inits) - $(AWK) -f $< subdirs='$(+init_subdirs)' $(word 2,$^) > $@-t - mv -f $@-t $@ -generated += munch-init.c - -# All initialization source files. -+subdir_inits := $(wildcard $(foreach dir,$(subdirs),$(dir)/init-$(dir).c)) -# All subdirectories containing initialization source files. -+init_subdirs := $(patsubst %/,%,$(dir $(+subdir_inits))) -endif - ifeq ($(have-initfini),yes) CPPFLAGS += -DHAVE_INITFINI @@ -106,7 +95,7 @@ $(crtstuff:%=$(objpfx)%.o): %.o: %.S $(objpfx)defs.h CFLAGS-initfini.s = -g0 -fPIC -fno-inline-functions $(fno-unit-at-a-time) -vpath initfini.c $(full_config_sysdirs) +vpath initfini.c $(sysdirs) $(objpfx)initfini.s: initfini.c $(before-compile) $(compile.c) -S $(CFLAGS-initfini.s) -finhibit-size-directive \ @@ -211,8 +200,9 @@ $(objpfx)abi-tag.h: $(..)abi-tags if test -r $@.new; then mv -f $@.new $@; \ else echo >&2 'This configuration not matched in $<'; exit 1; fi -all-Banner-files = $(wildcard $(addsuffix /Banner, \ - $(addprefix $(..), $(subdirs)))) +all-Banner-files = $(wildcard $(addsuffix /Banner,\ + $(sort $(subdir-srcdirs) \ + $(sysdeps-srcdirs)))) $(objpfx)version-info.h: $(common-objpfx)config.make $(all-Banner-files) $(make-target-directory) (case $(config-os) in \ @@ -239,7 +229,7 @@ $(objpfx)version-info.h: $(common-objpfx)config.make $(all-Banner-files) esac; \ files="$(all-Banner-files)"; \ if test -n "$$files"; then \ - echo "\"Available extensions:\\n\""; \ + printf '"Available extensions:\\n"\n'; \ sed -e '/^#/d' -e 's/^[[:space:]]*/ /' \ -e 's/^\(.*\)$$/\"\1\\n\"/' $$files; \ fi) > $@T diff --git a/csu/check_fds.c b/csu/check_fds.c new file mode 100644 index 0000000000..10ba3da395 --- /dev/null +++ b/csu/check_fds.c @@ -0,0 +1,102 @@ +/* Copyright (C) 2000, 2002, 2003, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> + +/* Try to get a machine dependent instruction which will make the + program crash. This is used in case everything else fails. */ +#include <abort-instr.h> +#ifndef ABORT_INSTRUCTION +/* No such instruction is available. */ +# define ABORT_INSTRUCTION +#endif + +#include <device-nrs.h> +#include <not-cancel.h> + + +/* Should other OSes (e.g., Hurd) have different versions which can + be written in a better way? */ +static void +check_one_fd (int fd, int mode) +{ + /* Note that fcntl() with this parameter is not a cancellation point. */ + if (__builtin_expect (__libc_fcntl (fd, F_GETFD), 0) == -1 + && errno == EBADF) + { + const char *name; + dev_t dev; + + /* For writable descriptors we use /dev/full. */ + if ((mode & O_ACCMODE) == O_WRONLY) + { + name = _PATH_DEV "full"; + dev = makedev (DEV_FULL_MAJOR, DEV_FULL_MINOR); + } + else + { + name = _PATH_DEVNULL; + dev = makedev (DEV_NULL_MAJOR, DEV_NULL_MINOR); + } + + /* Something is wrong with this descriptor, it's probably not + opened. Open /dev/null so that the SUID program we are + about to start does not accidently use this descriptor. */ + int nullfd = open_not_cancel (name, mode, 0); + + /* We are very paranoid here. With all means we try to ensure + that we are actually opening the /dev/null device and nothing + else. + + Note that the following code assumes that STDIN_FILENO, + STDOUT_FILENO, STDERR_FILENO are the three lowest file + decsriptor numbers, in this order. */ + struct stat64 st; + if (__builtin_expect (nullfd != fd, 0) + || __builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) != 0 + || __builtin_expect (S_ISCHR (st.st_mode), 1) == 0 + || st.st_rdev != dev) + /* We cannot even give an error message here since it would + run into the same problems. */ + while (1) + /* Try for ever and ever. */ + ABORT_INSTRUCTION; + } +} + + +void +__libc_check_standard_fds (void) +{ + /* This is really paranoid but some people actually are. If /dev/null + should happen to be a symlink to somewhere else and not the device + commonly known as "/dev/null" we bail out. We can detect this with + the O_NOFOLLOW flag for open() but only on some system. */ +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif + /* Check all three standard file descriptors. */ + check_one_fd (STDIN_FILENO, O_WRONLY | O_NOFOLLOW); + check_one_fd (STDOUT_FILENO, O_RDONLY | O_NOFOLLOW); + check_one_fd (STDERR_FILENO, O_RDONLY | O_NOFOLLOW); +} diff --git a/csu/dso_handle.c b/csu/dso_handle.c index 04ed078625..fd295f2442 100644 --- a/csu/dso_handle.c +++ b/csu/dso_handle.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,4 +18,5 @@ /* We have to define __dso_handle ourselves since we do not use gcc's crtbegin files. */ -void *__dso_handle __attribute__ ((__visibility__ ("hidden"))) = &__dso_handle; +const void *const __dso_handle __attribute__ ((__visibility__ ("hidden"))) + = &__dso_handle; diff --git a/csu/elf-init.c b/csu/elf-init.c index d4e0b3fb88..d0a518f9fb 100644 --- a/csu/elf-init.c +++ b/csu/elf-init.c @@ -1,5 +1,5 @@ /* Startup support for ELF initializers/finalizers in the main executable. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 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 @@ -36,16 +36,37 @@ #include <stddef.h> -#ifdef HAVE_INITFINI_ARRAY + /* These magic symbols are provided by the linker. */ -extern void (*__preinit_array_start []) (void) attribute_hidden; -extern void (*__preinit_array_end []) (void) attribute_hidden; -extern void (*__init_array_start []) (void) attribute_hidden; -extern void (*__init_array_end []) (void) attribute_hidden; +extern void (*__preinit_array_start []) (int, char **, char **) + attribute_hidden; +extern void (*__preinit_array_end []) (int, char **, char **) + attribute_hidden; +extern void (*__init_array_start []) (int, char **, char **) + attribute_hidden; +extern void (*__init_array_end []) (int, char **, char **) + attribute_hidden; extern void (*__fini_array_start []) (void) attribute_hidden; extern void (*__fini_array_end []) (void) attribute_hidden; + +#if defined HAVE_VISIBILITY_ATTRIBUTE \ + && (defined SHARED || defined LIBC_NONSHARED) +# define hidden_undef_2(x) #x +# define hidden_undef_1(x) hidden_undef_2 (x) +# define hidden_undef(x) \ + __asm (hidden_undef_1 (ASM_GLOBAL_DIRECTIVE) " " #x); \ + __asm (".hidden " #x); +#else +# define hidden_undef(x) #endif +hidden_undef (__preinit_array_start) +hidden_undef (__preinit_array_end) +hidden_undef (__init_array_start) +hidden_undef (__init_array_end) +hidden_undef (__fini_array_start) +hidden_undef (__fini_array_end) + /* These function symbols are provided for the .init/.fini section entry points automagically by the linker. */ extern void _init (void); @@ -57,43 +78,39 @@ extern void _fini (void); the libc.a module in that it doesn't call the preinit array. */ void -__libc_csu_init (void) +__libc_csu_init (int argc, char **argv, char **envp) { -#ifdef HAVE_INITFINI_ARRAY /* For dynamically linked executables the preinit array is executed by the dynamic linker (before initializing any shared object. */ -# ifndef LIBC_NONSHARED +#ifndef LIBC_NONSHARED /* For static executables, preinit happens rights before init. */ { const size_t size = __preinit_array_end - __preinit_array_start; size_t i; for (i = 0; i < size; i++) - (*__preinit_array_start [i]) (); + (*__preinit_array_start [i]) (argc, argv, envp); } -# endif #endif _init (); -#ifdef HAVE_INITFINI_ARRAY - { - const size_t size = __init_array_end - __init_array_start; - size_t i; - for (i = 0; i < size; i++) - (*__init_array_start [i]) (); - } -#endif + const size_t size = __init_array_end - __init_array_start; + for (size_t i = 0; i < size; i++) + (*__init_array_start [i]) (argc, argv, envp); } +/* This function should not be used anymore. We run the executable's + destructor now just like any other. We cannot remove the function, + though. */ void __libc_csu_fini (void) { -#ifdef HAVE_INITFINI_ARRAY +#ifndef LIBC_NONSHARED size_t i = __fini_array_end - __fini_array_start; while (i-- > 0) (*__fini_array_start [i]) (); -#endif _fini (); +#endif } diff --git a/csu/munch-tmpl.c b/csu/errno-loc.c index f807cf9a3f..633590f4f9 100644 --- a/csu/munch-tmpl.c +++ b/csu/errno-loc.c @@ -1,4 +1,6 @@ -/* Copyright (C) 1991, 1995, 1997, 2000 Free Software Foundation, Inc. +/* MT support function to get address of `errno' variable, non-threaded + version. + Copyright (C) 1996, 1998, 2002, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,23 +18,20 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <stdlib.h> +#include <errno.h> +#include <tls.h> +#if ! USE___THREAD && !RTLD_PRIVATE_ERRNO +#undef errno +extern int errno; +#endif -EXTERNS - -void -__libc_init (int argc, char **argv, char **envp) -{ - CALLS - -#ifdef HAVE_INITFINI - { - /* These functions are defined in crti.o to run the .init and .fini - sections, which are used for initializers and finalizers. */ - extern void _init (void), _fini (void); - atexit (&_fini); /* Arrange for _fini to run at exit. */ - _init (); - } +int * +#if ! USE___THREAD +weak_const_function #endif +__errno_location (void) +{ + return &errno; } +libc_hidden_def (__errno_location) diff --git a/csu/errno.c b/csu/errno.c new file mode 100644 index 0000000000..03d661b717 --- /dev/null +++ b/csu/errno.c @@ -0,0 +1,53 @@ +/* Definition of `errno' variable. Canonical version. + Copyright (C) 2002, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <tls.h> +#include <dl-sysdep.h> +#undef errno + +#if RTLD_PRIVATE_ERRNO + +/* Code compiled for rtld refers only to this name. */ +int rtld_errno attribute_hidden; + +#elif USE___THREAD + +__thread int errno; +extern __thread int __libc_errno __attribute__ ((alias ("errno"))) + attribute_hidden; + +#else + +/* This differs from plain `int errno;' in that it doesn't create + a common definition, but a plain symbol that resides in .bss, + which can have an alias. */ +int errno __attribute__ ((nocommon)); +strong_alias (errno, _errno) + +/* We declare these with compat_symbol so that they are not visible at + link time. Programs must use the accessor functions. RTLD is special, + since it's not exported from there at any time. */ +# if defined HAVE_ELF && defined SHARED && defined DO_VERSIONING +# include <shlib-compat.h> +compat_symbol (libc, errno, errno, GLIBC_2_0); +compat_symbol (libc, _errno, _errno, GLIBC_2_0); +# endif + +#endif diff --git a/csu/init-first.c b/csu/init-first.c new file mode 100644 index 0000000000..fa21274c73 --- /dev/null +++ b/csu/init-first.c @@ -0,0 +1,59 @@ +/* Initialization code run first thing by the ELF startup code. Stub version. + Copyright (C) 1995, 1997, 1998, 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 + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <unistd.h> +#include <sys/types.h> + +/* Set nonzero if we have to be prepared for more then one libc being + used in the process. Safe assumption if initializer never runs. */ +int __libc_multiple_libcs attribute_hidden = 1; + +extern void __libc_init (int, char **, char **); +#ifdef USE_NONOPTION_FLAGS +extern void __getopt_clean_environment (char **); +#endif + +#ifdef SHARED +void +__libc_init_first (void) +{ +} +#endif + +#ifdef SHARED +/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT + pointer in the dynamic section based solely on that. It is convention + for this function to be in the `.init' section, but the symbol name is + the only thing that really matters!! */ +void _init +#else +void __libc_init_first +#endif +(int argc, char *arg0, ...) +{ + char **argv = &arg0, **envp = &argv[argc + 1]; + + __environ = envp; + __libc_init (argc, argv, envp); + +#ifdef USE_NONOPTION_FLAGS + /* This is a hack to make the special getopt in GNU libc working. */ + __getopt_clean_environment (envp); +#endif +} diff --git a/csu/libc-start.c b/csu/libc-start.c new file mode 100644 index 0000000000..194db6b1ec --- /dev/null +++ b/csu/libc-start.c @@ -0,0 +1,263 @@ +/* Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <ldsodefs.h> +#include <bp-start.h> +#include <bp-sym.h> + +extern void __libc_init_first (int argc, char **argv, char **envp); + +extern int __libc_multiple_libcs; + +#include <tls.h> +#ifndef SHARED +# include <dl-osinfo.h> +extern void __pthread_initialize_minimal (void) +# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP + __attribute__ ((weak)) +# endif + ; +# ifndef THREAD_SET_STACK_GUARD +/* Only exported for architectures that don't store the stack guard canary + in thread local area. */ +uintptr_t __stack_chk_guard attribute_relro; +# endif +#endif + +#ifdef HAVE_PTR_NTHREADS +/* We need atomic operations. */ +# include <atomic.h> +#endif + + +#ifdef LIBC_START_MAIN +# ifdef LIBC_START_DISABLE_INLINE +# define STATIC static +# else +# define STATIC static inline __attribute__ ((always_inline)) +# endif +#else +# define STATIC +# define LIBC_START_MAIN BP_SYM (__libc_start_main) +#endif + +#ifdef MAIN_AUXVEC_ARG +/* main gets passed a pointer to the auxiliary. */ +# define MAIN_AUXVEC_DECL , void * +# define MAIN_AUXVEC_PARAM , auxvec +#else +# define MAIN_AUXVEC_DECL +# define MAIN_AUXVEC_PARAM +#endif + +STATIC int LIBC_START_MAIN (int (*main) (int, char **, char ** + MAIN_AUXVEC_DECL), + int argc, + char *__unbounded *__unbounded ubp_av, +#ifdef LIBC_START_MAIN_AUXVEC_ARG + ElfW(auxv_t) *__unbounded auxvec, +#endif + __typeof (main) init, + void (*fini) (void), + void (*rtld_fini) (void), + void *__unbounded stack_end) + __attribute__ ((noreturn)); + + +/* Note: the fini parameter is ignored here for shared library. It + is registered with __cxa_atexit. This had the disadvantage that + finalizers were called in more than one place. */ +STATIC int +LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), + int argc, char *__unbounded *__unbounded ubp_av, +#ifdef LIBC_START_MAIN_AUXVEC_ARG + ElfW(auxv_t) *__unbounded auxvec, +#endif + __typeof (main) init, + void (*fini) (void), + void (*rtld_fini) (void), void *__unbounded stack_end) +{ +#if __BOUNDED_POINTERS__ + char **argv; +#else +# define argv ubp_av +#endif + + /* Result of the 'main' function. */ + int result; + + __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; + +#ifndef SHARED + char *__unbounded *__unbounded ubp_ev = &ubp_av[argc + 1]; + + INIT_ARGV_and_ENVIRON; + + /* Store the lowest stack address. This is done in ld.so if this is + the code for the DSO. */ |
