It seems to link, and I need Unwind now.

I'm too tired to mess with this.  I'll probably break something.
Time to go to bed.
This commit is contained in:
2015-05-03 03:53:52 -04:00
parent db2bda84c8
commit aa17f3857f
7 changed files with 120 additions and 57 deletions

View File

@ -3,12 +3,14 @@ SRCS = libcpprt_entry.c libcpprt.cc
RUNTIME_SOURCES = c++_runtime.cc c++_exceptions_runtime.cc RUNTIME_SOURCES = c++_runtime.cc c++_exceptions_runtime.cc
.PATH: ${.CURDIR}/runtime .PATH: ${.CURDIR}/runtime
#RUNTIME_SOURCES+= typeinfo.cc libelftc_dem_gnu3.c dynamic_cast.cc RUNTIME_SOURCES+= typeinfo.cc libelftc_dem_gnu3.c dynamic_cast.cc
#RUNTIME_SOURCES+= exception.cc RUNTIME_SOURCES+= exception.cc
RUNTIME_SOURCES+= auxhelper.cc guard.cc memory.cc stdexcept.cc terminate.cc
SRCS+= $(RUNTIME_SOURCES) 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 CFLAGS+= -I. -Iinclude
.include <bsd.kmod.mk> .include <bsd.kmod.mk>

View File

@ -10,4 +10,9 @@ namespace cpp_runtime
{ {
panic( "Catch not implemented." ); panic( "Catch not implemented." );
} }
void *catch_impl_end( void *e ) noexcept
{
panic( "Catch not implemented." );
}
} }

View File

@ -10,6 +10,10 @@ extern "C"
extern "C" void *__cxa_begin_catch( void *e ) noexcept; extern "C" void *__cxa_begin_catch( void *e ) noexcept;
#include <stdlib.h> #include <stdlib.h>
namespace cxxruntime
{
MALLOC_DECLARE( cxxruntime_pool );
}
namespace std 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 namespace cpp_runtime
{ {
void *catch_impl( void *e ) noexcept; void *catch_impl( void *e ) noexcept;
void *catch_impl_end( void *e ) noexcept;
} }
extern "C" void * extern "C" void *
__cxa_begin_catch( void *e ) noexcept disabled__cxa_begin_catch( void *e ) noexcept
{ {
return cpp_runtime::catch_impl( e ); 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 //namespace __cxxabiv1
//{ //{
@ -68,19 +78,25 @@ namespace cxxruntime
void * void *
malloc( std::size_t s ) malloc( std::size_t s )
{ {
return malloc( s, cxxruntime_pool, M_WAITOK ); return ::malloc( s, cxxruntime_pool, M_WAITOK );
} }
void * void *
realloc( void *p, std::size_t s ) realloc( void *p, std::size_t s )
{ {
return realloc( p, s, cxxruntime_pool, M_WAITOK ); return ::realloc( p, s, cxxruntime_pool, M_WAITOK );
} }
void void
free( void *p ) 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" ); panic( "C++ Runtime: abort" );
} }
#if 0
typedef enum typedef enum
{ {
_URC_OK = 0, /* operation completed successfully */ _URC_OK = 0, /* operation completed successfully */
@ -125,6 +143,7 @@ abort()
_URC_FAILURE = 9, /* unspecified failure of some kind */ _URC_FAILURE = 9, /* unspecified failure of some kind */
_URC_FATAL_PHASE1_ERROR = _URC_FAILURE _URC_FATAL_PHASE1_ERROR = _URC_FAILURE
} _Unwind_Reason_Code; } _Unwind_Reason_Code;
struct _Unwind_Exception; struct _Unwind_Exception;
struct _Unwind_Context; struct _Unwind_Context;
typedef uint32_t _Unwind_State; 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, extern "C" _Unwind_Reason_Code __gxx_personality_v0(_Unwind_State state,
struct _Unwind_Exception *exceptionObject, struct _Unwind_Exception *exceptionObject,
struct _Unwind_Context *context){abort();} struct _Unwind_Context *context){abort();}
#endif

View File

@ -0,0 +1,12 @@
#include <sys/types.h>
#include <sys/systm.h>
#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__ )

View File

@ -18,6 +18,8 @@ namespace cxxruntime
extern void *malloc( std::size_t ); extern void *malloc( std::size_t );
extern void *realloc(void *, std::size_t); extern void *realloc(void *, std::size_t);
extern void free(void *); extern void free(void *);
extern void *calloc( std::size_t, std::size_t );
} }
#define __extern_c extern "C" #define __extern_c extern "C"
#else #else

View File

@ -32,15 +32,26 @@ class TestingImpl : public Testing
void void
libcpprt_entry() libcpprt_entry()
try
{ {
uprintf( "Hello\n" ); uprintf( "Hello\n" );
if( 1 ) tester= new TestingImpl(); tester= new TestingImpl();
tester->core();
}
catch( ... )
{
} }
void void
libcpprt_close() libcpprt_close()
try
{ {
uprintf( "Goodbye\n" ); uprintf( "Goodbye\n" );
if( 1 ) delete tester; tester->core();
delete tester;
}
catch( ... )
{
} }

View File

@ -35,10 +35,10 @@
#include "atomic.h" #include "atomic.h"
#include "cxxabi.h" #include "cxxabi.h"
#pragma weak pthread_key_create //#pragma weak pthread_key_create
#pragma weak pthread_setspecific //#pragma weak pthread_setspecific
#pragma weak pthread_getspecific //#pragma weak pthread_getspecific
#pragma weak pthread_once //#pragma weak pthread_once
#ifdef LIBCXXRT_WEAK_LOCKS #ifdef LIBCXXRT_WEAK_LOCKS
#pragma weak pthread_mutex_lock #pragma weak pthread_mutex_lock
#define pthread_mutex_lock(mtx) do {\ #define pthread_mutex_lock(mtx) do {\
@ -257,6 +257,7 @@ static const uint32_t abi_exception_class =
static bool isCXXException(uint64_t cls) static bool isCXXException(uint64_t cls)
{ {
(void) abi_exception_class;
return (cls == exception_class) || (cls == dependent_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; static unexpected_handler unexpectedHandler = std::terminate;
/** Key used for thread-local data. */ /** 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. * 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, * 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) static void init_key(void)
{ {
if ((0 == pthread_key_create) || //if ((0 == pthread_key_create) ||
(0 == pthread_setspecific) || //(0 == pthread_setspecific) ||
(0 == pthread_getspecific)) //(0 == pthread_getspecific))
{ //{
fakeTLS = true; fakeTLS = true;
return; return;
} //}
pthread_key_create(&eh_key, thread_cleanup); (void) thread_cleanup;
pthread_setspecific(eh_key, reinterpret_cast<void *>(0x42)); //pthread_key_create(&eh_key, thread_cleanup);
fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast<void *>(0x42)); //pthread_setspecific(eh_key, reinterpret_cast<void *>(0x42));
pthread_setspecific(eh_key, 0); //fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast<void *>(0x42));
//pthread_setspecific(eh_key, 0);
} }
/** /**
@ -389,18 +391,19 @@ static void init_key(void)
*/ */
static __cxa_thread_info *thread_info() 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; fakeTLS = true;
} //}
if (fakeTLS) { return &singleThreadInfo; } if (fakeTLS || true ) { return &singleThreadInfo; }
__cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); //__cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key));
if (0 == info) //if (0 == info)
{ //{
info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info))); //info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info)));
pthread_setspecific(eh_key, info); //pthread_setspecific(eh_key, info);
} //}
return info; //return info;
} }
/** /**
* Fast version of thread_info(). May fail if thread_info() is not called on * 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() static __cxa_thread_info *thread_info_fast()
{ {
if (fakeTLS) { return &singleThreadInfo; } if (fakeTLS || true) { return &singleThreadInfo; }
return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); //return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key));
} }
/** /**
* ABI function returning the __cxa_eh_globals structure. * ABI function returning the __cxa_eh_globals structure.
@ -439,12 +442,12 @@ static bool buffer_allocated[16];
/** /**
* Lock used to protect emergency allocation. * 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 * Condition variable used to wait when two threads are both trying to use the
* emergency malloc() buffer at once. * 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. * 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! // Only 4 emergency buffers allowed per thread!
if (info->emergencyBuffersHeld > 3) { return 0; } if (info->emergencyBuffersHeld > 3) { return 0; }
pthread_mutex_lock(&emergency_malloc_lock); //pthread_mutex_lock(&emergency_malloc_lock);
int buffer = -1; int buffer = -1;
while (buffer < 0) 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 // 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 // using the emergency buffer if there is some real memory that we can
// use... // use...
void *m = calloc(1, size); void *m = cxxruntime::calloc(1, size);
if (0 != m) if (0 != m)
{ {
pthread_mutex_unlock(&emergency_malloc_lock); //pthread_mutex_unlock(&emergency_malloc_lock);
return static_cast<char*>(m); return static_cast<char*>(m);
} }
for (int i=0 ; i<16 ; i++) for (int i=0 ; i<16 ; i++)
@ -488,10 +491,14 @@ static char *emergency_malloc(size_t size)
// of the emergency buffers. // of the emergency buffers.
if (buffer < 0) 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++; info->emergencyBuffersHeld++;
return emergency_buffer + (1024 * buffer); return emergency_buffer + (1024 * buffer);
} }
@ -524,18 +531,18 @@ static void emergency_malloc_free(char *ptr)
memset(ptr, 0, 1024); memset(ptr, 0, 1024);
// Signal the condition variable to wake up any threads that are blocking // Signal the condition variable to wake up any threads that are blocking
// waiting for some space in the emergency buffer // 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, // 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 // our array of bools will probably be updated using 32-bit or 64-bit
// memory operations, so this update may clobber adjacent values. // memory operations, so this update may clobber adjacent values.
buffer_allocated[buffer] = false; buffer_allocated[buffer] = false;
pthread_cond_signal(&emergency_malloc_wait); // pthread_cond_signal(&emergency_malloc_wait);
pthread_mutex_unlock(&emergency_malloc_lock); // pthread_mutex_unlock(&emergency_malloc_lock);
} }
static char *alloc_or_die(size_t size) static char *alloc_or_die(size_t size)
{ {
char *buffer = static_cast<char*>(calloc(1, size)); char *buffer = static_cast<char*>(cxxruntime::calloc(1, size));
// If calloc() doesn't want to give us any memory, try using an emergency // If calloc() doesn't want to give us any memory, try using an emergency
// buffer. // buffer.
@ -563,7 +570,7 @@ static void free_exception(char *e)
} }
else 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 * Note: As of FreeBSD 8.1, dladd() still doesn't work properly, so this only
* correctly prints function names from public, relocatable, symbols. * correctly prints function names from public, relocatable, symbols.
*/ */
#if 0
static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c) static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c)
{ {
Dl_info myinfo; Dl_info myinfo;
@ -666,6 +674,7 @@ static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c)
} }
return _URC_CONTINUE_UNWIND; return _URC_CONTINUE_UNWIND;
} }
#endif
/** /**
* Report a failure that occurred when attempting to throw an exception. * 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; size_t bufferSize = 128;
char *demangled = static_cast<char*>(malloc(bufferSize)); char *demangled = static_cast<char*>(cxxruntime::malloc(bufferSize));
const char *mangled = thrown_exception->exceptionType->name(); const char *mangled = thrown_exception->exceptionType->name();
int status; int status;
demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status); demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status);
fprintf(stderr, " of type %s\n", fprintf(stderr, " of type %s\n",
status == 0 ? demangled : mangled); status == 0 ? demangled : mangled);
if (status == 0) { free(demangled); } if (status == 0) { cxxruntime::free(demangled); }
// Print a back trace if no handler is found. // Print a back trace if no handler is found.
// TODO: Make this optional // TODO: Make this optional
#ifndef __arm__ #ifndef __arm__
_Unwind_Backtrace(trace, 0); //_Unwind_Backtrace(trace, 0);
#endif #endif
// Just abort. No need to call std::terminate for the second time // 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 * Terminates the program, calling a custom terminate implementation if
* required. * required.
*/ */
void terminate() void userland_terminate()
{ {
static __cxa_thread_info *info = thread_info(); static __cxa_thread_info *info = thread_info();
if (0 != info && 0 != info->terminateHandler) if (0 != info && 0 != info->terminateHandler)
@ -1498,6 +1507,7 @@ namespace std
return ATOMIC_LOAD(&terminateHandler); return ATOMIC_LOAD(&terminateHandler);
} }
} }
#if 0
#if defined(__arm__) && !defined(__ARM_DWARF_EH__) #if defined(__arm__) && !defined(__ARM_DWARF_EH__)
extern "C" _Unwind_Exception *__cxa_get_cleanup(void) extern "C" _Unwind_Exception *__cxa_get_cleanup(void)
{ {
@ -1533,3 +1543,4 @@ asm (
".popsection \n" ".popsection \n"
); );
#endif #endif
#endif