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; } } }
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; } } }