From 5a8686eaf913396746712724527f48aaf1c7123d Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Mon, 16 Sep 2019 18:07:32 +0200 Subject: [PATCH] Compatibility with LLVM libunwind --- repos/base/src/ld/genode.ld | 4 ++ repos/base/src/lib/cxx/Tupfile | 19 ++++++--- repos/base/src/lib/cxx/malloc_free.cc | 26 +++++++++--- repos/base/src/lib/cxx/misc.cc | 57 ++++++++++++++++++++++++++- repos/base/src/lib/cxx/new_delete.cc | 2 +- 5 files changed, 93 insertions(+), 15 deletions(-) diff --git a/repos/base/src/ld/genode.ld b/repos/base/src/ld/genode.ld index 1179c69e1..c5f8989cc 100644 --- a/repos/base/src/ld/genode.ld +++ b/repos/base/src/ld/genode.ld @@ -51,6 +51,8 @@ SECTIONS __ex_table : { *(__ex_table) } .eh_frame_hdr : { *(.eh_frame_hdr) } + __eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0; + __eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0; . = ALIGN(0x1000); @@ -91,7 +93,9 @@ SECTIONS /* exception frames for C++ */ .eh_frame : { __eh_frame_start__ = .; + __eh_frame_start = .; KEEP (*(.eh_frame)) + __eh_frame_end = .; LONG(0) } : rw diff --git a/repos/base/src/lib/cxx/Tupfile b/repos/base/src/lib/cxx/Tupfile index 04529c5ad..c81355d40 100644 --- a/repos/base/src/lib/cxx/Tupfile +++ b/repos/base/src/lib/cxx/Tupfile @@ -3,6 +3,16 @@ include_rules DEFINES = -ffunction-sections -fno-strict-aliasing -g -fPIC # drop the standard defines to avoid -nostdinc +export LIBCXX +export LIBCXXABI +export LIBUNWIND + +INCLUDES += -I$LIBCXX/include/c++/v1 +INCLUDES += -I$LIBCXXABI/include + +LLVM_LIBS += $LIBCXXABI/lib/libc++abi.a +LLVM_LIBS += $LIBUNWIND/lib/libunwind.a + : foreach *.cc |> !cxx |> {supc++} # @@ -18,11 +28,7 @@ KEEP_SYMBOLS = \ -u _ZTVN10__cxxabiv119__pointer_type_infoE \ -u _ZTSN10__cxxabiv120__function_type_infoE \ -LIBCXX_GCC = \ - `$(CXX) $(CC_MARCH) -print-file-name=libsupc++.a` \ - `$(CXX) $(CC_MARCH) -print-file-name=libgcc_eh.a` \ - -: {supc++} |> $(LD) $(LD_MARCH) $(KEEP_SYMBOLS) -r %f $(LIBCXX_GCC) -o %o |> supc++.tmp +: {supc++} |> $(LD) $(LD_MARCH) $(KEEP_SYMBOLS) -r %f $(LLVM_LIBS) -o %o |> supc++.tmp # # Here we define all symbols we want to hide in libsupc++ and libgcc_eh @@ -63,7 +69,8 @@ EH_SYMBOLS += \ REDEF_SYMBOLS = `echo $(EH_SYMBOLS) | awk -v RS=' ' '{ print "--redefine-sym "$1"=_cxx_"$1 }'` -: supc++.tmp |> $(OBJCOPY) $(LOCAL_SYMBOLS) $(REDEF_SYMBOLS) %f %o |> supc++.o {obj} +export OBJCOPY +: supc++.tmp |> $OBJCOPY $(LOCAL_SYMBOLS) $(REDEF_SYMBOLS) %f %o |> supc++.o {obj} : foreach *.c |> !cc |> {obj} diff --git a/repos/base/src/lib/cxx/malloc_free.cc b/repos/base/src/lib/cxx/malloc_free.cc index 3900be132..63572dd30 100644 --- a/repos/base/src/lib/cxx/malloc_free.cc +++ b/repos/base/src/lib/cxx/malloc_free.cc @@ -66,8 +66,14 @@ typedef unsigned long Block_header; extern "C" void *malloc(size_t size) { - /* enforce size to be a multiple of 4 bytes */ - size = (size + 3) & ~3; + /* + * Use a double-word aligned allocations as required by the Itanium C++ ABI. + * + * See https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-data + */ + + constexpr size_t align_mask = sizeof(long)*2 - 1; + size = (size + align_mask) & ~align_mask; /* * We store the size of the allocation at the very @@ -75,13 +81,21 @@ extern "C" void *malloc(size_t size) * the subsequent address. This way, we can retrieve * the size information when freeing the block. */ - unsigned long real_size = size + sizeof(Block_header); + unsigned long real_size = size + sizeof(Block_header)*2; void *addr = 0; if (!cxx_heap().alloc(real_size, &addr)) return 0; *(Block_header *)addr = real_size; - return (Block_header *)addr + 1; + + return (Block_header *)addr + 2; +} + + +extern "C" int posix_memalign(void **dest, size_t /*align*/, size_t size) +{ + *dest = malloc(size); + return *dest ? 0 : 1; } @@ -97,7 +111,7 @@ extern "C" void free(void *ptr) { if (!ptr) return; - unsigned long *addr = ((unsigned long *)ptr) - 1; + unsigned long *addr = ((unsigned long *)ptr) - 2; cxx_heap().free(addr, *addr); } @@ -113,7 +127,7 @@ extern "C" void *realloc(void *ptr, Genode::size_t size) } /* determine size of old block content (without header) */ - unsigned long old_size = *((Block_header *)ptr - 1) + unsigned long old_size = *((Block_header *)ptr - 2) - sizeof(Block_header); /* do not reallocate if new size is less than the current size */ diff --git a/repos/base/src/lib/cxx/misc.cc b/repos/base/src/lib/cxx/misc.cc index d739162fc..fc511950b 100644 --- a/repos/base/src/lib/cxx/misc.cc +++ b/repos/base/src/lib/cxx/misc.cc @@ -62,9 +62,9 @@ extern "C" int __cxa_atexit(void(*func)(void*), void *arg, extern int genode___cxa_finalize(void *dso); -extern "C" void __cxa_finalize(void *dso) +extern "C" int __cxa_finalize(void *dso) { - genode___cxa_finalize(dso); + return genode___cxa_finalize(dso); } @@ -127,6 +127,17 @@ extern "C" void abort(void) } +extern "C" int fflush(void*) { + return 0; +} + + +extern "C" int fprintf(void*, const char *msg, ...) { + Genode::warning("C++ runtime: ", msg); + return 0; +} + + extern "C" int fputc(int, void*) { return 0; } @@ -215,6 +226,12 @@ extern "C" int strcmp(const char *s1, const char *s2) } +extern "C" char *getenv(const char *) +{ + return NULL; +} + + /* * Needed by ARM EABI (gcc-4.4 Codesourcery release1039) */ @@ -225,6 +242,42 @@ extern "C" int sprintf(char *, const char *, ...) } +/* + * Needed by Clang/Libunwind/Libc++abi + */ + +extern "C" { + + +void __assert(const char *, const char *, int, const char *) { + std::terminate(); +} + +int tolower(int c) { return c; } +int isdigit(int) { return 0; } +int isxdigit(int) { return 0; } +int islower(int) { return 0; } + + +int snprintf(char *, size_t, const char *, ...) { return 0; } + +int vfprintf(FILE *, const char *msg, va_list) +{ + Genode::warning("C++ runtime: ", msg); + return 0; +} + +struct Dl_info; +int dladdr(const void *, Dl_info *) { return 0; } + +struct pthread_rwlock_t; +int pthread_rwlock_rdlock(pthread_rwlock_t *) { return 0; } +int pthread_rwlock_unlock(pthread_rwlock_t *) { return 0; } +int pthread_rwlock_wrlock(pthread_rwlock_t *) { return 0; } + +} + + /********************************** ** Support for stack protection ** **********************************/ diff --git a/repos/base/src/lib/cxx/new_delete.cc b/repos/base/src/lib/cxx/new_delete.cc index 65c2c98c8..65773fa5f 100644 --- a/repos/base/src/lib/cxx/new_delete.cc +++ b/repos/base/src/lib/cxx/new_delete.cc @@ -67,7 +67,7 @@ void operator delete (void *ptr, Deallocator &dealloc) { try_dealloc(ptr, deall * implementation of the 'stdcxx' library instead. To make this possible, the * 'delete (void *)' implementation in the 'cxx' library must be 'weak'. */ -__attribute__((weak)) void operator delete (void *) +__attribute__((weak)) void operator delete (void *) noexcept { Genode::error("cxx: operator delete (void *) called - not implemented. " "A working implementation is available in the 'stdcxx' library.");