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
This commit is contained in:
parent
066ed7e4a1
commit
cf59f89bfb
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -16,12 +16,33 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue