unify static and dynamic libc init/fini code paths

use weak definitions that the dynamic linker can override instead of
preprocessor conditionals on SHARED so that the same libc start and
exit code can be used for both static and dynamic linking.
This commit is contained in:
Rich Felker 2015-11-11 22:08:23 -05:00
parent 4aaf879eb0
commit ad1cd43a86
3 changed files with 24 additions and 30 deletions

View File

@ -8,21 +8,15 @@
void __init_tls(size_t *); void __init_tls(size_t *);
#ifndef SHARED extern void _init() __attribute__((weak));
static void dummy() {}
weak_alias(dummy, _init);
extern void (*const __init_array_start)() __attribute__((weak)); extern void (*const __init_array_start)() __attribute__((weak));
extern void (*const __init_array_end)() __attribute__((weak)); extern void (*const __init_array_end)() __attribute__((weak));
#endif
static void dummy1(void *p) {} static void dummy1(void *p) {}
weak_alias(dummy1, __init_ssp); weak_alias(dummy1, __init_ssp);
#define AUX_CNT 38 #define AUX_CNT 38
#ifndef SHARED
static
#endif
void __init_libc(char **envp, char *pn) void __init_libc(char **envp, char *pn)
{ {
size_t i, *auxv, aux[AUX_CNT] = { 0 }; size_t i, *auxv, aux[AUX_CNT] = { 0 };
@ -57,20 +51,22 @@ void __init_libc(char **envp, char *pn)
libc.secure = 1; libc.secure = 1;
} }
static void libc_start_init(void)
{
if (_init) _init();
uintptr_t a = (uintptr_t)&__init_array_start;
for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
(*(void (**)())a)();
}
weak_alias(libc_start_init, __libc_start_init);
int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv) int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
{ {
char **envp = argv+argc+1; char **envp = argv+argc+1;
#ifndef SHARED
__init_libc(envp, argv[0]); __init_libc(envp, argv[0]);
_init();
uintptr_t a = (uintptr_t)&__init_array_start;
for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
(*(void (**)())a)();
#else
void __libc_start_init(void);
__libc_start_init(); __libc_start_init();
#endif
/* Pass control to the application */ /* Pass control to the application */
exit(main(argc, argv, envp)); exit(main(argc, argv, envp));

View File

@ -11,24 +11,24 @@ static void dummy()
weak_alias(dummy, __funcs_on_exit); weak_alias(dummy, __funcs_on_exit);
weak_alias(dummy, __stdio_exit); weak_alias(dummy, __stdio_exit);
#ifndef SHARED extern void _fini() __attribute__((weak));
weak_alias(dummy, _fini);
extern void (*const __fini_array_start)() __attribute__((weak)); extern void (*const __fini_array_start)() __attribute__((weak));
extern void (*const __fini_array_end)() __attribute__((weak)); extern void (*const __fini_array_end)() __attribute__((weak));
#endif
static void libc_exit_fini(void)
{
uintptr_t a = (uintptr_t)&__fini_array_end;
for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
(*(void (**)())(a-sizeof(void(*)())))();
if (_fini) _fini();
}
weak_alias(libc_exit_fini, __libc_exit_fini);
_Noreturn void exit(int code) _Noreturn void exit(int code)
{ {
__funcs_on_exit(); __funcs_on_exit();
__libc_exit_fini();
#ifndef SHARED
uintptr_t a = (uintptr_t)&__fini_array_end;
for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
(*(void (**)())(a-sizeof(void(*)())))();
_fini();
#endif
__stdio_exit(); __stdio_exit();
_Exit(code); _Exit(code);
} }

View File

@ -1175,7 +1175,7 @@ static void kernel_mapped_dso(struct dso *p)
p->kernel_mapped = 1; p->kernel_mapped = 1;
} }
static void do_fini() void __libc_exit_fini()
{ {
struct dso *p; struct dso *p;
size_t dyn[DYN_CNT]; size_t dyn[DYN_CNT];
@ -1659,8 +1659,6 @@ _Noreturn void __dls3(size_t *sp)
debug.state = 0; debug.state = 0;
_dl_debug_state(); _dl_debug_state();
__init_libc(envp, argv[0]);
atexit(do_fini);
errno = 0; errno = 0;
CRTJMP((void *)aux[AT_ENTRY], argv-1); CRTJMP((void *)aux[AT_ENTRY], argv-1);