2015-05-22 Eric Botcazou <ebotcazou@adacore.com>
[official-gcc.git] / gcc / ada / raise-gcc.c
blob4a10fbff0d9e02c1de4b62089eafa9e39a2deaf1
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * R A I S E - G C C *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 1992-2014, Free Software Foundation, Inc. *
10 * *
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. *
17 * *
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. *
21 * *
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/>. *
26 * *
27 * GNAT was originally developed by the GNAT team at New York University. *
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
29 * *
30 ****************************************************************************/
32 /* Code related to the integration of the GCC mechanism for exception
33 handling. */
35 #ifndef IN_RTS
36 #error "RTS unit only"
37 #endif
39 #include "tconfig.h"
40 #include "tsystem.h"
42 #include <stdarg.h>
43 typedef char bool;
44 # define true 1
45 # define false 0
47 #include "raise.h"
49 #ifdef __APPLE__
50 /* On MacOS X, versions older than 10.5 don't export _Unwind_GetIPInfo. */
51 #undef HAVE_GETIPINFO
52 #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
53 #define HAVE_GETIPINFO 1
54 #endif
55 #endif
57 #if defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
58 /* HP-UX B.11.31 ia64 libunwind doesn't have _Unwind_GetIPInfo. */
59 #undef HAVE_GETIPINFO
60 #define _UA_END_OF_STACK 0
61 #endif
63 /* The names of a couple of "standard" routines for unwinding/propagation
64 actually vary depending on the underlying GCC scheme for exception handling
65 (SJLJ or DWARF). We need a consistently named interface to import from
66 a-except, so wrappers are defined here. */
68 #include "unwind.h"
70 typedef struct _Unwind_Context _Unwind_Context;
71 typedef struct _Unwind_Exception _Unwind_Exception;
73 _Unwind_Reason_Code
74 __gnat_Unwind_RaiseException (_Unwind_Exception *);
76 _Unwind_Reason_Code
77 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *, void *, void *);
79 extern struct Exception_Occurrence *__gnat_setup_current_excep
80 (_Unwind_Exception *);
81 extern void __gnat_unhandled_except_handler (_Unwind_Exception *);
83 #include "unwind-pe.h"
85 /* The known and handled exception classes. */
87 #ifdef __ARM_EABI_UNWINDER__
88 #define CXX_EXCEPTION_CLASS "GNUCC++"
89 #define GNAT_EXCEPTION_CLASS "GNU-Ada"
90 #else
91 #define CXX_EXCEPTION_CLASS 0x474e5543432b2b00ULL
92 #define GNAT_EXCEPTION_CLASS 0x474e552d41646100ULL
93 #endif
95 /* Structure of a C++ exception, represented as a C structure... See
96 unwind-cxx.h for the full definition. */
98 struct __cxa_exception
100 void *exceptionType;
101 void (*exceptionDestructor)(void *);
103 void (*unexpectedHandler)();
104 void (*terminateHandler)();
106 struct __cxa_exception *nextException;
108 int handlerCount;
110 #ifdef __ARM_EABI_UNWINDER__
111 struct __cxa_exception* nextPropagatingException;
113 int propagationCount;
114 #else
115 int handlerSwitchValue;
116 const unsigned char *actionRecord;
117 const unsigned char *languageSpecificData;
118 _Unwind_Ptr catchTemp;
119 void *adjustedPtr;
120 #endif
122 _Unwind_Exception unwindHeader;
125 /* --------------------------------------------------------------
126 -- The DB stuff below is there for debugging purposes only. --
127 -------------------------------------------------------------- */
129 #ifndef inhibit_libc
131 #define DB_PHASES 0x1
132 #define DB_CSITE 0x2
133 #define DB_ACTIONS 0x4
134 #define DB_REGIONS 0x8
136 #define DB_ERR 0x1000
138 /* The "action" stuff below is also there for debugging purposes only. */
140 typedef struct
142 _Unwind_Action phase;
143 const char * description;
144 } phase_descriptor;
146 static const phase_descriptor phase_descriptors[]
147 = {{ _UA_SEARCH_PHASE, "SEARCH_PHASE" },
148 { _UA_CLEANUP_PHASE, "CLEANUP_PHASE" },
149 { _UA_HANDLER_FRAME, "HANDLER_FRAME" },
150 { _UA_FORCE_UNWIND, "FORCE_UNWIND" },
151 { -1, 0}};
153 static int
154 db_accepted_codes (void)
156 static int accepted_codes = -1;
158 if (accepted_codes == -1)
160 char * db_env = (char *) getenv ("EH_DEBUG");
162 accepted_codes = db_env ? (atoi (db_env) | DB_ERR) : 0;
163 /* Arranged for ERR stuff to always be visible when the variable
164 is defined. One may just set the variable to 0 to see the ERR
165 stuff only. */
168 return accepted_codes;
171 #define DB_INDENT_INCREASE 0x01
172 #define DB_INDENT_DECREASE 0x02
173 #define DB_INDENT_OUTPUT 0x04
174 #define DB_INDENT_NEWLINE 0x08
175 #define DB_INDENT_RESET 0x10
177 #define DB_INDENT_UNIT 8
179 static void
180 db_indent (int requests)
182 static int current_indentation_level = 0;
184 if (requests & DB_INDENT_RESET)
185 current_indentation_level = 0;
187 if (requests & DB_INDENT_INCREASE)
188 current_indentation_level ++;
190 if (requests & DB_INDENT_DECREASE)
191 current_indentation_level --;
193 if (requests & DB_INDENT_NEWLINE)
194 fprintf (stderr, "\n");
196 if (requests & DB_INDENT_OUTPUT)
197 fprintf (stderr, "%*s", current_indentation_level * DB_INDENT_UNIT, " ");
200 static void ATTRIBUTE_PRINTF_2
201 db (int db_code, char * msg_format, ...)
203 if (db_accepted_codes () & db_code)
205 va_list msg_args;
207 db_indent (DB_INDENT_OUTPUT);
209 va_start (msg_args, msg_format);
210 vfprintf (stderr, msg_format, msg_args);
211 va_end (msg_args);
215 static void
216 db_phases (int phases)
218 const phase_descriptor *a = phase_descriptors;
220 if (! (db_accepted_codes () & DB_PHASES))
221 return;
223 db (DB_PHASES, "\n");
225 for (; a->description != 0; a++)
226 if (phases & a->phase)
227 db (DB_PHASES, "%s ", a->description);
229 db (DB_PHASES, " :\n");
231 #else /* !inhibit_libc */
232 #define db_phases(X)
233 #define db_indent(X)
234 #define db(X, ...)
235 #endif /* !inhibit_libc */
237 /* ---------------------------------------------------------------
238 -- Now come a set of useful structures and helper routines. --
239 --------------------------------------------------------------- */
241 /* There are three major runtime tables involved, generated by the
242 GCC back-end. Contents slightly vary depending on the underlying
243 implementation scheme (dwarf zero cost / sjlj).
245 =======================================
246 * Tables for the dwarf zero cost case *
247 =======================================
249 They are fully documented in:
250 http://sourcery.mentor.com/public/cxx-abi/exceptions.pdf
251 Here is a shorter presentation, with some specific comments for Ada.
253 call_site []
254 -------------------------------------------------------------------
255 * region-start | region-length | landing-pad | first-action-index *
256 -------------------------------------------------------------------
258 Identify possible actions to be taken and where to resume control
259 for that when an exception propagates through a pc inside the region
260 delimited by start and length.
262 A null landing-pad indicates that nothing is to be done.
264 Otherwise, first-action-index provides an entry into the action[]
265 table which heads a list of possible actions to be taken (see below).
267 If it is determined that indeed an action should be taken, that
268 is, if one action filter matches the exception being propagated,
269 then control should be transferred to landing-pad.
271 A null first-action-index indicates that there are only cleanups
272 to run there.
274 action []
275 -------------------------------
276 * action-filter | next-action *
277 -------------------------------
279 This table contains lists (called action chains) of possible actions
280 associated with call-site entries described in the call-site [] table.
281 There is at most one action list per call-site entry. It is SLEB128
282 encoded.
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 being propagated.
290 * action-filter > 0:
291 means there is a regular handler to be run The value is also passed
292 to the landing pad to dispatch the exception.
294 * action-filter < 0:
295 means there is a some "exception_specification" data to retrieve,
296 which is only relevant for C++ and should never show up for Ada.
297 (Exception specification specifies which exceptions can be thrown
298 by a function. Such filter is emitted around the body of C++
299 functions defined like:
300 void foo ([...]) throw (A, B) { [...] }
301 These can be viewed as negativ filter: the landing pad is branched
302 to for exceptions that doesn't match the filter and usually aborts
303 the program).
305 * next-action
306 points to the next entry in the list using a relative byte offset. 0
307 indicates there is no other entry.
309 ttypes []
310 ---------------
311 * ttype-value *
312 ---------------
314 This table is an array of addresses.
316 A null value indicates a catch-all handler. (Not used by Ada)
318 Non null values are used to match the exception being propagated:
319 In C++ this is a pointer to some rtti data, while in Ada this is an
320 exception id (with a fake id for others).
322 For C++, this table is actually also used to store "exception
323 specification" data. The differentiation between the two kinds
324 of entries is made by the sign of the associated action filter,
325 which translates into positive or negative offsets from the
326 so called base of the table:
328 Exception Specification data is stored at positive offsets from
329 the ttypes table base, which Exception Type data is stored at
330 negative offsets:
332 ---------------------------------------------------------------------------
334 Here is a quick summary of the tables organization:
336 +-- Unwind_Context (pc, ...)
338 |(pc)
340 | CALL-SITE[]
342 | +=============================================================+
343 | | region-start + length | landing-pad | first-action-index |
344 | +=============================================================+
345 +-> | pc range 0 => no-action 0 => cleanups only |
346 | !0 => jump @ N --+ |
347 +====================================================== | ====+
350 ACTION [] |
352 +==========================================================+ |
353 | action-filter | next-action | |
354 +==========================================================+ |
355 | 0 => cleanup | |
356 | >0 => ttype index for handler ------+ 0 => end of chain | <-+
357 | <0 => ttype index for spec data | |
358 +==================================== | ===================+
361 TTYPES [] |
362 | Offset negated from
363 +=====================+ | the actual base.
364 | ttype-value | |
365 +============+=====================+ |
366 | | ... | |
367 | ... | exception id | <---+
368 | | ... |
369 | handlers +---------------------+
370 | | ... |
371 | ... | ... |
372 | | ... |
373 +============+=====================+ <<------ Table base
374 | ... | ... |
375 | specs | ... | (should not see negative filter
376 | ... | ... | values for Ada).
377 +============+=====================+
380 ============================
381 * Tables for the sjlj case *
382 ============================
384 So called "function contexts" are pushed on a context stack by calls to
385 _Unwind_SjLj_Register on function entry, and popped off at exit points by
386 calls to _Unwind_SjLj_Unregister. The current call_site for a function is
387 updated in the function context as the function's code runs along.
389 The generic unwinding engine in _Unwind_RaiseException walks the function
390 context stack and not the actual call chain.
392 The ACTION and TTYPES tables remain unchanged, which allows to search them
393 during the propagation phase to determine whether or not the propagated
394 exception is handled somewhere. When it is, we only "jump" up once directly
395 to the context where the handler will be found. Besides, this allows "break
396 exception unhandled" to work also
398 The CALL-SITE table is setup differently, though: the pc attached to the
399 unwind context is a direct index into the table, so the entries in this
400 table do not hold region bounds any more.
402 A special index (-1) is used to indicate that no action is possibly
403 connected with the context at hand, so null landing pads cannot appear
404 in the table.
406 Additionally, landing pad values in the table do not represent code address
407 to jump at, but so called "dispatch" indices used by a common landing pad
408 for the function to switch to the appropriate post-landing-pad.
410 +-- Unwind_Context (pc, ...)
412 | pc = call-site index
413 | 0 => terminate (should not see this for Ada)
414 | -1 => no-action
416 | CALL-SITE[]
418 | +=====================================+
419 | | landing-pad | first-action-index |
420 | +=====================================+
421 +-> | 0 => cleanups only |
422 | dispatch index N |
423 +=====================================+
426 ===================================
427 * Basic organization of this unit *
428 ===================================
430 The major point of this unit is to provide an exception propagation
431 personality routine for Ada. This is __gnat_personality_v0.
433 It is provided with a pointer to the propagated exception, an unwind
434 context describing a location the propagation is going through, and a
435 couple of other arguments including a description of the current
436 propagation phase.
438 It shall return to the generic propagation engine what is to be performed
439 next, after possible context adjustments, depending on what it finds in the
440 traversed context (a handler for the exception, a cleanup, nothing, ...),
441 and on the propagation phase.
443 A number of structures and subroutines are used for this purpose, as
444 sketched below:
446 o region_descriptor: General data associated with the context (base pc,
447 call-site table, action table, ttypes table, ...)
449 o action_descriptor: Data describing the action to be taken for the
450 propagated exception in the provided context (kind of action: nothing,
451 handler, cleanup; pointer to the action table entry, ...).
453 raise
455 ... (a-except.adb)
457 Propagate_Exception (a-exexpr.adb)
460 _Unwind_RaiseException (libgcc)
462 | (Ada frame)
464 +--> __gnat_personality_v0 (context, exception)
466 +--> get_region_description_for (context)
468 +--> get_action_description_for (ip, exception, region)
470 | +--> get_call_site_action_for (context, region)
471 | (one version for each underlying scheme)
473 +--> setup_to_install (context)
475 This unit is inspired from the C++ version found in eh_personality.cc,
476 part of libstdc++-v3.
481 /* This is an incomplete "proxy" of the structure of exception objects as
482 built by the GNAT runtime library. Accesses to other fields than the common
483 header are performed through subprogram calls to alleviate the need of an
484 exact counterpart here and potential alignment/size issues for the common
485 header. See a-exexpr.adb. */
487 typedef struct
489 _Unwind_Exception common;
490 /* ABI header, maximally aligned. */
491 } _GNAT_Exception;
493 /* The two constants below are specific ttype identifiers for special
494 exception ids. Their type should match what a-exexpr exports. */
496 extern const int __gnat_others_value;
497 #define GNAT_OTHERS ((_Unwind_Ptr) &__gnat_others_value)
499 extern const int __gnat_all_others_value;
500 #define GNAT_ALL_OTHERS ((_Unwind_Ptr) &__gnat_all_others_value)
502 extern const int __gnat_unhandled_others_value;
503 #define GNAT_UNHANDLED_OTHERS ((_Unwind_Ptr) &__gnat_unhandled_others_value)
505 /* Describe the useful region data associated with an unwind context. */
507 typedef struct
509 /* The base pc of the region. */
510 _Unwind_Ptr base;
512 /* Pointer to the Language Specific Data for the region. */
513 _Unwind_Ptr lsda;
515 /* Call-Site data associated with this region. */
516 unsigned char call_site_encoding;
517 const unsigned char *call_site_table;
519 /* The base to which are relative landing pad offsets inside the call-site
520 entries . */
521 _Unwind_Ptr lp_base;
523 /* Action-Table associated with this region. */
524 const unsigned char *action_table;
526 /* Ttype data associated with this region. */
527 unsigned char ttype_encoding;
528 const unsigned char *ttype_table;
529 _Unwind_Ptr ttype_base;
531 } region_descriptor;
533 /* Extract and adjust the IP (instruction pointer) from an exception
534 context. */
536 static _Unwind_Ptr
537 get_ip_from_context (_Unwind_Context *uw_context)
539 int ip_before_insn = 0;
540 #ifdef HAVE_GETIPINFO
541 _Unwind_Ptr ip = _Unwind_GetIPInfo (uw_context, &ip_before_insn);
542 #else
543 _Unwind_Ptr ip = _Unwind_GetIP (uw_context);
544 #endif
545 /* Subtract 1 if necessary because GetIPInfo yields a call return address
546 in this case, while we are interested in information for the call point.
547 This does not always yield the exact call instruction address but always
548 brings the IP back within the corresponding region. */
549 if (!ip_before_insn)
550 ip--;
552 return ip;
555 static void
556 db_region_for (region_descriptor *region, _Unwind_Ptr ip)
558 #ifndef inhibit_libc
559 if (! (db_accepted_codes () & DB_REGIONS))
560 return;
562 db (DB_REGIONS, "For ip @ %p => ", (void *)ip);
564 if (region->lsda)
565 db (DB_REGIONS, "lsda @ %p", (void *)region->lsda);
566 else
567 db (DB_REGIONS, "no lsda");
569 db (DB_REGIONS, "\n");
570 #endif
573 /* Retrieve the ttype entry associated with FILTER in the REGION's
574 ttype table. */
576 static _Unwind_Ptr
577 get_ttype_entry_for (region_descriptor *region, long filter)
579 _Unwind_Ptr ttype_entry;
581 filter *= size_of_encoded_value (region->ttype_encoding);
582 read_encoded_value_with_base
583 (region->ttype_encoding, region->ttype_base,
584 region->ttype_table - filter, &ttype_entry);
586 return ttype_entry;
589 /* Fill out the REGION descriptor for the provided UW_CONTEXT. */
591 static void
592 get_region_description_for (_Unwind_Context *uw_context,
593 region_descriptor *region)
595 const unsigned char * p;
596 _uleb128_t tmp;
597 unsigned char lpbase_encoding;
599 /* Get the base address of the lsda information. If the provided context
600 is null or if there is no associated language specific data, there's
601 nothing we can/should do. */
602 region->lsda
603 = (_Unwind_Ptr) (uw_context
604 ? _Unwind_GetLanguageSpecificData (uw_context) : 0);
606 if (! region->lsda)
607 return;
609 /* Parse the lsda and fill the region descriptor. */
610 p = (const unsigned char *)region->lsda;
612 region->base = _Unwind_GetRegionStart (uw_context);
614 /* Find @LPStart, the base to which landing pad offsets are relative. */
615 lpbase_encoding = *p++;
616 if (lpbase_encoding != DW_EH_PE_omit)
617 p = read_encoded_value
618 (uw_context, lpbase_encoding, p, &region->lp_base);
619 else
620 region->lp_base = region->base;
622 /* Find @TType, the base of the handler and exception spec type data. */
623 region->ttype_encoding = *p++;
624 if (region->ttype_encoding != DW_EH_PE_omit)
626 p = read_uleb128 (p, &tmp);
627 region->ttype_table = p + tmp;
629 else
630 region->ttype_table = 0;
632 region->ttype_base
633 = base_of_encoded_value (region->ttype_encoding, uw_context);
635 /* Get the encoding and length of the call-site table; the action table
636 immediately follows. */
637 region->call_site_encoding = *p++;
638 region->call_site_table = read_uleb128 (p, &tmp);
640 region->action_table = region->call_site_table + tmp;
644 /* Describe an action to be taken when propagating an exception up to
645 some context. */
647 enum action_kind
649 /* Found some call site base data, but need to analyze further
650 before being able to decide. */
651 unknown,
653 /* There is nothing relevant in the context at hand. */
654 nothing,
656 /* There are only cleanups to run in this context. */
657 cleanup,
659 /* There is a handler for the exception in this context. */
660 handler,
662 /* There is a handler for the exception, but it is only for catching
663 unhandled exceptions. */
664 unhandler
667 /* filter value for cleanup actions. */
668 static const int cleanup_filter = 0;
670 typedef struct
672 /* The kind of action to be taken. */
673 enum action_kind kind;
675 /* A pointer to the action record entry. */
676 const unsigned char *table_entry;
678 /* Where we should jump to actually take an action (trigger a cleanup or an
679 exception handler). */
680 _Unwind_Ptr landing_pad;
682 /* If we have a handler matching our exception, these are the filter to
683 trigger it and the corresponding id. */
684 _Unwind_Sword ttype_filter;
686 } action_descriptor;
688 static void
689 db_action_for (action_descriptor *action, _Unwind_Ptr ip)
691 #ifndef inhibit_libc
692 db (DB_ACTIONS, "For ip @ %p => ", (void *)ip);
694 switch (action->kind)
696 case unknown:
697 db (DB_ACTIONS, "lpad @ %p, record @ %p\n",
698 (void *) action->landing_pad, action->table_entry);
699 break;
701 case nothing:
702 db (DB_ACTIONS, "Nothing\n");
703 break;
705 case cleanup:
706 db (DB_ACTIONS, "Cleanup\n");
707 break;
709 case handler:
710 db (DB_ACTIONS, "Handler, filter = %d\n", (int) action->ttype_filter);
711 break;
713 default:
714 db (DB_ACTIONS, "Err? Unexpected action kind !\n");
715 break;
717 #endif
720 /* Search the call_site_table of REGION for an entry appropriate for the
721 UW_CONTEXT's IP. If one is found, store the associated landing_pad
722 and action_table entry, and set the ACTION kind to unknown for further
723 analysis. Otherwise, set the ACTION kind to nothing.
725 There are two variants of this routine, depending on the underlying
726 mechanism (DWARF/SJLJ), which account for differences in the tables. */
728 #ifdef __USING_SJLJ_EXCEPTIONS__
730 #define __builtin_eh_return_data_regno(x) x
732 static void
733 get_call_site_action_for (_Unwind_Ptr call_site,
734 region_descriptor *region,
735 action_descriptor *action)
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
740 be unsigned. */
742 if ((int)call_site < 0)
744 action->kind = nothing;
746 else if (call_site == 0)
748 db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n");
749 action->kind = nothing;
751 else
753 _uleb128_t cs_lp, cs_action;
754 const unsigned char *p;
756 /* Let the caller know there may be an action to take, but let it
757 determine the kind. */
758 action->kind = unknown;
760 /* We have a direct index into the call-site table, but this table is
761 made of leb128 values, the encoding length of which is variable. We
762 can't merely compute an offset from the index, then, but have to read
763 all the entries before the one of interest. */
764 p = region->call_site_table;
767 p = read_uleb128 (p, &cs_lp);
768 p = read_uleb128 (p, &cs_action);
770 while (--call_site);
772 action->landing_pad = cs_lp + 1;
774 if (cs_action)
775 action->table_entry = region->action_table + cs_action - 1;
776 else
777 action->table_entry = 0;
781 #else /* !__USING_SJLJ_EXCEPTIONS__ */
783 static void
784 get_call_site_action_for (_Unwind_Ptr ip,
785 region_descriptor *region,
786 action_descriptor *action)
788 const unsigned char *p = region->call_site_table;
790 /* Unless we are able to determine otherwise... */
791 action->kind = nothing;
793 db (DB_CSITE, "\n");
795 while (p < region->action_table)
797 _Unwind_Ptr cs_start, cs_len, cs_lp;
798 _uleb128_t cs_action;
800 /* Note that all call-site encodings are "absolute" displacements. */
801 p = read_encoded_value (0, region->call_site_encoding, p, &cs_start);
802 p = read_encoded_value (0, region->call_site_encoding, p, &cs_len);
803 p = read_encoded_value (0, region->call_site_encoding, p, &cs_lp);
804 p = read_uleb128 (p, &cs_action);
806 db (DB_CSITE,
807 "c_site @ %p (+%p), len = %p, lpad @ %p (+%p)\n",
808 (void *)region->base + cs_start, (void *)cs_start, (void *)cs_len,
809 (void *)region->lp_base + cs_lp, (void *)cs_lp);
811 /* The table is sorted, so if we've passed the IP, stop. */
812 if (ip < region->base + cs_start)
813 break;
815 /* If we have a match, fill the ACTION fields accordingly. */
816 else if (ip < region->base + cs_start + cs_len)
818 /* Let the caller know there may be an action to take, but let it
819 determine the kind. */
820 action->kind = unknown;
822 if (cs_lp)
823 action->landing_pad = region->lp_base + cs_lp;
824 else
825 action->landing_pad = 0;
827 if (cs_action)
828 action->table_entry = region->action_table + cs_action - 1;
829 else
830 action->table_entry = 0;
832 db (DB_CSITE, "+++\n");
833 return;
837 db (DB_CSITE, "---\n");
840 #endif /* __USING_SJLJ_EXCEPTIONS__ */
842 /* With CHOICE an exception choice representing an "exception - when"
843 argument, and PROPAGATED_EXCEPTION a pointer to the currently propagated
844 occurrence, return true if the latter matches the former, that is, if
845 PROPAGATED_EXCEPTION is caught by the handling code controlled by CHOICE.
846 This takes care of the special Non_Ada_Error case on VMS. */
848 #define Is_Handled_By_Others __gnat_is_handled_by_others
849 #define Language_For __gnat_language_for
850 #define Foreign_Data_For __gnat_foreign_data_for
851 #define EID_For __gnat_eid_for
853 extern bool Is_Handled_By_Others (_Unwind_Ptr eid);
854 extern char Language_For (_Unwind_Ptr eid);
856 extern void *Foreign_Data_For (_Unwind_Ptr eid);
858 extern Exception_Id EID_For (_GNAT_Exception * e);
860 #define Foreign_Exception system__exceptions__foreign_exception
861 extern struct Exception_Data Foreign_Exception;
863 #ifdef VMS
864 #define Non_Ada_Error system__aux_dec__non_ada_error
865 extern struct Exception_Data Non_Ada_Error;
866 #endif
868 /* Return true iff the exception class of EXCEPT is EC. */
870 static int
871 exception_class_eq (const _GNAT_Exception *except, _Unwind_Exception_Class ec)
873 #ifdef __ARM_EABI_UNWINDER__
874 return memcmp (except->common.exception_class, ec, 8) == 0;
875 #else
876 return except->common.exception_class == ec;
877 #endif
880 /* Return how CHOICE matches PROPAGATED_EXCEPTION. */
882 static enum action_kind
883 is_handled_by (_Unwind_Ptr choice, _GNAT_Exception *propagated_exception)
885 /* All others choice match everything. */
886 if (choice == GNAT_ALL_OTHERS)
887 return handler;
889 /* GNAT exception occurrence. */
890 if (exception_class_eq (propagated_exception, GNAT_EXCEPTION_CLASS))
892 /* Pointer to the GNAT exception data corresponding to the propagated
893 occurrence. */
894 _Unwind_Ptr E = (_Unwind_Ptr) EID_For (propagated_exception);
896 if (choice == GNAT_UNHANDLED_OTHERS)
897 return unhandler;
899 E = (_Unwind_Ptr) EID_For (propagated_exception);
901 /* Base matching rules: An exception data (id) matches itself, "when
902 all_others" matches anything and "when others" matches anything
903 unless explicitly stated otherwise in the propagated occurrence. */
904 if (choice == E || (choice == GNAT_OTHERS && Is_Handled_By_Others (E)))
905 return handler;
907 #ifdef VMS
908 /* In addition, on OpenVMS, Non_Ada_Error matches VMS exceptions, and we
909 may have different exception data pointers that should match for the
910 same condition code, if both an export and an import have been
911 registered. The import code for both the choice and the propagated
912 occurrence are expected to have been masked off regarding severity
913 bits already (at registration time for the former and from within the
914 low level exception vector for the latter). */
915 if ((Language_For (E) == 'V'
916 && choice != GNAT_OTHERS
917 && ((Language_For (choice) == 'V'
918 && Foreign_Data_For (choice) != 0
919 && Foreign_Data_For (choice) == Foreign_Data_For (E))
920 || choice == (_Unwind_Ptr)&Non_Ada_Error)))
921 return handler;
922 #endif
924 /* Otherwise, it doesn't match an Ada choice. */
925 return nothing;
928 /* All others and others choice match any foreign exception. */
929 if (choice == GNAT_ALL_OTHERS
930 || choice == GNAT_OTHERS
931 || choice == (_Unwind_Ptr) &Foreign_Exception)
932 return handler;
934 /* C++ exception occurrences. */
935 if (exception_class_eq (propagated_exception, CXX_EXCEPTION_CLASS)
936 && Language_For (choice) == 'C')
938 void *choice_typeinfo = Foreign_Data_For (choice);
939 void *except_typeinfo =
940 (((struct __cxa_exception *)
941 ((_Unwind_Exception *)propagated_exception + 1)) - 1)
942 ->exceptionType;
944 /* Typeinfo are directly compared, which might not be correct if they
945 aren't merged. ??? We should call the == operator if this module is
946 compiled in C++. */
947 if (choice_typeinfo == except_typeinfo)
948 return handler;
951 return nothing;
954 /* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
955 UW_CONTEXT in REGION. */
957 static void
958 get_action_description_for (_Unwind_Ptr ip,
959 _Unwind_Exception *uw_exception,
960 _Unwind_Action uw_phase,
961 region_descriptor *region,
962 action_descriptor *action)
964 _GNAT_Exception *gnat_exception = (_GNAT_Exception *) uw_exception;
966 /* Search the call site table first, which may get us a landing pad as well
967 as the head of an action record list. */
968 get_call_site_action_for (ip, region, action);
969 db_action_for (action, ip);
971 /* If there is not even a call_site entry, we are done. */
972 if (action->kind == nothing)
973 return;
975 /* Otherwise, check what we have at the place of the call site. */
977 /* No landing pad => no cleanups or handlers. */
978 if (action->landing_pad == 0)
980 action->kind = nothing;
981 return;
984 /* Landing pad + null table entry => only cleanups. */
985 else if (action->table_entry == 0)
987 action->kind = cleanup;
988 action->ttype_filter = cleanup_filter;
989 /* The filter initialization is not strictly necessary, as cleanup-only
990 landing pads don't look at the filter value. It is there to ensure
991 we don't pass random values and so trigger potential confusion when
992 installing the context later on. */
993 return;
996 /* Landing pad + Table entry => handlers + possible cleanups. */
997 else
999 const unsigned char * p = action->table_entry;
1000 _sleb128_t ar_filter, ar_disp;
1002 action->kind = nothing;
1004 while (1)
1006 p = read_sleb128 (p, &ar_filter);
1007 read_sleb128 (p, &ar_disp);
1008 /* Don't assign p here, as it will be incremented by ar_disp
1009 below. */
1011 /* Null filters are for cleanups. */
1012 if (ar_filter == cleanup_filter)
1014 action->kind = cleanup;
1015 action->ttype_filter = cleanup_filter;
1016 /* The filter initialization is required here, to ensure
1017 the target landing pad branches to the cleanup code if
1018 we happen not to find a matching handler. */
1021 /* Positive filters are for regular handlers. */
1022 else if (ar_filter > 0)
1024 /* Do not catch an exception if the _UA_FORCE_UNWIND flag is
1025 passed (to follow the ABI). */
1026 if (!(uw_phase & _UA_FORCE_UNWIND))
1028 enum action_kind act;
1030 /* See if the filter we have is for an exception which
1031 matches the one we are propagating. */
1032 _Unwind_Ptr choice =
1033 get_ttype_entry_for (region, ar_filter);
1035 act = is_handled_by (choice, gnat_exception);
1036 if (act != nothing)
1038 action->kind = act;
1039 action->ttype_filter = ar_filter;
1040 return;
1045 /* Negative filter values are for C++ exception specifications.
1046 Should not be there for Ada :/ */
1047 else
1048 db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");
1050 if (ar_disp == 0)
1051 return;
1053 p += ar_disp;
1058 /* Setup in UW_CONTEXT the eh return target IP and data registers, which will
1059 be restored with the others and retrieved by the landing pad once the jump
1060 occurred. */
1062 static void
1063 setup_to_install (_Unwind_Context *uw_context,
1064 _Unwind_Exception *uw_exception,
1065 _Unwind_Ptr uw_landing_pad,
1066 int uw_filter)
1068 /* 1/ exception object pointer, which might be provided back to
1069 _Unwind_Resume (and thus to this personality routine) if we are jumping
1070 to a cleanup. */
1071 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (0),
1072 (_Unwind_Word)uw_exception);
1074 /* 2/ handler switch value register, which will also be used by the target
1075 landing pad to decide what action it shall take. */
1076 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (1),
1077 (_Unwind_Word)uw_filter);
1079 /* Setup the address we should jump at to reach the code where there is the
1080 "something" we found. */
1081 _Unwind_SetIP (uw_context, uw_landing_pad);
1084 /* The following is defined from a-except.adb. Its purpose is to enable
1085 automatic backtraces upon exception raise, as provided through the
1086 GNAT.Traceback facilities. */
1087 extern void __gnat_notify_handled_exception (struct Exception_Occurrence *);
1088 extern void __gnat_notify_unhandled_exception (struct Exception_Occurrence *);
1090 /* Below is the eh personality routine per se. We currently assume that only
1091 GNU-Ada exceptions are met. */
1093 /* By default, the personality routine is public. */
1094 #define PERSONALITY_STORAGE
1096 #ifdef __USING_SJLJ_EXCEPTIONS__
1097 #define PERSONALITY_FUNCTION __gnat_personality_sj0
1098 #elif defined (__SEH__)
1099 #define PERSONALITY_FUNCTION __gnat_personality_imp
1100 /* The public personality routine for seh is __gnat_personality_seh0, defined
1101 below using the SEH convention. This is a wrapper around the GNU routine,
1102 which is static. */
1103 #undef PERSONALITY_STORAGE
1104 #define PERSONALITY_STORAGE static
1105 #else
1106 #define PERSONALITY_FUNCTION __gnat_personality_v0
1107 #endif
1109 /* Code executed to continue unwinding. With the ARM unwinder, the
1110 personality routine must unwind one frame (per EHABI 7.3 4.). */
1112 static _Unwind_Reason_Code
1113 continue_unwind (struct _Unwind_Exception* ue_header ATTRIBUTE_UNUSED,
1114 struct _Unwind_Context* uw_context ATTRIBUTE_UNUSED)
1116 #ifdef __ARM_EABI_UNWINDER__
1117 if (__gnu_unwind_frame (ue_header, uw_context) != _URC_OK)
1118 return _URC_FAILURE;
1119 #endif
1120 return _URC_CONTINUE_UNWIND;
1123 /* Common code for the body of GNAT personality routine. This code is shared
1124 between all unwinders. */
1126 static _Unwind_Reason_Code
1127 personality_body (_Unwind_Action uw_phases,
1128 _Unwind_Exception *uw_exception,
1129 _Unwind_Context *uw_context)
1131 region_descriptor region;
1132 action_descriptor action;
1133 _Unwind_Ptr ip;
1135 /* Debug traces. */
1136 db_indent (DB_INDENT_RESET);
1137 db_phases (uw_phases);
1138 db_indent (DB_INDENT_INCREASE);
1140 /* Get the region description for the context we were provided with. This
1141 will tell us if there is some lsda, call_site, action and/or ttype data
1142 for the associated ip. */
1143 get_region_description_for (uw_context, &region);
1145 /* No LSDA => no handlers or cleanups => we shall unwind further up. */
1146 if (! region.lsda)
1147 return continue_unwind (uw_exception, uw_context);
1149 /* Get the instruction pointer. */
1150 ip = get_ip_from_context (uw_context);
1151 db_region_for (&region, ip);
1153 /* Search the call-site and action-record tables for the action associated
1154 with this IP. */
1155 get_action_description_for (ip, uw_exception, uw_phases, &region, &action);
1156 db_action_for (&action, ip);
1158 /* Whatever the phase, if there is nothing relevant in this frame,
1159 unwinding should just go on. */
1160 if (action.kind == nothing)
1161 return continue_unwind (uw_exception, uw_context);
1163 /* If we found something in search phase, we should return a code indicating
1164 what to do next depending on what we found. If we only have cleanups
1165 around, we shall try to unwind further up to find a handler, otherwise,
1166 tell we have a handler, which will trigger the second phase. */
1167 if (uw_phases & _UA_SEARCH_PHASE)
1169 if (action.kind == cleanup)
1171 return continue_unwind (uw_exception, uw_context);
1173 else
1175 struct Exception_Occurrence *excep;
1177 /* Trigger the appropriate notification routines before the second
1178 phase starts, which ensures the stack is still intact.
1179 First, setup the Ada occurrence. */
1180 excep = __gnat_setup_current_excep (uw_exception);
1181 if (action.kind == unhandler)
1182 __gnat_notify_unhandled_exception (excep);
1183 else
1184 __gnat_notify_handled_exception (excep);
1186 return _URC_HANDLER_FOUND;
1190 /* We found something in cleanup/handler phase, which might be the handler
1191 or a cleanup for a handled occurrence, or a cleanup for an unhandled
1192 occurrence (we are in a FORCED_UNWIND phase in this case). Install the
1193 context to get there. */
1195 setup_to_install
1196 (uw_context, uw_exception, action.landing_pad, action.ttype_filter);
1198 /* Write current exception, so that it can be retrieved from Ada. It was
1199 already done during phase 1 (just above), but in between, one or several
1200 exceptions may have been raised (in cleanup handlers). */
1201 __gnat_setup_current_excep (uw_exception);
1203 return _URC_INSTALL_CONTEXT;
1206 #ifndef __ARM_EABI_UNWINDER__
1207 /* Major tweak for ia64-vms : the CHF propagation phase calls this personality
1208 routine with sigargs/mechargs arguments and has very specific expectations
1209 on possible return values.
1211 We handle this with a number of specific tricks:
1213 1. We tweak the personality routine prototype to have the "version" and
1214 "phases" two first arguments be void * instead of int and _Unwind_Action
1215 as nominally expected in the GCC context.
1217 This allows us to access the full range of bits passed in every case and
1218 has no impact on the callers side since each argument remains assigned
1219 the same single 64bit slot.
1221 2. We retrieve the corresponding int and _Unwind_Action values within the
1222 routine for regular use with truncating conversions. This is a noop when
1223 called from the libgcc unwinder.
1225 3. We assume we're called by the VMS CHF when unexpected bits are set in
1226 both those values. The incoming arguments are then real sigargs and
1227 mechargs pointers, which we then redirect to __gnat_handle_vms_condition
1228 for proper processing.
1230 #if defined (VMS) && defined (__IA64)
1231 typedef void * version_arg_t;
1232 typedef void * phases_arg_t;
1233 #else
1234 typedef int version_arg_t;
1235 typedef _Unwind_Action phases_arg_t;
1236 #endif
1238 PERSONALITY_STORAGE _Unwind_Reason_Code
1239 PERSONALITY_FUNCTION (version_arg_t, phases_arg_t,
1240 _Unwind_Exception_Class, _Unwind_Exception *,
1241 _Unwind_Context *);
1243 PERSONALITY_STORAGE _Unwind_Reason_Code
1244 PERSONALITY_FUNCTION (version_arg_t version_arg,
1245 phases_arg_t phases_arg,
1246 _Unwind_Exception_Class uw_exception_class
1247 ATTRIBUTE_UNUSED,
1248 _Unwind_Exception *uw_exception,
1249 _Unwind_Context *uw_context)
1251 /* Fetch the version and phases args with their nominal ABI types for later
1252 use. This is a noop everywhere except on ia64-vms when called from the
1253 Condition Handling Facility. */
1254 int uw_version = (int) version_arg;
1255 _Unwind_Action uw_phases = (_Unwind_Action) phases_arg;
1257 /* Check that we're called from the ABI context we expect, with a major
1258 possible variation on VMS for IA64. */
1259 if (uw_version != 1)
1261 #if defined (VMS) && defined (__IA64)
1263 /* Assume we're called with sigargs/mechargs arguments if really
1264 unexpected bits are set in our first two formals. Redirect to the
1265 GNAT condition handling code in this case. */
1267 extern long __gnat_handle_vms_condition (void *, void *);
1269 unsigned int version_unexpected_bits_mask = 0xffffff00U;
1270 unsigned int phases_unexpected_bits_mask = 0xffffff00U;
1272 if ((unsigned int)uw_version & version_unexpected_bits_mask
1273 && (unsigned int)uw_phases & phases_unexpected_bits_mask)
1274 return __gnat_handle_vms_condition (version_arg, phases_arg);
1275 #endif
1277 return _URC_FATAL_PHASE1_ERROR;
1280 return personality_body (uw_phases, uw_exception, uw_context);
1283 #else /* __ARM_EABI_UNWINDER__ */
1285 PERSONALITY_STORAGE _Unwind_Reason_Code
1286 PERSONALITY_FUNCTION (_Unwind_State state,
1287 struct _Unwind_Exception* ue_header,
1288 struct _Unwind_Context* uw_context);
1290 PERSONALITY_STORAGE _Unwind_Reason_Code
1291 PERSONALITY_FUNCTION (_Unwind_State state,
1292 struct _Unwind_Exception* uw_exception,
1293 struct _Unwind_Context* uw_context)
1295 _Unwind_Action uw_phases;
1297 switch (state & _US_ACTION_MASK)
1299 case _US_VIRTUAL_UNWIND_FRAME:
1300 /* Phase 1. */
1301 uw_phases = _UA_SEARCH_PHASE;
1302 break;
1304 case _US_UNWIND_FRAME_STARTING:
1305 /* Phase 2, to call a cleanup. */
1306 uw_phases = _UA_CLEANUP_PHASE;
1307 #if 0
1308 /* ??? We don't use UA_HANDLER_FRAME (except to debug). Futhermore,
1309 barrier_cache.sp isn't yet set. */
1310 if (!(state & _US_FORCE_UNWIND)
1311 && (uw_exception->barrier_cache.sp
1312 == _Unwind_GetGR (uw_context, UNWIND_STACK_REG)))
1313 uw_phases |= _UA_HANDLER_FRAME;
1314 #endif
1315 break;
1317 case _US_UNWIND_FRAME_RESUME:
1318 /* Phase 2, called at the return of a cleanup. In the GNU
1319 implementation, there is nothing left to do, so we simply go on. */
1320 return continue_unwind (uw_exception, uw_context);
1322 default:
1323 return _URC_FAILURE;
1325 uw_phases |= (state & _US_FORCE_UNWIND);
1327 /* The dwarf unwinder assumes the context structure holds things like the
1328 function and LSDA pointers. The ARM implementation caches these in
1329 the exception header (UCB). To avoid rewriting everything we make a
1330 virtual scratch register point at the UCB. This is a GNU specific
1331 requirement. */
1332 _Unwind_SetGR (uw_context, UNWIND_POINTER_REG, (_Unwind_Ptr) uw_exception);
1334 return personality_body (uw_phases, uw_exception, uw_context);
1336 #endif /* __ARM_EABI_UNWINDER__ */
1338 /* Callback routine called by Unwind_ForcedUnwind to execute all the cleanup
1339 before exiting the task. */
1341 _Unwind_Reason_Code
1342 __gnat_cleanupunwind_handler (int version ATTRIBUTE_UNUSED,
1343 _Unwind_Action phases,
1344 _Unwind_Exception_Class eclass ATTRIBUTE_UNUSED,
1345 struct _Unwind_Exception *exception,
1346 struct _Unwind_Context *context ATTRIBUTE_UNUSED,
1347 void *arg ATTRIBUTE_UNUSED)
1349 /* Terminate when the end of the stack is reached. */
1350 if ((phases & _UA_END_OF_STACK) != 0
1351 #if defined (__ia64__) && defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
1352 /* Strictely follow the ia64 ABI: when end of stack is reached,
1353 the callback will be called with a NULL stack pointer.
1354 No need for that when using libgcc unwinder. */
1355 || _Unwind_GetGR (context, 12) == 0
1356 #endif
1358 __gnat_unhandled_except_handler (exception);
1360 /* We know there is at least one cleanup further up. Return so that it
1361 is searched and entered, after which Unwind_Resume will be called
1362 and this hook will gain control again. */
1363 return _URC_NO_REASON;
1366 /* Define the consistently named wrappers imported by Propagate_Exception. */
1368 _Unwind_Reason_Code
1369 __gnat_Unwind_RaiseException (_Unwind_Exception *e)
1371 #ifdef __USING_SJLJ_EXCEPTIONS__
1372 return _Unwind_SjLj_RaiseException (e);
1373 #else
1374 return _Unwind_RaiseException (e);
1375 #endif
1378 _Unwind_Reason_Code
1379 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e ATTRIBUTE_UNUSED,
1380 void *handler ATTRIBUTE_UNUSED,
1381 void *argument ATTRIBUTE_UNUSED)
1383 #ifdef __USING_SJLJ_EXCEPTIONS__
1385 # if defined (__APPLE__) && defined (__arm__)
1386 /* There is not ForcedUnwind routine in arm-darwin system library. */
1387 return _URC_FATAL_PHASE1_ERROR;
1388 # else
1389 return _Unwind_SjLj_ForcedUnwind (e, handler, argument);
1390 # endif
1392 #else
1393 return _Unwind_ForcedUnwind (e, handler, argument);
1394 #endif
1397 #if defined (__SEH__) && !defined (__USING_SJLJ_EXCEPTIONS__)
1399 #define STATUS_USER_DEFINED (1U << 29)
1401 /* From unwind-seh.c. */
1402 #define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C')
1403 #define GCC_EXCEPTION(TYPE) \
1404 (STATUS_USER_DEFINED | ((TYPE) << 24) | GCC_MAGIC)
1405 #define STATUS_GCC_THROW GCC_EXCEPTION (0)
1407 EXCEPTION_DISPOSITION __gnat_SEH_error_handler
1408 (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
1410 struct Exception_Data *
1411 __gnat_map_SEH (EXCEPTION_RECORD* ExceptionRecord, const char **msg);
1413 struct _Unwind_Exception *
1414 __gnat_create_machine_occurrence_from_signal_handler (Exception_Id,
1415 const char *);
1417 /* Unwind opcodes. */
1418 #define UWOP_PUSH_NONVOL 0
1419 #define UWOP_ALLOC_LARGE 1
1420 #define UWOP_ALLOC_SMALL 2
1421 #define UWOP_SET_FPREG 3
1422 #define UWOP_SAVE_NONVOL 4
1423 #define UWOP_SAVE_NONVOL_FAR 5
1424 #define UWOP_SAVE_XMM128 8
1425 #define UWOP_SAVE_XMM128_FAR 9
1426 #define UWOP_PUSH_MACHFRAME 10
1428 /* Modify the IP value saved in the machine frame. This is really a kludge,
1429 that will be removed if we could propagate the Windows exception (and not
1430 the GCC one).
1431 What is very wrong is that the Windows unwinder will try to decode the
1432 instruction at IP, which isn't valid anymore after the adjust. */
1434 static void
1435 __gnat_adjust_context (unsigned char *unw, ULONG64 rsp)
1437 unsigned int len;
1439 /* Version = 1, no flags, no prologue. */
1440 if (unw[0] != 1 || unw[1] != 0)
1441 return;
1442 len = unw[2];
1443 /* No frame pointer. */
1444 if (unw[3] != 0)
1445 return;
1446 unw += 4;
1447 while (len > 0)
1449 /* Offset in prologue = 0. */
1450 if (unw[0] != 0)
1451 return;
1452 switch (unw[1] & 0xf)
1454 case UWOP_ALLOC_LARGE:
1455 /* Expect < 512KB. */
1456 if ((unw[1] & 0xf0) != 0)
1457 return;
1458 rsp += *(unsigned short *)(unw + 2) * 8;
1459 len--;
1460 unw += 2;
1461 break;
1462 case UWOP_SAVE_NONVOL:
1463 case UWOP_SAVE_XMM128:
1464 len--;
1465 unw += 2;
1466 break;
1467 case UWOP_PUSH_MACHFRAME:
1469 ULONG64 *rip;
1470 rip = (ULONG64 *)rsp;
1471 if ((unw[1] & 0xf0) == 0x10)
1472 rip++;
1473 /* Adjust rip. */
1474 (*rip)++;
1476 return;
1477 default:
1478 /* Unexpected. */
1479 return;
1481 unw += 2;
1482 len--;
1486 EXCEPTION_DISPOSITION
1487 __gnat_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
1488 PCONTEXT ms_orig_context,
1489 PDISPATCHER_CONTEXT ms_disp)
1491 /* Possibly transform run-time errors into Ada exceptions. As a small
1492 optimization, we call __gnat_SEH_error_handler only on non-user
1493 exceptions. */
1494 if (!(ms_exc->ExceptionCode & STATUS_USER_DEFINED))
1496 struct Exception_Data *exception;
1497 const char *msg;
1498 ULONG64 excpip = (ULONG64) ms_exc->ExceptionAddress;
1500 if (excpip != 0
1501 && excpip >= (ms_disp->ImageBase
1502 + ms_disp->FunctionEntry->BeginAddress)
1503 && excpip < (ms_disp->ImageBase
1504 + ms_disp->FunctionEntry->EndAddress))
1506 /* This is a fault in this function. We need to adjust the return
1507 address before raising the GCC exception. */
1508 CONTEXT context;
1509 PRUNTIME_FUNCTION mf_func = NULL;
1510 ULONG64 mf_imagebase;
1511 ULONG64 mf_rsp = 0;
1513 /* Get the context. */
1514 RtlCaptureContext (&context);
1516 while (1)
1518 PRUNTIME_FUNCTION RuntimeFunction;
1519 ULONG64 ImageBase;
1520 VOID *HandlerData;
1521 ULONG64 EstablisherFrame;
1523 /* Get function metadata. */
1524 RuntimeFunction = RtlLookupFunctionEntry
1525 (context.Rip, &ImageBase, ms_disp->HistoryTable);
1526 if (RuntimeFunction == ms_disp->FunctionEntry)
1527 break;
1528 mf_func = RuntimeFunction;
1529 mf_imagebase = ImageBase;
1530 mf_rsp = context.Rsp;
1532 if (!RuntimeFunction)
1534 /* In case of failure, assume this is a leaf function. */
1535 context.Rip = *(ULONG64 *) context.Rsp;
1536 context.Rsp += 8;
1538 else
1540 /* Unwind. */
1541 RtlVirtualUnwind (0, ImageBase, context.Rip, RuntimeFunction,
1542 &context, &HandlerData, &EstablisherFrame,
1543 NULL);
1546 /* 0 means bottom of the stack. */
1547 if (context.Rip == 0)
1549 mf_func = NULL;
1550 break;
1553 if (mf_func != NULL)
1554 __gnat_adjust_context
1555 ((unsigned char *)(mf_imagebase + mf_func->UnwindData), mf_rsp);
1558 exception = __gnat_map_SEH (ms_exc, &msg);
1559 if (exception != NULL)
1561 struct _Unwind_Exception *exc;
1563 /* Directly convert the system exception to a GCC one.
1564 This is really breaking the API, but is necessary for stack size
1565 reasons: the normal way is to call Raise_From_Signal_Handler,
1566 which build the exception and calls _Unwind_RaiseException, which
1567 unwinds the stack and will call this personality routine. But
1568 the Windows unwinder needs about 2KB of stack. */
1569 exc = __gnat_create_machine_occurrence_from_signal_handler
1570 (exception, msg);
1571 memset (exc->private_, 0, sizeof (exc->private_));
1572 ms_exc->ExceptionCode = STATUS_GCC_THROW;
1573 ms_exc->NumberParameters = 1;
1574 ms_exc->ExceptionInformation[0] = (ULONG_PTR)exc;
1579 return _GCC_specific_handler (ms_exc, this_frame, ms_orig_context,
1580 ms_disp, __gnat_personality_imp);
1582 #endif /* SEH */
1584 #if !defined (__USING_SJLJ_EXCEPTIONS__)
1585 /* Size of the _Unwind_Exception structure. This is used by g-cppexc to get
1586 the offset to the C++ object. */
1588 const int __gnat_unwind_exception_size = sizeof (_Unwind_Exception);
1589 #endif