Be it statically or dynamically linked, the startup of glibc-based programs is quite hairy on GNU Hurd systems.
open issue documentation, open issue glibc
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) callsfirst_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 itsmain
parameter.- the
main
parameter was actuallydoinit
(in sysdeps/mach/hurd/i386/init-first.c), which mangles the stack and callsdoinit1
which callsinit
. init
sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to callinit1
.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 checksstd*
).- We are back to
_start
, which jumps to_start1
which is the normal libc startup which calls__libc_start_main
__libc_start_main
(actually calledLIBC_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) callspreinit_array_start
functions__libc_csu_init
calls_init
_init
(sysdeps/i386/crti.S) callsPREINIT_FUNCTION
, (actually libpthread on Linux,__gmon_start__
on hurd)- back to
__libc_csu_init
callsinit_array_start
functions - back to
__libc_start_main
, it calls calls application'smain
, thenexit
.
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) initializesbootstrap_map
, calls_dl_start_final
_dl_start_final
calls_dl_sysdep_start
._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 itsmain
parameter.- the
main
parameter was actuallygo
inside_dl_sysdep_start
, which callsdl_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) runsRTLD_START_SPECIAL_INIT
(sysdeps/mach/hurd/i386/dl-machine.h) which calls_dl_init_first
._dl_init_first
(sysdeps/mach/hurd/i386/init-first.c) callsfirst_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
callsinit
.init
sets threadvars, tries to initialize threads (and perhaps switches to the new stack) and gets to callinit1
.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 checksstd*
).- 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 calledLIBC_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
(csu/elf-init.c) calls_init
_init
(sysdeps/i386/crti.S) callsPREINIT_FUNCTION
, (actually libpthread on Linux,__gmon_start__
on hurd)- back to
__libc_csu_init
callsinit_array_start
functions - back to
__libc_start_main
, it calls application'smain
, thenexit
.
IRC, freenode, #hurd, 2013-12-31
<youpi> braunr: btw, after patching glibc and trying installing it, do you
try rebuilding hurd against it? ext2fs.static often breaks due to details
<braunr> youpi: yes
<braunr> youpi: always
<youpi> ok, good :)
<braunr> i want the rootfs to benefit from it too :)
<youpi> heh :)
<braunr> and yes, there were issues that occurred only in the rootfs
<braunr> but because of the special early state, not because of static
linking