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:
8
Makefile
8
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 <bsd.kmod.mk>
|
||||
|
@ -10,4 +10,9 @@ namespace cpp_runtime
|
||||
{
|
||||
panic( "Catch not implemented." );
|
||||
}
|
||||
|
||||
void *catch_impl_end( void *e ) noexcept
|
||||
{
|
||||
panic( "Catch not implemented." );
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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__ )
|
||||
|
@ -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
|
||||
|
15
libcpprt.cc
15
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( ... )
|
||||
{
|
||||
}
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user