From cf59f89bfb0f411fd4e4a022e4a5bd92efcdd58b Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 15 Apr 2025 22:29:26 +0300 Subject: [PATCH] LibC: Rework constructor/destructor calling constructors are now called in _init_libc instead of crt0 destructors are now registered with atexit() instead of called manually --- userspace/libraries/LibC/arch/i686/crt0.S | 34 +++++++++------------ userspace/libraries/LibC/arch/x86_64/crt0.S | 23 ++++++-------- userspace/libraries/LibC/stdlib.cpp | 3 -- userspace/libraries/LibC/unistd.cpp | 23 +++++++++++++- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/userspace/libraries/LibC/arch/i686/crt0.S b/userspace/libraries/LibC/arch/i686/crt0.S index f50cdfb4..a1bb0202 100644 --- a/userspace/libraries/LibC/arch/i686/crt0.S +++ b/userspace/libraries/LibC/arch/i686/crt0.S @@ -3,9 +3,9 @@ .global _start _start: pushl $0 - pushl %edi - pushl %esi pushl %edx + pushl %esi + pushl %edi # STACK LAYOUT # null @@ -15,27 +15,21 @@ _start: xorl %ebp, %ebp - # init libc (envp already as argument) + pushl $__fini_array_end + pushl $__fini_array_start + pushl $_fini + + pushl $__init_array_end + pushl $__init_array_start + pushl $_init + + pushl %edx + call _init_libc - # call global constructors - movl $_init, %eax - testl %eax, %eax - jz 1f - call *%eax - 1: + addl $(4 * 8), %esp - movl $__init_array_start, %ebx - jmp 2f - 1: call *(%ebx) - addl $4, %ebx - 2: cmpl $__init_array_end, %ebx - jne 1b - - # call main - movl 0(%esp), %eax - xchgl %eax, 8(%esp) - movl %eax, (%esp) + # argc, argv, envp already on stack call main subl $12, %esp diff --git a/userspace/libraries/LibC/arch/x86_64/crt0.S b/userspace/libraries/LibC/arch/x86_64/crt0.S index b5b543c9..36d4a1da 100644 --- a/userspace/libraries/LibC/arch/x86_64/crt0.S +++ b/userspace/libraries/LibC/arch/x86_64/crt0.S @@ -17,21 +17,18 @@ _start: # init libc movq 0(%rsp), %rdi + + pushq $__fini_array_end + pushq $__fini_array_start + pushq $_fini + + pushq $__init_array_end + pushq $__init_array_start + pushq $_init + call _init_libc - # call global constructors - movq $_init, %rax - testq %rax, %rax - jz 1f - call *%rax - 1: - - movq $__init_array_start, %rbx - jmp 2f - 1: call *(%rbx) - addq $8, %rbx - 2: cmpq $__init_array_end, %rbx - jne 1b + addq $(6 * 8), %rsp # call main movq 16(%rsp), %rdi diff --git a/userspace/libraries/LibC/stdlib.cpp b/userspace/libraries/LibC/stdlib.cpp index 466009ab..89ddfcb2 100644 --- a/userspace/libraries/LibC/stdlib.cpp +++ b/userspace/libraries/LibC/stdlib.cpp @@ -23,8 +23,6 @@ char** __environ; weak_alias(__environ, environ); static bool s_environ_malloced = false; -extern "C" __attribute__((weak)) void _fini(); - void abort(void) { sigset_t set; @@ -43,7 +41,6 @@ void exit(int status) { fflush(nullptr); __cxa_finalize(nullptr); - if (_fini) _fini(); _exit(status); ASSERT_NOT_REACHED(); } diff --git a/userspace/libraries/LibC/unistd.cpp b/userspace/libraries/LibC/unistd.cpp index 41779ec2..404388df 100644 --- a/userspace/libraries/LibC/unistd.cpp +++ b/userspace/libraries/LibC/unistd.cpp @@ -16,12 +16,33 @@ #include #include +struct init_funcs_t +{ + void (*func)(); + void (**array_start)(); + void (**array_end)(); +}; + extern "C" char** environ; -extern "C" void _init_libc(char** _environ) +extern "C" void _init_libc(char** environ, init_funcs_t init_funcs, init_funcs_t fini_funcs) { if (::environ == nullptr) ::environ = environ; + + // call global constructors + if (init_funcs.func) + init_funcs.func(); + const size_t init_array_count = init_funcs.array_end - init_funcs.array_start; + for (size_t i = 0; i < init_array_count; i++) + init_funcs.array_start[i](); + + // register global destructors + const size_t fini_array_count = fini_funcs.array_end - fini_funcs.array_start; + for (size_t i = 0; i < fini_array_count; i++) + atexit(fini_funcs.array_start[i]); + if (fini_funcs.func) + atexit(fini_funcs.func); } void _exit(int status)