Home | History | Annotate | Line # | Download | only in libgcc
unwind.inc revision 1.1
      1  1.1  mrg /* Exception handling and frame unwind runtime interface routines. -*- C -*-
      2  1.1  mrg    Copyright (C) 2001-2013 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg    This file is part of GCC.
      5  1.1  mrg 
      6  1.1  mrg    GCC is free software; you can redistribute it and/or modify it
      7  1.1  mrg    under the terms of the GNU General Public License as published by
      8  1.1  mrg    the Free Software Foundation; either version 3, or (at your option)
      9  1.1  mrg    any later version.
     10  1.1  mrg 
     11  1.1  mrg    GCC is distributed in the hope that it will be useful, but WITHOUT
     12  1.1  mrg    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13  1.1  mrg    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14  1.1  mrg    License for more details.
     15  1.1  mrg 
     16  1.1  mrg    Under Section 7 of GPL version 3, you are granted additional
     17  1.1  mrg    permissions described in the GCC Runtime Library Exception, version
     18  1.1  mrg    3.1, as published by the Free Software Foundation.
     19  1.1  mrg 
     20  1.1  mrg    You should have received a copy of the GNU General Public License and
     21  1.1  mrg    a copy of the GCC Runtime Library Exception along with this program;
     22  1.1  mrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     24  1.1  mrg 
     25  1.1  mrg /* This is derived from the C++ ABI for IA-64.  Where we diverge
     26  1.1  mrg    for cross-architecture compatibility are noted with "@@@".
     27  1.1  mrg    This file is included from unwind-dw2.c, unwind-sjlj.c or
     28  1.1  mrg    unwind-ia64.c.  */
     29  1.1  mrg 
     30  1.1  mrg /* Subroutine of _Unwind_RaiseException also invoked from _Unwind_Resume.
     31  1.1  mrg 
     32  1.1  mrg    Unwind the stack calling the personality routine to find both the
     33  1.1  mrg    exception handler and intermediary cleanup code.  We'll only locate
     34  1.1  mrg    the first such frame here.  Cleanup code will call back into
     35  1.1  mrg    _Unwind_Resume and we'll continue Phase 2 there.  */
     36  1.1  mrg 
     37  1.1  mrg static _Unwind_Reason_Code
     38  1.1  mrg _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
     39  1.1  mrg 			      struct _Unwind_Context *context)
     40  1.1  mrg {
     41  1.1  mrg   _Unwind_Reason_Code code;
     42  1.1  mrg 
     43  1.1  mrg   while (1)
     44  1.1  mrg     {
     45  1.1  mrg       _Unwind_FrameState fs;
     46  1.1  mrg       int match_handler;
     47  1.1  mrg 
     48  1.1  mrg       code = uw_frame_state_for (context, &fs);
     49  1.1  mrg 
     50  1.1  mrg       /* Identify when we've reached the designated handler context.  */
     51  1.1  mrg       match_handler = (uw_identify_context (context) == exc->private_2
     52  1.1  mrg 		       ? _UA_HANDLER_FRAME : 0);
     53  1.1  mrg 
     54  1.1  mrg       if (code != _URC_NO_REASON)
     55  1.1  mrg 	/* Some error encountered.  Usually the unwinder doesn't
     56  1.1  mrg 	   diagnose these and merely crashes.  */
     57  1.1  mrg 	return _URC_FATAL_PHASE2_ERROR;
     58  1.1  mrg 
     59  1.1  mrg       /* Unwind successful.  Run the personality routine, if any.  */
     60  1.1  mrg       if (fs.personality)
     61  1.1  mrg 	{
     62  1.1  mrg 	  code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler,
     63  1.1  mrg 				    exc->exception_class, exc, context);
     64  1.1  mrg 	  if (code == _URC_INSTALL_CONTEXT)
     65  1.1  mrg 	    break;
     66  1.1  mrg 	  if (code != _URC_CONTINUE_UNWIND)
     67  1.1  mrg 	    return _URC_FATAL_PHASE2_ERROR;
     68  1.1  mrg 	}
     69  1.1  mrg 
     70  1.1  mrg       /* Don't let us unwind past the handler context.  */
     71  1.1  mrg       gcc_assert (!match_handler);
     72  1.1  mrg 
     73  1.1  mrg       uw_update_context (context, &fs);
     74  1.1  mrg     }
     75  1.1  mrg 
     76  1.1  mrg   return code;
     77  1.1  mrg }
     78  1.1  mrg 
     79  1.1  mrg /* Raise an exception, passing along the given exception object.  */
     80  1.1  mrg 
     81  1.1  mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
     82  1.1  mrg _Unwind_RaiseException(struct _Unwind_Exception *exc)
     83  1.1  mrg {
     84  1.1  mrg   struct _Unwind_Context this_context, cur_context;
     85  1.1  mrg   _Unwind_Reason_Code code;
     86  1.1  mrg 
     87  1.1  mrg   /* Set up this_context to describe the current stack frame.  */
     88  1.1  mrg   uw_init_context (&this_context);
     89  1.1  mrg   cur_context = this_context;
     90  1.1  mrg 
     91  1.1  mrg   /* Phase 1: Search.  Unwind the stack, calling the personality routine
     92  1.1  mrg      with the _UA_SEARCH_PHASE flag set.  Do not modify the stack yet.  */
     93  1.1  mrg   while (1)
     94  1.1  mrg     {
     95  1.1  mrg       _Unwind_FrameState fs;
     96  1.1  mrg 
     97  1.1  mrg       /* Set up fs to describe the FDE for the caller of cur_context.  The
     98  1.1  mrg 	 first time through the loop, that means __cxa_throw.  */
     99  1.1  mrg       code = uw_frame_state_for (&cur_context, &fs);
    100  1.1  mrg 
    101  1.1  mrg       if (code == _URC_END_OF_STACK)
    102  1.1  mrg 	/* Hit end of stack with no handler found.  */
    103  1.1  mrg 	return _URC_END_OF_STACK;
    104  1.1  mrg 
    105  1.1  mrg       if (code != _URC_NO_REASON)
    106  1.1  mrg 	/* Some error encountered.  Usually the unwinder doesn't
    107  1.1  mrg 	   diagnose these and merely crashes.  */
    108  1.1  mrg 	return _URC_FATAL_PHASE1_ERROR;
    109  1.1  mrg 
    110  1.1  mrg       /* Unwind successful.  Run the personality routine, if any.  */
    111  1.1  mrg       if (fs.personality)
    112  1.1  mrg 	{
    113  1.1  mrg 	  code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class,
    114  1.1  mrg 				    exc, &cur_context);
    115  1.1  mrg 	  if (code == _URC_HANDLER_FOUND)
    116  1.1  mrg 	    break;
    117  1.1  mrg 	  else if (code != _URC_CONTINUE_UNWIND)
    118  1.1  mrg 	    return _URC_FATAL_PHASE1_ERROR;
    119  1.1  mrg 	}
    120  1.1  mrg 
    121  1.1  mrg       /* Update cur_context to describe the same frame as fs.  */
    122  1.1  mrg       uw_update_context (&cur_context, &fs);
    123  1.1  mrg     }
    124  1.1  mrg 
    125  1.1  mrg   /* Indicate to _Unwind_Resume and associated subroutines that this
    126  1.1  mrg      is not a forced unwind.  Further, note where we found a handler.  */
    127  1.1  mrg   exc->private_1 = 0;
    128  1.1  mrg   exc->private_2 = uw_identify_context (&cur_context);
    129  1.1  mrg 
    130  1.1  mrg   cur_context = this_context;
    131  1.1  mrg   code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
    132  1.1  mrg   if (code != _URC_INSTALL_CONTEXT)
    133  1.1  mrg     return code;
    134  1.1  mrg 
    135  1.1  mrg   uw_install_context (&this_context, &cur_context);
    136  1.1  mrg }
    137  1.1  mrg 
    138  1.1  mrg 
    139  1.1  mrg /* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume.  */
    140  1.1  mrg 
    141  1.1  mrg static _Unwind_Reason_Code
    142  1.1  mrg _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
    143  1.1  mrg 			     struct _Unwind_Context *context)
    144  1.1  mrg {
    145  1.1  mrg   _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
    146  1.1  mrg   void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
    147  1.1  mrg   _Unwind_Reason_Code code, stop_code;
    148  1.1  mrg 
    149  1.1  mrg   while (1)
    150  1.1  mrg     {
    151  1.1  mrg       _Unwind_FrameState fs;
    152  1.1  mrg       int action;
    153  1.1  mrg 
    154  1.1  mrg       /* Set up fs to describe the FDE for the caller of cur_context.  */
    155  1.1  mrg       code = uw_frame_state_for (context, &fs);
    156  1.1  mrg       if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
    157  1.1  mrg 	return _URC_FATAL_PHASE2_ERROR;
    158  1.1  mrg 
    159  1.1  mrg       /* Unwind successful.  */
    160  1.1  mrg       action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;
    161  1.1  mrg       if (code == _URC_END_OF_STACK)
    162  1.1  mrg 	action |= _UA_END_OF_STACK;
    163  1.1  mrg       stop_code = (*stop) (1, action, exc->exception_class, exc,
    164  1.1  mrg 			   context, stop_argument);
    165  1.1  mrg       if (stop_code != _URC_NO_REASON)
    166  1.1  mrg 	return _URC_FATAL_PHASE2_ERROR;
    167  1.1  mrg 
    168  1.1  mrg       /* Stop didn't want to do anything.  Invoke the personality
    169  1.1  mrg 	 handler, if applicable, to run cleanups.  */
    170  1.1  mrg       if (code == _URC_END_OF_STACK)
    171  1.1  mrg 	break;
    172  1.1  mrg 
    173  1.1  mrg       if (fs.personality)
    174  1.1  mrg 	{
    175  1.1  mrg 	  code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE,
    176  1.1  mrg 				    exc->exception_class, exc, context);
    177  1.1  mrg 	  if (code == _URC_INSTALL_CONTEXT)
    178  1.1  mrg 	    break;
    179  1.1  mrg 	  if (code != _URC_CONTINUE_UNWIND)
    180  1.1  mrg 	    return _URC_FATAL_PHASE2_ERROR;
    181  1.1  mrg 	}
    182  1.1  mrg 
    183  1.1  mrg       /* Update cur_context to describe the same frame as fs, and discard
    184  1.1  mrg 	 the previous context if necessary.  */
    185  1.1  mrg       uw_advance_context (context, &fs);
    186  1.1  mrg     }
    187  1.1  mrg 
    188  1.1  mrg   return code;
    189  1.1  mrg }
    190  1.1  mrg 
    191  1.1  mrg 
    192  1.1  mrg /* Raise an exception for forced unwinding.  */
    193  1.1  mrg 
    194  1.1  mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
    195  1.1  mrg _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
    196  1.1  mrg 		      _Unwind_Stop_Fn stop, void * stop_argument)
    197  1.1  mrg {
    198  1.1  mrg   struct _Unwind_Context this_context, cur_context;
    199  1.1  mrg   _Unwind_Reason_Code code;
    200  1.1  mrg 
    201  1.1  mrg   uw_init_context (&this_context);
    202  1.1  mrg   cur_context = this_context;
    203  1.1  mrg 
    204  1.1  mrg   exc->private_1 = (_Unwind_Ptr) stop;
    205  1.1  mrg   exc->private_2 = (_Unwind_Ptr) stop_argument;
    206  1.1  mrg 
    207  1.1  mrg   code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
    208  1.1  mrg   if (code != _URC_INSTALL_CONTEXT)
    209  1.1  mrg     return code;
    210  1.1  mrg 
    211  1.1  mrg   uw_install_context (&this_context, &cur_context);
    212  1.1  mrg }
    213  1.1  mrg 
    214  1.1  mrg 
    215  1.1  mrg /* Resume propagation of an existing exception.  This is used after
    216  1.1  mrg    e.g. executing cleanup code, and not to implement rethrowing.  */
    217  1.1  mrg 
    218  1.1  mrg void LIBGCC2_UNWIND_ATTRIBUTE
    219  1.1  mrg _Unwind_Resume (struct _Unwind_Exception *exc)
    220  1.1  mrg {
    221  1.1  mrg   struct _Unwind_Context this_context, cur_context;
    222  1.1  mrg   _Unwind_Reason_Code code;
    223  1.1  mrg 
    224  1.1  mrg   uw_init_context (&this_context);
    225  1.1  mrg   cur_context = this_context;
    226  1.1  mrg 
    227  1.1  mrg   /* Choose between continuing to process _Unwind_RaiseException
    228  1.1  mrg      or _Unwind_ForcedUnwind.  */
    229  1.1  mrg   if (exc->private_1 == 0)
    230  1.1  mrg     code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
    231  1.1  mrg   else
    232  1.1  mrg     code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
    233  1.1  mrg 
    234  1.1  mrg   gcc_assert (code == _URC_INSTALL_CONTEXT);
    235  1.1  mrg 
    236  1.1  mrg   uw_install_context (&this_context, &cur_context);
    237  1.1  mrg }
    238  1.1  mrg 
    239  1.1  mrg 
    240  1.1  mrg /* Resume propagation of an FORCE_UNWIND exception, or to rethrow
    241  1.1  mrg    a normal exception that was handled.  */
    242  1.1  mrg 
    243  1.1  mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
    244  1.1  mrg _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
    245  1.1  mrg {
    246  1.1  mrg   struct _Unwind_Context this_context, cur_context;
    247  1.1  mrg   _Unwind_Reason_Code code;
    248  1.1  mrg 
    249  1.1  mrg   /* Choose between continuing to process _Unwind_RaiseException
    250  1.1  mrg      or _Unwind_ForcedUnwind.  */
    251  1.1  mrg   if (exc->private_1 == 0)
    252  1.1  mrg     return _Unwind_RaiseException (exc);
    253  1.1  mrg 
    254  1.1  mrg   uw_init_context (&this_context);
    255  1.1  mrg   cur_context = this_context;
    256  1.1  mrg 
    257  1.1  mrg   code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
    258  1.1  mrg 
    259  1.1  mrg   gcc_assert (code == _URC_INSTALL_CONTEXT);
    260  1.1  mrg 
    261  1.1  mrg   uw_install_context (&this_context, &cur_context);
    262  1.1  mrg }
    263  1.1  mrg 
    264  1.1  mrg 
    265  1.1  mrg /* A convenience function that calls the exception_cleanup field.  */
    266  1.1  mrg 
    267  1.1  mrg void
    268  1.1  mrg _Unwind_DeleteException (struct _Unwind_Exception *exc)
    269  1.1  mrg {
    270  1.1  mrg   if (exc->exception_cleanup)
    271  1.1  mrg     (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
    272  1.1  mrg }
    273  1.1  mrg 
    274  1.1  mrg 
    275  1.1  mrg /* Perform stack backtrace through unwind data.  */
    276  1.1  mrg 
    277  1.1  mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
    278  1.1  mrg _Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
    279  1.1  mrg {
    280  1.1  mrg   struct _Unwind_Context context;
    281  1.1  mrg   _Unwind_Reason_Code code;
    282  1.1  mrg 
    283  1.1  mrg   uw_init_context (&context);
    284  1.1  mrg 
    285  1.1  mrg   while (1)
    286  1.1  mrg     {
    287  1.1  mrg       _Unwind_FrameState fs;
    288  1.1  mrg 
    289  1.1  mrg       /* Set up fs to describe the FDE for the caller of context.  */
    290  1.1  mrg       code = uw_frame_state_for (&context, &fs);
    291  1.1  mrg       if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
    292  1.1  mrg 	return _URC_FATAL_PHASE1_ERROR;
    293  1.1  mrg 
    294  1.1  mrg       /* Call trace function.  */
    295  1.1  mrg       if ((*trace) (&context, trace_argument) != _URC_NO_REASON)
    296  1.1  mrg 	return _URC_FATAL_PHASE1_ERROR;
    297  1.1  mrg 
    298  1.1  mrg       /* We're done at end of stack.  */
    299  1.1  mrg       if (code == _URC_END_OF_STACK)
    300  1.1  mrg 	break;
    301  1.1  mrg 
    302  1.1  mrg       /* Update context to describe the same frame as fs.  */
    303  1.1  mrg       uw_update_context (&context, &fs);
    304  1.1  mrg     }
    305  1.1  mrg 
    306  1.1  mrg   return code;
    307  1.1  mrg }
    308