Compatibility with LLVM libunwind

This commit is contained in:
Ehmry - 2019-09-16 18:07:32 +02:00
parent 4e94dd4265
commit 5a8686eaf9
5 changed files with 93 additions and 15 deletions

View File

@ -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

View File

@ -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}

View File

@ -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 */

View File

@ -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 **
**********************************/

View File

@ -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.");