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
.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 <bsd.kmod.mk>

View File

@ -10,4 +10,9 @@ namespace cpp_runtime
{
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;
#include <stdlib.h>
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

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 *realloc(void *, std::size_t);
extern void free(void *);
extern void *calloc( std::size_t, std::size_t );
}
#define __extern_c extern "C"
#else

View File

@ -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( ... )
{
}

View File

@ -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<void *>(0x42));
fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast<void *>(0x42));
pthread_setspecific(eh_key, 0);
//}
(void) thread_cleanup;
//pthread_key_create(&eh_key, thread_cleanup);
//pthread_setspecific(eh_key, reinterpret_cast<void *>(0x42));
//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()
{
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<char*>(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<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
// 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<char*>(malloc(bufferSize));
char *demangled = static_cast<char*>(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