diff options
author | Dan Albert <danalbert@google.com> | 2015-06-17 11:09:54 -0700 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2015-06-17 14:15:22 -0700 |
commit | f378ebf14df0952eae870c9865bab8326aa8f137 (patch) | |
tree | 31794503eb2a8c64ea5f313b93100f1163afcffb /gcc-4.6/libobjc/exception.c | |
parent | 2c58169824949d3a597d9fa81931e001ef9b1bd0 (diff) | |
download | toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.tar.gz toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.tar.bz2 toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.zip |
Delete old versions of GCC.
Change-Id: I710f125d905290e1024cbd67f48299861790c66c
Diffstat (limited to 'gcc-4.6/libobjc/exception.c')
-rw-r--r-- | gcc-4.6/libobjc/exception.c | 551 |
1 files changed, 0 insertions, 551 deletions
diff --git a/gcc-4.6/libobjc/exception.c b/gcc-4.6/libobjc/exception.c deleted file mode 100644 index 1ffb80b53..000000000 --- a/gcc-4.6/libobjc/exception.c +++ /dev/null @@ -1,551 +0,0 @@ -/* The implementation of exception handling primitives for Objective-C. - Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -GCC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "objc-private/common.h" -#include <stdlib.h> -#include "config.h" -#include "objc/runtime.h" -#include "objc/objc-exception.h" -#include "unwind.h" -#include "unwind-pe.h" -#include <string.h> /* For memcpy */ - -/* This hook allows libraries to sepecify special actions when an - exception is thrown without a handler in place. This is deprecated - in favour of objc_set_uncaught_exception_handler (). */ -void (*_objc_unexpected_exception) (id exception); /* !T:SAFE */ - - -/* 'is_kind_of_exception_matcher' is our default exception matcher - - it determines if the object 'exception' is of class 'catch_class', - or of a subclass. */ -static int -is_kind_of_exception_matcher (Class catch_class, id exception) -{ - /* NULL catch_class is catch-all (eg, @catch (id object)). */ - if (catch_class == Nil) - return 1; - - /* If exception is nil (eg, @throw nil;), then it can only be - catched by a catch-all (eg, @catch (id object)). */ - if (exception != nil) - { - Class c; - - for (c = exception->class_pointer; c != Nil; - c = class_getSuperclass (c)) - if (c == catch_class) - return 1; - } - return 0; -} - -/* The exception matcher currently in use. */ -static objc_exception_matcher -__objc_exception_matcher = is_kind_of_exception_matcher; - -objc_exception_matcher -objc_setExceptionMatcher (objc_exception_matcher new_matcher) -{ - objc_exception_matcher old_matcher = __objc_exception_matcher; - __objc_exception_matcher = new_matcher; - return old_matcher; -} - -/* The uncaught exception handler currently in use. */ -static objc_uncaught_exception_handler -__objc_uncaught_exception_handler = NULL; - -objc_uncaught_exception_handler -objc_setUncaughtExceptionHandler (objc_uncaught_exception_handler - new_handler) -{ - objc_uncaught_exception_handler old_handler - = __objc_uncaught_exception_handler; - __objc_uncaught_exception_handler = new_handler; - return old_handler; -} - - - -#ifdef __ARM_EABI_UNWINDER__ - -const _Unwind_Exception_Class __objc_exception_class - = {'G', 'N', 'U', 'C', 'O', 'B', 'J', 'C'}; - -#else - -/* This is the exception class we report -- "GNUCOBJC". */ -static const _Unwind_Exception_Class __objc_exception_class - = ((((((((_Unwind_Exception_Class) 'G' - << 8 | (_Unwind_Exception_Class) 'N') - << 8 | (_Unwind_Exception_Class) 'U') - << 8 | (_Unwind_Exception_Class) 'C') - << 8 | (_Unwind_Exception_Class) 'O') - << 8 | (_Unwind_Exception_Class) 'B') - << 8 | (_Unwind_Exception_Class) 'J') - << 8 | (_Unwind_Exception_Class) 'C'); - -#endif - -/* This is the object that is passed around by the Objective C runtime - to represent the exception in flight. */ -struct ObjcException -{ - /* This bit is needed in order to interact with the unwind runtime. */ - struct _Unwind_Exception base; - - /* The actual object we want to throw. Note: must come immediately - after unwind header. */ - id value; - -#ifdef __ARM_EABI_UNWINDER__ - /* Note: we use the barrier cache defined in the unwind control - block for ARM EABI. */ -#else - /* Cache some internal unwind data between phase 1 and phase 2. */ - _Unwind_Ptr landingPad; - int handlerSwitchValue; -#endif -}; - - - -struct lsda_header_info -{ - _Unwind_Ptr Start; - _Unwind_Ptr LPStart; - _Unwind_Ptr ttype_base; - const unsigned char *TType; - const unsigned char *action_table; - unsigned char ttype_encoding; - unsigned char call_site_encoding; -}; - -static const unsigned char * -parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p, - struct lsda_header_info *info) -{ - _uleb128_t tmp; - unsigned char lpstart_encoding; - - info->Start = (context ? _Unwind_GetRegionStart (context) : 0); - - /* Find @LPStart, the base to which landing pad offsets are - relative. */ - lpstart_encoding = *p++; - if (lpstart_encoding != DW_EH_PE_omit) - p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart); - else - info->LPStart = info->Start; - - /* Find @TType, the base of the handler and exception spec type - data. */ - info->ttype_encoding = *p++; - if (info->ttype_encoding != DW_EH_PE_omit) - { - p = read_uleb128 (p, &tmp); - info->TType = p + tmp; - } - else - info->TType = 0; - - /* The encoding and length of the call-site table; the action table - immediately follows. */ - info->call_site_encoding = *p++; - p = read_uleb128 (p, &tmp); - info->action_table = p + tmp; - - return p; -} - -#ifdef __ARM_EABI_UNWINDER__ - -static Class -get_ttype_entry (struct lsda_header_info *info, _uleb128_t i) -{ - _Unwind_Ptr ptr; - - ptr = (_Unwind_Ptr) (info->TType - (i * 4)); - ptr = _Unwind_decode_target2 (ptr); - - /* NULL ptr means catch-all. Note that if the class is not found, - this will abort the program. */ - if (ptr) - return objc_getRequiredClass ((const char *) ptr); - else - return 0; -} - -#else - -static Class -get_ttype_entry (struct lsda_header_info *info, _Unwind_Word i) -{ - _Unwind_Ptr ptr; - - i *= size_of_encoded_value (info->ttype_encoding); - read_encoded_value_with_base (info->ttype_encoding, info->ttype_base, - info->TType - i, &ptr); - - /* NULL ptr means catch-all. Note that if the class is not found, - this will abort the program. */ - if (ptr) - return objc_getRequiredClass ((const char *) ptr); - else - return 0; -} - -#endif - -/* Using a different personality function name causes link failures - when trying to mix code using different exception handling - models. */ -#ifdef SJLJ_EXCEPTIONS -#define PERSONALITY_FUNCTION __gnu_objc_personality_sj0 -#define __builtin_eh_return_data_regno(x) x -#else -#define PERSONALITY_FUNCTION __gnu_objc_personality_v0 -#endif - -#ifdef __ARM_EABI_UNWINDER__ - -#define CONTINUE_UNWINDING \ - do \ - { \ - if (__gnu_unwind_frame(ue_header, context) != _URC_OK) \ - return _URC_FAILURE; \ - return _URC_CONTINUE_UNWIND; \ - } \ - while (0) - -_Unwind_Reason_Code -PERSONALITY_FUNCTION (_Unwind_State state, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -#else - -#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND - -_Unwind_Reason_Code -PERSONALITY_FUNCTION (int version, - _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -#endif -{ - struct ObjcException *xh = (struct ObjcException *) ue_header; - - struct lsda_header_info info; - const unsigned char *language_specific_data; - const unsigned char *action_record; - const unsigned char *p; - _Unwind_Ptr landing_pad, ip; - int handler_switch_value; - int saw_cleanup = 0, saw_handler, foreign_exception; - void *return_object; - int ip_before_insn = 0; - -#ifdef __ARM_EABI_UNWINDER__ - _Unwind_Action actions; - - switch (state & _US_ACTION_MASK) - { - case _US_VIRTUAL_UNWIND_FRAME: - actions = _UA_SEARCH_PHASE; - break; - - case _US_UNWIND_FRAME_STARTING: - actions = _UA_CLEANUP_PHASE; - if (!(state & _US_FORCE_UNWIND) - && ue_header->barrier_cache.sp == _Unwind_GetGR (context, 13)) - actions |= _UA_HANDLER_FRAME; - break; - - case _US_UNWIND_FRAME_RESUME: - CONTINUE_UNWINDING; - break; - - default: - abort(); - } - actions |= state & _US_FORCE_UNWIND; - - /* TODO: Foreign exceptions need some attention (e.g. rethrowing - doesn't work). */ - foreign_exception = 0; - - /* The dwarf unwinder assumes the context structure holds things - like the function and LSDA pointers. The ARM implementation - caches these in the exception header (UCB). To avoid rewriting - everything we make the virtual IP register point at the UCB. */ - ip = (_Unwind_Ptr) ue_header; - _Unwind_SetGR (context, 12, ip); - -#else /* !__ARM_EABI_UNWINDER. */ - /* Interface version check. */ - if (version != 1) - return _URC_FATAL_PHASE1_ERROR; - - foreign_exception = (exception_class != __objc_exception_class); -#endif - - /* Shortcut for phase 2 found handler for domestic exception. */ - if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) - && !foreign_exception) - { -#ifdef __ARM_EABI_UNWINDER__ - handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1]; - landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3]; -#else - handler_switch_value = xh->handlerSwitchValue; - landing_pad = xh->landingPad; -#endif - goto install_context; - } - - language_specific_data = (const unsigned char *) - _Unwind_GetLanguageSpecificData (context); - - /* If no LSDA, then there are no handlers or cleanups. */ - if (! language_specific_data) - CONTINUE_UNWINDING; - - /* Parse the LSDA header. */ - p = parse_lsda_header (context, language_specific_data, &info); - info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); -#ifdef HAVE_GETIPINFO - ip = _Unwind_GetIPInfo (context, &ip_before_insn); -#else - ip = _Unwind_GetIP (context); -#endif - if (!ip_before_insn) - --ip; - landing_pad = 0; - action_record = 0; - handler_switch_value = 0; - -#ifdef SJLJ_EXCEPTIONS - /* The given "IP" is an index into the call-site table, with two - exceptions -- -1 means no-action, and 0 means terminate. But - since we're using uleb128 values, we've not got random access to - the array. */ - if ((int) ip < 0) - return _URC_CONTINUE_UNWIND; - else - { - _uleb128_t cs_lp, cs_action; - do - { - p = read_uleb128 (p, &cs_lp); - p = read_uleb128 (p, &cs_action); - } - while (--ip); - - /* Can never have null landing pad for sjlj -- that would have - been indicated by a -1 call site index. */ - landing_pad = cs_lp + 1; - if (cs_action) - action_record = info.action_table + cs_action - 1; - goto found_something; - } -#else - /* Search the call-site table for the action associated with this - IP. */ - while (p < info.action_table) - { - _Unwind_Ptr cs_start, cs_len, cs_lp; - _uleb128_t cs_action; - - /* Note that all call-site encodings are "absolute" - displacements. */ - p = read_encoded_value (0, info.call_site_encoding, p, &cs_start); - p = read_encoded_value (0, info.call_site_encoding, p, &cs_len); - p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp); - p = read_uleb128 (p, &cs_action); - - /* The table is sorted, so if we've passed the ip, stop. */ - if (ip < info.Start + cs_start) - p = info.action_table; - else if (ip < info.Start + cs_start + cs_len) - { - if (cs_lp) - landing_pad = info.LPStart + cs_lp; - if (cs_action) - action_record = info.action_table + cs_action - 1; - goto found_something; - } - } -#endif /* SJLJ_EXCEPTIONS */ - - /* If ip is not present in the table, C++ would call terminate. */ - /* ??? As with Java, it's perhaps better to tweek the LSDA to that - no-action is mapped to no-entry. */ - CONTINUE_UNWINDING; - - found_something: - saw_cleanup = 0; - saw_handler = 0; - - if (landing_pad == 0) - { - /* If ip is present, and has a null landing pad, there are no - cleanups or handlers to be run. */ - } - else if (action_record == 0) - { - /* If ip is present, has a non-null landing pad, and a null - action table offset, then there are only cleanups present. - Cleanups use a zero switch value, as set above. */ - saw_cleanup = 1; - } - else - { - /* Otherwise we have a catch handler. */ - _sleb128_t ar_filter, ar_disp; - - while (1) - { - p = action_record; - p = read_sleb128 (p, &ar_filter); - read_sleb128 (p, &ar_disp); - - if (ar_filter == 0) - { - /* Zero filter values are cleanups. */ - saw_cleanup = 1; - } - - /* During forced unwinding, we only run cleanups. With a - foreign exception class, we have no class info to - match. */ - else if ((actions & _UA_FORCE_UNWIND) || foreign_exception) - ; - - else if (ar_filter > 0) - { - /* Positive filter values are handlers. */ - Class catch_type = get_ttype_entry (&info, ar_filter); - - if ((*__objc_exception_matcher) (catch_type, xh->value)) - { - handler_switch_value = ar_filter; - saw_handler = 1; - break; - } - } - else - { - /* Negative filter values are exception specifications, - which Objective-C does not use. */ - abort (); - } - - if (ar_disp == 0) - break; - action_record = p + ar_disp; - } - } - - if (! saw_handler && ! saw_cleanup) - CONTINUE_UNWINDING; - - if (actions & _UA_SEARCH_PHASE) - { - if (!saw_handler) - CONTINUE_UNWINDING; - - /* For domestic exceptions, we cache data from phase 1 for phase - 2. */ - if (!foreign_exception) - { -#ifdef __ARM_EABI_UNWINDER__ - ue_header->barrier_cache.sp = _Unwind_GetGR (context, 13); - ue_header->barrier_cache.bitpattern[1] = (_uw) handler_switch_value; - ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad; -#else - xh->handlerSwitchValue = handler_switch_value; - xh->landingPad = landing_pad; -#endif - } - return _URC_HANDLER_FOUND; - } - - install_context: - if (saw_cleanup == 0) - { - return_object = xh->value; - if (!(actions & _UA_SEARCH_PHASE)) - _Unwind_DeleteException(&xh->base); - } - - _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), - __builtin_extend_pointer (saw_cleanup ? xh : return_object)); - _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), - handler_switch_value); - _Unwind_SetIP (context, landing_pad); - return _URC_INSTALL_CONTEXT; -} - -static void -__objc_exception_cleanup (_Unwind_Reason_Code code __attribute__((unused)), - struct _Unwind_Exception *exc) -{ - free (exc); -} - -void -objc_exception_throw (id exception) -{ - struct ObjcException *header = calloc (1, sizeof (*header)); - - memcpy (&header->base.exception_class, &__objc_exception_class, - sizeof (__objc_exception_class)); - header->base.exception_cleanup = __objc_exception_cleanup; - header->value = exception; - -#ifdef SJLJ_EXCEPTIONS - _Unwind_SjLj_RaiseException (&header->base); -#else - _Unwind_RaiseException (&header->base); -#endif - - /* No exception handler was installed. Call the uncaught exception - handler if any is defined. */ - if (__objc_uncaught_exception_handler != 0) - { - (*__objc_uncaught_exception_handler) (exception); - } - - /* As a last resort support the old, deprecated way of setting an - uncaught exception handler. */ - if (_objc_unexpected_exception != 0) - { - (*_objc_unexpected_exception) (exception); - } - - abort (); -} - |