__noreturn void __libc_init(void* raw_args, void (*onexit)(void), int (*slingshot)(int, char**, char**), structors_array_t const * const structors) { KernelArgumentBlock args(raw_args); __libc_init_tls(args); __libc_init_common(args); apply_gnu_relro(); // Several Linux ABIs don't pass the onexit pointer, and the ones that // do never use it. Therefore, we ignore it. call_array(structors->preinit_array); call_array(structors->init_array); // The executable may have its own destructors listed in its .fini_array // so we need to ensure that these are called when the program exits // normally. if (structors->fini_array != NULL) { __cxa_atexit(__libc_fini,structors->fini_array,NULL); } exit(slingshot(args.argc, args.argv, args.envp)); }
__noreturn void __libc_init(uintptr_t *elfdata, void (*onexit)(void), int (*slingshot)(int, char**, char**), structors_array_t const * const structors) { int argc; char **argv, **envp; __libc_init_tls(NULL); /* Initialize the C runtime environment */ __libc_init_common(elfdata); /* Several Linux ABIs don't pass the onexit pointer, and the ones that * do never use it. Therefore, we ignore it. */ /* pre-init array. */ call_array(structors->preinit_array); // call static constructors call_array(structors->init_array); argc = (int) *elfdata; argv = (char**)(elfdata + 1); envp = argv + argc + 1; /* The executable may have its own destructors listed in its .fini_array * so we need to ensure that these are called when the program exits * normally. */ if (structors->fini_array) __cxa_atexit(__libc_fini,structors->fini_array,NULL); apply_gnu_relro(); exit(slingshot(argc, argv, envp)); }