libc+tests+tools: Call global constructors in userspace code
This commit is contained in:
parent
d9899f1c3d
commit
e34395915d
@ -3,6 +3,8 @@
|
|||||||
.global _start
|
.global _start
|
||||||
.extern exit
|
.extern exit
|
||||||
.extern libc_init
|
.extern libc_init
|
||||||
|
.extern _init
|
||||||
|
.extern _fini
|
||||||
_start:
|
_start:
|
||||||
# Set up end of the stack frame linked list.
|
# Set up end of the stack frame linked list.
|
||||||
movq $0, %rbp
|
movq $0, %rbp
|
||||||
@ -26,6 +28,11 @@ _start:
|
|||||||
# Run main
|
# Run main
|
||||||
call main
|
call main
|
||||||
|
|
||||||
|
# Store the exit code before calling _fini.
|
||||||
|
push %rax
|
||||||
|
|
||||||
|
call _fini
|
||||||
|
|
||||||
# Terminate the process with the exit code.
|
# Terminate the process with the exit code.
|
||||||
movl %eax, %edi
|
pop %rdi
|
||||||
call exit
|
call exit
|
||||||
|
@ -7,6 +7,14 @@ extern char** environ;
|
|||||||
extern "C" FILE* _fdopen_impl(int, const char*, int);
|
extern "C" FILE* _fdopen_impl(int, const char*, int);
|
||||||
extern "C" void _init_stdio();
|
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"
|
extern "C"
|
||||||
{
|
{
|
||||||
void libc_init(int argc, char** argv, int envc, char** envp)
|
void libc_init(int argc, char** argv, int envc, char** envp)
|
||||||
@ -19,5 +27,7 @@ extern "C"
|
|||||||
stdin = _fdopen_impl(STDIN_FILENO, "r", _IOLBF);
|
stdin = _fdopen_impl(STDIN_FILENO, "r", _IOLBF);
|
||||||
stdout = _fdopen_impl(STDOUT_FILENO, "w", _IOLBF);
|
stdout = _fdopen_impl(STDOUT_FILENO, "w", _IOLBF);
|
||||||
stderr = _fdopen_impl(STDERR_FILENO, "w", _IONBF);
|
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/TestScanf.cpp TestScanf)
|
||||||
luna_test(libc/TestString.cpp TestString)
|
luna_test(libc/TestString.cpp TestString)
|
||||||
luna_test(libc/TestEnv.cpp TestEnv)
|
luna_test(libc/TestEnv.cpp TestEnv)
|
||||||
|
luna_test(libc/TestGlobalCtors.cpp TestGlobalCtors)
|
||||||
|
|
||||||
luna_app(run-tests.cpp run-tests)
|
luna_app(run-tests.cpp run-tests)
|
||||||
endif()
|
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 LD
|
||||||
unset AR
|
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...
|
echo Building Binutils...
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ unset CXX
|
|||||||
unset LD
|
unset LD
|
||||||
unset AR
|
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...
|
echo Building GCC...
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user