From 9eaa0e179962a10db91fe566753fc38623097dbe Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Wed, 3 Jan 2024 20:14:42 +0300 Subject: hurd: Make init-first.c no longer x86-specific This will make it usable in other ports. Signed-off-by: Sergey Bugaev Message-ID: <20240103171502.1358371-10-bugaevc@gmail.com> --- sysdeps/mach/hurd/init-first.c | 253 +++++++++++++++++++++++++++++++++++++ sysdeps/mach/hurd/x86/init-first.c | 253 ------------------------------------- 2 files changed, 253 insertions(+), 253 deletions(-) create mode 100644 sysdeps/mach/hurd/init-first.c delete mode 100644 sysdeps/mach/hurd/x86/init-first.c (limited to 'sysdeps/mach/hurd') diff --git a/sysdeps/mach/hurd/init-first.c b/sysdeps/mach/hurd/init-first.c new file mode 100644 index 0000000000..8526191692 --- /dev/null +++ b/sysdeps/mach/hurd/init-first.c @@ -0,0 +1,253 @@ +/* Initialization code run first thing by the ELF startup code. For Hurd. + Copyright (C) 1995-2024 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hurdstartup.h" + +#include +#include +#include +#include + +extern void __mach_init (void); +extern void __init_misc (int, char **, char **); + +extern int __libc_argc attribute_hidden; +extern char **__libc_argv attribute_hidden; +extern char **_dl_argv; + +#ifndef SHARED +static tcbhead_t __init1_tcbhead; +#endif + +/* Things that want to be run before _hurd_init or much anything else. + Importantly, these are called before anything tries to use malloc. */ +DEFINE_HOOK (_hurd_preinit_hook, (void)); + + +/* We call this once the Hurd magic is all set up and we are ready to be a + Posixoid program. This does the same things the generic version does. */ +static void +posixland_init (int argc, char **argv, char **envp) +{ + /* Now we have relocations etc. we can start signals etc. */ + _hurd_libc_proc_init (argv); + +#ifdef SHARED + /* Make sure we don't initialize twice. */ + if (__libc_initial) + { + /* Set the FPU control word to the proper default value. */ + __setfpucw (__fpu_control); + } + else + { + /* Initialize data structures so the additional libc can do RPCs. */ + __mach_init (); + } +#else /* !SHARED */ + __setfpucw (__fpu_control); +#endif + + /* Save the command-line arguments. */ + __libc_argc = argc; + __libc_argv = argv; + __environ = envp; + +#ifndef SHARED + _dl_non_dynamic_init (); +#endif + __init_misc (argc, argv, envp); +} + +static void +init (void **data) +{ + int argc = (int) (uintptr_t) *data; + char **argv = (void *) (data + 1); + char **envp = &argv[argc + 1]; + struct hurd_startup_data *d; + + /* Since the cthreads initialization code uses malloc, and the + malloc initialization code needs to get at the environment, make + sure we can find it. We'll need to do this again later on since + switching stacks changes the location where the environment is + stored. */ + __environ = envp; + + while (*envp) + ++envp; + d = (void *) ++envp; + +#ifndef SHARED + + /* If we are the bootstrap task started by the kernel, + then after the environment pointers there is no Hurd + data block; the argument strings start there. */ + if ((void *) d == argv[0] || d->phdr == 0) + { + __libc_enable_secure = 0; + /* With a new enough linker (binutils-2.23 or better), + the magic __ehdr_start symbol will be available and + __libc_start_main will have done this that way already. */ + if (_dl_phdr == NULL) + { + /* We may need to see our own phdrs, e.g. for TLS setup. + Try the usual kludge to find the headers without help from + the exec server. */ + extern const void __executable_start; + const ElfW(Ehdr) *const ehdr = &__executable_start; + _dl_phdr = (const void *) ehdr + ehdr->e_phoff; + _dl_phnum = ehdr->e_phnum; + assert (ehdr->e_phentsize == sizeof (ElfW(Phdr))); + } + } + else + { + __libc_enable_secure = d->flags & EXEC_SECURE; + _dl_phdr = (ElfW(Phdr) *) d->phdr; + _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr)); + assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0); + } +#endif + + if ((void *) d == argv[0]) + return; + + _hurd_init_dtable = d->dtable; + _hurd_init_dtablesize = d->dtablesize; + + if (d->portarray || d->intarray) + /* Initialize library data structures, start signal processing, etc. */ + _hurd_init (d->flags, argv, + d->portarray, d->portarraysize, + d->intarray, d->intarraysize); +} + +/* Do the first essential initializations that must precede all else. */ +static inline void +first_init (void) +{ + /* Initialize data structures so we can do RPCs. */ + __mach_init (); + +#ifndef SHARED + /* In the static case, we need to set up TLS early so that the stack + protection guard can be read at from TLS by the GCC-generated snippets. */ + _hurd_tls_init (&__init1_tcbhead, 0); +#endif + + RUN_RELHOOK (_hurd_preinit_hook, ()); +} + +#ifdef SHARED +/* This function is called specially by the dynamic linker to do early + initialization of the shared C library before normal initializers + expecting a Posixoid environment can run. */ + +void +_dl_init_first (void *data) +{ + first_init (); + init (data); +} + +/* The regular posixland initialization is what goes into libc's + normal initializer. */ +/* 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!! */ +strong_alias (posixland_init, _init); + +void +__libc_init_first (int argc, char **argv, char **envp) +{ + /* Everything was done in the shared library initializer, _init. */ +} + +#else /* SHARED */ + +strong_alias (posixland_init, __libc_init_first); + +/* XXX This is all a crock and I am not happy with it. + This poorly-named function is called by static-start.S, + which should not exist at all. */ +void +inhibit_stack_protector +_hurd_stack_setup (void **argptr) +{ + /* This is the very first C code that runs in a statically linked + executable -- calling this function is the first thing that _start in + static-start.S does. Once this function returns, the unusual way that it + does (see below), _start jumps to _start1, the regular start-up code. + + _start1 expects the arguments, environment, and a Hurd data block to be + located at the top of the stack. The data may already be located there, + or we may need to receive it from the exec server. If the data is located + on the stack (just above our call frame), argptr points to it. Note that + this may not be a valid pointer in case we're supposed to receive the + arguments from the exec server, so we can not dereference it yet. */ + + void *caller = __builtin_extract_return_addr (__builtin_return_address (0)); + /* Init the essential things. */ + first_init (); + + void doinit (intptr_t *data) + { + init ((void **) data); + RETURN_TO (data, caller, 0); + __builtin_unreachable (); + } + + /* _hurd_startup () will attempt to receive the data block from the exec + server; or if that is not possible, will take the data from the pointer + we pass it here. The important point here is that the data + _hurd_startup () collects may be allocated in its stack frame (with + alloca), which is why _hurd_startup () does not return the normal way. + Instead, it invokes a callback (which is not expected to return normally + either). + + Our callback not only passes the data pointer to init (), but also jumps + out of the call stack back to our caller (i.e. to _start1), while setting + the stack pointer to the data (which is somewhere on the current stack + anyway). This way, _start1 find the data on the top of the stack, just as + it expects to. */ + _hurd_startup (argptr, &doinit); + __builtin_unreachable (); +} +#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. */ + +void +_dl_start (void) +{ + abort (); +} diff --git a/sysdeps/mach/hurd/x86/init-first.c b/sysdeps/mach/hurd/x86/init-first.c deleted file mode 100644 index 211b2096b6..0000000000 --- a/sysdeps/mach/hurd/x86/init-first.c +++ /dev/null @@ -1,253 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. For x86/Hurd. - Copyright (C) 1995-2024 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 - . */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "hurdstartup.h" - -#include -#include -#include -#include - -extern void __mach_init (void); -extern void __init_misc (int, char **, char **); - -extern int __libc_argc attribute_hidden; -extern char **__libc_argv attribute_hidden; -extern char **_dl_argv; - -#ifndef SHARED -static tcbhead_t __init1_tcbhead; -#endif - -/* Things that want to be run before _hurd_init or much anything else. - Importantly, these are called before anything tries to use malloc. */ -DEFINE_HOOK (_hurd_preinit_hook, (void)); - - -/* We call this once the Hurd magic is all set up and we are ready to be a - Posixoid program. This does the same things the generic version does. */ -static void -posixland_init (int argc, char **argv, char **envp) -{ - /* Now we have relocations etc. we can start signals etc. */ - _hurd_libc_proc_init (argv); - -#ifdef SHARED - /* Make sure we don't initialize twice. */ - if (__libc_initial) - { - /* Set the FPU control word to the proper default value. */ - __setfpucw (__fpu_control); - } - else - { - /* Initialize data structures so the additional libc can do RPCs. */ - __mach_init (); - } -#else /* !SHARED */ - __setfpucw (__fpu_control); -#endif - - /* Save the command-line arguments. */ - __libc_argc = argc; - __libc_argv = argv; - __environ = envp; - -#ifndef SHARED - _dl_non_dynamic_init (); -#endif - __init_misc (argc, argv, envp); -} - -static void -init (void **data) -{ - int argc = (int) (uintptr_t) *data; - char **argv = (void *) (data + 1); - char **envp = &argv[argc + 1]; - struct hurd_startup_data *d; - - /* Since the cthreads initialization code uses malloc, and the - malloc initialization code needs to get at the environment, make - sure we can find it. We'll need to do this again later on since - switching stacks changes the location where the environment is - stored. */ - __environ = envp; - - while (*envp) - ++envp; - d = (void *) ++envp; - -#ifndef SHARED - - /* If we are the bootstrap task started by the kernel, - then after the environment pointers there is no Hurd - data block; the argument strings start there. */ - if ((void *) d == argv[0] || d->phdr == 0) - { - __libc_enable_secure = 0; - /* With a new enough linker (binutils-2.23 or better), - the magic __ehdr_start symbol will be available and - __libc_start_main will have done this that way already. */ - if (_dl_phdr == NULL) - { - /* We may need to see our own phdrs, e.g. for TLS setup. - Try the usual kludge to find the headers without help from - the exec server. */ - extern const void __executable_start; - const ElfW(Ehdr) *const ehdr = &__executable_start; - _dl_phdr = (const void *) ehdr + ehdr->e_phoff; - _dl_phnum = ehdr->e_phnum; - assert (ehdr->e_phentsize == sizeof (ElfW(Phdr))); - } - } - else - { - __libc_enable_secure = d->flags & EXEC_SECURE; - _dl_phdr = (ElfW(Phdr) *) d->phdr; - _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr)); - assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0); - } -#endif - - if ((void *) d == argv[0]) - return; - - _hurd_init_dtable = d->dtable; - _hurd_init_dtablesize = d->dtablesize; - - if (d->portarray || d->intarray) - /* Initialize library data structures, start signal processing, etc. */ - _hurd_init (d->flags, argv, - d->portarray, d->portarraysize, - d->intarray, d->intarraysize); -} - -/* Do the first essential initializations that must precede all else. */ -static inline void -first_init (void) -{ - /* Initialize data structures so we can do RPCs. */ - __mach_init (); - -#ifndef SHARED - /* In the static case, we need to set up TLS early so that the stack - protection guard can be read at gs:0x14 by the gcc-generated snippets. */ - _hurd_tls_init (&__init1_tcbhead, 0); -#endif - - RUN_RELHOOK (_hurd_preinit_hook, ()); -} - -#ifdef SHARED -/* This function is called specially by the dynamic linker to do early - initialization of the shared C library before normal initializers - expecting a Posixoid environment can run. */ - -void -_dl_init_first (void *data) -{ - first_init (); - init (data); -} - -/* The regular posixland initialization is what goes into libc's - normal initializer. */ -/* 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!! */ -strong_alias (posixland_init, _init); - -void -__libc_init_first (int argc, char **argv, char **envp) -{ - /* Everything was done in the shared library initializer, _init. */ -} - -#else /* SHARED */ - -strong_alias (posixland_init, __libc_init_first); - -/* XXX This is all a crock and I am not happy with it. - This poorly-named function is called by static-start.S, - which should not exist at all. */ -void -inhibit_stack_protector -_hurd_stack_setup (void **argptr) -{ - /* This is the very first C code that runs in a statically linked - executable -- calling this function is the first thing that _start in - static-start.S does. Once this function returns, the unusual way that it - does (see below), _start jumps to _start1, the regular start-up code. - - _start1 expects the arguments, environment, and a Hurd data block to be - located at the top of the stack. The data may already be located there, - or we may need to receive it from the exec server. If the data is located - on the stack (just above our call frame), argptr points to it. Note that - this may not be a valid pointer in case we're supposed to receive the - arguments from the exec server, so we can not dereference it yet. */ - - void *caller = __builtin_extract_return_addr (__builtin_return_address (0)); - /* Init the essential things. */ - first_init (); - - void doinit (intptr_t *data) - { - init ((void **) data); - RETURN_TO (data, caller, 0); - __builtin_unreachable (); - } - - /* _hurd_startup () will attempt to receive the data block from the exec - server; or if that is not possible, will take the data from the pointer - we pass it here. The important point here is that the data - _hurd_startup () collects may be allocated in its stack frame (with - alloca), which is why _hurd_startup () does not return the normal way. - Instead, it invokes a callback (which is not expected to return normally - either). - - Our callback not only passes the data pointer to init (), but also jumps - out of the call stack back to our caller (i.e. to _start1), while setting - the stack pointer to the data (which is somewhere on the current stack - anyway). This way, _start1 find the data on the top of the stack, just as - it expects to. */ - _hurd_startup (argptr, &doinit); - __builtin_unreachable (); -} -#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. */ - -void -_dl_start (void) -{ - abort (); -} -- cgit v1.2.3