From 7e10bb1469ff394994402c6cbbf5617a30cbc4c2 Mon Sep 17 00:00:00 2001 From: avdgrinten Date: Sat, 5 Dec 2015 19:00:01 +0100 Subject: [PATCH] Implement __cxa_atexit() --- libc/generic/lsb/dir.makefile | 4 +++ libc/generic/lsb/src/dso_exit.cpp | 33 +++++++++++++++++-- .../include/mlibc/frigg-alloc.hpp | 25 ++++++++++++++ libc/platform/x86_64-managarm/src/entry.cpp | 4 +++ libc/platform/x86_64-managarm/src/malloc.cpp | 21 +++++------- 5 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 libc/platform/x86_64-managarm/include/mlibc/frigg-alloc.hpp diff --git a/libc/generic/lsb/dir.makefile b/libc/generic/lsb/dir.makefile index 9ba18bb3..0125f4d8 100644 --- a/libc/generic/lsb/dir.makefile +++ b/libc/generic/lsb/dir.makefile @@ -10,10 +10,14 @@ $c_OBJECT_PATHS := $(addprefix $($c_OBJDIR)/,$($c_OBJECTS)) $c_CXX := x86_64-managarm-g++ $c_CPPFLAGS := -std=c++11 -Wall +$c_CPPFLAGS += -I$(FRIGG_PATH)/include $c_CPPFLAGS += -I$(TREE_PATH)/libc/generic/ansi/include $c_CPPFLAGS += -I$(TREE_PATH)/libc/generic/posix/include $c_CPPFLAGS += -I$(TREE_PATH)/libc/compilers/gcc/include +$c_CPPFLAGS += -I$(TREE_PATH)/libc/platform/x86_64-managarm/include +$c_CPPFLAGS += -DFRIGG_HAVE_LIBC $c_CXXFLAGS := $($c_CPPFLAGS) -fPIC -O2 +$c_CXXFLAGS += -fno-rtti -fno-exceptions $c_TARGETS := clean-$c install-$c $($c_OBJECT_PATHS) diff --git a/libc/generic/lsb/src/dso_exit.cpp b/libc/generic/lsb/src/dso_exit.cpp index c51bca18..d76d9259 100644 --- a/libc/generic/lsb/src/dso_exit.cpp +++ b/libc/generic/lsb/src/dso_exit.cpp @@ -1,8 +1,35 @@ #include -extern "C" int __cxa_atexit(void (*handler)(void *), void *argument, void *dso) { - __ensure(!"Not implemented"); - __builtin_unreachable(); +#pragma GCC visibility push(hidden) + +#include +#include + +#include +#include + +struct ExitHandler { + void (*function)(void *); + void *argument; + void *dsoTag; +}; + +frigg::LazyInitializer> exitHandlers; + +#pragma GCC visibility pop + +extern "C" int __cxa_atexit(void (*function)(void *), void *argument, void *dso_tag) { + // FIXME: initialize this from a global library guard constructor + __ensure(memoryAllocator); + if(!exitHandlers) + exitHandlers.initialize(*memoryAllocator); + + ExitHandler handler; + handler.function = function; + handler.argument = argument; + handler.dsoTag = dso_tag; + exitHandlers->push(handler); + return 0; } diff --git a/libc/platform/x86_64-managarm/include/mlibc/frigg-alloc.hpp b/libc/platform/x86_64-managarm/include/mlibc/frigg-alloc.hpp new file mode 100644 index 00000000..7ef4b027 --- /dev/null +++ b/libc/platform/x86_64-managarm/include/mlibc/frigg-alloc.hpp @@ -0,0 +1,25 @@ + +#ifndef MLIBC_FRIGG_ALLOC +#define MLIBC_FRIGG_ALLOC + +#pragma GCC visibility push(hidden) + +#include +#include + +struct VirtualAllocator { +public: + uintptr_t map(size_t length); + + void unmap(uintptr_t address, size_t length); +}; + +typedef frigg::SlabAllocator MemoryAllocator; + +extern VirtualAllocator virtualAllocator; +extern frigg::LazyInitializer memoryAllocator; + +#pragma GCC visibility pop + +#endif // MLIBC_FRIGG_ALLOC + diff --git a/libc/platform/x86_64-managarm/src/entry.cpp b/libc/platform/x86_64-managarm/src/entry.cpp index a7a8789d..30a6a00c 100644 --- a/libc/platform/x86_64-managarm/src/entry.cpp +++ b/libc/platform/x86_64-managarm/src/entry.cpp @@ -16,6 +16,10 @@ LibraryGuard::LibraryGuard() { //__mlibc_initMalloc(); } +// __dso_handle is usually defined in crtbeginS.o +// Since we link with -nostdlib we have to manually define it here +__attribute__ (( visibility("hidden") )) int __dso_handle; + extern "C" int main(int argc, char *argv[], char *env[]); extern "C" void __mlibc_entry() { diff --git a/libc/platform/x86_64-managarm/src/malloc.cpp b/libc/platform/x86_64-managarm/src/malloc.cpp index 93959a0e..11615c3e 100644 --- a/libc/platform/x86_64-managarm/src/malloc.cpp +++ b/libc/platform/x86_64-managarm/src/malloc.cpp @@ -4,23 +4,23 @@ #include #include +#include #pragma GCC visibility push(hidden) -#include -#include - #include #include -struct VirtualAllocator { -public: - uintptr_t map(size_t length); +// -------------------------------------------------------- +// Globals +// -------------------------------------------------------- - void unmap(uintptr_t address, size_t length); -}; +VirtualAllocator virtualAllocator; +frigg::LazyInitializer memoryAllocator; -typedef frigg::SlabAllocator MemoryAllocator; +// -------------------------------------------------------- +// VirtualAllocator +// -------------------------------------------------------- uintptr_t VirtualAllocator::map(size_t length) { assert((length % 0x1000) == 0); @@ -38,9 +38,6 @@ void VirtualAllocator::unmap(uintptr_t address, size_t length) { HEL_CHECK(helUnmapMemory(kHelNullHandle, (void *)address, length)); } -VirtualAllocator virtualAllocator; -frigg::LazyInitializer memoryAllocator; - #pragma GCC visibility pop void __mlibc_initMalloc() {