1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 1992-2011, Free Software Foundation, Inc. *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 3, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. *
18 * As a special exception under Section 7 of GPL version 3, you are granted *
19 * additional permissions described in the GCC Runtime Library Exception, *
20 * version 3.1, as published by the Free Software Foundation. *
22 * You should have received a copy of the GNU General Public License and *
23 * a copy of the GCC Runtime Library Exception along with this program; *
24 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
25 * <http://www.gnu.org/licenses/>. *
27 * GNAT was originally developed by the GNAT team at New York University. *
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
30 ****************************************************************************/
32 /* Code related to the integration of the GCC mechanism for exception
52 /* On MacOS X, versions older than 10.5 don't export _Unwind_GetIPInfo. */
54 #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
55 #define HAVE_GETIPINFO 1
59 /* The names of a couple of "standard" routines for unwinding/propagation
60 actually vary depending on the underlying GCC scheme for exception handling
61 (SJLJ or DWARF). We need a consistently named interface to import from
62 a-except, so wrappers are defined here.
64 Besides, even though the compiler is never setup to use the GCC propagation
65 circuitry, it still relies on exceptions internally and part of the sources
66 to handle to exceptions are shared with the run-time library. We need
67 dummy definitions for the wrappers to satisfy the linker in this case.
69 The types to be used by those wrappers in the run-time library are target
70 types exported by unwind.h. We used to piggyback on them for the compiler
71 stubs, but there is no guarantee that unwind.h is always in sight so we
72 define our own set below. These are dummy types as the wrappers are never
73 called in the compiler case. */
79 typedef struct _Unwind_Context _Unwind_Context;
80 typedef struct _Unwind_Exception _Unwind_Exception;
84 typedef void _Unwind_Context;
85 typedef void _Unwind_Exception;
86 typedef int _Unwind_Reason_Code;
91 __gnat_Unwind_RaiseException (_Unwind_Exception *);
94 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *, void *, void *);
96 extern void __gnat_setup_current_excep (_Unwind_Exception *);
98 #ifdef IN_RTS /* For eh personality routine */
101 #include "unwind-dw2-fde.h"
102 #include "unwind-pe.h"
104 /* The known and handled exception classes. */
106 #define CXX_EXCEPTION_CLASS 0x474e5543432b2b00ULL
107 #define GNAT_EXCEPTION_CLASS 0x474e552d41646100ULL
109 /* --------------------------------------------------------------
110 -- The DB stuff below is there for debugging purposes only. --
111 -------------------------------------------------------------- */
113 #define DB_PHASES 0x1
115 #define DB_ACTIONS 0x4
116 #define DB_REGIONS 0x8
118 #define DB_ERR 0x1000
120 /* The "action" stuff below is also there for debugging purposes only. */
124 _Unwind_Action phase;
125 const char * description;
128 static const phase_descriptor phase_descriptors[]
129 = {{ _UA_SEARCH_PHASE, "SEARCH_PHASE" },
130 { _UA_CLEANUP_PHASE, "CLEANUP_PHASE" },
131 { _UA_HANDLER_FRAME, "HANDLER_FRAME" },
132 { _UA_FORCE_UNWIND, "FORCE_UNWIND" },
136 db_accepted_codes (void)
138 static int accepted_codes = -1;
140 if (accepted_codes == -1)
142 char * db_env = (char *) getenv ("EH_DEBUG");
144 accepted_codes = db_env ? (atoi (db_env) | DB_ERR) : 0;
145 /* Arranged for ERR stuff to always be visible when the variable
146 is defined. One may just set the variable to 0 to see the ERR
150 return accepted_codes;
153 #define DB_INDENT_INCREASE 0x01
154 #define DB_INDENT_DECREASE 0x02
155 #define DB_INDENT_OUTPUT 0x04
156 #define DB_INDENT_NEWLINE 0x08
157 #define DB_INDENT_RESET 0x10
159 #define DB_INDENT_UNIT 8
162 db_indent (int requests)
164 static int current_indentation_level = 0;
166 if (requests & DB_INDENT_RESET)
168 current_indentation_level = 0;
171 if (requests & DB_INDENT_INCREASE)
173 current_indentation_level ++;
176 if (requests & DB_INDENT_DECREASE)
178 current_indentation_level --;
181 if (requests & DB_INDENT_NEWLINE)
183 fprintf (stderr, "\n");
186 if (requests & DB_INDENT_OUTPUT)
188 fprintf (stderr, "%*s",
189 current_indentation_level * DB_INDENT_UNIT, " ");
194 static void ATTRIBUTE_PRINTF_2
195 db (int db_code, char * msg_format, ...)
197 if (db_accepted_codes () & db_code)
201 db_indent (DB_INDENT_OUTPUT);
203 va_start (msg_args, msg_format);
204 vfprintf (stderr, msg_format, msg_args);
210 db_phases (int phases)
212 const phase_descriptor *a = phase_descriptors;
214 if (! (db_accepted_codes() & DB_PHASES))
217 db (DB_PHASES, "\n");
219 for (; a->description != 0; a++)
220 if (phases & a->phase)
221 db (DB_PHASES, "%s ", a->description);
223 db (DB_PHASES, " :\n");
227 /* ---------------------------------------------------------------
228 -- Now come a set of useful structures and helper routines. --
229 --------------------------------------------------------------- */
231 /* There are three major runtime tables involved, generated by the
232 GCC back-end. Contents slightly vary depending on the underlying
233 implementation scheme (dwarf zero cost / sjlj).
235 =======================================
236 * Tables for the dwarf zero cost case *
237 =======================================
240 -------------------------------------------------------------------
241 * region-start | region-length | landing-pad | first-action-index *
242 -------------------------------------------------------------------
244 Identify possible actions to be taken and where to resume control
245 for that when an exception propagates through a pc inside the region
246 delimited by start and length.
248 A null landing-pad indicates that nothing is to be done.
250 Otherwise, first-action-index provides an entry into the action[]
251 table which heads a list of possible actions to be taken (see below).
253 If it is determined that indeed an action should be taken, that
254 is, if one action filter matches the exception being propagated,
255 then control should be transfered to landing-pad.
257 A null first-action-index indicates that there are only cleanups
261 -------------------------------
262 * action-filter | next-action *
263 -------------------------------
265 This table contains lists (called action chains) of possible actions
266 associated with call-site entries described in the call-site [] table.
267 There is at most one action list per call-site entry.
269 A null action-filter indicates a cleanup.
271 Non null action-filters provide an index into the ttypes [] table
272 (see below), from which information may be retrieved to check if it
273 matches the exception being propagated.
275 action-filter > 0 means there is a regular handler to be run,
277 action-filter < 0 means there is a some "exception_specification"
278 data to retrieve, which is only relevant for C++
279 and should never show up for Ada.
281 next-action indexes the next entry in the list. 0 indicates there is
289 A null value indicates a catch-all handler in C++, and an "others"
292 Non null values are used to match the exception being propagated:
293 In C++ this is a pointer to some rtti data, while in Ada this is an
296 The special id value 1 indicates an "all_others" handler.
298 For C++, this table is actually also used to store "exception
299 specification" data. The differentiation between the two kinds
300 of entries is made by the sign of the associated action filter,
301 which translates into positive or negative offsets from the
302 so called base of the table:
304 Exception Specification data is stored at positive offsets from
305 the ttypes table base, which Exception Type data is stored at
308 ---------------------------------------------------------------------------
310 Here is a quick summary of the tables organization:
312 +-- Unwind_Context (pc, ...)
318 | +=============================================================+
319 | | region-start + length | landing-pad | first-action-index |
320 | +=============================================================+
321 +-> | pc range 0 => no-action 0 => cleanups only |
322 | !0 => jump @ N --+ |
323 +====================================================== | ====+
328 +==========================================================+ |
329 | action-filter | next-action | |
330 +==========================================================+ |
332 | >0 => ttype index for handler ------+ 0 => end of chain | <-+
333 | <0 => ttype index for spec data | |
334 +==================================== | ===================+
338 | Offset negated from
339 +=====================+ | the actual base.
341 +============+=====================+ |
342 | | 0 => "others" | |
343 | ... | 1 => "all others" | <---+
344 | | X => exception id |
345 | handlers +---------------------+
349 +============+=====================+ <<------ Table base
351 | specs | ... | (should not see negative filter
352 | ... | ... | values for Ada).
353 +============+=====================+
356 ============================
357 * Tables for the sjlj case *
358 ============================
360 So called "function contexts" are pushed on a context stack by calls to
361 _Unwind_SjLj_Register on function entry, and popped off at exit points by
362 calls to _Unwind_SjLj_Unregister. The current call_site for a function is
363 updated in the function context as the function's code runs along.
365 The generic unwinding engine in _Unwind_RaiseException walks the function
366 context stack and not the actual call chain.
368 The ACTION and TTYPES tables remain unchanged, which allows to search them
369 during the propagation phase to determine whether or not the propagated
370 exception is handled somewhere. When it is, we only "jump" up once directly
371 to the context where the handler will be found. Besides, this allows "break
372 exception unhandled" to work also
374 The CALL-SITE table is setup differently, though: the pc attached to the
375 unwind context is a direct index into the table, so the entries in this
376 table do not hold region bounds any more.
378 A special index (-1) is used to indicate that no action is possibly
379 connected with the context at hand, so null landing pads cannot appear
382 Additionally, landing pad values in the table do not represent code address
383 to jump at, but so called "dispatch" indices used by a common landing pad
384 for the function to switch to the appropriate post-landing-pad.
386 +-- Unwind_Context (pc, ...)
388 | pc = call-site index
389 | 0 => terminate (should not see this for Ada)
394 | +=====================================+
395 | | landing-pad | first-action-index |
396 | +=====================================+
397 +-> | 0 => cleanups only |
399 +=====================================+
402 ===================================
403 * Basic organization of this unit *
404 ===================================
406 The major point of this unit is to provide an exception propagation
407 personality routine for Ada. This is __gnat_personality_v0.
409 It is provided with a pointer to the propagated exception, an unwind
410 context describing a location the propagation is going through, and a
411 couple of other arguments including a description of the current
414 It shall return to the generic propagation engine what is to be performed
415 next, after possible context adjustments, depending on what it finds in the
416 traversed context (a handler for the exception, a cleanup, nothing, ...),
417 and on the propagation phase.
419 A number of structures and subroutines are used for this purpose, as
422 o region_descriptor: General data associated with the context (base pc,
423 call-site table, action table, ttypes table, ...)
425 o action_descriptor: Data describing the action to be taken for the
426 propagated exception in the provided context (kind of action: nothing,
427 handler, cleanup; pointer to the action table entry, ...).
433 Propagate_Exception (a-exexpr.adb)
436 _Unwind_RaiseException (libgcc)
440 +--> __gnat_personality_v0 (context, exception)
442 +--> get_region_descriptor_for (context)
444 +--> get_action_descriptor_for (context, exception, region)
446 | +--> get_call_site_action_for (context, region)
447 | (one version for each underlying scheme)
449 +--> setup_to_install (context)
451 This unit is inspired from the C++ version found in eh_personality.cc,
452 part of libstdc++-v3.
457 /* This is an incomplete "proxy" of the structure of exception objects as
458 built by the GNAT runtime library. Accesses to other fields than the common
459 header are performed through subprogram calls to alleviate the need of an
460 exact counterpart here and potential alignment/size issues for the common
461 header. See a-exexpr.adb. */
465 _Unwind_Exception common;
466 /* ABI header, maximally aligned. */
469 /* The two constants below are specific ttype identifiers for special
470 exception ids. Their type should match what a-exexpr exports. */
472 extern const int __gnat_others_value;
473 #define GNAT_OTHERS ((_Unwind_Ptr) &__gnat_others_value)
475 extern const int __gnat_all_others_value;
476 #define GNAT_ALL_OTHERS ((_Unwind_Ptr) &__gnat_all_others_value)
478 /* Describe the useful region data associated with an unwind context. */
482 /* The base pc of the region. */
485 /* Pointer to the Language Specific Data for the region. */
488 /* Call-Site data associated with this region. */
489 unsigned char call_site_encoding;
490 const unsigned char *call_site_table;
492 /* The base to which are relative landing pad offsets inside the call-site
496 /* Action-Table associated with this region. */
497 const unsigned char *action_table;
499 /* Ttype data associated with this region. */
500 unsigned char ttype_encoding;
501 const unsigned char *ttype_table;
502 _Unwind_Ptr ttype_base;
506 /* Extract and adjust the IP (instruction pointer) from an exception
510 get_ip_from_context (_Unwind_Context *uw_context)
512 int ip_before_insn = 0;
513 #ifdef HAVE_GETIPINFO
514 _Unwind_Ptr ip = _Unwind_GetIPInfo (uw_context, &ip_before_insn);
516 _Unwind_Ptr ip = _Unwind_GetIP (uw_context);
518 /* Subtract 1 if necessary because GetIPInfo yields a call return address
519 in this case, while we are interested in information for the call point.
520 This does not always yield the exact call instruction address but always
521 brings the IP back within the corresponding region. */
529 db_region_for (region_descriptor *region, _Unwind_Context *uw_context)
533 if (! (db_accepted_codes () & DB_REGIONS))
536 ip = get_ip_from_context (uw_context);
538 db (DB_REGIONS, "For ip @ 0x%08x => ", ip);
541 db (DB_REGIONS, "lsda @ 0x%x", region->lsda);
543 db (DB_REGIONS, "no lsda");
545 db (DB_REGIONS, "\n");
548 /* Retrieve the ttype entry associated with FILTER in the REGION's
551 static const _Unwind_Ptr
552 get_ttype_entry_for (region_descriptor *region, long filter)
554 _Unwind_Ptr ttype_entry;
556 filter *= size_of_encoded_value (region->ttype_encoding);
557 read_encoded_value_with_base
558 (region->ttype_encoding, region->ttype_base,
559 region->ttype_table - filter, &ttype_entry);
564 /* Fill out the REGION descriptor for the provided UW_CONTEXT. */
567 get_region_description_for (_Unwind_Context *uw_context,
568 region_descriptor *region)
570 const unsigned char * p;
572 unsigned char lpbase_encoding;
574 /* Get the base address of the lsda information. If the provided context
575 is null or if there is no associated language specific data, there's
576 nothing we can/should do. */
578 = (_Unwind_Ptr) (uw_context
579 ? _Unwind_GetLanguageSpecificData (uw_context) : 0);
584 /* Parse the lsda and fill the region descriptor. */
585 p = (char *)region->lsda;
587 region->base = _Unwind_GetRegionStart (uw_context);
589 /* Find @LPStart, the base to which landing pad offsets are relative. */
590 lpbase_encoding = *p++;
591 if (lpbase_encoding != DW_EH_PE_omit)
592 p = read_encoded_value
593 (uw_context, lpbase_encoding, p, ®ion->lp_base);
595 region->lp_base = region->base;
597 /* Find @TType, the base of the handler and exception spec type data. */
598 region->ttype_encoding = *p++;
599 if (region->ttype_encoding != DW_EH_PE_omit)
601 p = read_uleb128 (p, &tmp);
602 region->ttype_table = p + tmp;
605 region->ttype_table = 0;
608 = base_of_encoded_value (region->ttype_encoding, uw_context);
610 /* Get the encoding and length of the call-site table; the action table
611 immediately follows. */
612 region->call_site_encoding = *p++;
613 region->call_site_table = read_uleb128 (p, &tmp);
615 region->action_table = region->call_site_table + tmp;
619 /* Describe an action to be taken when propagating an exception up to
624 /* Found some call site base data, but need to analyze further
625 before being able to decide. */
628 /* There is nothing relevant in the context at hand. */
631 /* There are only cleanups to run in this context. */
634 /* There is a handler for the exception in this context. */
638 /* filter value for cleanup actions. */
639 static const int cleanup_filter = 0;
643 /* The kind of action to be taken. */
646 /* A pointer to the action record entry. */
647 const unsigned char *table_entry;
649 /* Where we should jump to actually take an action (trigger a cleanup or an
650 exception handler). */
651 _Unwind_Ptr landing_pad;
653 /* If we have a handler matching our exception, these are the filter to
654 trigger it and the corresponding id. */
655 _Unwind_Sword ttype_filter;
656 _Unwind_Ptr ttype_entry;
661 db_action_for (action_descriptor *action, _Unwind_Context *uw_context)
663 _Unwind_Ptr ip = get_ip_from_context (uw_context);
665 db (DB_ACTIONS, "For ip @ 0x%08x => ", ip);
667 switch (action->kind)
670 db (DB_ACTIONS, "lpad @ 0x%x, record @ 0x%x\n",
671 action->landing_pad, action->table_entry);
675 db (DB_ACTIONS, "Nothing\n");
679 db (DB_ACTIONS, "Cleanup\n");
683 db (DB_ACTIONS, "Handler, filter = %d\n", action->ttype_filter);
687 db (DB_ACTIONS, "Err? Unexpected action kind !\n");
694 /* Search the call_site_table of REGION for an entry appropriate for the
695 UW_CONTEXT's IP. If one is found, store the associated landing_pad
696 and action_table entry, and set the ACTION kind to unknown for further
697 analysis. Otherwise, set the ACTION kind to nothing.
699 There are two variants of this routine, depending on the underlying
700 mechanism (DWARF/SJLJ), which account for differences in the tables. */
702 #ifdef __USING_SJLJ_EXCEPTIONS__
704 #define __builtin_eh_return_data_regno(x) x
707 get_call_site_action_for (_Unwind_Context *uw_context,
708 region_descriptor *region,
709 action_descriptor *action)
711 _Unwind_Ptr call_site = get_ip_from_context (uw_context);
713 /* call_site is a direct index into the call-site table, with two special
714 values : -1 for no-action and 0 for "terminate". The latter should never
715 show up for Ada. To test for the former, beware that _Unwind_Ptr might
718 if ((int)call_site < 0)
720 action->kind = nothing;
723 else if (call_site == 0)
725 db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n");
726 action->kind = nothing;
731 _uleb128_t cs_lp, cs_action;
733 /* Let the caller know there may be an action to take, but let it
734 determine the kind. */
735 action->kind = unknown;
737 /* We have a direct index into the call-site table, but this table is
738 made of leb128 values, the encoding length of which is variable. We
739 can't merely compute an offset from the index, then, but have to read
740 all the entries before the one of interest. */
742 const unsigned char *p = region->call_site_table;
745 p = read_uleb128 (p, &cs_lp);
746 p = read_uleb128 (p, &cs_action);
747 } while (--call_site);
749 action->landing_pad = cs_lp + 1;
752 action->table_entry = region->action_table + cs_action - 1;
754 action->table_entry = 0;
760 #else /* !__USING_SJLJ_EXCEPTIONS__ */
763 get_call_site_action_for (_Unwind_Context *uw_context,
764 region_descriptor *region,
765 action_descriptor *action)
767 const unsigned char *p = region->call_site_table;
768 _Unwind_Ptr ip = get_ip_from_context (uw_context);
770 /* Unless we are able to determine otherwise... */
771 action->kind = nothing;
775 while (p < region->action_table)
777 _Unwind_Ptr cs_start, cs_len, cs_lp;
778 _uleb128_t cs_action;
780 /* Note that all call-site encodings are "absolute" displacements. */
781 p = read_encoded_value (0, region->call_site_encoding, p, &cs_start);
782 p = read_encoded_value (0, region->call_site_encoding, p, &cs_len);
783 p = read_encoded_value (0, region->call_site_encoding, p, &cs_lp);
784 p = read_uleb128 (p, &cs_action);
787 "c_site @ 0x%08x (+0x%03x), len = %3d, lpad @ 0x%08x (+0x%03x)\n",
788 region->base+cs_start, cs_start, cs_len,
789 region->lp_base+cs_lp, cs_lp);
791 /* The table is sorted, so if we've passed the IP, stop. */
792 if (ip < region->base + cs_start)
795 /* If we have a match, fill the ACTION fields accordingly. */
796 else if (ip < region->base + cs_start + cs_len)
798 /* Let the caller know there may be an action to take, but let it
799 determine the kind. */
800 action->kind = unknown;
803 action->landing_pad = region->lp_base + cs_lp;
805 action->landing_pad = 0;
808 action->table_entry = region->action_table + cs_action - 1;
810 action->table_entry = 0;
812 db (DB_CSITE, "+++\n");
817 db (DB_CSITE, "---\n");
820 #endif /* __USING_SJLJ_EXCEPTIONS__ */
822 /* With CHOICE an exception choice representing an "exception - when"
823 argument, and PROPAGATED_EXCEPTION a pointer to the currently propagated
824 occurrence, return true if the latter matches the former, that is, if
825 PROPAGATED_EXCEPTION is caught by the handling code controlled by CHOICE.
826 This takes care of the special Non_Ada_Error case on VMS. */
828 #define Is_Handled_By_Others __gnat_is_handled_by_others
829 #define Language_For __gnat_language_for
830 #define Import_Code_For __gnat_import_code_for
831 #define EID_For __gnat_eid_for
833 extern bool Is_Handled_By_Others (_Unwind_Ptr eid);
834 extern char Language_For (_Unwind_Ptr eid);
836 extern Exception_Code Import_Code_For (_Unwind_Ptr eid);
838 extern Exception_Id EID_For (_GNAT_Exception * e);
841 is_handled_by (_Unwind_Ptr choice, _GNAT_Exception * propagated_exception)
843 if (propagated_exception->common.exception_class == GNAT_EXCEPTION_CLASS)
845 /* Pointer to the GNAT exception data corresponding to the propagated
847 _Unwind_Ptr E = (_Unwind_Ptr) EID_For (propagated_exception);
849 /* Base matching rules: An exception data (id) matches itself, "when
850 all_others" matches anything and "when others" matches anything
851 unless explicitly stated otherwise in the propagated occurrence. */
855 || choice == GNAT_ALL_OTHERS
856 || (choice == GNAT_OTHERS && Is_Handled_By_Others (E));
858 /* In addition, on OpenVMS, Non_Ada_Error matches VMS exceptions, and we
859 may have different exception data pointers that should match for the
860 same condition code, if both an export and an import have been
861 registered. The import code for both the choice and the propagated
862 occurrence are expected to have been masked off regarding severity
863 bits already (at registration time for the former and from within the
864 low level exception vector for the latter). */
866 # define Non_Ada_Error system__aux_dec__non_ada_error
867 extern struct Exception_Data Non_Ada_Error;
870 (Language_For (E) == 'V'
871 && choice != GNAT_OTHERS && choice != GNAT_ALL_OTHERS
872 && ((Language_For (choice) == 'V' && Import_Code_For (choice) != 0
873 && Import_Code_For (choice) == Import_Code_For (E))
874 || choice == (_Unwind_Ptr)&Non_Ada_Error));
881 # define Foreign_Exception system__exceptions__foreign_exception;
882 extern struct Exception_Data Foreign_Exception;
884 return choice == GNAT_ALL_OTHERS
885 || choice == GNAT_OTHERS
886 || choice == (_Unwind_Ptr)&Foreign_Exception;
890 /* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
891 UW_CONTEXT in REGION. */
894 get_action_description_for (_Unwind_Context *uw_context,
895 _Unwind_Exception *uw_exception,
896 _Unwind_Action uw_phase,
897 region_descriptor *region,
898 action_descriptor *action)
900 _GNAT_Exception * gnat_exception = (_GNAT_Exception *) uw_exception;
902 /* Search the call site table first, which may get us a landing pad as well
903 as the head of an action record list. */
904 get_call_site_action_for (uw_context, region, action);
905 db_action_for (action, uw_context);
907 /* If there is not even a call_site entry, we are done. */
908 if (action->kind == nothing)
911 /* Otherwise, check what we have at the place of the call site. */
913 /* No landing pad => no cleanups or handlers. */
914 if (action->landing_pad == 0)
916 action->kind = nothing;
920 /* Landing pad + null table entry => only cleanups. */
921 else if (action->table_entry == 0)
923 action->kind = cleanup;
924 action->ttype_filter = cleanup_filter;
925 /* The filter initialization is not strictly necessary, as cleanup-only
926 landing pads don't look at the filter value. It is there to ensure
927 we don't pass random values and so trigger potential confusion when
928 installing the context later on. */
932 /* Landing pad + Table entry => handlers + possible cleanups. */
935 const unsigned char * p = action->table_entry;
937 _sleb128_t ar_filter, ar_disp;
939 action->kind = nothing;
943 p = read_sleb128 (p, &ar_filter);
944 read_sleb128 (p, &ar_disp);
945 /* Don't assign p here, as it will be incremented by ar_disp
948 /* Null filters are for cleanups. */
949 if (ar_filter == cleanup_filter)
951 action->kind = cleanup;
952 action->ttype_filter = cleanup_filter;
953 /* The filter initialization is required here, to ensure
954 the target landing pad branches to the cleanup code if
955 we happen not to find a matching handler. */
958 /* Positive filters are for regular handlers. */
959 else if (ar_filter > 0)
961 /* Do not catch an exception if the _UA_FORCE_UNWIND flag is
962 passed (to follow the ABI). */
963 if (!(uw_phase & _UA_FORCE_UNWIND))
965 /* See if the filter we have is for an exception which
966 matches the one we are propagating. */
967 _Unwind_Ptr choice = get_ttype_entry_for (region, ar_filter);
969 if (is_handled_by (choice, gnat_exception))
971 action->kind = handler;
972 action->ttype_filter = ar_filter;
973 action->ttype_entry = choice;
979 /* Negative filter values are for C++ exception specifications.
980 Should not be there for Ada :/ */
982 db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");
992 /* Setup in UW_CONTEXT the eh return target IP and data registers, which will
993 be restored with the others and retrieved by the landing pad once the jump
997 setup_to_install (_Unwind_Context *uw_context,
998 _Unwind_Exception *uw_exception,
999 _Unwind_Ptr uw_landing_pad,
1002 /* 1/ exception object pointer, which might be provided back to
1003 _Unwind_Resume (and thus to this personality routine) if we are jumping
1005 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (0),
1006 (_Unwind_Word)uw_exception);
1008 /* 2/ handler switch value register, which will also be used by the target
1009 landing pad to decide what action it shall take. */
1010 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (1),
1011 (_Unwind_Word)uw_filter);
1013 /* Setup the address we should jump at to reach the code where there is the
1014 "something" we found. */
1015 _Unwind_SetIP (uw_context, uw_landing_pad);
1018 /* The following is defined from a-except.adb. Its purpose is to enable
1019 automatic backtraces upon exception raise, as provided through the
1020 GNAT.Traceback facilities. */
1021 extern void __gnat_notify_handled_exception (void);
1022 extern void __gnat_notify_unhandled_exception (void);
1024 /* Below is the eh personality routine per se. We currently assume that only
1025 GNU-Ada exceptions are met. */
1027 #ifdef __USING_SJLJ_EXCEPTIONS__
1028 #define PERSONALITY_FUNCTION __gnat_personality_sj0
1030 #define PERSONALITY_FUNCTION __gnat_personality_v0
1033 /* Major tweak for ia64-vms : the CHF propagation phase calls this personality
1034 routine with sigargs/mechargs arguments and has very specific expectations
1035 on possible return values.
1037 We handle this with a number of specific tricks:
1039 1. We tweak the personality routine prototype to have the "version" and
1040 "phases" two first arguments be void * instead of int and _Unwind_Action
1041 as nominally expected in the GCC context.
1043 This allows us to access the full range of bits passed in every case and
1044 has no impact on the callers side since each argument remains assigned
1045 the same single 64bit slot.
1047 2. We retrieve the corresponding int and _Unwind_Action values within the
1048 routine for regular use with truncating conversions. This is a noop when
1049 called from the libgcc unwinder.
1051 3. We assume we're called by the VMS CHF when unexpected bits are set in
1052 both those values. The incoming arguments are then real sigargs and
1053 mechargs pointers, which we then redirect to __gnat_handle_vms_condition
1054 for proper processing.
1056 #if defined (VMS) && defined (__IA64)
1057 typedef void * version_arg_t;
1058 typedef void * phases_arg_t;
1060 typedef int version_arg_t;
1061 typedef _Unwind_Action phases_arg_t;
1065 PERSONALITY_FUNCTION (version_arg_t, phases_arg_t,
1066 _Unwind_Exception_Class, _Unwind_Exception *,
1070 PERSONALITY_FUNCTION (version_arg_t version_arg,
1071 phases_arg_t phases_arg,
1072 _Unwind_Exception_Class uw_exception_class,
1073 _Unwind_Exception *uw_exception,
1074 _Unwind_Context *uw_context)
1076 /* Fetch the version and phases args with their nominal ABI types for later
1077 use. This is a noop everywhere except on ia64-vms when called from the
1078 Condition Handling Facility. */
1079 int uw_version = (int) version_arg;
1080 _Unwind_Action uw_phases = (_Unwind_Action) phases_arg;
1081 region_descriptor region;
1082 action_descriptor action;
1084 /* Check that we're called from the ABI context we expect, with a major
1085 possible variation on VMS for IA64. */
1086 if (uw_version != 1)
1088 #if defined (VMS) && defined (__IA64)
1090 /* Assume we're called with sigargs/mechargs arguments if really
1091 unexpected bits are set in our first two formals. Redirect to the
1092 GNAT condition handling code in this case. */
1094 extern long __gnat_handle_vms_condition (void *, void *);
1096 unsigned int version_unexpected_bits_mask = 0xffffff00U;
1097 unsigned int phases_unexpected_bits_mask = 0xffffff00U;
1099 if ((unsigned int)uw_version & version_unexpected_bits_mask
1100 && (unsigned int)uw_phases & phases_unexpected_bits_mask)
1101 return __gnat_handle_vms_condition (version_arg, phases_arg);
1104 return _URC_FATAL_PHASE1_ERROR;
1107 db_indent (DB_INDENT_RESET);
1108 db_phases (uw_phases);
1109 db_indent (DB_INDENT_INCREASE);
1111 /* Get the region description for the context we were provided with. This
1112 will tell us if there is some lsda, call_site, action and/or ttype data
1113 for the associated ip. */
1114 get_region_description_for (uw_context, ®ion);
1115 db_region_for (®ion, uw_context);
1117 /* No LSDA => no handlers or cleanups => we shall unwind further up. */
1119 return _URC_CONTINUE_UNWIND;
1121 /* Search the call-site and action-record tables for the action associated
1123 get_action_description_for (uw_context, uw_exception, uw_phases,
1125 db_action_for (&action, uw_context);
1127 /* Whatever the phase, if there is nothing relevant in this frame,
1128 unwinding should just go on. */
1129 if (action.kind == nothing)
1130 return _URC_CONTINUE_UNWIND;
1132 /* If we found something in search phase, we should return a code indicating
1133 what to do next depending on what we found. If we only have cleanups
1134 around, we shall try to unwind further up to find a handler, otherwise,
1135 tell we have a handler, which will trigger the second phase. */
1136 if (uw_phases & _UA_SEARCH_PHASE)
1138 if (action.kind == cleanup)
1140 return _URC_CONTINUE_UNWIND;
1144 /* Trigger the appropriate notification routines before the second
1145 phase starts, which ensures the stack is still intact.
1146 First, setup the Ada occurrence. */
1147 __gnat_setup_current_excep (uw_exception);
1148 __gnat_notify_handled_exception ();
1150 return _URC_HANDLER_FOUND;
1154 /* We found something in cleanup/handler phase, which might be the handler
1155 or a cleanup for a handled occurrence, or a cleanup for an unhandled
1156 occurrence (we are in a FORCED_UNWIND phase in this case). Install the
1157 context to get there. */
1160 (uw_context, uw_exception, action.landing_pad, action.ttype_filter);
1162 /* Write current exception, so that it can be retrieved from Ada. */
1163 __gnat_setup_current_excep (uw_exception);
1165 return _URC_INSTALL_CONTEXT;
1168 /* Define the consistently named wrappers imported by Propagate_Exception. */
1170 #ifdef __USING_SJLJ_EXCEPTIONS__
1172 #undef _Unwind_RaiseException
1175 __gnat_Unwind_RaiseException (_Unwind_Exception *e)
1177 return _Unwind_SjLj_RaiseException (e);
1181 #undef _Unwind_ForcedUnwind
1184 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e,
1188 return _Unwind_SjLj_ForcedUnwind (e, handler, argument);
1192 #else /* __USING_SJLJ_EXCEPTIONS__ */
1195 __gnat_Unwind_RaiseException (_Unwind_Exception *e)
1197 return _Unwind_RaiseException (e);
1201 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e,
1205 return _Unwind_ForcedUnwind (e, handler, argument);
1208 #endif /* __USING_SJLJ_EXCEPTIONS__ */
1213 /* Define the corresponding stubs for the compiler. */
1215 /* We don't want fancy_abort here. */
1219 __gnat_Unwind_RaiseException (_Unwind_Exception *e ATTRIBUTE_UNUSED)
1226 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e ATTRIBUTE_UNUSED,
1227 void * handler ATTRIBUTE_UNUSED,
1228 void * argument ATTRIBUTE_UNUSED)