Ejemplo n.º 1
0
static void
get_action_description_for (_Unwind_Ptr ip,
                            _Unwind_Exception *uw_exception,
                            _Unwind_Action uw_phase,
                            region_descriptor *region,
                            action_descriptor *action)
{
  _GNAT_Exception *gnat_exception = (_GNAT_Exception *) uw_exception;

  /* Search the call site table first, which may get us a landing pad as well
     as the head of an action record list.  */
  get_call_site_action_for (ip, region, action);
  db_action_for (action, ip);

  /* If there is not even a call_site entry, we are done.  */
  if (action->kind == nothing)
    return;

  /* Otherwise, check what we have at the place of the call site.  */

  /* No landing pad => no cleanups or handlers.  */
  if (action->landing_pad == 0)
    {
      action->kind = nothing;
      return;
    }

  /* Landing pad + null table entry => only cleanups.  */
  else if (action->table_entry == 0)
    {
      action->kind = cleanup;
      action->ttype_filter = cleanup_filter;
      /* The filter initialization is not strictly necessary, as cleanup-only
	 landing pads don't look at the filter value.  It is there to ensure
	 we don't pass random values and so trigger potential confusion when
	 installing the context later on.  */
      return;
    }

  /* Landing pad + Table entry => handlers + possible cleanups.  */
  else
    {
      const unsigned char * p = action->table_entry;

      _sleb128_t ar_filter, ar_disp;

      action->kind = nothing;

      while (1)
	{
	  p = read_sleb128 (p, &ar_filter);
	  read_sleb128 (p, &ar_disp);
	  /* Don't assign p here, as it will be incremented by ar_disp
	     below.  */

	  /* Null filters are for cleanups. */
	  if (ar_filter == cleanup_filter)
	    {
	      action->kind = cleanup;
	      action->ttype_filter = cleanup_filter;
	      /* The filter initialization is required here, to ensure
		 the target landing pad branches to the cleanup code if
		 we happen not to find a matching handler.  */
	    }

	  /* Positive filters are for regular handlers.  */
	  else if (ar_filter > 0)
	    {
              /* Do not catch an exception if the _UA_FORCE_UNWIND flag is
                 passed (to follow the ABI).  */
              if (!(uw_phase & _UA_FORCE_UNWIND))
                {
		  enum action_kind act;

                  /* See if the filter we have is for an exception which
                     matches the one we are propagating.  */
                  _Unwind_Ptr choice = get_ttype_entry_for (region, ar_filter);

		  act = is_handled_by (choice, gnat_exception);
                  if (act != nothing)
                    {
		      action->kind = act;
                      action->ttype_filter = ar_filter;
                      return;
                    }
                }
	    }

	  /* Negative filter values are for C++ exception specifications.
	     Should not be there for Ada :/  */
	  else
	    db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");

	  if (ar_disp == 0)
	    return;

	  p += ar_disp;
	}
    }
}
Ejemplo n.º 2
0
Archivo: raise.c Proyecto: aosm/gcc_40
static void
get_action_description_for (_Unwind_Context *uw_context,
                            _Unwind_Exception *uw_exception,
                            region_descriptor *region,
                            action_descriptor *action)
{
  _GNAT_Exception * gnat_exception = (_GNAT_Exception *) uw_exception;

  /* Search the call site table first, which may get us a landing pad as well
     as the head of an action record list.  */
  get_call_site_action_for (uw_context, region, action);
  db_action_for (action, uw_context);

  /* If there is not even a call_site entry, we are done.  */
  if (action->kind == nothing)
    return;

  /* Otherwise, check what we have at the place of the call site  */

  /* No landing pad => no cleanups or handlers.  */
  if (action->landing_pad == 0)
    {
      action->kind = nothing;
      return;
    }

  /* Landing pad + null table entry => only cleanups.  */
  else if (action->table_entry == 0)
    {
      action->kind = cleanup;
      return;
    }

  /* Landing pad + Table entry => handlers + possible cleanups.  */
  else
    {
      const unsigned char * p = action->table_entry;

      _Unwind_Sword ar_filter, ar_disp;

      action->kind = nothing;

      while (1)
	{
	  p = read_sleb128 (p, &ar_filter);
	  read_sleb128 (p, &ar_disp);
	  /* Don't assign p here, as it will be incremented by ar_disp
	     below.  */

	  /* Null filters are for cleanups. */
	  if (ar_filter == 0)
	    action->kind = cleanup;

	  /* Positive filters are for regular handlers.  */
	  else if (ar_filter > 0)
	    {
	      /* See if the filter we have is for an exception which matches
		 the one we are propagating.  */
	      _Unwind_Ptr choice = get_ttype_entry_for (region, ar_filter);

	      if (is_handled_by (choice, gnat_exception))
		{
		  action->ttype_filter = ar_filter;
		  action->ttype_entry = choice;
		  action->kind = handler;
		  return;
		}
	    }

	  /* Negative filter values are for C++ exception specifications.
	     Should not be there for Ada :/  */
	  else
	    db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");

	  if (ar_disp == 0)
	    return;

	  p += ar_disp;
	}
    }
}