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
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
pushl $0
|
pushl $0
|
||||||
pushl %edi
|
|
||||||
pushl %esi
|
|
||||||
pushl %edx
|
pushl %edx
|
||||||
|
pushl %esi
|
||||||
|
pushl %edi
|
||||||
|
|
||||||
# STACK LAYOUT
|
# STACK LAYOUT
|
||||||
# null
|
# null
|
||||||
|
@ -15,27 +15,21 @@ _start:
|
||||||
|
|
||||||
xorl %ebp, %ebp
|
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 _init_libc
|
||||||
|
|
||||||
# call global constructors
|
addl $(4 * 8), %esp
|
||||||
movl $_init, %eax
|
|
||||||
testl %eax, %eax
|
|
||||||
jz 1f
|
|
||||||
call *%eax
|
|
||||||
1:
|
|
||||||
|
|
||||||
movl $__init_array_start, %ebx
|
# argc, argv, envp already on stack
|
||||||
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)
|
|
||||||
call main
|
call main
|
||||||
|
|
||||||
subl $12, %esp
|
subl $12, %esp
|
||||||
|
|
|
@ -17,21 +17,18 @@ _start:
|
||||||
|
|
||||||
# init libc
|
# init libc
|
||||||
movq 0(%rsp), %rdi
|
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 _init_libc
|
||||||
|
|
||||||
# call global constructors
|
addq $(6 * 8), %rsp
|
||||||
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
|
|
||||||
|
|
||||||
# call main
|
# call main
|
||||||
movq 16(%rsp), %rdi
|
movq 16(%rsp), %rdi
|
||||||
|
|
|
@ -23,8 +23,6 @@ char** __environ;
|
||||||
weak_alias(__environ, environ);
|
weak_alias(__environ, environ);
|
||||||
static bool s_environ_malloced = false;
|
static bool s_environ_malloced = false;
|
||||||
|
|
||||||
extern "C" __attribute__((weak)) void _fini();
|
|
||||||
|
|
||||||
void abort(void)
|
void abort(void)
|
||||||
{
|
{
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
|
@ -43,7 +41,6 @@ void exit(int status)
|
||||||
{
|
{
|
||||||
fflush(nullptr);
|
fflush(nullptr);
|
||||||
__cxa_finalize(nullptr);
|
__cxa_finalize(nullptr);
|
||||||
if (_fini) _fini();
|
|
||||||
_exit(status);
|
_exit(status);
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,33 @@
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct init_funcs_t
|
||||||
|
{
|
||||||
|
void (*func)();
|
||||||
|
void (**array_start)();
|
||||||
|
void (**array_end)();
|
||||||
|
};
|
||||||
|
|
||||||
extern "C" char** environ;
|
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)
|
if (::environ == nullptr)
|
||||||
::environ = environ;
|
::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)
|
void _exit(int status)
|
||||||
|
|
Loading…
Reference in New Issue