From 6ecd152e7e262fd9511e3f739a6305e3050ebf0f Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 16 Mar 2018 23:49:14 +0100 Subject: document the libc startup dance --- glibc/startup.mdwn | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'glibc') diff --git a/glibc/startup.mdwn b/glibc/startup.mdwn index ac7cdde6..9e1137f5 100644 --- a/glibc/startup.mdwn +++ b/glibc/startup.mdwn @@ -21,6 +21,44 @@ is quite hairy on GNU Hurd systems. * [[!message-id "871xc9qv6y.wl@ulysses.g10code.de"]] +# How libc startup in a process works + +## Statically-linked program + + * The ELF headers points program start at `_start`. + * `_start` (sysdeps/mach/hurd/i386/static-start.S) calls `_hurd_stack_setup` + * `_hurd_stack_setup` (sysdeps/mach/hurd/i386/init-first.c) calls `first_init` which calls `__mach_init` to initialize enough to run RPCs, then runs the `_hurd_preinit_hook` hooks, which initialize global variables of libc. + * `_hurd_stack_setup` (sysdeps/mach/hurd/i386/init-first.c) calls `_hurd_startup`. + * `_hurd_startup` (hurd/hurdstartup.c) gets hurdish information from servers and calls its `main` parameter. + * the `main` parameter was actually `doinit`, which mangles the stack and calls `doinit1` which calls `init`. + * `init` sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to call `init1`. + * `init1` checks the new stack, calls `_hurd_init` (hurd/hurdinit.c) + * `_hurd_init` initializes initial ports, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). + * We are back to `_start`, which jumps to `_start1` which is the normal libc startup which calls `__libc_start_main` + * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, tls, libpthread, atexit, an initialization function given as parameter, then calls application's `main`, then `exit`. + +## dynamically-linked program + + * dl.so ELF headers point its start at `_start`. + * `_start` (sysdeps/i386/dl-machine.h) calls `_dl_start`. + * `_dl_start` (elf/rtld.c) initializes `bootstrap_map`, calls `_dl_start_final` + * `_dl_start_final` calls `_dl_sysdep_start`. + * `_dl_sysdep_start` calls `__mach_init` to initialize enough to run RPCs, then calls `_hurd_startup`. + * `_hurd_startup` (hurd/hurdstartup.c) gets hurdish information from servers and calls its `main` parameter. + * the `main` parameter was actually `go`, which calls `dl_main`. + * `dl_main` (elf/rtld.c) interprets ld.so parameters, loads the binary and libraries, calls `_dl_allocate_tls_init`. + * we are back to `go`, which branches to `_dl_start_user`. + * `_dl_start_user` (./sysdeps/i386/dl-machine.h) runs `RTLD_START_SPECIAL_INIT` (sysdeps/mach/hurd/i386/dl-machine.h) which calls `_dl_init_first`. + * `_dl_init_first` calls `first_init` which calls `__mach_init` to initialize enough to run RPCs, then runs the `_hurd_preinit_hook` hooks, which initialize global variables of libc. + * `_dl_init_first` calls `init`. + * `init` sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to call `init1`. + * `init1` checks the new stack, calls `_hurd_init` (hurd/hurdinit.c) + * `_hurd_init` initializes initial ports, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). + * we are back to `_dl_start_user`, which calls `_dl_init` (elf/dl-init.c) which calls application initializers. + * `_dl_start_user` jumps to the application's entry point, `_start` + * `_start` (sysdeps/i386/start.S) calls `__libc_start_main` + * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, tls, libpthread, atexit, an initialization function given as parameter, then calls application's `main`, then `exit`. + # IRC, freenode, #hurd, 2013-12-31 braunr: btw, after patching glibc and trying installing it, do you -- cgit v1.2.3 From 9fb5b9c57cbc8420a1207574c4d969d90794fb7b Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sat, 17 Mar 2018 00:40:51 +0100 Subject: add initialization details --- glibc/startup.mdwn | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'glibc') diff --git a/glibc/startup.mdwn b/glibc/startup.mdwn index 9e1137f5..0fe15b3b 100644 --- a/glibc/startup.mdwn +++ b/glibc/startup.mdwn @@ -35,7 +35,13 @@ is quite hairy on GNU Hurd systems. * `init1` checks the new stack, calls `_hurd_init` (hurd/hurdinit.c) * `_hurd_init` initializes initial ports, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). * We are back to `_start`, which jumps to `_start1` which is the normal libc startup which calls `__libc_start_main` - * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, tls, libpthread, atexit, an initialization function given as parameter, then calls application's `main`, then `exit`. + * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, tls, libpthread, atexit + * `__libc_start_main` calls initialization function given as parameter `__libc_csu_init`, + * `__libc_csu_init` (csu/elf-init.c) calls `preinit_array_start` functions + * `__libc_csu_init` calls `_init` + * `_init` (sysdeps/i386/crti.S) calls `PREINIT_FUNCTION`, (actually libpthread on Linux, `__gmon_start__` on hurd) + * back to `__libc_csu_init` (csu/elf-init.c) calls `init_array_start` functions + * back to `__libc_start_main`, it calls calls application's `main`, then `exit`. ## dynamically-linked program @@ -57,7 +63,12 @@ is quite hairy on GNU Hurd systems. * we are back to `_dl_start_user`, which calls `_dl_init` (elf/dl-init.c) which calls application initializers. * `_dl_start_user` jumps to the application's entry point, `_start` * `_start` (sysdeps/i386/start.S) calls `__libc_start_main` - * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, tls, libpthread, atexit, an initialization function given as parameter, then calls application's `main`, then `exit`. + * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, atexit, + * `__libc_start_main` calls initialization function given as parameter `__libc_csu_init`, + * `__libc_csu_init` calls `_init` + * `_init` (sysdeps/i386/crti.S) calls `PREINIT_FUNCTION`, (actually libpthread on Linux, `__gmon_start__` on hurd) + * back to `__libc_csu_init` (csu/elf-init.c) calls `init_array_start` functions + * back to `__libc_start_main`, it calls application's `main`, then `exit`. # IRC, freenode, #hurd, 2013-12-31 -- cgit v1.2.3 From 8026152efb84ec1ef45f0023ebff69654b92dadd Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sat, 17 Mar 2018 01:35:16 +0100 Subject: Note where the signals thread is created --- glibc/startup.mdwn | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'glibc') diff --git a/glibc/startup.mdwn b/glibc/startup.mdwn index 0fe15b3b..67d66c1b 100644 --- a/glibc/startup.mdwn +++ b/glibc/startup.mdwn @@ -32,8 +32,8 @@ is quite hairy on GNU Hurd systems. * `_hurd_startup` (hurd/hurdstartup.c) gets hurdish information from servers and calls its `main` parameter. * the `main` parameter was actually `doinit`, which mangles the stack and calls `doinit1` which calls `init`. * `init` sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to call `init1`. - * `init1` checks the new stack, calls `_hurd_init` (hurd/hurdinit.c) - * `_hurd_init` initializes initial ports, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). + * `init1` gets the Hurd block, calls `_hurd_init` (hurd/hurdinit.c) on it + * `_hurd_init` initializes initial ports, starts the signal thread, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). * We are back to `_start`, which jumps to `_start1` which is the normal libc startup which calls `__libc_start_main` * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, tls, libpthread, atexit * `__libc_start_main` calls initialization function given as parameter `__libc_csu_init`, @@ -56,10 +56,10 @@ is quite hairy on GNU Hurd systems. * we are back to `go`, which branches to `_dl_start_user`. * `_dl_start_user` (./sysdeps/i386/dl-machine.h) runs `RTLD_START_SPECIAL_INIT` (sysdeps/mach/hurd/i386/dl-machine.h) which calls `_dl_init_first`. * `_dl_init_first` calls `first_init` which calls `__mach_init` to initialize enough to run RPCs, then runs the `_hurd_preinit_hook` hooks, which initialize global variables of libc. - * `_dl_init_first` calls `init`. + * `_dl_init_first` (sysdeps/mach/hurd/i386/init-first.c) calls `init`. * `init` sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to call `init1`. - * `init1` checks the new stack, calls `_hurd_init` (hurd/hurdinit.c) - * `_hurd_init` initializes initial ports, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). + * `init1` gets the Hurd block, calls `_hurd_init` (hurd/hurdinit.c) on it + * `_hurd_init` initializes initial ports, starts the signal thread, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). * we are back to `_dl_start_user`, which calls `_dl_init` (elf/dl-init.c) which calls application initializers. * `_dl_start_user` jumps to the application's entry point, `_start` * `_start` (sysdeps/i386/start.S) calls `__libc_start_main` -- cgit v1.2.3 From 96dba7ef358153dd1a608ab45f52226d08d62e3c Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sat, 21 Apr 2018 13:17:29 +0200 Subject: rearrange filenames --- glibc/startup.mdwn | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'glibc') diff --git a/glibc/startup.mdwn b/glibc/startup.mdwn index 67d66c1b..7c3f3d5a 100644 --- a/glibc/startup.mdwn +++ b/glibc/startup.mdwn @@ -30,17 +30,17 @@ is quite hairy on GNU Hurd systems. * `_hurd_stack_setup` (sysdeps/mach/hurd/i386/init-first.c) calls `first_init` which calls `__mach_init` to initialize enough to run RPCs, then runs the `_hurd_preinit_hook` hooks, which initialize global variables of libc. * `_hurd_stack_setup` (sysdeps/mach/hurd/i386/init-first.c) calls `_hurd_startup`. * `_hurd_startup` (hurd/hurdstartup.c) gets hurdish information from servers and calls its `main` parameter. - * the `main` parameter was actually `doinit`, which mangles the stack and calls `doinit1` which calls `init`. + * the `main` parameter was actually `doinit` (in sysdeps/mach/hurd/i386/init-first.c), which mangles the stack and calls `doinit1` which calls `init`. * `init` sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to call `init1`. - * `init1` gets the Hurd block, calls `_hurd_init` (hurd/hurdinit.c) on it - * `_hurd_init` initializes initial ports, starts the signal thread, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). + * `init1` gets the Hurd block, calls `_hurd_init` on it + * `_hurd_init` (hurd/hurdinit.c) initializes initial ports, starts the signal thread, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). * We are back to `_start`, which jumps to `_start1` which is the normal libc startup which calls `__libc_start_main` * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, tls, libpthread, atexit * `__libc_start_main` calls initialization function given as parameter `__libc_csu_init`, * `__libc_csu_init` (csu/elf-init.c) calls `preinit_array_start` functions * `__libc_csu_init` calls `_init` * `_init` (sysdeps/i386/crti.S) calls `PREINIT_FUNCTION`, (actually libpthread on Linux, `__gmon_start__` on hurd) - * back to `__libc_csu_init` (csu/elf-init.c) calls `init_array_start` functions + * back to `__libc_csu_init` calls `init_array_start` functions * back to `__libc_start_main`, it calls calls application's `main`, then `exit`. ## dynamically-linked program @@ -49,25 +49,25 @@ is quite hairy on GNU Hurd systems. * `_start` (sysdeps/i386/dl-machine.h) calls `_dl_start`. * `_dl_start` (elf/rtld.c) initializes `bootstrap_map`, calls `_dl_start_final` * `_dl_start_final` calls `_dl_sysdep_start`. - * `_dl_sysdep_start` calls `__mach_init` to initialize enough to run RPCs, then calls `_hurd_startup`. + * `_dl_sysdep_start` (sysdeps/mach/hurd/dl-sysdep.c) calls `__mach_init` to initialize enough to run RPCs, then calls `_hurd_startup`. * `_hurd_startup` (hurd/hurdstartup.c) gets hurdish information from servers and calls its `main` parameter. - * the `main` parameter was actually `go`, which calls `dl_main`. + * the `main` parameter was actually `go` inside `_dl_sysdep_start`, which calls `dl_main`. * `dl_main` (elf/rtld.c) interprets ld.so parameters, loads the binary and libraries, calls `_dl_allocate_tls_init`. * we are back to `go`, which branches to `_dl_start_user`. * `_dl_start_user` (./sysdeps/i386/dl-machine.h) runs `RTLD_START_SPECIAL_INIT` (sysdeps/mach/hurd/i386/dl-machine.h) which calls `_dl_init_first`. - * `_dl_init_first` calls `first_init` which calls `__mach_init` to initialize enough to run RPCs, then runs the `_hurd_preinit_hook` hooks, which initialize global variables of libc. - * `_dl_init_first` (sysdeps/mach/hurd/i386/init-first.c) calls `init`. + * `_dl_init_first` (sysdeps/mach/hurd/i386/init-first.c) calls `first_init` which calls `__mach_init` to initialize enough to run RPCs, then runs the `_hurd_preinit_hook` hooks, which initialize global variables of libc. + * `_dl_init_first` calls `init`. * `init` sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to call `init1`. - * `init1` gets the Hurd block, calls `_hurd_init` (hurd/hurdinit.c) on it - * `_hurd_init` initializes initial ports, starts the signal thread, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). + * `init1` gets the Hurd block, calls `_hurd_init` on it + * `_hurd_init` (hurd/hurdinit.c) initializes initial ports, starts the signal thread, runs the `_hurd_subinit` hooks (`init_dtable` hurd/dtable.c notably initializes the FD table and the `_hurd_fd_subinit` hooks, which notably checks `std*`). * we are back to `_dl_start_user`, which calls `_dl_init` (elf/dl-init.c) which calls application initializers. * `_dl_start_user` jumps to the application's entry point, `_start` * `_start` (sysdeps/i386/start.S) calls `__libc_start_main` * `__libc_start_main` (actually called `LIBC_START_MAIN` in csu/libc-start.c) initializes libc, atexit, * `__libc_start_main` calls initialization function given as parameter `__libc_csu_init`, - * `__libc_csu_init` calls `_init` + * `__libc_csu_init` (csu/elf-init.c) calls `_init` * `_init` (sysdeps/i386/crti.S) calls `PREINIT_FUNCTION`, (actually libpthread on Linux, `__gmon_start__` on hurd) - * back to `__libc_csu_init` (csu/elf-init.c) calls `init_array_start` functions + * back to `__libc_csu_init` calls `init_array_start` functions * back to `__libc_start_main`, it calls application's `main`, then `exit`. # IRC, freenode, #hurd, 2013-12-31 -- cgit v1.2.3