diff --git a/Makefile b/Makefile index 2ae27ec..27da4e8 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,14 @@ SRCS = libcpprt_entry.c libcpprt.cc RUNTIME_SOURCES = c++_runtime.cc c++_exceptions_runtime.cc .PATH: ${.CURDIR}/runtime -#RUNTIME_SOURCES+= typeinfo.cc libelftc_dem_gnu3.c dynamic_cast.cc -#RUNTIME_SOURCES+= exception.cc +RUNTIME_SOURCES+= typeinfo.cc libelftc_dem_gnu3.c dynamic_cast.cc +RUNTIME_SOURCES+= exception.cc +RUNTIME_SOURCES+= auxhelper.cc guard.cc memory.cc stdexcept.cc terminate.cc SRCS+= $(RUNTIME_SOURCES) -CXXFLAGS+= -I. -Iinclude -std=c++11 -fno-rtti -fno-exceptions +CXXFLAGS+= -I. -Iinclude -std=c++11 +#CXXFLAGS+= -I. -Iinclude -std=c++11 -fno-rtti -fno-exceptions CFLAGS+= -I. -Iinclude .include diff --git a/c++_exceptions_runtime.cc b/c++_exceptions_runtime.cc index 27fd2c3..1cc93ac 100644 --- a/c++_exceptions_runtime.cc +++ b/c++_exceptions_runtime.cc @@ -10,4 +10,9 @@ namespace cpp_runtime { panic( "Catch not implemented." ); } + + void *catch_impl_end( void *e ) noexcept + { + panic( "Catch not implemented." ); + } } diff --git a/c++_runtime.cc b/c++_runtime.cc index 0c9a25b..d8f71bf 100644 --- a/c++_runtime.cc +++ b/c++_runtime.cc @@ -10,6 +10,10 @@ extern "C" extern "C" void *__cxa_begin_catch( void *e ) noexcept; #include +namespace cxxruntime +{ + MALLOC_DECLARE( cxxruntime_pool ); +} namespace std { @@ -19,16 +23,16 @@ namespace std } -void *operator new( std::size_t s ) +void *operator new( const std::size_t s ) { - std::terminate(); + return malloc( s, cxxruntime::cxxruntime_pool, M_WAITOK ); } -void operator delete( void * ) +void operator delete( void *const p ) { - std::terminate(); + return free( p, cxxruntime::cxxruntime_pool ); } @@ -45,13 +49,19 @@ namespace std namespace cpp_runtime { void *catch_impl( void *e ) noexcept; + void *catch_impl_end( void *e ) noexcept; } extern "C" void * -__cxa_begin_catch( void *e ) noexcept +disabled__cxa_begin_catch( void *e ) noexcept { return cpp_runtime::catch_impl( e ); } +extern "C" void * +disabled__cxa_end_catch( void *e ) noexcept +{ + return cpp_runtime::catch_impl_end( e ); +} //namespace __cxxabiv1 //{ @@ -68,19 +78,25 @@ namespace cxxruntime void * malloc( std::size_t s ) { - return malloc( s, cxxruntime_pool, M_WAITOK ); + return ::malloc( s, cxxruntime_pool, M_WAITOK ); } void * realloc( void *p, std::size_t s ) { - return realloc( p, s, cxxruntime_pool, M_WAITOK ); + return ::realloc( p, s, cxxruntime_pool, M_WAITOK ); } void free( void *p ) { - return free( p, cxxruntime_pool ); + return ::free( p, cxxruntime_pool ); + } + + void * + calloc( const std::size_t number, const std::size_t size ) + { + return ::malloc( number * size, cxxruntime_pool, M_WAITOK | M_ZERO ); } } @@ -114,6 +130,8 @@ abort() panic( "C++ Runtime: abort" ); } +#if 0 + typedef enum { _URC_OK = 0, /* operation completed successfully */ @@ -125,6 +143,7 @@ abort() _URC_FAILURE = 9, /* unspecified failure of some kind */ _URC_FATAL_PHASE1_ERROR = _URC_FAILURE } _Unwind_Reason_Code; + struct _Unwind_Exception; struct _Unwind_Context; typedef uint32_t _Unwind_State; @@ -132,3 +151,4 @@ typedef uint32_t _Unwind_State; extern "C" _Unwind_Reason_Code __gxx_personality_v0(_Unwind_State state, struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context){abort();} +#endif diff --git a/include/stdio.h b/include/stdio.h index e69de29..40e1f1a 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -0,0 +1,12 @@ +#include +#include + +#ifdef __cplusplus +#define __extern_C extern "C" +#else +#define __extern_C extern +#endif + +enum FILE{ stdin, stdout, stderr }; + +#define fprintf( file, format, ... ) printf( format, ## __VA_ARGS__ ) diff --git a/include/stdlib.h b/include/stdlib.h index aead29e..56f9b43 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -18,6 +18,8 @@ namespace cxxruntime extern void *malloc( std::size_t ); extern void *realloc(void *, std::size_t); extern void free(void *); + + extern void *calloc( std::size_t, std::size_t ); } #define __extern_c extern "C" #else diff --git a/libcpprt.cc b/libcpprt.cc index 66d7072..c40d2cd 100644 --- a/libcpprt.cc +++ b/libcpprt.cc @@ -32,15 +32,26 @@ class TestingImpl : public Testing void libcpprt_entry() +try { uprintf( "Hello\n" ); - if( 1 ) tester= new TestingImpl(); + tester= new TestingImpl(); + + tester->core(); +} +catch( ... ) +{ } void libcpprt_close() +try { uprintf( "Goodbye\n" ); - if( 1 ) delete tester; + tester->core(); + delete tester; +} +catch( ... ) +{ } diff --git a/runtime/exception.cc b/runtime/exception.cc index 9c3c32a..7f1f28d 100644 --- a/runtime/exception.cc +++ b/runtime/exception.cc @@ -35,10 +35,10 @@ #include "atomic.h" #include "cxxabi.h" -#pragma weak pthread_key_create -#pragma weak pthread_setspecific -#pragma weak pthread_getspecific -#pragma weak pthread_once +//#pragma weak pthread_key_create +//#pragma weak pthread_setspecific +//#pragma weak pthread_getspecific +//#pragma weak pthread_once #ifdef LIBCXXRT_WEAK_LOCKS #pragma weak pthread_mutex_lock #define pthread_mutex_lock(mtx) do {\ @@ -257,6 +257,7 @@ static const uint32_t abi_exception_class = static bool isCXXException(uint64_t cls) { + (void) abi_exception_class; return (cls == exception_class) || (cls == dependent_exception_class); } @@ -294,7 +295,7 @@ static terminate_handler terminateHandler = abort; static unexpected_handler unexpectedHandler = std::terminate; /** Key used for thread-local data. */ -static pthread_key_t eh_key; +//static pthread_key_t eh_key; /** @@ -354,7 +355,7 @@ static void thread_cleanup(void* thread_info) /** * Once control used to protect the key creation. */ -static pthread_once_t once_control = PTHREAD_ONCE_INIT; +//static pthread_once_t once_control = PTHREAD_ONCE_INIT; /** * We may not be linked against a full pthread implementation. If we're not, @@ -371,17 +372,18 @@ static __cxa_thread_info singleThreadInfo; */ static void init_key(void) { - if ((0 == pthread_key_create) || - (0 == pthread_setspecific) || - (0 == pthread_getspecific)) - { + //if ((0 == pthread_key_create) || + //(0 == pthread_setspecific) || + //(0 == pthread_getspecific)) + //{ fakeTLS = true; return; - } - pthread_key_create(&eh_key, thread_cleanup); - pthread_setspecific(eh_key, reinterpret_cast(0x42)); - fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast(0x42)); - pthread_setspecific(eh_key, 0); + //} + (void) thread_cleanup; + //pthread_key_create(&eh_key, thread_cleanup); + //pthread_setspecific(eh_key, reinterpret_cast(0x42)); + //fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast(0x42)); + //pthread_setspecific(eh_key, 0); } /** @@ -389,18 +391,19 @@ static void init_key(void) */ static __cxa_thread_info *thread_info() { - if ((0 == pthread_once) || pthread_once(&once_control, init_key)) - { + (void) init_key; + //if ((0 == pthread_once) || pthread_once(&once_control, init_key)) + //{ fakeTLS = true; - } - if (fakeTLS) { return &singleThreadInfo; } - __cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); - if (0 == info) - { - info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info))); - pthread_setspecific(eh_key, info); - } - return info; + //} + if (fakeTLS || true ) { return &singleThreadInfo; } + //__cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); + //if (0 == info) + //{ + //info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info))); + //pthread_setspecific(eh_key, info); + //} + //return info; } /** * Fast version of thread_info(). May fail if thread_info() is not called on @@ -408,8 +411,8 @@ static __cxa_thread_info *thread_info() */ static __cxa_thread_info *thread_info_fast() { - if (fakeTLS) { return &singleThreadInfo; } - return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); + if (fakeTLS || true) { return &singleThreadInfo; } + //return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); } /** * ABI function returning the __cxa_eh_globals structure. @@ -439,12 +442,12 @@ static bool buffer_allocated[16]; /** * Lock used to protect emergency allocation. */ -static pthread_mutex_t emergency_malloc_lock = PTHREAD_MUTEX_INITIALIZER; +//static pthread_mutex_t emergency_malloc_lock = PTHREAD_MUTEX_INITIALIZER; /** * Condition variable used to wait when two threads are both trying to use the * emergency malloc() buffer at once. */ -static pthread_cond_t emergency_malloc_wait = PTHREAD_COND_INITIALIZER; +//static pthread_cond_t emergency_malloc_wait = PTHREAD_COND_INITIALIZER; /** * Allocates size bytes from the emergency allocation mechanism, if possible. @@ -460,7 +463,7 @@ static char *emergency_malloc(size_t size) // Only 4 emergency buffers allowed per thread! if (info->emergencyBuffersHeld > 3) { return 0; } - pthread_mutex_lock(&emergency_malloc_lock); + //pthread_mutex_lock(&emergency_malloc_lock); int buffer = -1; while (buffer < 0) { @@ -468,10 +471,10 @@ static char *emergency_malloc(size_t size) // enough memory for us to use, so try the allocation again - no point // using the emergency buffer if there is some real memory that we can // use... - void *m = calloc(1, size); + void *m = cxxruntime::calloc(1, size); if (0 != m) { - pthread_mutex_unlock(&emergency_malloc_lock); + //pthread_mutex_unlock(&emergency_malloc_lock); return static_cast(m); } for (int i=0 ; i<16 ; i++) @@ -488,10 +491,14 @@ static char *emergency_malloc(size_t size) // of the emergency buffers. if (buffer < 0) { - pthread_cond_wait(&emergency_malloc_wait, &emergency_malloc_lock); + //pthread_cond_wait(&emergency_malloc_wait, &emergency_malloc_lock); + printf( "OH SHIT!" ); + uprintf( "OH SHIT!" ); + while( true ); + panic( "OH SHIT!!!!!!!" ); } } - pthread_mutex_unlock(&emergency_malloc_lock); + //pthread_mutex_unlock(&emergency_malloc_lock); info->emergencyBuffersHeld++; return emergency_buffer + (1024 * buffer); } @@ -524,18 +531,18 @@ static void emergency_malloc_free(char *ptr) memset(ptr, 0, 1024); // Signal the condition variable to wake up any threads that are blocking // waiting for some space in the emergency buffer - pthread_mutex_lock(&emergency_malloc_lock); +// pthread_mutex_lock(&emergency_malloc_lock); // In theory, we don't need to do this with the lock held. In practice, // our array of bools will probably be updated using 32-bit or 64-bit // memory operations, so this update may clobber adjacent values. buffer_allocated[buffer] = false; - pthread_cond_signal(&emergency_malloc_wait); - pthread_mutex_unlock(&emergency_malloc_lock); +// pthread_cond_signal(&emergency_malloc_wait); +// pthread_mutex_unlock(&emergency_malloc_lock); } static char *alloc_or_die(size_t size) { - char *buffer = static_cast(calloc(1, size)); + char *buffer = static_cast(cxxruntime::calloc(1, size)); // If calloc() doesn't want to give us any memory, try using an emergency // buffer. @@ -563,7 +570,7 @@ static void free_exception(char *e) } else { - free(e); + cxxruntime::free(e); } } @@ -650,6 +657,7 @@ void __cxa_free_dependent_exception(void *thrown_exception) * Note: As of FreeBSD 8.1, dladd() still doesn't work properly, so this only * correctly prints function names from public, relocatable, symbols. */ +#if 0 static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c) { Dl_info myinfo; @@ -666,6 +674,7 @@ static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c) } return _URC_CONTINUE_UNWIND; } +#endif /** * Report a failure that occurred when attempting to throw an exception. @@ -713,17 +722,17 @@ static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exce } size_t bufferSize = 128; - char *demangled = static_cast(malloc(bufferSize)); + char *demangled = static_cast(cxxruntime::malloc(bufferSize)); const char *mangled = thrown_exception->exceptionType->name(); int status; demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status); fprintf(stderr, " of type %s\n", status == 0 ? demangled : mangled); - if (status == 0) { free(demangled); } + if (status == 0) { cxxruntime::free(demangled); } // Print a back trace if no handler is found. // TODO: Make this optional #ifndef __arm__ - _Unwind_Backtrace(trace, 0); + //_Unwind_Backtrace(trace, 0); #endif // Just abort. No need to call std::terminate for the second time @@ -1435,7 +1444,7 @@ namespace std * Terminates the program, calling a custom terminate implementation if * required. */ - void terminate() + void userland_terminate() { static __cxa_thread_info *info = thread_info(); if (0 != info && 0 != info->terminateHandler) @@ -1498,6 +1507,7 @@ namespace std return ATOMIC_LOAD(&terminateHandler); } } +#if 0 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) extern "C" _Unwind_Exception *__cxa_get_cleanup(void) { @@ -1533,3 +1543,4 @@ asm ( ".popsection \n" ); #endif +#endif