1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 1992-2003, 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 2, 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. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, USA. *
22 * As a special exception, if you link this file with other files to *
23 * produce an executable, this file does not by itself cause the resulting *
24 * executable to be covered by the GNU General Public License. This except- *
25 * ion does not however invalidate any other reasons why the executable *
26 * file might be covered by the GNU Public License. *
28 * GNAT was originally developed by the GNAT team at New York University. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
31 ****************************************************************************/
33 /* Routines to support runtime exception handling */
37 /* In the top-of-tree GCC, tconfig does not include tm.h, but in GCC 3.2
38 it does. To avoid branching raise.c just for that purpose, we kludge by
39 looking for a symbol always defined by tm.h and if it's not defined,
41 #ifndef FIRST_PSEUDO_REGISTER
42 #include "coretypes.h"
58 /* We have not yet figured out how to import this directly */
61 _gnat_builtin_longjmp (ptr
, flag
)
63 int flag ATTRIBUTE_UNUSED
;
65 __builtin_longjmp (ptr
, 1);
68 /* When an exception is raised for which no handler exists, the procedure
69 Ada.Exceptions.Unhandled_Exception is called, which performs the call to
70 adafinal to complete finalization, and then prints out the error messages
71 for the unhandled exception. The final step is to call this routine, which
72 performs any system dependent cleanup required. */
75 __gnat_unhandled_terminate ()
77 /* Special termination handling for VMS */
83 /* Remove the exception vector so it won't intercept any errors
84 in the call to exit, and go into and endless loop */
86 SYS$
SETEXV (1, 0, 3, &prvhnd
);
90 /* Termination handling for all other systems. */
92 #elif !defined (__RT__)
97 /* Below is the code related to the integration of the GCC mechanism for
98 exception handling. */
102 /* The names of a couple of "standard" routines for unwinding/propagation
103 actually vary depending on the underlying GCC scheme for exception handling
104 (SJLJ or DWARF). We need a consistently named interface to import from
105 a-except, so stubs are defined here. */
107 typedef struct _Unwind_Context _Unwind_Context
;
108 typedef struct _Unwind_Exception _Unwind_Exception
;
111 __gnat_Unwind_RaiseException
PARAMS ((_Unwind_Exception
*));
114 __gnat_Unwind_ForcedUnwind
PARAMS ((_Unwind_Exception
*, void *, void *));
117 #ifdef IN_RTS /* For eh personality routine */
120 #include "unwind-dw2-fde.h"
121 #include "unwind-pe.h"
124 /* --------------------------------------------------------------
125 -- The DB stuff below is there for debugging purposes only. --
126 -------------------------------------------------------------- */
128 #define DB_PHASES 0x1
130 #define DB_ACTIONS 0x4
131 #define DB_REGIONS 0x8
133 #define DB_ERR 0x1000
135 /* The "action" stuff below is also there for debugging purposes only. */
139 _Unwind_Action phase
;
143 static phase_descriptor phase_descriptors
[]
144 = {{ _UA_SEARCH_PHASE
, "SEARCH_PHASE" },
145 { _UA_CLEANUP_PHASE
, "CLEANUP_PHASE" },
146 { _UA_HANDLER_FRAME
, "HANDLER_FRAME" },
147 { _UA_FORCE_UNWIND
, "FORCE_UNWIND" },
151 db_accepted_codes (void)
153 static int accepted_codes
= -1;
155 if (accepted_codes
== -1)
157 char * db_env
= getenv ("EH_DEBUG");
159 accepted_codes
= db_env
? (atoi (db_env
) | DB_ERR
) : 0;
160 /* Arranged for ERR stuff to always be visible when the variable
161 is defined. One may just set the variable to 0 to see the ERR
165 return accepted_codes
;
168 #define DB_INDENT_INCREASE 0x01
169 #define DB_INDENT_DECREASE 0x02
170 #define DB_INDENT_OUTPUT 0x04
171 #define DB_INDENT_NEWLINE 0x08
172 #define DB_INDENT_RESET 0x10
174 #define DB_INDENT_UNIT 8
177 db_indent (int requests
)
179 static int current_indentation_level
= 0;
181 if (requests
& DB_INDENT_RESET
)
183 current_indentation_level
= 0;
186 if (requests
& DB_INDENT_INCREASE
)
188 current_indentation_level
++;
191 if (requests
& DB_INDENT_DECREASE
)
193 current_indentation_level
--;
196 if (requests
& DB_INDENT_NEWLINE
)
198 fprintf (stderr
, "\n");
201 if (requests
& DB_INDENT_OUTPUT
)
203 fprintf (stderr
, "%*s",
204 current_indentation_level
* DB_INDENT_UNIT
, " ");
210 db (int db_code
, char * msg_format
, ...)
212 if (db_accepted_codes () & db_code
)
216 db_indent (DB_INDENT_OUTPUT
);
218 va_start (msg_args
, msg_format
);
219 vfprintf (stderr
, msg_format
, msg_args
);
225 db_phases (int phases
)
227 phase_descriptor
*a
= phase_descriptors
;
229 if (! (db_accepted_codes() & DB_PHASES
))
232 db (DB_PHASES
, "\n");
234 for (; a
->description
!= 0; a
++)
235 if (phases
& a
->phase
)
236 db (DB_PHASES
, "%s ", a
->description
);
238 db (DB_PHASES
, " :\n");
242 /* ---------------------------------------------------------------
243 -- Now come a set of useful structures and helper routines. --
244 --------------------------------------------------------------- */
246 /* There are three major runtime tables involved, generated by the
247 GCC back-end. Contents slightly vary depending on the underlying
248 implementation scheme (dwarf zero cost / sjlj).
250 =======================================
251 * Tables for the dwarf zero cost case *
252 =======================================
255 -------------------------------------------------------------------
256 * region-start | region-length | landing-pad | first-action-index *
257 -------------------------------------------------------------------
259 Identify possible actions to be taken and where to resume control
260 for that when an exception propagates through a pc inside the region
261 delimited by start and length.
263 A null landing-pad indicates that nothing is to be done.
265 Otherwise, first-action-index provides an entry into the action[]
266 table which heads a list of possible actions to be taken (see below).
268 If it is determined that indeed an action should be taken, that
269 is, if one action filter matches the exception beeing propagated,
270 then control should be transfered to landing-pad.
272 A null first-action-index indicates that there are only cleanups
276 -------------------------------
277 * action-filter | next-action *
278 -------------------------------
280 This table contains lists (called action chains) of possible actions
281 associated with call-site entries described in the call-site [] table.
282 There is at most one action list per call-site entry.
284 A null action-filter indicates a cleanup.
286 Non null action-filters provide an index into the ttypes [] table
287 (see below), from which information may be retrieved to check if it
288 matches the exception beeing propagated.
290 action-filter > 0 means there is a regular handler to be run,
292 action-filter < 0 means there is a some "exception_specification"
293 data to retrieve, which is only relevant for C++
294 and should never show up for Ada.
296 next-action indexes the next entry in the list. 0 indicates there is
304 A null value indicates a catch-all handler in C++, and an "others"
307 Non null values are used to match the exception beeing propagated:
308 In C++ this is a pointer to some rtti data, while in Ada this is an
311 The special id value 1 indicates an "all_others" handler.
313 For C++, this table is actually also used to store "exception
314 specification" data. The differentiation between the two kinds
315 of entries is made by the sign of the associated action filter,
316 which translates into positive or negative offsets from the
317 so called base of the table:
319 Exception Specification data is stored at positive offsets from
320 the ttypes table base, which Exception Type data is stored at
323 ---------------------------------------------------------------------------
325 Here is a quick summary of the tables organization:
327 +-- Unwind_Context (pc, ...)
333 | +=============================================================+
334 | | region-start + length | landing-pad | first-action-index |
335 | +=============================================================+
336 +-> | pc range 0 => no-action 0 => cleanups only |
337 | !0 => jump @ N --+ |
338 +====================================================== | ====+
343 +==========================================================+ |
344 | action-filter | next-action | |
345 +==========================================================+ |
347 | >0 => ttype index for handler ------+ 0 => end of chain | <-+
348 | <0 => ttype index for spec data | |
349 +==================================== | ===================+
353 | Offset negated from
354 +=====================+ | the actual base.
356 +============+=====================+ |
357 | | 0 => "others" | |
358 | ... | 1 => "all others" | <---+
359 | | X => exception id |
360 | handlers +---------------------+
364 +============+=====================+ <<------ Table base
366 | specs | ... | (should not see negative filter
367 | ... | ... | values for Ada).
368 +============+=====================+
371 ============================
372 * Tables for the sjlj case *
373 ============================
375 So called "function contexts" are pushed on a context stack by calls to
376 _Unwind_SjLj_Register on function entry, and popped off at exit points by
377 calls to _Unwind_SjLj_Unregister. The current call_site for a function is
378 updated in the function context as the function's code runs along.
380 The generic unwinding engine in _Unwind_RaiseException walks the function
381 context stack and not the actual call chain.
383 The ACTION and TTYPES tables remain unchanged, which allows to search them
384 during the propagation phase to determine wether or not the propagated
385 exception is handled somewhere. When it is, we only "jump" up once directly
386 to the context where the handler will be found. Besides, this allows "break
387 exception unhandled" to work also
389 The CALL-SITE table is setup differently, though: the pc attached to the
390 unwind context is a direct index into the table, so the entries in this
391 table do not hold region bounds any more.
393 A special index (-1) is used to indicate that no action is possibly
394 connected with the context at hand, so null landing pads cannot appear
397 Additionally, landing pad values in the table do not represent code address
398 to jump at, but so called "dispatch" indices used by a common landing pad
399 for the function to switch to the appropriate post-landing-pad.
401 +-- Unwind_Context (pc, ...)
403 | pc = call-site index
404 | 0 => terminate (should not see this for Ada)
409 | +=====================================+
410 | | landing-pad | first-action-index |
411 | +=====================================+
412 +-> | 0 => cleanups only |
414 +=====================================+
417 ===================================
418 * Basic organization of this unit *
419 ===================================
421 The major point of this unit is to provide an exception propagation
422 personality routine for Ada. This is __gnat_eh_personality.
424 It is provided with a pointer to the propagated exception, an unwind
425 context describing a location the propagation is going through, and a
426 couple of other arguments including a description of the current
429 It shall return to the generic propagation engine what is to be performed
430 next, after possible context adjustments, depending on what it finds in the
431 traversed context (a handler for the exception, a cleanup, nothing, ...),
432 and on the propagation phase.
434 A number of structures and subroutines are used for this purpose, as
437 o region_descriptor: General data associated with the context (base pc,
438 call-site table, action table, ttypes table, ...)
440 o action_descriptor: Data describing the action to be taken for the
441 propagated exception in the provided context (kind of action: nothing,
442 handler, cleanup; pointer to the action table entry, ...).
448 Propagate_Exception (a-exexpr.adb)
451 _Unwind_RaiseException (libgcc)
455 +--> __gnat_eh_personality (context, exception)
457 +--> get_region_descriptor_for (context)
459 +--> get_action_descriptor_for (context, exception, region)
461 | +--> get_call_site_action_for (context, region)
462 | (one version for each underlying scheme)
464 +--> setup_to_install (context)
466 This unit is inspired from the C++ version found in eh_personality.cc,
467 part of libstdc++-v3.
472 /* This is the structure of exception objects as built by the GNAT runtime
473 library (a-exexpr.adb). The layouts should exactly match, and the "common"
474 header is mandated by the exception handling ABI. */
478 _Unwind_Exception common
;
479 /* ABI header, maximally aligned. */
482 /* Id of the exception beeing propagated, filled by Propagate_Exception.
484 This is compared against the ttype entries associated with actions in the
485 examined context to see if one of these actions matches. */
487 bool handled_by_others
;
488 /* Indicates wether a "when others" may catch this exception, also filled by
491 This is used to decide if a GNAT_OTHERS ttype entry matches. */
493 int n_cleanups_to_trigger
;
494 /* Number of cleanups on the propagation way for the occurrence. This is
495 initialized to 0 by Propagate_Exception and computed by the personality
496 routine during the first phase of the propagation (incremented for each
497 context in which only cleanup actions match).
499 This is used by Propagate_Exception when the occurrence is not handled,
500 to control a forced unwinding phase aimed at triggering all the cleanups
501 before calling Unhandled_Exception_Terminate.
503 This is also used by __gnat_eh_personality to identify the point at which
504 the notification routine shall be called for a handled occurrence. */
507 /* The two constants below are specific ttype identifiers for special
508 exception ids. Their value is currently hardcoded at the gigi level
509 (see N_Exception_Handler). */
511 #define GNAT_OTHERS ((_Unwind_Ptr) 0x0)
512 #define GNAT_ALL_OTHERS ((_Unwind_Ptr) 0x1)
514 /* Describe the useful region data associated with an unwind context. */
518 /* The base pc of the region. */
521 /* Pointer to the Language Specific Data for the region. */
524 /* Call-Site data associated with this region. */
525 unsigned char call_site_encoding
;
526 const unsigned char *call_site_table
;
528 /* The base to which are relative landing pad offsets inside the call-site
532 /* Action-Table associated with this region. */
533 const unsigned char *action_table
;
535 /* Ttype data associated with this region. */
536 unsigned char ttype_encoding
;
537 const unsigned char *ttype_table
;
538 _Unwind_Ptr ttype_base
;
543 db_region_for (region
, uw_context
)
544 region_descriptor
*region
;
545 _Unwind_Context
*uw_context
;
547 _Unwind_Ptr ip
= _Unwind_GetIP (uw_context
) - 1;
549 if (! (db_accepted_codes () & DB_REGIONS
))
552 db (DB_REGIONS
, "For ip @ 0x%08x => ", ip
);
555 db (DB_REGIONS
, "lsda @ 0x%x", region
->lsda
);
557 db (DB_REGIONS
, "no lsda");
559 db (DB_REGIONS
, "\n");
562 /* Retrieve the ttype entry associated with FILTER in the REGION's
565 static const _Unwind_Ptr
566 get_ttype_entry_for (region
, filter
)
567 region_descriptor
*region
;
570 _Unwind_Ptr ttype_entry
;
572 filter
*= size_of_encoded_value (region
->ttype_encoding
);
573 read_encoded_value_with_base
574 (region
->ttype_encoding
, region
->ttype_base
,
575 region
->ttype_table
- filter
, &ttype_entry
);
580 /* Fill out the REGION descriptor for the provided UW_CONTEXT. */
583 get_region_description_for (uw_context
, region
)
584 _Unwind_Context
*uw_context
;
585 region_descriptor
*region
;
587 const unsigned char * p
;
589 unsigned char lpbase_encoding
;
591 /* Get the base address of the lsda information. If the provided context
592 is null or if there is no associated language specific data, there's
593 nothing we can/should do. */
595 = (_Unwind_Ptr
) (uw_context
596 ? _Unwind_GetLanguageSpecificData (uw_context
) : 0);
601 /* Parse the lsda and fill the region descriptor. */
602 p
= (char *)region
->lsda
;
604 region
->base
= _Unwind_GetRegionStart (uw_context
);
606 /* Find @LPStart, the base to which landing pad offsets are relative. */
607 lpbase_encoding
= *p
++;
608 if (lpbase_encoding
!= DW_EH_PE_omit
)
609 p
= read_encoded_value
610 (uw_context
, lpbase_encoding
, p
, ®ion
->lp_base
);
612 region
->lp_base
= region
->base
;
614 /* Find @TType, the base of the handler and exception spec type data. */
615 region
->ttype_encoding
= *p
++;
616 if (region
->ttype_encoding
!= DW_EH_PE_omit
)
618 p
= read_uleb128 (p
, &tmp
);
619 region
->ttype_table
= p
+ tmp
;
622 region
->ttype_table
= 0;
625 = base_of_encoded_value (region
->ttype_encoding
, uw_context
);
627 /* Get the encoding and length of the call-site table; the action table
628 immediately follows. */
629 region
->call_site_encoding
= *p
++;
630 region
->call_site_table
= read_uleb128 (p
, &tmp
);
632 region
->action_table
= region
->call_site_table
+ tmp
;
636 /* Describe an action to be taken when propagating an exception up to
641 /* Found some call site base data, but need to analyze further
642 before beeing able to decide. */
645 /* There is nothing relevant in the context at hand. */
648 /* There are only cleanups to run in this context. */
651 /* There is a handler for the exception in this context. */
658 /* The kind of action to be taken. */
661 /* A pointer to the action record entry. */
662 const unsigned char *table_entry
;
664 /* Where we should jump to actually take an action (trigger a cleanup or an
665 exception handler). */
666 _Unwind_Ptr landing_pad
;
668 /* If we have a handler matching our exception, these are the filter to
669 trigger it and the corresponding id. */
670 _Unwind_Sword ttype_filter
;
671 _Unwind_Ptr ttype_entry
;
677 db_action_for (action
, uw_context
)
678 action_descriptor
*action
;
679 _Unwind_Context
*uw_context
;
681 _Unwind_Ptr ip
= _Unwind_GetIP (uw_context
) - 1;
683 db (DB_ACTIONS
, "For ip @ 0x%08x => ", ip
);
685 switch (action
->kind
)
688 db (DB_ACTIONS
, "lpad @ 0x%x, record @ 0x%x\n",
689 ip
, action
->landing_pad
, action
->table_entry
);
693 db (DB_ACTIONS
, "Nothing\n");
697 db (DB_ACTIONS
, "Cleanup\n");
701 db (DB_ACTIONS
, "Handler, filter = %d\n", action
->ttype_filter
);
705 db (DB_ACTIONS
, "Err? Unexpected action kind !\n");
713 /* Search the call_site_table of REGION for an entry appropriate for the
714 UW_CONTEXT's ip. If one is found, store the associated landing_pad and
715 action_table entry, and set the ACTION kind to unknown for further
716 analysis. Otherwise, set the ACTION kind to nothing.
718 There are two variants of this routine, depending on the underlying
719 mechanism (dwarf/sjlj), which account for differences in the tables
723 #ifdef __USING_SJLJ_EXCEPTIONS__
725 #define __builtin_eh_return_data_regno(x) x
728 get_call_site_action_for (uw_context
, region
, action
)
729 _Unwind_Context
*uw_context
;
730 region_descriptor
*region
;
731 action_descriptor
*action
;
733 _Unwind_Ptr call_site
734 = _Unwind_GetIP (uw_context
) - 1;
735 /* Subtract 1 because GetIP returns the actual call_site value + 1. */
737 /* call_site is a direct index into the call-site table, with two special
738 values : -1 for no-action and 0 for "terminate". The latter should never
739 show up for Ada. To test for the former, beware that _Unwind_Ptr might be
742 if ((int)call_site
< 0)
744 action
->kind
= nothing
;
747 else if (call_site
== 0)
749 db (DB_ERR
, "========> Err, null call_site for Ada/sjlj\n");
750 action
->kind
= nothing
;
755 _Unwind_Word cs_lp
, cs_action
;
757 /* Let the caller know there may be an action to take, but let it
758 determine the kind. */
759 action
->kind
= unknown
;
761 /* We have a direct index into the call-site table, but this table is
762 made of leb128 values, the encoding length of which is variable. We
763 can't merely compute an offset from the index, then, but have to read
764 all the entries before the one of interest. */
766 const unsigned char * p
= region
->call_site_table
;
769 p
= read_uleb128 (p
, &cs_lp
);
770 p
= read_uleb128 (p
, &cs_action
);
771 } while (--call_site
);
774 action
->landing_pad
= cs_lp
+ 1;
777 action
->table_entry
= region
->action_table
+ cs_action
- 1;
779 action
->table_entry
= 0;
786 /* ! __USING_SJLJ_EXCEPTIONS__ */
789 get_call_site_action_for (uw_context
, region
, action
)
790 _Unwind_Context
*uw_context
;
791 region_descriptor
*region
;
792 action_descriptor
*action
;
795 = _Unwind_GetIP (uw_context
) - 1;
796 /* Substract 1 because GetIP yields a call return address while we are
797 interested in information for the call point. This does not always yield
798 the exact call instruction address but always brings the ip back within
799 the corresponding region.
801 ??? When unwinding up from a signal handler triggered by a trap on some
802 instruction, we usually have the faulting instruction address here and
803 subtracting 1 might get us into the wrong region. */
805 const unsigned char * p
806 = region
->call_site_table
;
808 /* Unless we are able to determine otherwise ... */
809 action
->kind
= nothing
;
813 while (p
< region
->action_table
)
815 _Unwind_Ptr cs_start
, cs_len
, cs_lp
;
816 _Unwind_Word cs_action
;
818 /* Note that all call-site encodings are "absolute" displacements. */
819 p
= read_encoded_value (0, region
->call_site_encoding
, p
, &cs_start
);
820 p
= read_encoded_value (0, region
->call_site_encoding
, p
, &cs_len
);
821 p
= read_encoded_value (0, region
->call_site_encoding
, p
, &cs_lp
);
822 p
= read_uleb128 (p
, &cs_action
);
825 "c_site @ 0x%08x (+0x%03x), len = %3d, lpad @ 0x%08x (+0x%03x)\n",
826 region
->base
+cs_start
, cs_start
, cs_len
,
827 region
->lp_base
+cs_lp
, cs_lp
);
829 /* The table is sorted, so if we've passed the ip, stop. */
830 if (ip
< region
->base
+ cs_start
)
833 /* If we have a match, fill the ACTION fields accordingly. */
834 else if (ip
< region
->base
+ cs_start
+ cs_len
)
836 /* Let the caller know there may be an action to take, but let it
837 determine the kind. */
838 action
->kind
= unknown
;
841 action
->landing_pad
= region
->lp_base
+ cs_lp
;
843 action
->landing_pad
= 0;
846 action
->table_entry
= region
->action_table
+ cs_action
- 1;
848 action
->table_entry
= 0;
850 db (DB_CSITE
, "+++\n");
855 db (DB_CSITE
, "---\n");
860 /* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
861 UW_CONTEXT in REGION. */
864 get_action_description_for (uw_context
, uw_exception
, region
, action
)
865 _Unwind_Context
*uw_context
;
866 _Unwind_Exception
*uw_exception
;
867 region_descriptor
*region
;
868 action_descriptor
*action
;
870 _GNAT_Exception
* gnat_exception
= (_GNAT_Exception
*) uw_exception
;
872 /* Search the call site table first, which may get us a landing pad as well
873 as the head of an action record list. */
874 get_call_site_action_for (uw_context
, region
, action
);
875 db_action_for (action
, uw_context
);
877 /* If there is not even a call_site entry, we are done. */
878 if (action
->kind
== nothing
)
881 /* Otherwise, check what we have at the place of the call site */
883 /* No landing pad => no cleanups or handlers. */
884 if (action
->landing_pad
== 0)
886 action
->kind
= nothing
;
890 /* Landing pad + null table entry => only cleanups. */
891 else if (action
->table_entry
== 0)
893 action
->kind
= cleanup
;
897 /* Landing pad + Table entry => handlers + possible cleanups. */
900 const unsigned char * p
= action
->table_entry
;
902 _Unwind_Sword ar_filter
, ar_disp
;
904 action
->kind
= nothing
;
908 p
= read_sleb128 (p
, &ar_filter
);
909 read_sleb128 (p
, &ar_disp
);
910 /* Don't assign p here, as it will be incremented by ar_disp
913 /* Null filters are for cleanups. */
915 action
->kind
= cleanup
;
917 /* Positive filters are for regular handlers. */
918 else if (ar_filter
> 0)
920 /* See if the filter we have is for an exception which matches
921 the one we are propagating. */
922 _Unwind_Ptr eid
= get_ttype_entry_for (region
, ar_filter
);
924 if (eid
== gnat_exception
->id
925 || eid
== GNAT_ALL_OTHERS
926 || (eid
== GNAT_OTHERS
&& gnat_exception
->handled_by_others
))
928 action
->ttype_filter
= ar_filter
;
929 action
->ttype_entry
= eid
;
930 action
->kind
= handler
;
935 /* Negative filter values are for C++ exception specifications.
936 Should not be there for Ada :/ */
938 db (DB_ERR
, "========> Err, filter < 0 for Ada/dwarf\n");
948 /* Setup in UW_CONTEXT the eh return target IP and data registers, which will
949 be restored with the others and retrieved by the landing pad once the jump
953 setup_to_install (uw_context
, uw_exception
, uw_landing_pad
, uw_filter
)
954 _Unwind_Context
*uw_context
;
955 _Unwind_Exception
*uw_exception
;
957 _Unwind_Ptr uw_landing_pad
;
959 #ifndef EH_RETURN_DATA_REGNO
960 /* We should not be called if the appropriate underlying support is not
964 /* 1/ exception object pointer, which might be provided back to
965 _Unwind_Resume (and thus to this personality routine) if we are jumping
967 _Unwind_SetGR (uw_context
, __builtin_eh_return_data_regno (0),
968 (_Unwind_Word
)uw_exception
);
970 /* 2/ handler switch value register, which will also be used by the target
971 landing pad to decide what action it shall take. */
972 _Unwind_SetGR (uw_context
, __builtin_eh_return_data_regno (1),
973 (_Unwind_Word
)uw_filter
);
975 /* Setup the address we should jump at to reach the code where there is the
976 "something" we found. */
977 _Unwind_SetIP (uw_context
, uw_landing_pad
);
981 /* The following is defined from a-except.adb. Its purpose is to enable
982 automatic backtraces upon exception raise, as provided through the
983 GNAT.Traceback facilities. */
984 extern void __gnat_notify_handled_exception
PARAMS ((void));
985 extern void __gnat_notify_unhandled_exception
PARAMS ((void));
987 /* Below is the eh personality routine per se. We currently assume that only
988 GNU-Ada exceptions are met. */
991 __gnat_eh_personality (uw_version
, uw_phases
,
992 uw_exception_class
, uw_exception
, uw_context
)
994 _Unwind_Action uw_phases
;
995 _Unwind_Exception_Class uw_exception_class
;
996 _Unwind_Exception
*uw_exception
;
997 _Unwind_Context
*uw_context
;
999 _GNAT_Exception
* gnat_exception
= (_GNAT_Exception
*) uw_exception
;
1001 region_descriptor region
;
1002 action_descriptor action
;
1004 if (uw_version
!= 1)
1005 return _URC_FATAL_PHASE1_ERROR
;
1007 db_indent (DB_INDENT_RESET
);
1008 db_phases (uw_phases
);
1009 db_indent (DB_INDENT_INCREASE
);
1011 /* Get the region description for the context we were provided with. This
1012 will tell us if there is some lsda, call_site, action and/or ttype data
1013 for the associated ip. */
1014 get_region_description_for (uw_context
, ®ion
);
1015 db_region_for (®ion
, uw_context
);
1017 /* No LSDA => no handlers or cleanups => we shall unwind further up. */
1019 return _URC_CONTINUE_UNWIND
;
1021 /* Search the call-site and action-record tables for the action associated
1023 get_action_description_for (uw_context
, uw_exception
, ®ion
, &action
);
1024 db_action_for (&action
, uw_context
);
1026 /* Whatever the phase, if there is nothing relevant in this frame,
1027 unwinding should just go on. */
1028 if (action
.kind
== nothing
)
1029 return _URC_CONTINUE_UNWIND
;
1031 /* If we found something in search phase, we should return a code indicating
1032 what to do next depending on what we found. If we only have cleanups
1033 around, we shall try to unwind further up to find a handler, otherwise,
1034 tell we have a handler, which will trigger the second phase. */
1035 if (uw_phases
& _UA_SEARCH_PHASE
)
1037 if (action
.kind
== cleanup
)
1039 gnat_exception
->n_cleanups_to_trigger
++;
1040 return _URC_CONTINUE_UNWIND
;
1044 /* Trigger the appropriate notification routines before the second
1045 phase starts, which ensures the stack is still intact. */
1046 __gnat_notify_handled_exception ();
1048 return _URC_HANDLER_FOUND
;
1052 /* We found something in cleanup/handler phase, which might be the handler
1053 or a cleanup for a handled occurrence, or a cleanup for an unhandled
1054 occurrence (we are in a FORCED_UNWIND phase in this case). Install the
1055 context to get there. */
1057 /* If we are going to install a cleanup context, decrement the cleanup
1058 count. This is required in a FORCED_UNWINDing phase (for an unhandled
1059 exception), as this is used from the forced unwinding handler in
1060 Ada.Exceptions.Exception_Propagation to decide wether unwinding should
1061 proceed further or Unhandled_Exception_Terminate should be called. */
1062 if (action
.kind
== cleanup
)
1063 gnat_exception
->n_cleanups_to_trigger
--;
1066 (uw_context
, uw_exception
, action
.landing_pad
, action
.ttype_filter
);
1068 return _URC_INSTALL_CONTEXT
;
1071 /* Define the consistently named stubs imported by Propagate_Exception. */
1073 #ifdef __USING_SJLJ_EXCEPTIONS__
1075 #undef _Unwind_RaiseException
1078 __gnat_Unwind_RaiseException (e
)
1079 _Unwind_Exception
*e
;
1081 return _Unwind_SjLj_RaiseException (e
);
1085 #undef _Unwind_ForcedUnwind
1088 __gnat_Unwind_ForcedUnwind (e
, handler
, argument
)
1089 _Unwind_Exception
*e
;
1093 return _Unwind_SjLj_ForcedUnwind (e
, handler
, argument
);
1097 #else /* __USING_SJLJ_EXCEPTIONS__ */
1100 __gnat_Unwind_RaiseException (e
)
1101 _Unwind_Exception
*e
;
1103 return _Unwind_RaiseException (e
);
1107 __gnat_Unwind_ForcedUnwind (e
, handler
, argument
)
1108 _Unwind_Exception
*e
;
1112 return _Unwind_ForcedUnwind (e
, handler
, argument
);
1115 #endif /* __USING_SJLJ_EXCEPTIONS__ */
1120 /* The calls to the GCC runtime interface for exception raising are currently
1121 issued from a-exexpr.adb, which is used by both the runtime library and the
1124 As the compiler binary is not linked against the GCC runtime library, we
1125 need also need stubs for this interface in the compiler case. We should not
1126 be using the GCC eh mechanism for the compiler, however, so expect these
1127 functions never to be called. */
1130 __gnat_Unwind_RaiseException (e
)
1131 _Unwind_Exception
*e ATTRIBUTE_UNUSED
;
1138 __gnat_Unwind_ForcedUnwind (e
, handler
, argument
)
1139 _Unwind_Exception
*e ATTRIBUTE_UNUSED
;
1140 void * handler ATTRIBUTE_UNUSED
;
1141 void * argument ATTRIBUTE_UNUSED
;