diff options
author | marcus <marcus> | 2005-01-27 16:28:40 +0000 |
---|---|---|
committer | marcus <marcus> | 2005-01-27 16:28:40 +0000 |
commit | 246d90c42534d3e2951951ddc3033ac5f3ec6c07 (patch) | |
tree | 79b46f137e3766ae1effe59d496311c4cb187b58 /libc | |
parent | 6fb9b2965fca265d2496ed336db3a795ba3e2cff (diff) |
2005-01-27 Marcus Brinkmann <marcus@gnu.org>
* hurd-l4/sysdeps/l4/hurd/i386: New directory.
* hurd-l4/sysdeps/l4/hurd/i386/static-start.S: New file.
* hurd-l4/sysdeps/l4/hurd/i386/init-first.c: New file.
* hurd-l4/sysdeps/l4/hurd/init-first.c: Removed.
* hurd-l4/sysdeps/l4/hurd/enbl-secure.c: New file.
* hurd-l4/sysdeps/l4/hurd/brk.c: New file.
* hurd-l4/sysdeps/l4/hurd/Makeconf: New file.
* hurd-l4/sysdeps/l4/hurd/Makefile [$(subdir) eq csu]:
(crt0): New target.
(extra-objs): Add static-start.o.
Diffstat (limited to 'libc')
-rw-r--r-- | libc/ChangeLog | 11 | ||||
-rw-r--r-- | libc/hurd-l4/sysdeps/l4/hurd/Makeconfig | 4 | ||||
-rw-r--r-- | libc/hurd-l4/sysdeps/l4/hurd/Makefile | 11 | ||||
-rw-r--r-- | libc/hurd-l4/sysdeps/l4/hurd/brk.c | 134 | ||||
-rw-r--r-- | libc/hurd-l4/sysdeps/l4/hurd/enbl-secure.c | 45 | ||||
-rw-r--r-- | libc/hurd-l4/sysdeps/l4/hurd/i386/init-first.c | 341 | ||||
-rw-r--r-- | libc/hurd-l4/sysdeps/l4/hurd/i386/static-start.S | 39 | ||||
-rw-r--r-- | libc/hurd-l4/sysdeps/l4/hurd/init-first.c | 124 |
8 files changed, 585 insertions, 124 deletions
diff --git a/libc/ChangeLog b/libc/ChangeLog index 9e64478..a1f7530 100644 --- a/libc/ChangeLog +++ b/libc/ChangeLog @@ -1,5 +1,16 @@ 2005-01-27 Marcus Brinkmann <marcus@gnu.org> + * hurd-l4/sysdeps/l4/hurd/i386: New directory. + * hurd-l4/sysdeps/l4/hurd/i386/static-start.S: New file. + * hurd-l4/sysdeps/l4/hurd/i386/init-first.c: New file. + * hurd-l4/sysdeps/l4/hurd/init-first.c: Removed. + * hurd-l4/sysdeps/l4/hurd/enbl-secure.c: New file. + * hurd-l4/sysdeps/l4/hurd/brk.c: New file. + * hurd-l4/sysdeps/l4/hurd/Makeconf: New file. + * hurd-l4/sysdeps/l4/hurd/Makefile [$(subdir) eq csu]: + (crt0): New target. + (extra-objs): Add static-start.o. + * patches/51-nptl-hurd-l4-tls.patch: New file. * patches/08-sysdeps-generic-dl-sysdep.patch: New file. diff --git a/libc/hurd-l4/sysdeps/l4/hurd/Makeconfig b/libc/hurd-l4/sysdeps/l4/hurd/Makeconfig new file mode 100644 index 0000000..1b65bb0 --- /dev/null +++ b/libc/hurd-l4/sysdeps/l4/hurd/Makeconfig @@ -0,0 +1,4 @@ +# We need special startup code for statically linked binaries. +# See Makefile in this directory for the rule that builds this. +# We must define this variable earlier than sysdeps Makefiles are included. +static-start-installed-name = crt0.o diff --git a/libc/hurd-l4/sysdeps/l4/hurd/Makefile b/libc/hurd-l4/sysdeps/l4/hurd/Makefile index 04d95ac..671609a 100644 --- a/libc/hurd-l4/sysdeps/l4/hurd/Makefile +++ b/libc/hurd-l4/sysdeps/l4/hurd/Makefile @@ -42,4 +42,15 @@ inhibit-unix-syscalls = yes # be compatible with some existing binaries for that system. inhibit-glue = yes + +ifeq ($(subdir),csu) + +extra-objs += static-start.o + +# We need special startup code for statically linked binaries. +$(objpfx)crt0.o: $(objpfx)static-start.o $(objpfx)abi-note.o $(objpfx)init.o + $(link-relocatable) + +endif + endif # in-Makerules diff --git a/libc/hurd-l4/sysdeps/l4/hurd/brk.c b/libc/hurd-l4/sysdeps/l4/hurd/brk.c new file mode 100644 index 0000000..b834265 --- /dev/null +++ b/libc/hurd-l4/sysdeps/l4/hurd/brk.c @@ -0,0 +1,134 @@ +/* Copyright (C) 1991,1995,1996,1997, 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 + 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 <unistd.h> + + +/* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME */ +#include <l4.h> + +#include <hurd/types.h> +#include <hurd/startup.h> + +/* Allocate SIZE bytes according to FLAGS into container CONTAINER + starting with index START. *AMOUNT contains the number of bytes + successfully allocated. */ +static l4_word_t +allocate (l4_thread_id_t server, hurd_cap_handle_t container, + l4_fpage_t start, l4_word_t size, + l4_word_t flags, l4_word_t *amount) +{ + l4_msg_t msg; + l4_msg_tag_t tag; + + l4_msg_clear (msg); + l4_set_msg_label (msg, 132 /* Magic number for container_allocate_id. */); + l4_msg_append_word (msg, container); + l4_msg_append_word (msg, flags); + l4_msg_append_word (msg, start); + l4_msg_append_word (msg, size); + + l4_msg_load (msg); + + tag = l4_call (server); + l4_msg_store (tag, msg); + + *amount = l4_msg_word (msg, 0); + + return l4_msg_label (msg); +} + +/* Map the memory at offset OFFSET with size SIZE at address VADDR + from the container CONT in the physical memory server PHYSMEM. */ +static l4_word_t +map (l4_thread_id_t server, hurd_cap_handle_t container, + l4_word_t offset, size_t size, + void *vaddr, l4_word_t rights) +{ + l4_msg_t msg; + l4_msg_tag_t tag; + + /* Magic! If the offset is above 0x8000000 then we need to allocate + anonymous memory. */ + if (offset >= 0x8000000) + { + l4_word_t amount; + allocate (server, container, offset, size, 0, &amount); + } + + l4_msg_clear (msg); + l4_set_msg_label (msg, 134 /* XXX: Magic number for container_map_id. */); + l4_msg_append_word (msg, container); + l4_msg_append_word (msg, offset | rights); + l4_msg_append_word (msg, size); + l4_msg_append_word (msg, (l4_word_t) vaddr); + l4_msg_load (msg); + + tag = l4_call (server); + l4_msg_store (tag, msg); + + return l4_msg_label (msg); +} + + +/* sbrk.c expects this. */ +void *__curbrk; + +extern int _end; + +extern struct hurd_startup_data *_hurd_startup_data; + +/* Set the end of the process's data space to ADDR. + Return 0 if successful, -1 if not. */ +int +__brk (addr) + void *addr; +{ + if (addr == 0) + { + /* Initialization. */ + __curbrk = &_end; + return 0; + } + + /* FIXME: We only support growing the data section for now. */ + if (addr < __curbrk) + { + __set_errno (ENOSYS); + return -1; + } + else + { + l4_word_t pagend = l4_page_round ((l4_word_t) __curbrk); + l4_word_t new_pagend = l4_page_round ((l4_word_t) addr); + + if (new_pagend > pagend) + map (_hurd_startup_data->mapv[0].cont.server, + _hurd_startup_data->mapv[0].cont.cap_handle, + pagend, new_pagend - pagend, pagend, + L4_FPAGE_FULLY_ACCESSIBLE); + __curbrk = addr; + + return 0; + } +} +stub_warning (brk) + +weak_alias (__brk, brk) +#include <stub-tag.h> diff --git a/libc/hurd-l4/sysdeps/l4/hurd/enbl-secure.c b/libc/hurd-l4/sysdeps/l4/hurd/enbl-secure.c new file mode 100644 index 0000000..2bdc975 --- /dev/null +++ b/libc/hurd-l4/sysdeps/l4/hurd/enbl-secure.c @@ -0,0 +1,45 @@ +/* Define and initialize the `__libc_enable_secure' flag. Hurd version. + Copyright (C) 1996, 1997, 1998, 2000, 2003 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. */ + +/* This file is used in the static libc. For the shared library, + dl-sysdep.c defines and initializes __libc_enable_secure. */ + +#include <unistd.h> +#include <libc-internal.h> + +#include <hurd/startup.h> + +/* This definition is only needed if [HAVE_AUX_VECTOR] in + elf/dl-support.c, _dl_aux_init. As the Hurd doesn't use an aux + vector, it is not neeed. */ +#if 0 +/* If nonzero __libc_enable_secure is already set. */ +int __libc_enable_secure_decided; +#endif + +/* Safest assumption, if somehow the initializer isn't run. */ +int __libc_enable_secure = 1; + +void +__libc_init_secure (void) +{ + extern struct hurd_startup_data *_hurd_startup_data; + + __libc_enable_secure = _hurd_startup_data->flags & HURD_STARTUP_FLAG_SECURE; +} diff --git a/libc/hurd-l4/sysdeps/l4/hurd/i386/init-first.c b/libc/hurd-l4/sysdeps/l4/hurd/i386/init-first.c new file mode 100644 index 0000000..ff59582 --- /dev/null +++ b/libc/hurd-l4/sysdeps/l4/hurd/i386/init-first.c @@ -0,0 +1,341 @@ +/* Initialization code run first thing by the ELF startup code. Hurd version. + Copyright (C) 1995-1999,2000,01,02,03,04,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 <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 <assert.h> +#include <libc-internal.h> + +#include <ldsodefs.h> + +/* The function is called from assembly stubs the compiler can't see. */ +static void init (int, char **, char **) __attribute__ ((used)); + +/* 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; + +/* 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; + +#ifndef SHARED +#include <hurd/startup.h> +extern struct hurd_startup_data *_hurd_startup_data; +#endif + +static void +init (int argc, char **argv, char **envp) +{ +#ifdef USE_NONOPTION_FLAGS + extern void __getopt_clean_environment (char **); +#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. (In a static program we + don't have this information.) */ +#ifdef SHARED + if (__fpu_control != GLRO(dl_fpu_control)) +#endif + __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 + + __init_misc (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 + +#ifdef SHARED + __libc_global_ctors (); +#endif +} + +#ifdef SHARED + +strong_alias (init, _init); + +extern void __libc_init_first (void); + +void +__libc_init_first (void) +{ +} + +#else +extern void __libc_init_first (int argc, char **argv, char **envp); + +void +__libc_init_first (int argc, char **argv, char **envp) +{ + init (argc, argv, envp); +} +#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 (); +} + + + +#ifndef SHARED + +/* We define the global data for libl4. */ +#include <l4/globals.h> +#include <l4/init.h> +#include <l4/stubs.h> +#include <l4/stubs-init.h> + +#include <l4.h> + +#include <hurd/types.h> +#include <hurd/startup.h> + +/* FIXME! Use memory manager. */ + +/* Allocate SIZE bytes according to FLAGS into container CONTAINER + starting with index START. *AMOUNT contains the number of bytes + successfully allocated. */ +static l4_word_t +allocate (l4_thread_id_t server, hurd_cap_handle_t container, + l4_fpage_t start, l4_word_t size, + l4_word_t flags, l4_word_t *amount) +{ + l4_msg_t msg; + l4_msg_tag_t tag; + + l4_msg_clear (msg); + l4_set_msg_label (msg, 132 /* Magic number for container_allocate_id. */); + l4_msg_append_word (msg, container); + l4_msg_append_word (msg, flags); + l4_msg_append_word (msg, start); + l4_msg_append_word (msg, size); + + l4_msg_load (msg); + + tag = l4_call (server); + l4_msg_store (tag, msg); + + *amount = l4_msg_word (msg, 0); + + return l4_msg_label (msg); +} + +/* Map the memory at offset OFFSET with size SIZE at address VADDR + from the container CONT in the physical memory server PHYSMEM. */ +static l4_word_t +map (l4_thread_id_t server, hurd_cap_handle_t container, + l4_word_t offset, size_t size, + void *vaddr, l4_word_t rights) +{ + l4_msg_t msg; + l4_msg_tag_t tag; + + /* Magic! If the offset is above 0x8000000 then we need to allocate + anonymous memory. */ + if (offset >= 0x8000000) + { + l4_word_t amount; + allocate (server, container, offset, size, 0, &amount); + } + + l4_msg_clear (msg); + l4_set_msg_label (msg, 134 /* XXX: Magic number for container_map_id. */); + l4_msg_append_word (msg, container); + l4_msg_append_word (msg, offset | rights); + l4_msg_append_word (msg, size); + l4_msg_append_word (msg, (l4_word_t) vaddr); + l4_msg_load (msg); + + tag = l4_call (server); + l4_msg_store (tag, msg); + + return l4_msg_label (msg); +} + + + +/* This is used all over the place. */ +struct hurd_startup_data *_hurd_startup_data; + +extern ElfW(Phdr) *_dl_phdr; +extern size_t _dl_phnum; + +/* All this stuff should actually be called at the beginning of + sysdeps/generic/libc-start.c::__libc_start_main(), before TLS is + set up. */ +static void +init1 (void) +{ + _dl_phdr = (ElfW(Phdr) *) _hurd_startup_data->phdr; + _dl_phnum = _hurd_startup_data->phdr_len / sizeof (ElfW(Phdr)); + assert (_hurd_startup_data->phdr_len % sizeof (ElfW(Phdr)) == 0); + + __libc_init_secure (); +} + + +/* Initialize a statically linked application. This is called by + sysdeps/l4/hurd/i386/static-start.S. The function returns the + address of the new stack. */ +void * +_hurd_pre_start (struct hurd_startup_data *startup) +{ + l4_word_t stack_size; + /* Top of stack. */ + char *tos = (char *) 0xc0000000; + struct hurd_startup_data *new_startup; + int argc; + + /* Initialize the system call stubs. */ + l4_init (); + l4_init_stubs (); + + /* A small stack for now. Somewhat arbitrary (4MB allocates one + super-page). */ + stack_size = 4 * 1024 * 1024; + + /* Let physmem take over the address space completely. */ + l4_accept (l4_map_grant_items (L4_COMPLETE_ADDRESS_SPACE)); + + /* Map in the top of the stack. One page is enough for now + (actually depends on argv and env - libhurd-mm should grow this + automatically - FIXME). */ + /* FIXME: Check PT_GNU_STACK if we want it to be fully accessible. */ + map (startup->mapv[0].cont.server, startup->mapv[0].cont.cap_handle, + tos - stack_size, stack_size, tos - stack_size, + L4_FPAGE_FULLY_ACCESSIBLE); + + /* The startup data can easily be relocated. */ + tos -= sizeof (struct hurd_startup_data); + new_startup = (struct hurd_startup_data *) tos; + + /* Now relocate the startup data. */ + *new_startup = *startup; + + tos -= startup->mapc * sizeof (struct hurd_startup_map); + new_startup->mapv = (struct hurd_startup_map *) tos; + memcpy (new_startup->mapv, startup->mapv, + startup->mapc * sizeof (struct hurd_startup_map)); + + tos -= (startup->argz_len + sizeof (l4_word_t) - 1) + & ~(sizeof (l4_word_t) - 1); + new_startup->argz = tos; + memcpy (new_startup->argz, startup->argz, startup->argz_len); + + tos -= (startup->envz_len + sizeof (l4_word_t) - 1) + & ~(sizeof (l4_word_t) - 1); + new_startup->envz = tos; + memcpy (new_startup->envz, startup->envz, startup->envz_len); + + /* Now push the ELF data on the stack as specified by System V ABI, + ia32 Supplement, p 3-28, in reverse order. */ + + /* First the NULL-terminated aux vector. */ + tos -= sizeof (void *); + *((void **) tos) = 0; + /* FIXME: Define an extension. */ +#define AT_GNU_HURD_STARTUP_DATA 16384 + tos -= sizeof (Elf32_auxv_t); + *((Elf32_auxv_t *) tos) = (Elf32_auxv_t) { .a_type=AT_GNU_HURD_STARTUP_DATA, + .a_un.a_ptr=new_startup }; + +#define push_argz(argz,argz_len) \ +({ \ + int count = 0; \ + char *start = argz; \ + char *end = start + argz_len; \ + \ + tos -= sizeof (void *); \ + *((void **) tos) = 0; \ + \ + while (end > start) \ + { \ + /* Look for the beginning of the last string. */ \ + char *str = memrchr (start, 0, end - start - 1); \ + \ + if (!str) \ + str = start; \ + else \ + str++; \ + \ + tos -= sizeof (char *); \ + *((char **) tos) = str; \ + \ + count++; \ + end = str; \ + } \ + count; \ +}) + + /* Now the env and arg vector. */ + push_argz (new_startup->envz, new_startup->envz_len); + argc = push_argz (new_startup->argz, new_startup->argz_len); + + tos -= sizeof (int); + *((int **) tos) = argc; + + /* We are done. Our stack now looks exactly as required by the + System V ABI. We can now return its address to the caller, who + will fire up glibc for real. */ + + _hurd_startup_data = new_startup; + + /* But before we return, we do some hack magic. Putting it here + avoids modifying "generic" glibc files. */ + init1 (); + + return tos; +} + +#endif /* ! SHARED */ diff --git a/libc/hurd-l4/sysdeps/l4/hurd/i386/static-start.S b/libc/hurd-l4/sysdeps/l4/hurd/i386/static-start.S new file mode 100644 index 0000000..c791ec8 --- /dev/null +++ b/libc/hurd-l4/sysdeps/l4/hurd/i386/static-start.S @@ -0,0 +1,39 @@ +/* Startup code for statically linked Hurd/i386 binaries. + Copyright (C) 1998 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. */ + + .text + .globl _start +_start: + /* We start out with the following stack layout: + 4(%esp): struct hurd_startup_data *startup_data + 0(%esp): return address to startup code. */ + popl %eax /* Pop return address. */ + + /* _hurd_pre_start has the signature: + void *_hurd_pre_start (struct hurd_startup_data *data) + The function returns the new stack pointer. + The argument is already in place on the stack. */ + call _hurd_pre_start + + mov %eax, %esp /* Switch stack. */ + xorl %edx, %edx /* Function to be registered with atexit. */ + jmp _start1 /* And now for something completely different! */ + +#define _start _start1 +#include <sysdeps/i386/elf/start.S> diff --git a/libc/hurd-l4/sysdeps/l4/hurd/init-first.c b/libc/hurd-l4/sysdeps/l4/hurd/init-first.c deleted file mode 100644 index f002712..0000000 --- a/libc/hurd-l4/sysdeps/l4/hurd/init-first.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. Linux version. - Copyright (C) 1995-1999,2000,01,02,03,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 <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> - -/* The function is called from assembly stubs the compiler can't see. */ -static void init (int, char **, char **) __attribute__ ((used)); - -/* 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; - -/* 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; - - -static void -init (int argc, char **argv, char **envp) -{ -#ifdef USE_NONOPTION_FLAGS - extern void __getopt_clean_environment (char **); -#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. (In a static program we - don't have this information.) */ -#ifdef SHARED - if (__fpu_control != GLRO(dl_fpu_control)) -#endif - __setfpucw (__fpu_control); - } - - /* Save the command-line arguments. */ - __libc_argc = argc; - __libc_argv = argv; - __environ = envp; - -#ifndef SHARED - __libc_init_secure (); - - /* First the initialization which normally would be done by the - dynamic linker. */ - _dl_non_dynamic_init (); -#endif - - __init_misc (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 - -#ifdef SHARED - __libc_global_ctors (); -#endif -} - -#ifdef SHARED - -strong_alias (init, _init); - -extern void __libc_init_first (void); - -void -__libc_init_first (void) -{ -} - -#else -extern void __libc_init_first (int argc, char **argv, char **envp); - -void -__libc_init_first (int argc, char **argv, char **envp) -{ - init (argc, argv, envp); -} -#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 (); -} |