Compatibility with LLVM libunwind
This commit is contained in:
parent
b2d5dccd03
commit
236ad8695b
|
@ -50,8 +50,6 @@ SECTIONS
|
|||
/* Linux: exception section for uaccess mechanism */
|
||||
__ex_table : { *(__ex_table) }
|
||||
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
.data : {
|
||||
|
@ -90,11 +88,17 @@ SECTIONS
|
|||
|
||||
/* exception frames for C++ */
|
||||
.eh_frame : {
|
||||
__eh_frame_start__ = .;
|
||||
__eh_frame_start = .;
|
||||
KEEP (*(.eh_frame))
|
||||
__eh_frame_end = .;
|
||||
LONG(0)
|
||||
} : rw
|
||||
|
||||
.eh_frame_hdr : { KEEP(*(.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;
|
||||
|
||||
.gcc_except_table : {
|
||||
KEEP(*(.gcc_except_table))
|
||||
KEEP(*(.gcc_except_table.*))
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
/* base-internal includes */
|
||||
#include <base/internal/globals.h>
|
||||
|
||||
extern "C" char __eh_frame_start__[]; /* from linker script */
|
||||
extern "C" char __eh_frame_start; /* from linker script */
|
||||
extern "C" void __register_frame (const void *begin); /* from libgcc_eh */
|
||||
extern "C" char *__cxa_demangle(const char *mangled_name,
|
||||
char *output_buffer,
|
||||
|
@ -95,7 +95,7 @@ void Genode::init_exception_handling(Env &env)
|
|||
init_ldso_phdr(env);
|
||||
init_cxx_heap(env);
|
||||
|
||||
__register_frame(__eh_frame_start__);
|
||||
__register_frame(&__eh_frame_start);
|
||||
|
||||
std::set_terminate(terminate_handler);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -61,9 +61,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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,6 +126,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;
|
||||
}
|
||||
|
@ -213,6 +224,12 @@ extern "C" int strcmp(const char *s1, const char *s2)
|
|||
}
|
||||
|
||||
|
||||
extern "C" char *getenv(const char *var)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Needed by ARM EABI (gcc-4.4 Codesourcery release1039)
|
||||
*/
|
||||
|
@ -223,6 +240,43 @@ extern "C" int sprintf(char *, const char *, ...)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Needed by Clang/Libunwind/Libc++abi
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
|
||||
void wait_for_continue();
|
||||
|
||||
void __assert(const char *, const char *, int, const char *) {
|
||||
wait_for_continue();
|
||||
}
|
||||
|
||||
int tolower(int c) { return c; }
|
||||
int isdigit(int c) { 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 **
|
||||
**********************************/
|
||||
|
|
|
@ -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.");
|
||||
|
|
Loading…
Reference in New Issue