2024-01-03 17:14:42 +00:00
|
|
|
/* Initialization code run first thing by the ELF startup code. For Hurd.
|
2025-01-01 18:14:45 +00:00
|
|
|
Copyright (C) 1995-2025 Free Software Foundation, Inc.
|
1997-02-10 03:19:57 +00:00
|
|
|
This file is part of the GNU C Library.
|
1995-05-11 01:02:23 +00:00
|
|
|
|
1997-02-10 03:19:57 +00:00
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
2001-07-06 04:58:11 +00:00
|
|
|
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.
|
1995-05-11 01:02:23 +00:00
|
|
|
|
1997-02-10 03:19:57 +00:00
|
|
|
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
|
2001-07-06 04:58:11 +00:00
|
|
|
Lesser General Public License for more details.
|
1995-05-11 01:02:23 +00:00
|
|
|
|
2001-07-06 04:58:11 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2012-02-09 23:18:22 +00:00
|
|
|
License along with the GNU C Library; if not, see
|
Prefer https to http for gnu.org and fsf.org URLs
Also, change sources.redhat.com to sourceware.org.
This patch was automatically generated by running the following shell
script, which uses GNU sed, and which avoids modifying files imported
from upstream:
sed -ri '
s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g
s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g
' \
$(find $(git ls-files) -prune -type f \
! -name '*.po' \
! -name 'ChangeLog*' \
! -path COPYING ! -path COPYING.LIB \
! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \
! -path manual/texinfo.tex ! -path scripts/config.guess \
! -path scripts/config.sub ! -path scripts/install-sh \
! -path scripts/mkinstalldirs ! -path scripts/move-if-change \
! -path INSTALL ! -path locale/programs/charmap-kw.h \
! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \
! '(' -name configure \
-execdir test -f configure.ac -o -f configure.in ';' ')' \
! '(' -name preconfigure \
-execdir test -f preconfigure.ac ';' ')' \
-print)
and then by running 'make dist-prepare' to regenerate files built
from the altered files, and then executing the following to cleanup:
chmod a+x sysdeps/unix/sysv/linux/riscv/configure
# Omit irrelevant whitespace and comment-only changes,
# perhaps from a slightly-different Autoconf version.
git checkout -f \
sysdeps/csky/configure \
sysdeps/hppa/configure \
sysdeps/riscv/configure \
sysdeps/unix/sysv/linux/csky/configure
# Omit changes that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines
git checkout -f \
sysdeps/powerpc/powerpc64/ppc-mcount.S \
sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
# Omit change that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline
git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 05:40:42 +00:00
|
|
|
<https://www.gnu.org/licenses/>. */
|
1995-05-11 01:02:23 +00:00
|
|
|
|
2001-03-24 14:36:00 +00:00
|
|
|
#include <assert.h>
|
1995-05-11 01:02:23 +00:00
|
|
|
#include <hurd.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
1995-05-20 00:13:43 +00:00
|
|
|
#include <string.h>
|
1998-06-25 19:44:22 +00:00
|
|
|
#include <sysdep.h>
|
2023-02-23 15:14:35 +00:00
|
|
|
#include <dl-sysdep.h>
|
1998-06-25 19:44:22 +00:00
|
|
|
#include <set-hooks.h>
|
1995-05-11 01:02:23 +00:00
|
|
|
#include "hurdstartup.h"
|
|
|
|
|
2002-11-26 01:56:30 +00:00
|
|
|
#include <ldsodefs.h>
|
|
|
|
#include <fpu_control.h>
|
2019-11-15 17:36:58 +00:00
|
|
|
#include <libc-diag.h>
|
2020-12-16 14:09:52 +00:00
|
|
|
#include <libc-internal.h>
|
2002-11-26 01:56:30 +00:00
|
|
|
|
1995-05-11 01:02:23 +00:00
|
|
|
extern void __mach_init (void);
|
2002-02-23 08:47:54 +00:00
|
|
|
extern void __init_misc (int, char **, char **);
|
1995-05-11 01:02:23 +00:00
|
|
|
|
Update.
* stdio-common/itowa-digits.c (_itowa_lower_digits): Define as hidden.
(_itowa_upper_digits): Likewise.
* libio/stdio.c (_IO_stdin, _IO_stdout, _IO_stderr): Define as hidden.
* libio/libio.h [_LIBC] (_IO_stdin, _IO_stdout, _IO_stderr): Declare
as hidden.
* libio/libioP.h: Declare _IO_file_jumps_mmap, _IO_wfile_jumps,
_IO_wfile_jumps_mmap, _IO_proc_jumps, _IO_old_proc_jumps,
_IO_str_jumps, _IO_wstr_jumps, _IO_file_jumps_internal,
_IO_wfile_jumps_internal, and _IO_list_all_internal as hidden.
* gmon/gmon.c (__bb_head): Define as hidden.
* gmon/bb_exit_func.c (__bb_head): Declare as hidden.
* argp/argp-parse.c (_argp_hang): Define as static.
* include/libc-symbols.h (_INTVARDEF): Adjust for visibility
handling in latest compilers.
* inet/in6_addr.c (in6addr_any): Use INTVARDEF not INTDEF to
define alias.
* libio/fileops.c (_IO_file_jumps): Likewise.
* libio/stdfiles.c (_IO_list_all): Likewise.
* libio/wfileops.c (_IO_wfile_jumps): Likewise.
* malloc/malloc.h: Move __libc_malloc_initialized declaration to
include/malloc.h.
* include/malloc.h: Add __libc_malloc_initialized declaration
here. Mark variable hidden.
* malloc/malloc.c: Include <malloc.h> not "malloc.h".
* elf/dl-open.c (__libc_argc): Declare as hidden.
(__libc_argv): Likewise.
* sysdeps/generic/wordexp.c (__libc_argc): Declare as hidden.
(__libc_argv): Likewise.
* sysdeps/mach/hurd/i386/init-first.c: Define __libc_argc and
__libc_argv as hidden.
* sysdeps/mach/hurd/mips/init-first.c: Likewise.
* sysdeps/mach/hurd/powerpc/init-first.c: Likewise.
* sysdeps/unix/sysv/aix/init-first.c: Likewise.
* sysdeps/unix/sysv/linux/init-first.c: Likewise.
2002-03-13 02:17:12 +00:00
|
|
|
extern int __libc_argc attribute_hidden;
|
|
|
|
extern char **__libc_argv attribute_hidden;
|
2001-03-24 14:36:00 +00:00
|
|
|
extern char **_dl_argv;
|
1996-09-06 00:08:55 +00:00
|
|
|
|
2024-01-03 17:14:43 +00:00
|
|
|
#if !defined (SHARED) && (defined (THREAD_SET_STACK_GUARD) || defined (THREAD_SET_POINTER_GUARD))
|
|
|
|
/* 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,
|
|
|
|
on architectures that store the guard in TLS and not globally. */
|
|
|
|
# define USE_INIT1_TCBHEAD 1
|
|
|
|
#else
|
|
|
|
# define USE_INIT1_TCBHEAD 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USE_INIT1_TCBHEAD
|
2022-08-22 20:34:31 +00:00
|
|
|
static tcbhead_t __init1_tcbhead;
|
|
|
|
#endif
|
|
|
|
|
1995-05-11 01:02:23 +00:00
|
|
|
/* 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));
|
|
|
|
|
1998-10-18 22:53:04 +00:00
|
|
|
|
|
|
|
/* 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. */
|
2000-04-02 22:01:23 +00:00
|
|
|
static void
|
|
|
|
posixland_init (int argc, char **argv, char **envp)
|
1998-10-18 22:53:04 +00:00
|
|
|
{
|
2020-11-13 10:23:08 +00:00
|
|
|
/* Now we have relocations etc. we can start signals etc. */
|
|
|
|
_hurd_libc_proc_init (argv);
|
|
|
|
|
2020-12-16 14:09:52 +00:00
|
|
|
#ifdef SHARED
|
2002-11-22 04:23:05 +00:00
|
|
|
/* Make sure we don't initialize twice. */
|
2020-12-16 14:09:52 +00:00
|
|
|
if (__libc_initial)
|
2002-11-22 04:23:05 +00:00
|
|
|
{
|
|
|
|
/* Set the FPU control word to the proper default value. */
|
|
|
|
__setfpucw (__fpu_control);
|
|
|
|
}
|
2014-11-23 19:50:24 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Initialize data structures so the additional libc can do RPCs. */
|
|
|
|
__mach_init ();
|
|
|
|
}
|
2020-12-16 14:09:52 +00:00
|
|
|
#else /* !SHARED */
|
|
|
|
__setfpucw (__fpu_control);
|
|
|
|
#endif
|
2002-11-22 04:23:05 +00:00
|
|
|
|
|
|
|
/* Save the command-line arguments. */
|
2000-04-03 17:13:21 +00:00
|
|
|
__libc_argc = argc;
|
|
|
|
__libc_argv = argv;
|
|
|
|
__environ = envp;
|
|
|
|
|
2002-02-24 08:34:04 +00:00
|
|
|
#ifndef SHARED
|
|
|
|
_dl_non_dynamic_init ();
|
|
|
|
#endif
|
2002-02-23 08:47:54 +00:00
|
|
|
__init_misc (argc, argv, envp);
|
1998-10-18 22:53:04 +00:00
|
|
|
}
|
|
|
|
|
1995-05-11 01:02:23 +00:00
|
|
|
static void
|
2023-02-23 15:14:35 +00:00
|
|
|
init (void **data)
|
1995-05-11 01:02:23 +00:00
|
|
|
{
|
2023-03-19 15:09:55 +00:00
|
|
|
int argc = (int) (uintptr_t) *data;
|
1998-11-25 12:55:38 +00:00
|
|
|
char **argv = (void *) (data + 1);
|
|
|
|
char **envp = &argv[argc + 1];
|
2023-02-23 15:14:35 +00:00
|
|
|
struct hurd_startup_data *d;
|
1998-11-25 12:55:38 +00:00
|
|
|
|
2001-08-20 21:44:01 +00:00
|
|
|
/* 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;
|
|
|
|
|
1998-11-25 12:55:38 +00:00
|
|
|
while (*envp)
|
|
|
|
++envp;
|
|
|
|
d = (void *) ++envp;
|
|
|
|
|
2023-02-23 15:14:35 +00:00
|
|
|
#ifndef SHARED
|
|
|
|
|
2018-07-31 20:33:05 +00:00
|
|
|
/* 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)
|
|
|
|
{
|
2023-02-23 15:14:35 +00:00
|
|
|
__libc_enable_secure = 0;
|
2018-07-31 20:33:05 +00:00
|
|
|
/* 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
|
|
|
|
{
|
2023-02-23 15:14:35 +00:00
|
|
|
__libc_enable_secure = d->flags & EXEC_SECURE;
|
2018-07-31 20:33:05 +00:00
|
|
|
_dl_phdr = (ElfW(Phdr) *) d->phdr;
|
|
|
|
_dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
|
|
|
|
assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
|
|
|
|
}
|
|
|
|
#endif
|
1998-11-25 12:55:38 +00:00
|
|
|
|
2023-02-23 15:14:35 +00:00
|
|
|
if ((void *) d == argv[0])
|
|
|
|
return;
|
1999-07-28 18:19:47 +00:00
|
|
|
|
2023-02-23 15:14:35 +00:00
|
|
|
_hurd_init_dtable = d->dtable;
|
|
|
|
_hurd_init_dtablesize = d->dtablesize;
|
1998-11-25 12:55:38 +00:00
|
|
|
|
2023-02-23 15:14:35 +00:00
|
|
|
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);
|
|
|
|
}
|
1998-11-25 12:55:38 +00:00
|
|
|
|
2000-04-02 22:01:23 +00:00
|
|
|
/* Do the first essential initializations that must precede all else. */
|
|
|
|
static inline void
|
|
|
|
first_init (void)
|
1995-05-11 01:02:23 +00:00
|
|
|
{
|
|
|
|
/* Initialize data structures so we can do RPCs. */
|
|
|
|
__mach_init ();
|
|
|
|
|
2024-01-03 17:14:44 +00:00
|
|
|
#ifndef SHARED
|
|
|
|
GLRO(dl_pagesize) = __vm_page_size;
|
|
|
|
#endif
|
|
|
|
|
2024-01-03 17:14:43 +00:00
|
|
|
#if USE_INIT1_TCBHEAD
|
2023-04-20 18:42:19 +00:00
|
|
|
_hurd_tls_init (&__init1_tcbhead, 0);
|
2022-08-22 20:34:31 +00:00
|
|
|
#endif
|
|
|
|
|
2021-12-28 09:27:06 +00:00
|
|
|
RUN_RELHOOK (_hurd_preinit_hook, ());
|
2000-04-02 22:01:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SHARED
|
|
|
|
/* This function is called specially by the dynamic linker to do early
|
|
|
|
initialization of the shared C library before normal initializers
|
2023-02-23 15:14:35 +00:00
|
|
|
expecting a Posixoid environment can run. */
|
2000-04-02 22:01:23 +00:00
|
|
|
|
|
|
|
void
|
2023-02-23 15:14:35 +00:00
|
|
|
_dl_init_first (void *data)
|
2000-04-02 22:01:23 +00:00
|
|
|
{
|
|
|
|
first_init ();
|
2023-02-23 15:14:35 +00:00
|
|
|
init (data);
|
1998-11-22 17:32:14 +00:00
|
|
|
}
|
1995-05-11 01:02:23 +00:00
|
|
|
|
2000-04-02 22:01:23 +00:00
|
|
|
/* 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);
|
|
|
|
|
1995-05-11 01:02:23 +00:00
|
|
|
void
|
1998-10-18 22:53:04 +00:00
|
|
|
__libc_init_first (int argc, char **argv, char **envp)
|
1995-05-11 01:02:23 +00:00
|
|
|
{
|
1998-10-18 22:53:04 +00:00
|
|
|
/* Everything was done in the shared library initializer, _init. */
|
|
|
|
}
|
2000-04-02 22:01:23 +00:00
|
|
|
|
2023-02-23 15:14:35 +00:00
|
|
|
#else /* SHARED */
|
|
|
|
|
|
|
|
strong_alias (posixland_init, __libc_init_first);
|
1998-06-25 19:44:22 +00:00
|
|
|
|
1998-10-18 22:53:04 +00:00
|
|
|
/* 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. */
|
1998-06-25 19:44:22 +00:00
|
|
|
void
|
2022-08-22 20:34:31 +00:00
|
|
|
inhibit_stack_protector
|
2024-01-03 17:14:40 +00:00
|
|
|
_hurd_stack_setup (void **argptr)
|
1998-06-25 19:44:22 +00:00
|
|
|
{
|
2023-02-23 15:14:35 +00:00
|
|
|
/* 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,
|
2024-01-03 17:14:40 +00:00
|
|
|
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. */
|
2023-02-23 15:14:35 +00:00
|
|
|
|
2024-03-23 17:32:46 +00:00
|
|
|
void *caller = RETURN_ADDRESS (0);
|
2023-02-23 15:14:35 +00:00
|
|
|
/* Init the essential things. */
|
|
|
|
first_init ();
|
2005-10-16 09:53:04 +00:00
|
|
|
|
2002-08-30 01:51:11 +00:00
|
|
|
void doinit (intptr_t *data)
|
1995-05-11 01:02:23 +00:00
|
|
|
{
|
2023-02-23 15:14:35 +00:00
|
|
|
init ((void **) data);
|
2024-01-03 17:14:41 +00:00
|
|
|
RETURN_TO (data, caller, 0);
|
2023-02-23 15:14:35 +00:00
|
|
|
__builtin_unreachable ();
|
1995-05-11 01:02:23 +00:00
|
|
|
}
|
|
|
|
|
2023-02-23 15:14:35 +00:00
|
|
|
/* _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. */
|
2024-01-03 17:14:40 +00:00
|
|
|
_hurd_startup (argptr, &doinit);
|
2023-02-23 15:14:35 +00:00
|
|
|
__builtin_unreachable ();
|
1995-05-11 01:02:23 +00:00
|
|
|
}
|
2024-12-26 22:11:28 +00:00
|
|
|
|
|
|
|
RETURN_TO_TRAMPOLINE();
|
1998-10-18 22:53:04 +00:00
|
|
|
#endif
|
1996-09-21 20:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* 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. */
|
|
|
|
|
1997-09-21 01:47:02 +00:00
|
|
|
void
|
|
|
|
_dl_start (void)
|
|
|
|
{
|
|
|
|
abort ();
|
1996-09-21 20:05:50 +00:00
|
|
|
}
|