Index: src/exceptions/OFException.m ================================================================== --- src/exceptions/OFException.m +++ src/exceptions/OFException.m @@ -57,10 +57,14 @@ * exceptions are implemented as a wrapper around DWARF exceptions. */ #ifdef HAVE_SEH_EXCEPTIONS # define HAVE_DWARF_EXCEPTIONS #endif + +#if defined(OF_ARM) && !defined(__ARM_DWARF_EH__) +# define HAVE_ARM_EHABI_EXCEPTIONS +#endif #ifdef HAVE_DWARF_EXCEPTIONS struct _Unwind_Context; typedef enum { _URC_OK = 0, @@ -72,14 +76,14 @@ uint8_t i; }; extern _Unwind_Reason_Code _Unwind_Backtrace( _Unwind_Reason_Code(*)(struct _Unwind_Context*, void*), void*); -# ifdef OF_ARM -extern int _Unwind_VRS_Get(struct _Unwind_Context*, int, uint32_t, int, void*); +# ifndef HAVE_ARM_EHABI_EXCEPTIONS +extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*); # else -extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*); +extern int _Unwind_VRS_Get(struct _Unwind_Context*, int, uint32_t, int, void*); # endif #endif #if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS) static of_mutex_t mutex; @@ -213,17 +217,17 @@ backtrace_callback(struct _Unwind_Context *ctx, void *data) { struct backtrace_ctx *bt = data; if (bt->i < OF_BACKTRACE_SIZE) { -# ifdef OF_ARM +# ifndef HAVE_ARM_EHABI_EXCEPTIONS + bt->backtrace[bt->i++] = (void*)_Unwind_GetIP(ctx); +# else uintptr_t ip; _Unwind_VRS_Get(ctx, 0, 15, 0, &ip); bt->backtrace[bt->i++] = (void*)(ip & ~1); -# else - bt->backtrace[bt->i++] = (void*)_Unwind_GetIP(ctx); # endif return _URC_OK; } return _URC_END_OF_STACK; Index: src/runtime/exception.m ================================================================== --- src/runtime/exception.m +++ src/runtime/exception.m @@ -36,10 +36,14 @@ #elif defined(HAVE_SEH_EXCEPTIONS) # define PERSONALITY gnu_objc_personality #else # error Unknown exception type! #endif + +#if defined(OF_ARM) && !defined(__ARM_DWARF_EH__) +# define HAVE_ARM_EHABI_EXCEPTIONS +#endif static const uint64_t objc_exception_class = 0x474E55434F424A43; /* GNUCOBJC */ #define _UA_SEARCH_PHASE 0x01 #define _UA_CLEANUP_PHASE 0x02 @@ -86,11 +90,21 @@ struct objc_exception { struct _Unwind_Exception { uint64_t class; void (*cleanup)(_Unwind_Reason_Code, struct _Unwind_Exception*); -#ifdef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS +# ifdef HAVE_SEH_EXCEPTIONS + uint64_t private[6]; +# else + /* + * The Itanium Exception ABI says to have those and never touch + * them. + */ + uint64_t private1, private2; +# endif +#else /* From "Exception Handling ABI for the ARM(R) Architecture" */ struct { uint32_t reserved1, reserved2, reserved3, reserved4; uint32_t reserved; } unwinder_cache; @@ -106,24 +120,14 @@ uint32_t *ehtp; uint32_t additional; uint32_t reserved1; } pr_cache; long long int : 0; -#else -# ifdef HAVE_SEH_EXCEPTIONS - uint64_t private[6]; -# else - /* - * The Itanium Exception ABI says to have those and never touch - * them. - */ - uint64_t private1, private2; -# endif #endif } exception; id object; -#ifndef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS uintptr_t landingpad; intptr_t filter; #endif }; @@ -141,11 +145,17 @@ extern void* _Unwind_GetLanguageSpecificData(struct _Unwind_Context*); extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context*); extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context*); extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context*); -#ifdef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS +# define CONTINUE_UNWIND return _URC_CONTINUE_UNWIND + +extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*); +extern void _Unwind_SetIP(struct _Unwind_Context*, uintptr_t); +extern void _Unwind_SetGR(struct _Unwind_Context*, int, uintptr_t); +#else extern _Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception*, struct _Unwind_Context*); extern int _Unwind_VRS_Get(struct _Unwind_Context*, int, uint32_t, int, void*); extern int _Unwind_VRS_Set(struct _Unwind_Context*, int, uint32_t, int, void*); @@ -181,16 +191,10 @@ _Unwind_SetIP(struct _Unwind_Context *ctx, uintptr_t value) { uintptr_t thumb = _Unwind_GetGR(ctx, 15) & 1; _Unwind_SetGR(ctx, 15, (value | thumb)); } -#else -# define CONTINUE_UNWIND return _URC_CONTINUE_UNWIND - -extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*); -extern void _Unwind_SetIP(struct _Unwind_Context*, uintptr_t); -extern void _Unwind_SetGR(struct _Unwind_Context*, int, uintptr_t); #endif #ifdef HAVE_SEH_EXCEPTIONS extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void*, PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code(*)(int, int, uint64_t, @@ -314,11 +318,11 @@ #undef READ return value; } -#ifndef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS static uint64_t resolve_value(uint64_t value, uint8_t enc, const uint8_t *start, uint64_t base) { if (value == 0) return 0; @@ -461,28 +465,28 @@ Class class; const char *className; uintptr_t c; const uint8_t *tmp; -#ifdef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS + uintptr_t i; + + i = filter * size_for_encoding(lsda->typestable_enc); + tmp = lsda->typestable - i; + c = (uintptr_t)read_value(lsda->typestable_enc, &tmp); + c = (uintptr_t)resolve_value(c, lsda->typestable_enc, + lsda->typestable - i, lsda->typestable_base); +#else tmp = lsda->typestable - (filter * 4); c = *(uintptr_t*)(void*)tmp; if (c != 0) { c += (uintptr_t)tmp; # if defined(OF_LINUX) || defined(OF_NETBSD) c = *(uintptr_t*)c; # endif } -#else - uintptr_t i; - - i = filter * size_for_encoding(lsda->typestable_enc); - tmp = lsda->typestable - i; - c = (uintptr_t)read_value(lsda->typestable_enc, &tmp); - c = (uintptr_t)resolve_value(c, lsda->typestable_enc, - lsda->typestable - i, lsda->typestable_base); #endif className = (const char*)c; if (className != NULL && *className != '\0' && @@ -502,11 +506,19 @@ } while (displacement != 0); return 0; } -#ifdef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS +# ifdef HAVE_SEH_EXCEPTIONS +static +# endif +_Unwind_Reason_Code +PERSONALITY(int version, int actions, uint64_t ex_class, + struct _Unwind_Exception *ex, struct _Unwind_Context *ctx) +{ +#else _Unwind_Reason_Code PERSONALITY(uint32_t state, struct _Unwind_Exception *ex, struct _Unwind_Context *ctx) { int version = 1; @@ -527,18 +539,10 @@ default: return _URC_FAILURE; } _Unwind_SetGR(ctx, 12, (uintptr_t)ex); -#else -# ifdef HAVE_SEH_EXCEPTIONS -static -# endif -_Unwind_Reason_Code -PERSONALITY(int version, int actions, uint64_t ex_class, - struct _Unwind_Exception *ex, struct _Unwind_Context *ctx) -{ #endif struct objc_exception *e = (struct objc_exception*)ex; bool foreign = (ex_class != objc_exception_class); const uint8_t *lsda_addr, *actionrecords; struct lsda lsda; @@ -558,18 +562,18 @@ * For handlers, reg #0 must be the exception's object and reg * #1 the filter. */ _Unwind_SetGR(ctx, __builtin_eh_return_data_regno(0), (uintptr_t)e->object); -#ifdef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS + _Unwind_SetGR(ctx, __builtin_eh_return_data_regno(1), + e->filter); + _Unwind_SetIP(ctx, e->landingpad); +#else _Unwind_SetGR(ctx, __builtin_eh_return_data_regno(1), ex->barrier_cache.bitpattern[1]); _Unwind_SetIP(ctx, ex->barrier_cache.bitpattern[3]); -#else - _Unwind_SetGR(ctx, __builtin_eh_return_data_regno(1), - e->filter); - _Unwind_SetIP(ctx, e->landingpad); #endif _Unwind_DeleteException(ex); return _URC_INSTALL_CONTEXT; @@ -596,17 +600,17 @@ if (actions & _UA_SEARCH_PHASE) { if (!(found & HANDLER_FOUND) || foreign) CONTINUE_UNWIND; /* Cache it so we don't have to search it again in phase 2 */ -#ifdef OF_ARM +#ifndef HAVE_ARM_EHABI_EXCEPTIONS + e->landingpad = landingpad; + e->filter = filter; +#else ex->barrier_cache.sp = _Unwind_GetGR(ctx, 13); ex->barrier_cache.bitpattern[1] = filter; ex->barrier_cache.bitpattern[3] = landingpad; -#else - e->landingpad = landingpad; - e->filter = filter; #endif return _URC_HANDLER_FOUND; } else if (actions & _UA_CLEANUP_PHASE) { if (!(found & CLEANUP_FOUND))