This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][Ada] arm-linux sjlj port


On Mon, 2009-09-07 at 14:27 +0100, Richard Earnshaw wrote:
> However, I'm concerned that this
> short-term expediency will become a drag to long-term conformance.
> Sometimes it's important to get these things right from the beginning or
> the legacy will become impossible to eradicate.

Over the life of GNAT many ports switched from sjlj to zcx (1) and this
had no impact on users including big industrial users with millions LOC
Ada applications. The Ada world tend to be more self contained around
the language standard than the C world :).

Anyway, here is gcc/ada/raise-gcc.c personality:

_Unwind_Reason_Code
PERSONALITY_FUNCTION (version_arg_t version_arg,
                      phases_arg_t phases_arg,
                      _Unwind_Exception_Class uw_exception_class,
                      _Unwind_Exception *uw_exception,
                      _Unwind_Context *uw_context)
{
  /* Fetch the version and phases args with their nominal ABI types for later
     use. This is a noop everywhere except on ia64-vms when called from the
     Condition Handling Facility.  */
  int uw_version = (int) version_arg;
  _Unwind_Action uw_phases = (_Unwind_Action) phases_arg;

  _GNAT_Exception * gnat_exception = (_GNAT_Exception *) uw_exception;

  region_descriptor region;
  action_descriptor action;

  /* Check that we're called from the ABI context we expect, with a major
     possible variation on VMS for IA64.  */
  if (uw_version != 1)
    {
      return _URC_FATAL_PHASE1_ERROR;
    }

  db_indent (DB_INDENT_RESET);
  db_phases (uw_phases);
  db_indent (DB_INDENT_INCREASE);

  /* Get the region description for the context we were provided with. This
     will tell us if there is some lsda, call_site, action and/or ttype data
     for the associated ip.  */
  get_region_description_for (uw_context, &region);
  db_region_for (&region, uw_context);

  /* No LSDA => no handlers or cleanups => we shall unwind further up.  */
  if (! region.lsda)
    return _URC_CONTINUE_UNWIND;

  /* Search the call-site and action-record tables for the action associated
     with this IP.  */
  get_action_description_for (uw_context, uw_exception, &region, &action);
  db_action_for (&action, uw_context);

  /* Whatever the phase, if there is nothing relevant in this frame,
     unwinding should just go on.  */
  if (action.kind == nothing)
    return _URC_CONTINUE_UNWIND;

  /* If we found something in search phase, we should return a code indicating
     what to do next depending on what we found. If we only have cleanups
     around, we shall try to unwind further up to find a handler, otherwise,
     tell we have a handler, which will trigger the second phase.  */
  if (uw_phases & _UA_SEARCH_PHASE)
    {
      if (action.kind == cleanup)
	{
	  Adjust_N_Cleanups_For (gnat_exception, 1);
	  return _URC_CONTINUE_UNWIND;
	}
      else
	{
	  /* Trigger the appropriate notification routines before the second
	     phase starts, which ensures the stack is still intact. */
	  __gnat_notify_handled_exception ();

	  return _URC_HANDLER_FOUND;
	}
    }

  /* We found something in cleanup/handler phase, which might be the handler
     or a cleanup for a handled occurrence, or a cleanup for an unhandled
     occurrence (we are in a FORCED_UNWIND phase in this case). Install the
     context to get there.  */

  /* If we are going to install a cleanup context, decrement the cleanup
     count.  This is required in a FORCED_UNWINDing phase (for an unhandled
     exception), as this is used from the forced unwinding handler in
     Ada.Exceptions.Exception_Propagation to decide whether unwinding should
     proceed further or Unhandled_Exception_Terminate should be called.  */
  if (action.kind == cleanup)
    Adjust_N_Cleanups_For (gnat_exception, -1);

  setup_to_install
    (uw_context, uw_exception, action.landing_pad, action.ttype_filter);

  return _URC_INSTALL_CONTEXT;
}

Looking at libjava/exception.cc the ARM EABI unwinder seems to differ from the other 
platform versions by:

1/ spec of the personality function
2/ return _URC_CONTINUE_UNWIND => replaced by small CONTINUE_UNWINDING macro doing a bit more on ARM
3/ helper get_ttype_entry uses _Unwind_decode_target2 and formulae instead of size_of/read_encoded_value
4/ handle a few more state at the beginning of personality function, this looks like generic boilerplate.

I can try a "no understanding" update of gcc/ada/raise-gcc.c if an
EH/EABI expert tells me there's not much more to do (and understand :).

Thanks in advance,

Laurent

(1) IIRC GNAT was sjlj only for a long time.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]