libc+tests+tools: Call global constructors in userspace code
This commit is contained in:
parent
d9899f1c3d
commit
e34395915d
@ -3,6 +3,8 @@
|
||||
.global _start
|
||||
.extern exit
|
||||
.extern libc_init
|
||||
.extern _init
|
||||
.extern _fini
|
||||
_start:
|
||||
# Set up end of the stack frame linked list.
|
||||
movq $0, %rbp
|
||||
@ -26,6 +28,11 @@ _start:
|
||||
# Run main
|
||||
call main
|
||||
|
||||
# Store the exit code before calling _fini.
|
||||
push %rax
|
||||
|
||||
call _fini
|
||||
|
||||
# Terminate the process with the exit code.
|
||||
movl %eax, %edi
|
||||
pop %rdi
|
||||
call exit
|
||||
|
@ -7,6 +7,14 @@ extern char** environ;
|
||||
extern "C" FILE* _fdopen_impl(int, const char*, int);
|
||||
extern "C" void _init_stdio();
|
||||
|
||||
typedef void initfunc_t(void);
|
||||
extern initfunc_t *__init_array_start[], *__init_array_end[];
|
||||
|
||||
static void handle_init_array(void)
|
||||
{
|
||||
for (initfunc_t** p = __init_array_start; p != __init_array_end; p++) (*p)();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void libc_init(int argc, char** argv, int envc, char** envp)
|
||||
@ -19,5 +27,7 @@ extern "C"
|
||||
stdin = _fdopen_impl(STDIN_FILENO, "r", _IOLBF);
|
||||
stdout = _fdopen_impl(STDOUT_FILENO, "w", _IOLBF);
|
||||
stderr = _fdopen_impl(STDERR_FILENO, "w", _IONBF);
|
||||
|
||||
handle_init_array();
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ luna_test(libluna/TestSharedPtr.cpp TestSharedPtr)
|
||||
luna_test(libc/TestScanf.cpp TestScanf)
|
||||
luna_test(libc/TestString.cpp TestString)
|
||||
luna_test(libc/TestEnv.cpp TestEnv)
|
||||
luna_test(libc/TestGlobalCtors.cpp TestGlobalCtors)
|
||||
|
||||
luna_app(run-tests.cpp run-tests)
|
||||
endif()
|
||||
|
42
tests/libc/TestGlobalCtors.cpp
Normal file
42
tests/libc/TestGlobalCtors.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <test.h>
|
||||
#include <time.h>
|
||||
|
||||
struct TestStruct
|
||||
{
|
||||
TestStruct(const char* name) : m_name(name)
|
||||
{
|
||||
// Just to make sure this constructor doesn't get optimized out
|
||||
time_t t = time(NULL);
|
||||
ctime(&t);
|
||||
}
|
||||
|
||||
const char* name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* m_name;
|
||||
};
|
||||
|
||||
TestStruct g_struct("Example Struct");
|
||||
|
||||
TestResult test_successful_global_constructor()
|
||||
{
|
||||
validate(g_struct.name());
|
||||
|
||||
validate(!strcmp(g_struct.name(), "Example Struct"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
Result<void> test_main()
|
||||
{
|
||||
test_prelude;
|
||||
|
||||
run_test(test_successful_global_constructor);
|
||||
|
||||
return {};
|
||||
}
|
@ -39,7 +39,7 @@ unset CXX
|
||||
unset LD
|
||||
unset AR
|
||||
|
||||
../binutils-$LUNA_BINUTILS_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --disable-werror --enable-warn-rwx-segments=no
|
||||
../binutils-$LUNA_BINUTILS_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --disable-werror --enable-warn-rwx-segments=no --enable-initfini-array
|
||||
|
||||
echo Building Binutils...
|
||||
|
||||
|
@ -51,7 +51,7 @@ unset CXX
|
||||
unset LD
|
||||
unset AR
|
||||
|
||||
../gcc-$LUNA_GCC_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --enable-languages=c,c++
|
||||
../gcc-$LUNA_GCC_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --enable-languages=c,c++ --enable-initfini-array
|
||||
|
||||
echo Building GCC...
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user