diff options
Diffstat (limited to 'REORG.TODO/csu')
-rw-r--r-- | REORG.TODO/csu/Makefile | 161 | ||||
-rw-r--r-- | REORG.TODO/csu/Versions | 13 | ||||
-rw-r--r-- | REORG.TODO/csu/abi-note.S | 72 | ||||
-rw-r--r-- | REORG.TODO/csu/check_fds.c | 97 | ||||
-rw-r--r-- | REORG.TODO/csu/dso_handle.c | 21 | ||||
-rw-r--r-- | REORG.TODO/csu/elf-init.c | 106 | ||||
-rw-r--r-- | REORG.TODO/csu/errno-loc.c | 28 | ||||
-rw-r--r-- | REORG.TODO/csu/errno.c | 35 | ||||
-rw-r--r-- | REORG.TODO/csu/gmon-start.c | 92 | ||||
-rw-r--r-- | REORG.TODO/csu/init-first.c | 102 | ||||
-rw-r--r-- | REORG.TODO/csu/init.c | 26 | ||||
-rw-r--r-- | REORG.TODO/csu/libc-start.c | 336 | ||||
-rw-r--r-- | REORG.TODO/csu/libc-tls.c | 217 | ||||
-rw-r--r-- | REORG.TODO/csu/start.c | 11 | ||||
-rw-r--r-- | REORG.TODO/csu/sysdep.c | 2 | ||||
-rw-r--r-- | REORG.TODO/csu/version.c | 74 |
16 files changed, 1393 insertions, 0 deletions
diff --git a/REORG.TODO/csu/Makefile b/REORG.TODO/csu/Makefile new file mode 100644 index 0000000000..88646b6e8f --- /dev/null +++ b/REORG.TODO/csu/Makefile @@ -0,0 +1,161 @@ +# Makefile for csu code for GNU C library. +# Copyright (C) 1995-2017 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, see +# <http://www.gnu.org/licenses/>. + +# This directory contains the C startup code (that which calls main). This +# consists of the startfile, built from start.c and installed as crt0.o +# (traditionally) or crt1.o (for ELF). In ELF we also install crti.o and +# crtn.o, special "initializer" and "finalizer" files used in the link +# to make the .init and .fini sections work right. + +subdir := csu + +include ../Makeconfig + +routines = init-first libc-start $(libc-init) sysdep version check_fds \ + libc-tls elf-init dso_handle +aux = errno +elide-routines.os = libc-tls +static-only-routines = elf-init +csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o) +extra-objs = start.o \ + $(start-installed-name) g$(start-installed-name) $(csu-dummies) \ + S$(start-installed-name) +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) +generated += version-info.h +before-compile += $(objpfx)version-info.h + +# No tests are allowed in the csu/ subdirectory because the startup +# code is compiled with special flags. +tests = + +CFLAGS-.o += $(no-stack-protector) +CFLAGS-.op += $(no-stack-protector) +CFLAGS-.os += $(no-stack-protector) + +ifeq (yes,$(build-shared)) +extra-objs += S$(start-installed-name) gmon-start.os +ifneq ($(start-installed-name),$(static-start-installed-name)) +extra-objs += gmon-start.o +endif +install-lib += S$(start-installed-name) +generated += start.os +else +extra-objs += gmon-start.o +endif + +ifneq ($(start-installed-name),$(static-start-installed-name)) +extra-objs += $(static-start-installed-name) g$(static-start-installed-name) +omit-deps += $(patsubst %.o,%,$(static-start-installed-name) \ + g$(static-start-installed-name)) +install-lib += $(static-start-installed-name) g$(static-start-installed-name) +endif + +before-compile += $(objpfx)abi-tag.h +generated += abi-tag.h + +# These are the special initializer/finalizer files. They are always the +# first and last file in the link. crti.o ... crtn.o define the global +# "functions" _init and _fini to run the .init and .fini sections. +crtstuff = crti crtn + +install-lib += $(crtstuff:=.o) +extra-objs += $(crtstuff:=.o) + +extra-objs += abi-note.o init.o +asm-CPPFLAGS += -I$(objpfx). + +include ../Rules + +# Make these in the lib pass so they're available in time to link things with. +subdir_lib: $(extra-objs:%=$(objpfx)%) + +define link-relocatable +$(CC) -nostdlib -nostartfiles -r -o $@ $^ +endef + +ifndef start-installed-name-rule +# We link the ELF startfile along with a SHT_NOTE section indicating +# the kernel ABI the binaries linked with this library will require. +$(objpfx)$(start-installed-name): $(objpfx)start.o $(objpfx)abi-note.o \ + $(objpfx)init.o + $(link-relocatable) +$(objpfx)S$(start-installed-name): $(objpfx)start.os $(objpfx)abi-note.o \ + $(objpfx)init.o + $(link-relocatable) +endif + +# The profiling startfile is made by linking together the normal +# startfile with gmon-start.o, which defines a constructor function +# to turn on profiling code at startup. +ifeq (yes,$(build-shared)) +$(objpfx)g$(start-installed-name): \ + $(objpfx)g%: $(objpfx)S% $(objpfx)gmon-start.os + $(link-relocatable) +ifneq ($(start-installed-name),$(static-start-installed-name)) +$(objpfx)g$(static-start-installed-name): \ + $(objpfx)g%: $(objpfx)% $(objpfx)gmon-start.o + $(link-relocatable) +endif +else +$(addprefix $(objpfx),$(sort g$(start-installed-name) \ + g$(static-start-installed-name))): \ + $(objpfx)g%: $(objpfx)% $(objpfx)gmon-start.o + $(link-relocatable) +endif + +# These extra files are sometimes expected by system standard linking +# procedures, but we have nothing for them to do. So compile empty files. +$(addprefix $(objpfx),$(filter-out $(start-installed-name), $(csu-dummies))):\ + $(before-compile) + $(COMPILE.c) -o $@ -x c /dev/null + +# These headers are used by the startup code. +$(objpfx)abi-tag.h: $(..)abi-tags + $(make-target-directory) + rm -f $@.new + sed -e 's/#.*$$//' -e '/^[ ]*$$/d' $< | \ + while read conf tagos tagver; do \ + test `expr '$(config-machine)-$(config-vendor)-$(config-os)' \ + : "$$conf"` != 0 || continue; \ + ( echo "$$tagos" | \ + sed -e 's/[^0-9xXa-fA-F ]//' \ + -e 's/^/#define __ABI_TAG_OS /'; \ + echo "#ifndef __ABI_TAG_VERSION"; \ + echo "$$tagver" | \ + sed -e 's/[^0-9xXa-fA-F]/ /g' -e 's/ *$$//' \ + -e 's/ /,/g' -e 's/^/# define __ABI_TAG_VERSION /'; \ + echo "#endif" ) > $@.new; \ + done + 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,\ + $(sort $(subdir-srcdirs) \ + $(sysdeps-srcdirs)))) +$(objpfx)version-info.h: $(common-objpfx)config.make $(all-Banner-files) + $(make-target-directory) + (files="$(all-Banner-files)"; \ + if test -n "$$files"; then \ + printf '"Available extensions:\\n"\n'; \ + sed -e '/^#/d' -e 's/^[[:space:]]*/ /' \ + -e 's/^\(.*\)$$/\"\1\\n\"/' $$files; \ + fi) > $@T + mv -f $@T $@ diff --git a/REORG.TODO/csu/Versions b/REORG.TODO/csu/Versions new file mode 100644 index 0000000000..43010c3443 --- /dev/null +++ b/REORG.TODO/csu/Versions @@ -0,0 +1,13 @@ +libc { + GLIBC_2.0 { + # helper functions + __libc_init_first; __libc_start_main; + } + GLIBC_2.1 { + # New special glibc functions. + gnu_get_libc_release; gnu_get_libc_version; + } + GLIBC_PRIVATE { + errno; + } +} diff --git a/REORG.TODO/csu/abi-note.S b/REORG.TODO/csu/abi-note.S new file mode 100644 index 0000000000..a231296148 --- /dev/null +++ b/REORG.TODO/csu/abi-note.S @@ -0,0 +1,72 @@ +/* Special .init and .fini section support. + Copyright (C) 1997-2017 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. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + 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, see + <http://www.gnu.org/licenses/>. */ + +/* Define an ELF note identifying the operating-system ABI that the + executable was created for. The ELF note information identifies a + particular OS or coordinated development effort within which the + ELF header's e_machine value plus (for dynamically linked programs) + the PT_INTERP dynamic linker name and DT_NEEDED shared library + names fully identify the runtime environment required by an + executable. + + The general format of ELF notes is as follows. + Offsets and lengths are bytes or (parenthetical references) to the + values in other fields. + +offset length contents +0 4 length of name +4 4 length of data +8 4 note type +12 (0) vendor name + - null-terminated ASCII string, padded to 4-byte alignment +12+(0) (4) note data, + + The GNU project and cooperating development efforts (including the + Linux community) use note type 1 and a vendor name string of "GNU" + for a note descriptor that indicates ABI requirements. The note data + is four 32-bit words. The first of these is an operating system + number (0=Linux, 1=Hurd, 2=Solaris, ...) and the remaining three + identify the earliest release of that OS that supports this ABI. + See abi-tags (top level) for details. */ + +#include <config.h> +#include <abi-tag.h> /* OS-specific ABI tag value */ + +/* The linker (GNU ld 2.8 and later) recognizes an allocated section whose + name begins with `.note' and creates a PT_NOTE program header entry + pointing at it. */ + + .section ".note.ABI-tag", "a" + .p2align 2 + .long 1f - 0f /* name length */ + .long 3f - 2f /* data length */ + .long 1 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: .p2align 2 +2: .long __ABI_TAG_OS /* note data: the ABI tag */ + .long __ABI_TAG_VERSION +3: .p2align 2 /* pad out section */ diff --git a/REORG.TODO/csu/check_fds.c b/REORG.TODO/csu/check_fds.c new file mode 100644 index 0000000000..062c879373 --- /dev/null +++ b/REORG.TODO/csu/check_fds.c @@ -0,0 +1,97 @@ +/* Copyright (C) 2000-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#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 accidentally 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) +{ + /* Check all three standard file descriptors. The O_NOFOLLOW flag + 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. */ + 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/REORG.TODO/csu/dso_handle.c b/REORG.TODO/csu/dso_handle.c new file mode 100644 index 0000000000..98648f6fbf --- /dev/null +++ b/REORG.TODO/csu/dso_handle.c @@ -0,0 +1,21 @@ +/* Copyright (C) 2002-2017 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, see + <http://www.gnu.org/licenses/>. */ + +/* We have to define __dso_handle ourselves since we do not use gcc's + crtbegin files. */ +const void *const __dso_handle __attribute__ ((__visibility__ ("hidden"))) + = &__dso_handle; diff --git a/REORG.TODO/csu/elf-init.c b/REORG.TODO/csu/elf-init.c new file mode 100644 index 0000000000..34ee89b843 --- /dev/null +++ b/REORG.TODO/csu/elf-init.c @@ -0,0 +1,106 @@ +/* Startup support for ELF initializers/finalizers in the main executable. + Copyright (C) 2002-2017 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. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <stddef.h> + + +/* These magic symbols are provided by the linker. */ +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; + + +#ifndef NO_INITFINI +/* These function symbols are provided for the .init/.fini section entry + points automagically by the linker. */ +extern void _init (void); +extern void _fini (void); +#endif + + +/* These functions are passed to __libc_start_main by the startup code. + These get statically linked into each program. For dynamically linked + programs, this module will come from libc_nonshared.a and differs from + the libc.a module in that it doesn't call the preinit array. */ + + +void +__libc_csu_init (int argc, char **argv, char **envp) +{ + /* For dynamically linked executables the preinit array is executed by + the dynamic linker (before initializing any shared object). */ + +#ifndef LIBC_NONSHARED + /* For static executables, preinit happens right 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]) (argc, argv, envp); + } +#endif + +#ifndef NO_INITFINI + _init (); +#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) +{ +#ifndef LIBC_NONSHARED + size_t i = __fini_array_end - __fini_array_start; + while (i-- > 0) + (*__fini_array_start [i]) (); + +# ifndef NO_INITFINI + _fini (); +# endif +#endif +} diff --git a/REORG.TODO/csu/errno-loc.c b/REORG.TODO/csu/errno-loc.c new file mode 100644 index 0000000000..ddc4e14df2 --- /dev/null +++ b/REORG.TODO/csu/errno-loc.c @@ -0,0 +1,28 @@ +/* MT support function to get address of `errno' variable, non-threaded + version. + Copyright (C) 1996-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <tls.h> + +int * +__errno_location (void) +{ + return &errno; +} +libc_hidden_def (__errno_location) diff --git a/REORG.TODO/csu/errno.c b/REORG.TODO/csu/errno.c new file mode 100644 index 0000000000..8b2e3489c2 --- /dev/null +++ b/REORG.TODO/csu/errno.c @@ -0,0 +1,35 @@ +/* Definition of `errno' variable. Canonical version. + Copyright (C) 2002-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#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; + +#else + +__thread int errno; +extern __thread int __libc_errno __attribute__ ((alias ("errno"))) + attribute_hidden; + +#endif diff --git a/REORG.TODO/csu/gmon-start.c b/REORG.TODO/csu/gmon-start.c new file mode 100644 index 0000000000..a1f92d5e1a --- /dev/null +++ b/REORG.TODO/csu/gmon-start.c @@ -0,0 +1,92 @@ +/* Code to enable profiling at program startup. + Copyright (C) 1995-2017 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. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/types.h> +#include <sys/gmon.h> +#include <stdlib.h> +#include <unistd.h> +#define __ASSEMBLY__ +#include <entry.h> + +/* Beginning and end of our code segment. We cannot declare them + as the external functions since we want the addresses of those + labels. Taking the address of a function may have different + meanings on different platforms. */ +#ifdef ENTRY_POINT_DECL +ENTRY_POINT_DECL(extern) +#else +extern char ENTRY_POINT[]; +#endif +extern char etext[]; + +#ifndef TEXT_START +# ifdef ENTRY_POINT_DECL +# define TEXT_START ENTRY_POINT +# else +# define TEXT_START &ENTRY_POINT +# endif +#endif + +#ifdef GMON_START_ARRAY_SECTION +static void __gmon_start__ (void); +static void (*const gmon_start_initializer) (void) + __attribute__ ((used, section (GMON_START_ARRAY_SECTION))) = &__gmon_start__; +static +#else +/* We cannot use the normal constructor mechanism to call + __gmon_start__ because gcrt1.o appears before crtbegin.o in the link. + Instead crti.o calls it specially. */ +extern void __gmon_start__ (void); +#endif + +void +__gmon_start__ (void) +{ + /* Protect from being called more than once. Since crti.o is linked + into every shared library, each of their init functions will call us. */ + static int called; + + if (called) + return; + + called = 1; + + /* Start keeping profiling records. */ + __monstartup ((u_long) TEXT_START, (u_long) &etext); + + /* Call _mcleanup before exiting; it will write out gmon.out from the + collected data. */ + atexit (&_mcleanup); +} diff --git a/REORG.TODO/csu/init-first.c b/REORG.TODO/csu/init-first.c new file mode 100644 index 0000000000..510ea2db1e --- /dev/null +++ b/REORG.TODO/csu/init-first.c @@ -0,0 +1,102 @@ +/* Initialization code run first thing by the ELF startup code. Common version + Copyright (C) 1995-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sysdep.h> +#include <fpu_control.h> +#include <sys/param.h> +#include <sys/types.h> +#include <libc-internal.h> + +#include <ldsodefs.h> + +/* Set nonzero if we have to be prepared for more than one libc being + used in the process. Safe assumption if initializer never runs. */ +int __libc_multiple_libcs attribute_hidden = 1; + +/* Remember the command line argument and enviroment contents for + later calls of initializers for dynamic libraries. */ +int __libc_argc attribute_hidden; +char **__libc_argv attribute_hidden; + + +void +__libc_init_first (int argc, char **argv, char **envp) +{ +#ifdef SHARED + /* For DSOs we do not need __libc_init_first but instead _init. */ +} + +void +attribute_hidden +_init (int argc, char **argv, char **envp) +{ +#endif + + __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; + + /* Make sure we don't initialize twice. */ + if (!__libc_multiple_libcs) + { + /* Set the FPU control word to the proper default value if the + kernel would use a different value. */ + if (__fpu_control != GLRO(dl_fpu_control)) + __setfpucw (__fpu_control); + } + + /* Save the command-line arguments. */ + __libc_argc = argc; + __libc_argv = argv; + __environ = envp; + +#ifndef SHARED + /* First the initialization which normally would be done by the + dynamic linker. */ + _dl_non_dynamic_init (); +#endif + +#ifdef VDSO_SETUP + VDSO_SETUP (); +#endif + + __init_misc (argc, argv, envp); + + /* Initialize ctype data. */ + __ctype_init (); + +#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS + __libc_global_ctors (); +#endif +} + +/* This function is defined here so that if this file ever gets into + ld.so we will get a link error. Having this file silently included + in ld.so causes disaster, because the _init definition above will + cause ld.so to gain an init function, which is not a cool thing. */ + +extern void _dl_start (void) __attribute__ ((noreturn)); + +void +_dl_start (void) +{ + abort (); +} diff --git a/REORG.TODO/csu/init.c b/REORG.TODO/csu/init.c new file mode 100644 index 0000000000..bb68386c9b --- /dev/null +++ b/REORG.TODO/csu/init.c @@ -0,0 +1,26 @@ +/* Special startup support. + Copyright (C) 1997-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#if defined __GNUC__ && __GNUC__ >= 2 + +#include <_G_config.h> + +/* This records which stdio is linked against in the application. */ +const int _IO_stdin_used = _G_IO_IO_FILE_VERSION; + +#endif diff --git a/REORG.TODO/csu/libc-start.c b/REORG.TODO/csu/libc-start.c new file mode 100644 index 0000000000..c2dd1593eb --- /dev/null +++ b/REORG.TODO/csu/libc-start.c @@ -0,0 +1,336 @@ +/* Copyright (C) 1998-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <ldsodefs.h> +#include <exit-thread.h> +#include <libc-internal.h> + +#include <elf/dl-tunables.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> +# 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 +# ifndef THREAD_SET_POINTER_GUARD +/* Only exported for architectures that don't store the pointer guard + value in thread local area. */ +uintptr_t __pointer_chk_guard_local + attribute_relro attribute_hidden __attribute__ ((nocommon)); +# endif +#endif + +#ifdef HAVE_PTR_NTHREADS +/* We need atomic operations. */ +# include <atomic.h> +#endif + + +#ifndef SHARED +# include <link.h> +# include <dl-irel.h> + +# ifdef ELF_MACHINE_IRELA +# define IREL_T ElfW(Rela) +# define IPLT_START __rela_iplt_start +# define IPLT_END __rela_iplt_end +# define IREL elf_irela +# elif defined ELF_MACHINE_IREL +# define IREL_T ElfW(Rel) +# define IPLT_START __rel_iplt_start +# define IPLT_END __rel_iplt_end +# define IREL elf_irel +# endif + +static void +apply_irel (void) +{ +# ifdef IREL + /* We use weak references for these so that we'll still work with a linker + that doesn't define them. Such a linker doesn't support IFUNC at all + and so uses won't work, but a statically-linked program that doesn't + use any IFUNC symbols won't have a problem. */ + extern const IREL_T IPLT_START[] __attribute__ ((weak)); + extern const IREL_T IPLT_END[] __attribute__ ((weak)); + for (const IREL_T *ipltent = IPLT_START; ipltent < IPLT_END; ++ipltent) + IREL (ipltent); +# endif +} +#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 __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 + +#ifndef ARCH_INIT_CPU_FEATURES +# define ARCH_INIT_CPU_FEATURES() +#endif + +STATIC int LIBC_START_MAIN (int (*main) (int, char **, char ** + MAIN_AUXVEC_DECL), + int argc, + char **argv, +#ifdef LIBC_START_MAIN_AUXVEC_ARG + ElfW(auxv_t) *auxvec, +#endif + __typeof (main) init, + void (*fini) (void), + void (*rtld_fini) (void), + void *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 **argv, +#ifdef LIBC_START_MAIN_AUXVEC_ARG + ElfW(auxv_t) *auxvec, +#endif + __typeof (main) init, + void (*fini) (void), + void (*rtld_fini) (void), void *stack_end) +{ + /* Result of the 'main' function. */ + int result; + + __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; + +#ifndef SHARED + char **ev = &argv[argc + 1]; + + __environ = ev; + + /* Store the lowest stack address. This is done in ld.so if this is + the code for the DSO. */ + __libc_stack_end = stack_end; + +# ifdef HAVE_AUX_VECTOR + /* First process the auxiliary vector since we need to find the + program header to locate an eventually present PT_TLS entry. */ +# ifndef LIBC_START_MAIN_AUXVEC_ARG + ElfW(auxv_t) *auxvec; + { + char **evp = ev; + while (*evp++ != NULL) + ; + auxvec = (ElfW(auxv_t) *) evp; + } +# endif + _dl_aux_init (auxvec); + if (GL(dl_phdr) == NULL) +# endif + { + /* Starting from binutils-2.23, the linker will define the + magic symbol __ehdr_start to point to our own ELF header + if it is visible in a segment that also includes the phdrs. + So we can set up _dl_phdr and _dl_phnum even without any + information from auxv. */ + + extern const ElfW(Ehdr) __ehdr_start + __attribute__ ((weak, visibility ("hidden"))); + if (&__ehdr_start != NULL) + { + assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr)); + GL(dl_phdr) = (const void *) &__ehdr_start + __ehdr_start.e_phoff; + GL(dl_phnum) = __ehdr_start.e_phnum; + } + } + + /* Initialize very early so that tunables can use it. */ + __libc_init_secure (); + + __tunables_init (__environ); + + ARCH_INIT_CPU_FEATURES (); + + /* Perform IREL{,A} relocations. */ + apply_irel (); + + /* The stack guard goes into the TCB, so initialize it early. */ + __libc_setup_tls (); + + /* Set up the stack checker's canary. */ + uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); +# ifdef THREAD_SET_STACK_GUARD + THREAD_SET_STACK_GUARD (stack_chk_guard); +# else + __stack_chk_guard = stack_chk_guard; +# endif + +# ifdef DL_SYSDEP_OSCHECK + if (!__libc_multiple_libcs) + { + /* This needs to run to initiliaze _dl_osversion before TLS + setup might check it. */ + DL_SYSDEP_OSCHECK (__libc_fatal); + } +# endif + + /* Initialize libpthread if linked in. */ + if (__pthread_initialize_minimal != NULL) + __pthread_initialize_minimal (); + + /* Set up the pointer guard value. */ + uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random, + stack_chk_guard); +# ifdef THREAD_SET_POINTER_GUARD + THREAD_SET_POINTER_GUARD (pointer_chk_guard); +# else + __pointer_chk_guard_local = pointer_chk_guard; +# endif + +#endif + + /* Register the destructor of the dynamic linker if there is any. */ + if (__glibc_likely (rtld_fini != NULL)) + __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL); + +#ifndef SHARED + /* Call the initializer of the libc. This is only needed here if we + are compiling for the static library in which case we haven't + run the constructors in `_dl_start_user'. */ + __libc_init_first (argc, argv, __environ); + + /* Register the destructor of the program, if any. */ + if (fini) + __cxa_atexit ((void (*) (void *)) fini, NULL, NULL); + + /* Some security at this point. Prevent starting a SUID binary where + the standard file descriptors are not opened. We have to do this + only for statically linked applications since otherwise the dynamic + loader did the work already. */ + if (__builtin_expect (__libc_enable_secure, 0)) + __libc_check_standard_fds (); +#endif + + /* Call the initializer of the program, if any. */ +#ifdef SHARED + if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) + GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]); +#endif + if (init) + (*init) (argc, argv, __environ MAIN_AUXVEC_PARAM); + +#ifdef SHARED + /* Auditing checkpoint: we have a new object. */ + if (__glibc_unlikely (GLRO(dl_naudit) > 0)) + { + struct audit_ifaces *afct = GLRO(dl_audit); + struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt) + { + if (afct->preinit != NULL) + afct->preinit (&head->l_audit[cnt].cookie); + + afct = afct->next; + } + } +#endif + +#ifdef SHARED + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS)) + GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]); +#endif + +#ifndef SHARED + _dl_debug_initialize (0, LM_ID_BASE); +#endif +#ifdef HAVE_CLEANUP_JMP_BUF + /* Memory for the cancellation buffer. */ + struct pthread_unwind_buf unwind_buf; + + int not_first_call; + not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf); + if (__glibc_likely (! not_first_call)) + { + struct pthread *self = THREAD_SELF; + + /* Store old info. */ + unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf); + unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup); + + /* Store the new cleanup handler info. */ + THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf); + + /* Run the program. */ + result = main (argc, argv, __environ MAIN_AUXVEC_PARAM); + } + else + { + /* Remove the thread-local data. */ +# ifdef SHARED + PTHFCT_CALL (ptr__nptl_deallocate_tsd, ()); +# else + extern void __nptl_deallocate_tsd (void) __attribute ((weak)); + __nptl_deallocate_tsd (); +# endif + + /* One less thread. Decrement the counter. If it is zero we + terminate the entire process. */ + result = 0; +# ifdef SHARED + unsigned int *ptr = __libc_pthread_functions.ptr_nthreads; +# ifdef PTR_DEMANGLE + PTR_DEMANGLE (ptr); +# endif +# else + extern unsigned int __nptl_nthreads __attribute ((weak)); + unsigned int *const ptr = &__nptl_nthreads; +# endif + + if (! atomic_decrement_and_test (ptr)) + /* Not much left to do but to exit the thread, not the process. */ + __exit_thread (); + } +#else + /* Nothing fancy, just call the function. */ + result = main (argc, argv, __environ MAIN_AUXVEC_PARAM); +#endif + + exit (result); +} diff --git a/REORG.TODO/csu/libc-tls.c b/REORG.TODO/csu/libc-tls.c new file mode 100644 index 0000000000..3c897bf28b --- /dev/null +++ b/REORG.TODO/csu/libc-tls.c @@ -0,0 +1,217 @@ +/* Initialization code for TLS in statically linked application. + Copyright (C) 2002-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <ldsodefs.h> +#include <tls.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/param.h> + + +#ifdef SHARED + #error makefile bug, this file is for static only +#endif + +dtv_t _dl_static_dtv[2 + TLS_SLOTINFO_SURPLUS]; + + +static struct +{ + struct dtv_slotinfo_list si; + /* The dtv_slotinfo_list data structure does not include the actual + information since it is defined as an array of size zero. We define + here the necessary entries. Note that it is not important whether + there is padding or not since we will always access the information + through the 'si' element. */ + struct dtv_slotinfo info[2 + TLS_SLOTINFO_SURPLUS]; +} static_slotinfo; + + +/* Highest dtv index currently needed. */ +size_t _dl_tls_max_dtv_idx; +/* Flag signalling whether there are gaps in the module ID allocation. */ +bool _dl_tls_dtv_gaps; +/* Information about the dtv slots. */ +struct dtv_slotinfo_list *_dl_tls_dtv_slotinfo_list; +/* Number of modules in the static TLS block. */ +size_t _dl_tls_static_nelem; +/* Size of the static TLS block. Giving this initialized value + preallocates some surplus bytes in the static TLS area. */ +size_t _dl_tls_static_size = 2048; +/* Size actually allocated in the static TLS block. */ +size_t _dl_tls_static_used; +/* Alignment requirement of the static TLS block. */ +size_t _dl_tls_static_align; + +/* Generation counter for the dtv. */ +size_t _dl_tls_generation; + + +/* Additional definitions needed by TLS initialization. */ +#ifdef TLS_INIT_HELPER +TLS_INIT_HELPER +#endif + +static void +init_slotinfo (void) +{ + /* Create the slotinfo list. */ + static_slotinfo.si.len = (((char *) (&static_slotinfo + 1) + - (char *) &static_slotinfo.si.slotinfo[0]) + / sizeof static_slotinfo.si.slotinfo[0]); + // static_slotinfo.si.next = NULL; already zero + + /* The slotinfo list. Will be extended by the code doing dynamic + linking. */ + GL(dl_tls_max_dtv_idx) = 1; + GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo.si; +} + +static void +init_static_tls (size_t memsz, size_t align) +{ + /* That is the size of the TLS memory for this object. The initialized + value of _dl_tls_static_size is provided by dl-open.c to request some + surplus that permits dynamic loading of modules with IE-model TLS. */ + GL(dl_tls_static_size) = roundup (memsz + GL(dl_tls_static_size), + TLS_TCB_ALIGN); +#if TLS_TCB_AT_TP + GL(dl_tls_static_size) += TLS_TCB_SIZE; +#endif + GL(dl_tls_static_used) = memsz; + /* The alignment requirement for the static TLS block. */ + GL(dl_tls_static_align) = align; + /* Number of elements in the static TLS block. */ + GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx); +} + +void +__libc_setup_tls (void) +{ + void *tlsblock; + size_t memsz = 0; + size_t filesz = 0; + void *initimage = NULL; + size_t align = 0; + size_t max_align = TCB_ALIGNMENT; + size_t tcb_offset; + const ElfW(Phdr) *phdr; + + /* Look through the TLS segment if there is any. */ + if (_dl_phdr != NULL) + for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr) + if (phdr->p_type == PT_TLS) + { + /* Remember the values we need. */ + memsz = phdr->p_memsz; + filesz = phdr->p_filesz; + initimage = (void *) phdr->p_vaddr; + align = phdr->p_align; + if (phdr->p_align > max_align) + max_align = phdr->p_align; + break; + } + + /* We have to set up the TCB block which also (possibly) contains + 'errno'. Therefore we avoid 'malloc' which might touch 'errno'. + Instead we use 'sbrk' which would only uses 'errno' if it fails. + In this case we are right away out of memory and the user gets + what she/he deserves. + + The initialized value of _dl_tls_static_size is provided by dl-open.c + to request some surplus that permits dynamic loading of modules with + IE-model TLS. */ +#if TLS_TCB_AT_TP + /* Align the TCB offset to the maximum alignment, as + _dl_allocate_tls_storage (in elf/dl-tls.c) does using __libc_memalign + and dl_tls_static_align. */ + tcb_offset = roundup (memsz + GL(dl_tls_static_size), max_align); + tlsblock = __sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align); +#elif TLS_DTV_AT_TP + tcb_offset = roundup (TLS_INIT_TCB_SIZE, align ?: 1); + tlsblock = __sbrk (tcb_offset + memsz + max_align + + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size)); + tlsblock += TLS_PRE_TCB_SIZE; +#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. */ + _dl_static_dtv[0].counter = (sizeof (_dl_static_dtv) / sizeof (_dl_static_dtv[0])) - 2; + // _dl_static_dtv[1].counter = 0; would be needed if not already done + + struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; + + /* Initialize the TLS block. */ +#if TLS_TCB_AT_TP + _dl_static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset + - roundup (memsz, align ?: 1)); + main_map->l_tls_offset = roundup (memsz, align ?: 1); +#elif TLS_DTV_AT_TP + _dl_static_dtv[2].pointer.val = (char *) tlsblock + tcb_offset; + main_map->l_tls_offset = tcb_offset; +#else +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" +#endif + _dl_static_dtv[2].pointer.to_free = NULL; + /* sbrk gives us zero'd memory, so we don't need to clear the remainder. */ + memcpy (_dl_static_dtv[2].pointer.val, initimage, filesz); + + /* Install the pointer to the dtv. */ + + /* Initialize the thread pointer. */ +#if TLS_TCB_AT_TP + INSTALL_DTV ((char *) tlsblock + tcb_offset, _dl_static_dtv); + + const char *lossage = TLS_INIT_TP ((char *) tlsblock + tcb_offset); +#elif TLS_DTV_AT_TP + INSTALL_DTV (tlsblock, _dl_static_dtv); + const char *lossage = TLS_INIT_TP (tlsblock); +#else +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" +#endif + if (__builtin_expect (lossage != NULL, 0)) + __libc_fatal (lossage); + + /* Update the executable's link map with enough information to make + the TLS routines happy. */ + main_map->l_tls_align = align; + main_map->l_tls_blocksize = memsz; + main_map->l_tls_initimage = initimage; + main_map->l_tls_initimage_size = filesz; + main_map->l_tls_modid = 1; + + init_slotinfo (); + // static_slotinfo.si.slotinfo[1].gen = 0; already zero + static_slotinfo.si.slotinfo[1].map = main_map; + + memsz = roundup (memsz, align ?: 1); + +#if TLS_DTV_AT_TP + memsz += tcb_offset; +#endif + + init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align)); +} diff --git a/REORG.TODO/csu/start.c b/REORG.TODO/csu/start.c new file mode 100644 index 0000000000..d7d7a8510d --- /dev/null +++ b/REORG.TODO/csu/start.c @@ -0,0 +1,11 @@ +/* This file should define the low-level program entry point, + which should set up `__environ', and then do: + __libc_init(argc, argv, __environ); + exit(main(argc, argv, __environ)); + + This file should be prepared to be the first thing in the text section (on + Unix systems), or otherwise appropriately special. */ + +/* The first piece of initialized data. */ +int __data_start = 0; +weak_alias (__data_start, data_start) diff --git a/REORG.TODO/csu/sysdep.c b/REORG.TODO/csu/sysdep.c new file mode 100644 index 0000000000..5442eee00d --- /dev/null +++ b/REORG.TODO/csu/sysdep.c @@ -0,0 +1,2 @@ +/* This file should contain any system-dependent functions + that will be used by many parts of the library. */ diff --git a/REORG.TODO/csu/version.c b/REORG.TODO/csu/version.c new file mode 100644 index 0000000000..e0d884dbf3 --- /dev/null +++ b/REORG.TODO/csu/version.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1992-2017 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, see + <http://www.gnu.org/licenses/>. */ + +#include "version.h" +#include <tls.h> +#include <libc-abis.h> +#include <gnu/libc-version.h> + +static const char __libc_release[] = RELEASE; +static const char __libc_version[] = VERSION; + +static const char banner[] = +"GNU C Library "PKGVERSION RELEASE" release version "VERSION", by Roland McGrath et al.\n\ +Copyright (C) 2017 Free Software Foundation, Inc.\n\ +This is free software; see the source for copying conditions.\n\ +There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\ +PARTICULAR PURPOSE.\n\ +Compiled by GNU CC version "__VERSION__".\n" +#include "version-info.h" +#ifdef LIBC_ABIS_STRING +LIBC_ABIS_STRING +#endif +"For bug reporting instructions, please see:\n\ +"REPORT_BUGS_TO".\n"; + +#include <unistd.h> + +extern void __libc_print_version (void); +void +__libc_print_version (void) +{ + __write (STDOUT_FILENO, banner, sizeof banner - 1); +} + +extern const char *__gnu_get_libc_release (void); +const char * +__gnu_get_libc_release (void) +{ + return __libc_release; +} +weak_alias (__gnu_get_libc_release, gnu_get_libc_release) + +extern const char *__gnu_get_libc_version (void); +const char * +__gnu_get_libc_version (void) +{ + return __libc_version; +} +weak_alias (__gnu_get_libc_version, gnu_get_libc_version) + +/* This function is the entry point for the shared object. + Running the library as a program will get here. */ + +extern void __libc_main (void) __attribute__ ((noreturn)); +void +__libc_main (void) +{ + __libc_print_version (); + _exit (0); +} |