aboutsummaryrefslogtreecommitdiff
path: root/csu
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
commit0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch)
tree2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /csu
parent7d58530341304d403a6626d7f7a1913165fe2f32 (diff)
downloadglibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.xz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip
2.5-18.1
Diffstat (limited to 'csu')
-rw-r--r--csu/Makefile30
-rw-r--r--csu/check_fds.c102
-rw-r--r--csu/dso_handle.c5
-rw-r--r--csu/elf-init.c59
-rw-r--r--csu/errno-loc.c (renamed from csu/munch-tmpl.c)33
-rw-r--r--csu/errno.c53
-rw-r--r--csu/init-first.c59
-rw-r--r--csu/libc-start.c263
-rw-r--r--csu/libc-tls.c263
-rw-r--r--csu/munch.awk11
-rw-r--r--csu/start.c13
-rw-r--r--csu/sysdep.c2
-rw-r--r--csu/version.c4
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. */