PR rtl-optimization/79386
[official-gcc.git] / gcc / ada / raise-gcc.c
blob0074ad53fbc0def9a9bc9e7f2bfb3503cc10e574
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-2016, 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 #ifndef CERT
40 #include "tconfig.h"
41 #include "tsystem.h"
42 #else
43 #define ATTRIBUTE_UNUSED __attribute__((unused))
44 #define HAVE_GETIPINFO 1
45 #endif
47 #include <stdarg.h>
48 typedef char bool;
49 # define true 1
50 # define false 0
52 #include "raise.h"
54 #ifdef __APPLE__
55 /* On MacOS X, versions older than 10.5 don't export _Unwind_GetIPInfo. */
56 #undef HAVE_GETIPINFO
57 #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
58 #define HAVE_GETIPINFO 1
59 #endif
60 #endif
62 #if defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
63 /* HP-UX B.11.31 ia64 libunwind doesn't have _Unwind_GetIPInfo. */
64 #undef HAVE_GETIPINFO
65 #define _UA_END_OF_STACK 0
66 #endif
68 /* The names of a couple of "standard" routines for unwinding/propagation
69 actually vary depending on the underlying GCC scheme for exception handling
70 (SJLJ or DWARF). We need a consistently named interface to import from
71 a-except, so wrappers are defined here. */
73 #include "unwind.h"
75 typedef struct _Unwind_Context _Unwind_Context;
76 typedef struct _Unwind_Exception _Unwind_Exception;
78 _Unwind_Reason_Code
79 __gnat_Unwind_RaiseException (_Unwind_Exception *);
81 _Unwind_Reason_Code
82 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *, void *, void *);
84 extern struct Exception_Occurrence *__gnat_setup_current_excep
85 (_Unwind_Exception *);
86 extern void __gnat_unhandled_except_handler (_Unwind_Exception *);
88 #ifdef CERT
89 /* Called in case of error during propagation. */
90 extern void __gnat_raise_abort (void) __attribute__ ((noreturn));
91 #define abort() __gnat_raise_abort()
92 #endif
94 #include "unwind-pe.h"
96 /* The known and handled exception classes. */
98 #ifdef __ARM_EABI_UNWINDER__
99 #define CXX_EXCEPTION_CLASS "GNUCC++"
100 #define GNAT_EXCEPTION_CLASS "GNU-Ada"
101 #else
102 #define CXX_EXCEPTION_CLASS 0x474e5543432b2b00ULL
103 #define GNAT_EXCEPTION_CLASS 0x474e552d41646100ULL
104 #endif
106 /* Structure of a C++ exception, represented as a C structure... See
107 unwind-cxx.h for the full definition. */
109 struct __cxa_exception
111 void *exceptionType;
112 void (*exceptionDestructor)(void *);
114 void (*unexpectedHandler)();
115 void (*terminateHandler)();
117 struct __cxa_exception *nextException;
119 int handlerCount;
121 #ifdef __ARM_EABI_UNWINDER__
122 struct __cxa_exception* nextPropagatingException;
124 int propagationCount;
125 #else
126 int handlerSwitchValue;
127 const unsigned char *actionRecord;
128 const unsigned char *languageSpecificData;
129 _Unwind_Ptr catchTemp;
130 void *adjustedPtr;
131 #endif
133 _Unwind_Exception unwindHeader;
136 /* --------------------------------------------------------------
137 -- The DB stuff below is there for debugging purposes only. --
138 -------------------------------------------------------------- */
140 #ifndef inhibit_libc
142 #define DB_PHASES 0x1
143 #define DB_CSITE 0x2
144 #define DB_ACTIONS 0x4
145 #define DB_REGIONS 0x8
147 #define DB_ERR 0x1000
149 /* The "action" stuff below is also there for debugging purposes only. */
151 typedef struct
153 _Unwind_Action phase;
154 const char * description;
155 } phase_descriptor;
157 static const phase_descriptor phase_descriptors[]
158 = {{ _UA_SEARCH_PHASE, "SEARCH_PHASE" },
159 { _UA_CLEANUP_PHASE, "CLEANUP_PHASE" },
160 { _UA_HANDLER_FRAME, "HANDLER_FRAME" },
161 { _UA_FORCE_UNWIND, "FORCE_UNWIND" },
162 { -1, 0}};
164 static int
165 db_accepted_codes (void)
167 static int accepted_codes = -1;
169 if (accepted_codes == -1)
171 char * db_env = (char *) getenv ("EH_DEBUG");
173 accepted_codes = db_env ? (atoi (db_env) | DB_ERR) : 0;
174 /* Arranged for ERR stuff to always be visible when the variable
175 is defined. One may just set the variable to 0 to see the ERR
176 stuff only. */
179 return accepted_codes;
182 #define DB_INDENT_INCREASE 0x01
183 #define DB_INDENT_DECREASE 0x02
184 #define DB_INDENT_OUTPUT 0x04
185 #define DB_INDENT_NEWLINE 0x08
186 #define DB_INDENT_RESET 0x10
188 #define DB_INDENT_UNIT 8
190 static void
191 db_indent (int requests)
193 static int current_indentation_level = 0;
195 if (requests & DB_INDENT_RESET)
196 current_indentation_level = 0;
198 if (requests & DB_INDENT_INCREASE)
199 current_indentation_level ++;
201 if (requests & DB_INDENT_DECREASE)
202 current_indentation_level --;
204 if (requests & DB_INDENT_NEWLINE)
205 fprintf (stderr, "\n");
207 if (requests & DB_INDENT_OUTPUT)
208 fprintf (stderr, "%*s", current_indentation_level * DB_INDENT_UNIT, " ");
211 static void ATTRIBUTE_PRINTF_2
212 db (int db_code, char * msg_format, ...)
214 if (db_accepted_codes () & db_code)
216 va_list msg_args;
218 db_indent (DB_INDENT_OUTPUT);
220 va_start (msg_args, msg_format);
221 vfprintf (stderr, msg_format, msg_args);
222 va_end (msg_args);
226 static void
227 db_phases (int phases)
229 const phase_descriptor *a = phase_descriptors;
231 if (! (db_accepted_codes () & DB_PHASES))
232 return;
234 db (DB_PHASES, "\n");
236 for (; a->description != 0; a++)
237 if (phases & a->phase)
238 db (DB_PHASES, "%s ", a->description);
240 db (DB_PHASES, " :\n");
242 #else /* !inhibit_libc */
243 #define db_phases(X)
244 #define db_indent(X)
245 #define db(X, ...)
246 #endif /* !inhibit_libc */
248 /* ---------------------------------------------------------------
249 -- Now come a set of useful structures and helper routines. --
250 --------------------------------------------------------------- */
252 /* There are three major runtime tables involved, generated by the
253 GCC back-end. Contents slightly vary depending on the underlying
254 implementation scheme (dwarf zero cost / sjlj).
256 =======================================
257 * Tables for the dwarf zero cost case *
258 =======================================
260 They are fully documented in:
261 http://sourcery.mentor.com/public/cxx-abi/exceptions.pdf
262 Here is a shorter presentation, with some specific comments for Ada.
264 call_site []
265 -------------------------------------------------------------------
266 * region-start | region-length | landing-pad | first-action-index *
267 -------------------------------------------------------------------
269 Identify possible actions to be taken and where to resume control
270 for that when an exception propagates through a pc inside the region
271 delimited by start and length.
273 A null landing-pad indicates that nothing is to be done.
275 Otherwise, first-action-index provides an entry into the action[]
276 table which heads a list of possible actions to be taken (see below).
278 If it is determined that indeed an action should be taken, that
279 is, if one action filter matches the exception being propagated,
280 then control should be transferred to landing-pad.
282 A null first-action-index indicates that there are only cleanups
283 to run there.
285 action []
286 -------------------------------
287 * action-filter | next-action *
288 -------------------------------
290 This table contains lists (called action chains) of possible actions
291 associated with call-site entries described in the call-site [] table.
292 There is at most one action list per call-site entry. It is SLEB128
293 encoded.
295 A null action-filter indicates a cleanup.
297 Non null action-filters provide an index into the ttypes [] table
298 (see below), from which information may be retrieved to check if it
299 matches the exception being propagated.
301 * action-filter > 0:
302 means there is a regular handler to be run The value is also passed
303 to the landing pad to dispatch the exception.
305 * action-filter < 0:
306 means there is a some "exception_specification" data to retrieve,
307 which is only relevant for C++ and should never show up for Ada.
308 (Exception specification specifies which exceptions can be thrown
309 by a function. Such filter is emitted around the body of C++
310 functions defined like:
311 void foo ([...]) throw (A, B) { [...] }
312 These can be viewed as negativ filter: the landing pad is branched
313 to for exceptions that doesn't match the filter and usually aborts
314 the program).
316 * next-action
317 points to the next entry in the list using a relative byte offset. 0
318 indicates there is no other entry.
320 ttypes []
321 ---------------
322 * ttype-value *
323 ---------------
325 This table is an array of addresses.
327 A null value indicates a catch-all handler. (Not used by Ada)
329 Non null values are used to match the exception being propagated:
330 In C++ this is a pointer to some rtti data, while in Ada this is an
331 exception id (with a fake id for others).
333 For C++, this table is actually also used to store "exception
334 specification" data. The differentiation between the two kinds
335 of entries is made by the sign of the associated action filter,
336 which translates into positive or negative offsets from the
337 so called base of the table:
339 Exception Specification data is stored at positive offsets from
340 the ttypes table base, which Exception Type data is stored at
341 negative offsets:
343 ---------------------------------------------------------------------------
345 Here is a quick summary of the tables organization:
347 +-- Unwind_Context (pc, ...)
349 |(pc)
351 | CALL-SITE[]
353 | +=============================================================+
354 | | region-start + length | landing-pad | first-action-index |
355 | +=============================================================+
356 +-> | pc range 0 => no-action 0 => cleanups only |
357 | !0 => jump @ N --+ |
358 +====================================================== | ====+
361 ACTION [] |
363 +==========================================================+ |
364 | action-filter | next-action | |
365 +==========================================================+ |
366 | 0 => cleanup | |
367 | >0 => ttype index for handler ------+ 0 => end of chain | <-+
368 | <0 => ttype index for spec data | |
369 +==================================== | ===================+
372 TTYPES [] |
373 | Offset negated from
374 +=====================+ | the actual base.
375 | ttype-value | |
376 +============+=====================+ |
377 | | ... | |
378 | ... | exception id | <---+
379 | | ... |
380 | handlers +---------------------+
381 | | ... |
382 | ... | ... |
383 | | ... |
384 +============+=====================+ <<------ Table base
385 | ... | ... |
386 | specs | ... | (should not see negative filter
387 | ... | ... | values for Ada).
388 +============+=====================+
391 ============================
392 * Tables for the sjlj case *
393 ============================
395 So called "function contexts" are pushed on a context stack by calls to
396 _Unwind_SjLj_Register on function entry, and popped off at exit points by
397 calls to _Unwind_SjLj_Unregister. The current call_site for a function is
398 updated in the function context as the function's code runs along.
400 The generic unwinding engine in _Unwind_RaiseException walks the function
401 context stack and not the actual call chain.
403 The ACTION and TTYPES tables remain unchanged, which allows to search them
404 during the propagation phase to determine whether or not the propagated
405 exception is handled somewhere. When it is, we only "jump" up once directly
406 to the context where the handler will be found. Besides, this allows "break
407 exception unhandled" to work also
409 The CALL-SITE table is setup differently, though: the pc attached to the
410 unwind context is a direct index into the table, so the entries in this
411 table do not hold region bounds any more.
413 A special index (-1) is used to indicate that no action is possibly
414 connected with the context at hand, so null landing pads cannot appear
415 in the table.
417 Additionally, landing pad values in the table do not represent code address
418 to jump at, but so called "dispatch" indices used by a common landing pad
419 for the function to switch to the appropriate post-landing-pad.
421 +-- Unwind_Context (pc, ...)
423 | pc = call-site index
424 | 0 => terminate (should not see this for Ada)
425 | -1 => no-action
427 | CALL-SITE[]
429 | +=====================================+
430 | | landing-pad | first-action-index |
431 | +=====================================+
432 +-> | 0 => cleanups only |
433 | dispatch index N |
434 +=====================================+
437 ===================================
438 * Basic organization of this unit *
439 ===================================
441 The major point of this unit is to provide an exception propagation
442 personality routine for Ada. This is __gnat_personality_v0.
444 It is provided with a pointer to the propagated exception, an unwind
445 context describing a location the propagation is going through, and a
446 couple of other arguments including a description of the current
447 propagation phase.
449 It shall return to the generic propagation engine what is to be performed
450 next, after possible context adjustments, depending on what it finds in the
451 traversed context (a handler for the exception, a cleanup, nothing, ...),
452 and on the propagation phase.
454 A number of structures and subroutines are used for this purpose, as
455 sketched below:
457 o region_descriptor: General data associated with the context (base pc,
458 call-site table, action table, ttypes table, ...)
460 o action_descriptor: Data describing the action to be taken for the
461 propagated exception in the provided context (kind of action: nothing,
462 handler, cleanup; pointer to the action table entry, ...).
464 raise
466 ... (a-except.adb)
468 Propagate_Exception (a-exexpr.adb)
471 _Unwind_RaiseException (libgcc)
473 | (Ada frame)
475 +--> __gnat_personality_v0 (context, exception)
477 +--> get_region_description_for (context)
479 +--> get_action_description_for (ip, exception, region)
481 | +--> get_call_site_action_for (context, region)
482 | (one version for each underlying scheme)
484 +--> setup_to_install (context)
486 This unit is inspired from the C++ version found in eh_personality.cc,
487 part of libstdc++-v3.
492 /* This is an incomplete "proxy" of the structure of exception objects as
493 built by the GNAT runtime library. Accesses to other fields than the common
494 header are performed through subprogram calls to alleviate the need of an
495 exact counterpart here and potential alignment/size issues for the common
496 header. See a-exexpr.adb. */
498 typedef struct
500 _Unwind_Exception common;
501 /* ABI header, maximally aligned. */
502 } _GNAT_Exception;
504 /* The two constants below are specific ttype identifiers for special
505 exception ids. Their type should match what a-exexpr exports. */
507 extern const int __gnat_others_value;
508 #define GNAT_OTHERS ((_Unwind_Ptr) &__gnat_others_value)
510 extern const int __gnat_all_others_value;
511 #define GNAT_ALL_OTHERS ((_Unwind_Ptr) &__gnat_all_others_value)
513 extern const int __gnat_unhandled_others_value;
514 #define GNAT_UNHANDLED_OTHERS ((_Unwind_Ptr) &__gnat_unhandled_others_value)
516 /* Describe the useful region data associated with an unwind context. */
518 typedef struct
520 /* The base pc of the region. */
521 _Unwind_Ptr base;
523 /* Pointer to the Language Specific Data for the region. */
524 _Unwind_Ptr lsda;
526 /* Call-Site data associated with this region. */
527 unsigned char call_site_encoding;
528 const unsigned char *call_site_table;
530 /* The base to which are relative landing pad offsets inside the call-site
531 entries . */
532 _Unwind_Ptr lp_base;
534 /* Action-Table associated with this region. */
535 const unsigned char *action_table;
537 /* Ttype data associated with this region. */
538 unsigned char ttype_encoding;
539 const unsigned char *ttype_table;
540 _Unwind_Ptr ttype_base;
542 } region_descriptor;
544 /* Extract and adjust the IP (instruction pointer) from an exception
545 context. */
547 static _Unwind_Ptr
548 get_ip_from_context (_Unwind_Context *uw_context)
550 int ip_before_insn = 0;
551 #ifdef HAVE_GETIPINFO
552 _Unwind_Ptr ip = _Unwind_GetIPInfo (uw_context, &ip_before_insn);
553 #else
554 _Unwind_Ptr ip = _Unwind_GetIP (uw_context);
555 #endif
556 /* Subtract 1 if necessary because GetIPInfo yields a call return address
557 in this case, while we are interested in information for the call point.
558 This does not always yield the exact call instruction address but always
559 brings the IP back within the corresponding region. */
560 if (!ip_before_insn)
561 ip--;
563 return ip;
566 static void
567 db_region_for (region_descriptor *region, _Unwind_Ptr ip)
569 #ifndef inhibit_libc
570 if (! (db_accepted_codes () & DB_REGIONS))
571 return;
573 db (DB_REGIONS, "For ip @ %p => ", (void *)ip);
575 if (region->lsda)
576 db (DB_REGIONS, "lsda @ %p", (void *)region->lsda);
577 else
578 db (DB_REGIONS, "no lsda");
580 db (DB_REGIONS, "\n");
581 #endif
584 /* Retrieve the ttype entry associated with FILTER in the REGION's
585 ttype table. */
587 static _Unwind_Ptr
588 get_ttype_entry_for (region_descriptor *region, long filter)
590 _Unwind_Ptr ttype_entry;
592 filter *= size_of_encoded_value (region->ttype_encoding);
593 read_encoded_value_with_base
594 (region->ttype_encoding, region->ttype_base,
595 region->ttype_table - filter, &ttype_entry);
597 return ttype_entry;
600 /* Fill out the REGION descriptor for the provided UW_CONTEXT. */
602 static void
603 get_region_description_for (_Unwind_Context *uw_context,
604 region_descriptor *region)
606 const unsigned char * p;
607 _uleb128_t tmp;
608 unsigned char lpbase_encoding;
610 /* Get the base address of the lsda information. If the provided context
611 is null or if there is no associated language specific data, there's
612 nothing we can/should do. */
613 region->lsda
614 = (_Unwind_Ptr) (uw_context
615 ? _Unwind_GetLanguageSpecificData (uw_context) : 0);
617 if (! region->lsda)
618 return;
620 /* Parse the lsda and fill the region descriptor. */
621 p = (const unsigned char *)region->lsda;
623 region->base = _Unwind_GetRegionStart (uw_context);
625 /* Find @LPStart, the base to which landing pad offsets are relative. */
626 lpbase_encoding = *p++;
627 if (lpbase_encoding != DW_EH_PE_omit)
628 p = read_encoded_value
629 (uw_context, lpbase_encoding, p, &region->lp_base);
630 else
631 region->lp_base = region->base;
633 /* Find @TType, the base of the handler and exception spec type data. */
634 region->ttype_encoding = *p++;
635 if (region->ttype_encoding != DW_EH_PE_omit)
637 p = read_uleb128 (p, &tmp);
638 region->ttype_table = p + tmp;
640 else
641 region->ttype_table = 0;
643 region->ttype_base
644 = base_of_encoded_value (region->ttype_encoding, uw_context);
646 /* Get the encoding and length of the call-site table; the action table
647 immediately follows. */
648 region->call_site_encoding = *p++;
649 region->call_site_table = read_uleb128 (p, &tmp);
651 region->action_table = region->call_site_table + tmp;
655 /* Describe an action to be taken when propagating an exception up to
656 some context. */
658 enum action_kind
660 /* Found some call site base data, but need to analyze further
661 before being able to decide. */
662 unknown,
664 /* There is nothing relevant in the context at hand. */
665 nothing,
667 /* There are only cleanups to run in this context. */
668 cleanup,
670 /* There is a handler for the exception in this context. */
671 handler,
673 /* There is a handler for the exception, but it is only for catching
674 unhandled exceptions. */
675 unhandler
678 /* filter value for cleanup actions. */
679 static const int cleanup_filter = 0;
681 typedef struct
683 /* The kind of action to be taken. */
684 enum action_kind kind;
686 /* A pointer to the action record entry. */
687 const unsigned char *table_entry;
689 /* Where we should jump to actually take an action (trigger a cleanup or an
690 exception handler). */
691 _Unwind_Ptr landing_pad;
693 /* If we have a handler matching our exception, these are the filter to
694 trigger it and the corresponding id. */
695 _Unwind_Sword ttype_filter;
697 } action_descriptor;
699 static void
700 db_action_for (action_descriptor *action, _Unwind_Ptr ip)
702 #ifndef inhibit_libc
703 db (DB_ACTIONS, "For ip @ %p => ", (void *)ip);
705 switch (action->kind)
707 case unknown:
708 db (DB_ACTIONS, "lpad @ %p, record @ %p\n",
709 (void *) action->landing_pad, action->table_entry);
710 break;
712 case nothing:
713 db (DB_ACTIONS, "Nothing\n");
714 break;
716 case cleanup:
717 db (DB_ACTIONS, "Cleanup\n");
718 break;
720 case handler:
721 db (DB_ACTIONS, "Handler, filter = %d\n", (int) action->ttype_filter);
722 break;
724 default:
725 db (DB_ACTIONS, "Err? Unexpected action kind !\n");
726 break;
728 #endif
731 /* Search the call_site_table of REGION for an entry appropriate for the
732 UW_CONTEXT's IP. If one is found, store the associated landing_pad
733 and action_table entry, and set the ACTION kind to unknown for further
734 analysis. Otherwise, set the ACTION kind to nothing.
736 There are two variants of this routine, depending on the underlying
737 mechanism (DWARF/SJLJ), which account for differences in the tables. */
739 #ifdef __USING_SJLJ_EXCEPTIONS__
741 #define __builtin_eh_return_data_regno(x) x
743 static void
744 get_call_site_action_for (_Unwind_Ptr call_site,
745 region_descriptor *region,
746 action_descriptor *action)
748 /* call_site is a direct index into the call-site table, with two special
749 values : -1 for no-action and 0 for "terminate". The latter should never
750 show up for Ada. To test for the former, beware that _Unwind_Ptr might
751 be unsigned. */
753 if ((int)call_site < 0)
755 action->kind = nothing;
757 else if (call_site == 0)
759 db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n");
760 action->kind = nothing;
762 else
764 _uleb128_t cs_lp, cs_action;
765 const unsigned char *p;
767 /* Let the caller know there may be an action to take, but let it
768 determine the kind. */
769 action->kind = unknown;
771 /* We have a direct index into the call-site table, but this table is
772 made of leb128 values, the encoding length of which is variable. We
773 can't merely compute an offset from the index, then, but have to read
774 all the entries before the one of interest. */
775 p = region->call_site_table;
778 p = read_uleb128 (p, &cs_lp);
779 p = read_uleb128 (p, &cs_action);
781 while (--call_site);
783 action->landing_pad = cs_lp + 1;
785 if (cs_action)
786 action->table_entry = region->action_table + cs_action - 1;
787 else
788 action->table_entry = 0;
792 #else /* !__USING_SJLJ_EXCEPTIONS__ */
794 static void
795 get_call_site_action_for (_Unwind_Ptr ip,
796 region_descriptor *region,
797 action_descriptor *action)
799 const unsigned char *p = region->call_site_table;
801 /* Unless we are able to determine otherwise... */
802 action->kind = nothing;
804 db (DB_CSITE, "\n");
806 while (p < region->action_table)
808 _Unwind_Ptr cs_start, cs_len, cs_lp;
809 _uleb128_t cs_action;
811 /* Note that all call-site encodings are "absolute" displacements. */
812 p = read_encoded_value (0, region->call_site_encoding, p, &cs_start);
813 p = read_encoded_value (0, region->call_site_encoding, p, &cs_len);
814 p = read_encoded_value (0, region->call_site_encoding, p, &cs_lp);
815 p = read_uleb128 (p, &cs_action);
817 db (DB_CSITE,
818 "c_site @ %p (+%p), len = %p, lpad @ %p (+%p)\n",
819 (void *)region->base + cs_start, (void *)cs_start, (void *)cs_len,
820 (void *)region->lp_base + cs_lp, (void *)cs_lp);
822 /* The table is sorted, so if we've passed the IP, stop. */
823 if (ip < region->base + cs_start)
824 break;
826 /* If we have a match, fill the ACTION fields accordingly. */
827 else if (ip < region->base + cs_start + cs_len)
829 /* Let the caller know there may be an action to take, but let it
830 determine the kind. */
831 action->kind = unknown;
833 if (cs_lp)
834 action->landing_pad = region->lp_base + cs_lp;
835 else
836 action->landing_pad = 0;
838 if (cs_action)
839 action->table_entry = region->action_table + cs_action - 1;
840 else
841 action->table_entry = 0;
843 db (DB_CSITE, "+++\n");
844 return;
848 db (DB_CSITE, "---\n");
851 #endif /* __USING_SJLJ_EXCEPTIONS__ */
853 /* With CHOICE an exception choice representing an "exception - when"
854 argument, and PROPAGATED_EXCEPTION a pointer to the currently propagated
855 occurrence, return true if the latter matches the former, that is, if
856 PROPAGATED_EXCEPTION is caught by the handling code controlled by CHOICE.
857 This takes care of the special Non_Ada_Error case on VMS. */
859 #define Is_Handled_By_Others __gnat_is_handled_by_others
860 #define Language_For __gnat_language_for
861 #define Foreign_Data_For __gnat_foreign_data_for
862 #define EID_For __gnat_eid_for
864 extern bool Is_Handled_By_Others (_Unwind_Ptr eid);
865 extern char Language_For (_Unwind_Ptr eid);
867 extern void *Foreign_Data_For (_Unwind_Ptr eid);
869 extern Exception_Id EID_For (_GNAT_Exception * e);
871 #define Foreign_Exception system__exceptions__foreign_exception
872 extern struct Exception_Data Foreign_Exception;
874 #ifdef VMS
875 #define Non_Ada_Error system__aux_dec__non_ada_error
876 extern struct Exception_Data Non_Ada_Error;
877 #endif
879 /* Return true iff the exception class of EXCEPT is EC. */
881 static int
882 exception_class_eq (const _GNAT_Exception *except, _Unwind_Exception_Class ec)
884 #ifdef __ARM_EABI_UNWINDER__
885 return memcmp (except->common.exception_class, ec, 8) == 0;
886 #else
887 return except->common.exception_class == ec;
888 #endif
891 /* Return how CHOICE matches PROPAGATED_EXCEPTION. */
893 static enum action_kind
894 is_handled_by (_Unwind_Ptr choice, _GNAT_Exception *propagated_exception)
896 /* All others choice match everything. */
897 if (choice == GNAT_ALL_OTHERS)
898 return handler;
900 /* GNAT exception occurrence. */
901 if (exception_class_eq (propagated_exception, GNAT_EXCEPTION_CLASS))
903 /* Pointer to the GNAT exception data corresponding to the propagated
904 occurrence. */
905 _Unwind_Ptr E = (_Unwind_Ptr) EID_For (propagated_exception);
907 if (choice == GNAT_UNHANDLED_OTHERS)
908 return unhandler;
910 E = (_Unwind_Ptr) EID_For (propagated_exception);
912 /* Base matching rules: An exception data (id) matches itself, "when
913 all_others" matches anything and "when others" matches anything
914 unless explicitly stated otherwise in the propagated occurrence. */
915 if (choice == E || (choice == GNAT_OTHERS && Is_Handled_By_Others (E)))
916 return handler;
918 #ifdef VMS
919 /* In addition, on OpenVMS, Non_Ada_Error matches VMS exceptions, and we
920 may have different exception data pointers that should match for the
921 same condition code, if both an export and an import have been
922 registered. The import code for both the choice and the propagated
923 occurrence are expected to have been masked off regarding severity
924 bits already (at registration time for the former and from within the
925 low level exception vector for the latter). */
926 if ((Language_For (E) == 'V'
927 && choice != GNAT_OTHERS
928 && ((Language_For (choice) == 'V'
929 && Foreign_Data_For (choice) != 0
930 && Foreign_Data_For (choice) == Foreign_Data_For (E))
931 || choice == (_Unwind_Ptr)&Non_Ada_Error)))
932 return handler;
933 #endif
935 /* Otherwise, it doesn't match an Ada choice. */
936 return nothing;
939 /* All others and others choice match any foreign exception. */
940 if (choice == GNAT_ALL_OTHERS
941 || choice == GNAT_OTHERS
942 #ifndef CERT
943 || choice == (_Unwind_Ptr) &Foreign_Exception
944 #endif
946 return handler;
948 #ifndef CERT
949 /* C++ exception occurrences. */
950 if (exception_class_eq (propagated_exception, CXX_EXCEPTION_CLASS)
951 && Language_For (choice) == 'C')
953 void *choice_typeinfo = Foreign_Data_For (choice);
954 void *except_typeinfo =
955 (((struct __cxa_exception *)
956 ((_Unwind_Exception *)propagated_exception + 1)) - 1)
957 ->exceptionType;
959 /* Typeinfo are directly compared, which might not be correct if they
960 aren't merged. ??? We should call the == operator if this module is
961 compiled in C++. */
962 if (choice_typeinfo == except_typeinfo)
963 return handler;
965 #endif
967 return nothing;
970 /* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
971 UW_CONTEXT in REGION. */
973 static void
974 get_action_description_for (_Unwind_Ptr ip,
975 _Unwind_Exception *uw_exception,
976 _Unwind_Action uw_phase,
977 region_descriptor *region,
978 action_descriptor *action)
980 _GNAT_Exception *gnat_exception = (_GNAT_Exception *) uw_exception;
982 /* Search the call site table first, which may get us a landing pad as well
983 as the head of an action record list. */
984 get_call_site_action_for (ip, region, action);
985 db_action_for (action, ip);
987 /* If there is not even a call_site entry, we are done. */
988 if (action->kind == nothing)
989 return;
991 /* Otherwise, check what we have at the place of the call site. */
993 /* No landing pad => no cleanups or handlers. */
994 if (action->landing_pad == 0)
996 action->kind = nothing;
997 return;
1000 /* Landing pad + null table entry => only cleanups. */
1001 else if (action->table_entry == 0)
1003 action->kind = cleanup;
1004 action->ttype_filter = cleanup_filter;
1005 /* The filter initialization is not strictly necessary, as cleanup-only
1006 landing pads don't look at the filter value. It is there to ensure
1007 we don't pass random values and so trigger potential confusion when
1008 installing the context later on. */
1009 return;
1012 /* Landing pad + Table entry => handlers + possible cleanups. */
1013 else
1015 const unsigned char * p = action->table_entry;
1016 _sleb128_t ar_filter, ar_disp;
1018 action->kind = nothing;
1020 while (1)
1022 p = read_sleb128 (p, &ar_filter);
1023 read_sleb128 (p, &ar_disp);
1024 /* Don't assign p here, as it will be incremented by ar_disp
1025 below. */
1027 /* Null filters are for cleanups. */
1028 if (ar_filter == cleanup_filter)
1030 action->kind = cleanup;
1031 action->ttype_filter = cleanup_filter;
1032 /* The filter initialization is required here, to ensure
1033 the target landing pad branches to the cleanup code if
1034 we happen not to find a matching handler. */
1037 /* Positive filters are for regular handlers. */
1038 else if (ar_filter > 0)
1040 /* Do not catch an exception if the _UA_FORCE_UNWIND flag is
1041 passed (to follow the ABI). */
1042 if (!(uw_phase & _UA_FORCE_UNWIND))
1044 enum action_kind act;
1046 /* See if the filter we have is for an exception which
1047 matches the one we are propagating. */
1048 _Unwind_Ptr choice =
1049 get_ttype_entry_for (region, ar_filter);
1051 act = is_handled_by (choice, gnat_exception);
1052 if (act != nothing)
1054 action->kind = act;
1055 action->ttype_filter = ar_filter;
1056 return;
1061 /* Negative filter values are for C++ exception specifications.
1062 Should not be there for Ada :/ */
1063 else
1064 db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");
1066 if (ar_disp == 0)
1067 return;
1069 p += ar_disp;
1074 /* Setup in UW_CONTEXT the eh return target IP and data registers, which will
1075 be restored with the others and retrieved by the landing pad once the jump
1076 occurred. */
1078 static void
1079 setup_to_install (_Unwind_Context *uw_context,
1080 _Unwind_Exception *uw_exception,
1081 _Unwind_Ptr uw_landing_pad,
1082 int uw_filter)
1084 /* 1/ exception object pointer, which might be provided back to
1085 _Unwind_Resume (and thus to this personality routine) if we are jumping
1086 to a cleanup. */
1087 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (0),
1088 (_Unwind_Word)uw_exception);
1090 /* 2/ handler switch value register, which will also be used by the target
1091 landing pad to decide what action it shall take. */
1092 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (1),
1093 (_Unwind_Word)uw_filter);
1095 /* Setup the address we should jump at to reach the code where there is the
1096 "something" we found. */
1097 _Unwind_SetIP (uw_context, uw_landing_pad);
1100 /* The following is defined from a-except.adb. Its purpose is to enable
1101 automatic backtraces upon exception raise, as provided through the
1102 GNAT.Traceback facilities. */
1103 extern void __gnat_notify_handled_exception (struct Exception_Occurrence *);
1104 extern void __gnat_notify_unhandled_exception (struct Exception_Occurrence *);
1106 /* Below is the eh personality routine per se. We currently assume that only
1107 GNU-Ada exceptions are met. */
1109 /* By default, the personality routine is public. */
1110 #define PERSONALITY_STORAGE
1112 #ifdef __USING_SJLJ_EXCEPTIONS__
1113 #define PERSONALITY_FUNCTION __gnat_personality_sj0
1114 #elif defined (__SEH__)
1115 #define PERSONALITY_FUNCTION __gnat_personality_imp
1116 /* The public personality routine for seh is __gnat_personality_seh0, defined
1117 below using the SEH convention. This is a wrapper around the GNU routine,
1118 which is static. */
1119 #undef PERSONALITY_STORAGE
1120 #define PERSONALITY_STORAGE static
1121 #else
1122 #define PERSONALITY_FUNCTION __gnat_personality_v0
1123 #endif
1125 /* Code executed to continue unwinding. With the ARM unwinder, the
1126 personality routine must unwind one frame (per EHABI 7.3 4.). */
1128 static _Unwind_Reason_Code
1129 continue_unwind (struct _Unwind_Exception* ue_header ATTRIBUTE_UNUSED,
1130 struct _Unwind_Context* uw_context ATTRIBUTE_UNUSED)
1132 #ifdef __ARM_EABI_UNWINDER__
1133 if (__gnu_unwind_frame (ue_header, uw_context) != _URC_OK)
1134 return _URC_FAILURE;
1135 #endif
1136 return _URC_CONTINUE_UNWIND;
1139 /* Common code for the body of GNAT personality routine. This code is shared
1140 between all unwinders. */
1142 static _Unwind_Reason_Code
1143 personality_body (_Unwind_Action uw_phases,
1144 _Unwind_Exception *uw_exception,
1145 _Unwind_Context *uw_context)
1147 region_descriptor region;
1148 action_descriptor action;
1149 _Unwind_Ptr ip;
1151 /* Debug traces. */
1152 db_indent (DB_INDENT_RESET);
1153 db_phases (uw_phases);
1154 db_indent (DB_INDENT_INCREASE);
1156 /* Get the region description for the context we were provided with. This
1157 will tell us if there is some lsda, call_site, action and/or ttype data
1158 for the associated ip. */
1159 get_region_description_for (uw_context, &region);
1161 /* No LSDA => no handlers or cleanups => we shall unwind further up. */
1162 if (! region.lsda)
1163 return continue_unwind (uw_exception, uw_context);
1165 /* Get the instruction pointer. */
1166 ip = get_ip_from_context (uw_context);
1167 db_region_for (&region, ip);
1169 /* Search the call-site and action-record tables for the action associated
1170 with this IP. */
1171 get_action_description_for (ip, uw_exception, uw_phases, &region, &action);
1172 db_action_for (&action, ip);
1174 /* Whatever the phase, if there is nothing relevant in this frame,
1175 unwinding should just go on. */
1176 if (action.kind == nothing)
1177 return continue_unwind (uw_exception, uw_context);
1179 /* If we found something in search phase, we should return a code indicating
1180 what to do next depending on what we found. If we only have cleanups
1181 around, we shall try to unwind further up to find a handler, otherwise,
1182 tell we have a handler, which will trigger the second phase. */
1183 if (uw_phases & _UA_SEARCH_PHASE)
1185 if (action.kind == cleanup)
1187 return continue_unwind (uw_exception, uw_context);
1189 else
1191 #ifndef CERT
1192 struct Exception_Occurrence *excep;
1194 /* Trigger the appropriate notification routines before the second
1195 phase starts, which ensures the stack is still intact.
1196 First, setup the Ada occurrence. */
1197 excep = __gnat_setup_current_excep (uw_exception);
1198 if (action.kind == unhandler)
1199 __gnat_notify_unhandled_exception (excep);
1200 else
1201 __gnat_notify_handled_exception (excep);
1202 #endif
1204 return _URC_HANDLER_FOUND;
1208 /* We found something in cleanup/handler phase, which might be the handler
1209 or a cleanup for a handled occurrence, or a cleanup for an unhandled
1210 occurrence (we are in a FORCED_UNWIND phase in this case). Install the
1211 context to get there. */
1213 setup_to_install
1214 (uw_context, uw_exception, action.landing_pad, action.ttype_filter);
1216 #ifndef CERT
1217 /* Write current exception, so that it can be retrieved from Ada. It was
1218 already done during phase 1 (just above), but in between, one or several
1219 exceptions may have been raised (in cleanup handlers). */
1220 __gnat_setup_current_excep (uw_exception);
1221 #endif
1223 return _URC_INSTALL_CONTEXT;
1226 #ifndef __ARM_EABI_UNWINDER__
1227 /* Major tweak for ia64-vms : the CHF propagation phase calls this personality
1228 routine with sigargs/mechargs arguments and has very specific expectations
1229 on possible return values.
1231 We handle this with a number of specific tricks:
1233 1. We tweak the personality routine prototype to have the "version" and
1234 "phases" two first arguments be void * instead of int and _Unwind_Action
1235 as nominally expected in the GCC context.
1237 This allows us to access the full range of bits passed in every case and
1238 has no impact on the callers side since each argument remains assigned
1239 the same single 64bit slot.
1241 2. We retrieve the corresponding int and _Unwind_Action values within the
1242 routine for regular use with truncating conversions. This is a noop when
1243 called from the libgcc unwinder.
1245 3. We assume we're called by the VMS CHF when unexpected bits are set in
1246 both those values. The incoming arguments are then real sigargs and
1247 mechargs pointers, which we then redirect to __gnat_handle_vms_condition
1248 for proper processing.
1250 #if defined (VMS) && defined (__IA64)
1251 typedef void * version_arg_t;
1252 typedef void * phases_arg_t;
1253 #else
1254 typedef int version_arg_t;
1255 typedef _Unwind_Action phases_arg_t;
1256 #endif
1258 PERSONALITY_STORAGE _Unwind_Reason_Code
1259 PERSONALITY_FUNCTION (version_arg_t, phases_arg_t,
1260 _Unwind_Exception_Class, _Unwind_Exception *,
1261 _Unwind_Context *);
1263 PERSONALITY_STORAGE _Unwind_Reason_Code
1264 PERSONALITY_FUNCTION (version_arg_t version_arg,
1265 phases_arg_t phases_arg,
1266 _Unwind_Exception_Class uw_exception_class
1267 ATTRIBUTE_UNUSED,
1268 _Unwind_Exception *uw_exception,
1269 _Unwind_Context *uw_context)
1271 /* Fetch the version and phases args with their nominal ABI types for later
1272 use. This is a noop everywhere except on ia64-vms when called from the
1273 Condition Handling Facility. */
1274 int uw_version = (int) version_arg;
1275 _Unwind_Action uw_phases = (_Unwind_Action) phases_arg;
1277 /* Check that we're called from the ABI context we expect, with a major
1278 possible variation on VMS for IA64. */
1279 if (uw_version != 1)
1281 #if defined (VMS) && defined (__IA64)
1283 /* Assume we're called with sigargs/mechargs arguments if really
1284 unexpected bits are set in our first two formals. Redirect to the
1285 GNAT condition handling code in this case. */
1287 extern long __gnat_handle_vms_condition (void *, void *);
1289 unsigned int version_unexpected_bits_mask = 0xffffff00U;
1290 unsigned int phases_unexpected_bits_mask = 0xffffff00U;
1292 if ((unsigned int)uw_version & version_unexpected_bits_mask
1293 && (unsigned int)uw_phases & phases_unexpected_bits_mask)
1294 return __gnat_handle_vms_condition (version_arg, phases_arg);
1295 #endif
1297 return _URC_FATAL_PHASE1_ERROR;
1300 return personality_body (uw_phases, uw_exception, uw_context);
1303 #else /* __ARM_EABI_UNWINDER__ */
1305 PERSONALITY_STORAGE _Unwind_Reason_Code
1306 PERSONALITY_FUNCTION (_Unwind_State state,
1307 struct _Unwind_Exception* ue_header,
1308 struct _Unwind_Context* uw_context);
1310 PERSONALITY_STORAGE _Unwind_Reason_Code
1311 PERSONALITY_FUNCTION (_Unwind_State state,
1312 struct _Unwind_Exception* uw_exception,
1313 struct _Unwind_Context* uw_context)
1315 _Unwind_Action uw_phases;
1317 switch (state & _US_ACTION_MASK)
1319 case _US_VIRTUAL_UNWIND_FRAME:
1320 /* Phase 1. */
1321 uw_phases = _UA_SEARCH_PHASE;
1322 break;
1324 case _US_UNWIND_FRAME_STARTING:
1325 /* Phase 2, to call a cleanup. */
1326 uw_phases = _UA_CLEANUP_PHASE;
1327 #if 0
1328 /* ??? We don't use UA_HANDLER_FRAME (except to debug). Futhermore,
1329 barrier_cache.sp isn't yet set. */
1330 if (!(state & _US_FORCE_UNWIND)
1331 && (uw_exception->barrier_cache.sp
1332 == _Unwind_GetGR (uw_context, UNWIND_STACK_REG)))
1333 uw_phases |= _UA_HANDLER_FRAME;
1334 #endif
1335 break;
1337 case _US_UNWIND_FRAME_RESUME:
1338 /* Phase 2, called at the return of a cleanup. In the GNU
1339 implementation, there is nothing left to do, so we simply go on. */
1340 return continue_unwind (uw_exception, uw_context);
1342 default:
1343 return _URC_FAILURE;
1345 uw_phases |= (state & _US_FORCE_UNWIND);
1347 /* The dwarf unwinder assumes the context structure holds things like the
1348 function and LSDA pointers. The ARM implementation caches these in
1349 the exception header (UCB). To avoid rewriting everything we make a
1350 virtual scratch register point at the UCB. This is a GNU specific
1351 requirement. */
1352 _Unwind_SetGR (uw_context, UNWIND_POINTER_REG, (_Unwind_Ptr) uw_exception);
1354 return personality_body (uw_phases, uw_exception, uw_context);
1356 #endif /* __ARM_EABI_UNWINDER__ */
1358 /* Callback routine called by Unwind_ForcedUnwind to execute all the cleanup
1359 before exiting the task. */
1361 #ifndef CERT
1362 _Unwind_Reason_Code
1363 __gnat_cleanupunwind_handler (int version ATTRIBUTE_UNUSED,
1364 _Unwind_Action phases,
1365 _Unwind_Exception_Class eclass ATTRIBUTE_UNUSED,
1366 struct _Unwind_Exception *exception,
1367 struct _Unwind_Context *context ATTRIBUTE_UNUSED,
1368 void *arg ATTRIBUTE_UNUSED)
1370 /* Terminate when the end of the stack is reached. */
1371 if ((phases & _UA_END_OF_STACK) != 0
1372 #if defined (__ia64__) && defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
1373 /* Strictely follow the ia64 ABI: when end of stack is reached,
1374 the callback will be called with a NULL stack pointer.
1375 No need for that when using libgcc unwinder. */
1376 || _Unwind_GetGR (context, 12) == 0
1377 #endif
1379 __gnat_unhandled_except_handler (exception);
1381 /* We know there is at least one cleanup further up. Return so that it
1382 is searched and entered, after which Unwind_Resume will be called
1383 and this hook will gain control again. */
1384 return _URC_NO_REASON;
1386 #endif
1388 /* Define the consistently named wrappers imported by Propagate_Exception. */
1390 _Unwind_Reason_Code
1391 __gnat_Unwind_RaiseException (_Unwind_Exception *e)
1393 #ifdef __USING_SJLJ_EXCEPTIONS__
1394 return _Unwind_SjLj_RaiseException (e);
1395 #else
1396 return _Unwind_RaiseException (e);
1397 #endif
1400 _Unwind_Reason_Code
1401 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e ATTRIBUTE_UNUSED,
1402 void *handler ATTRIBUTE_UNUSED,
1403 void *argument ATTRIBUTE_UNUSED)
1405 #ifdef __USING_SJLJ_EXCEPTIONS__
1407 # if defined (__APPLE__) && defined (__arm__)
1408 /* There is not ForcedUnwind routine in arm-darwin system library. */
1409 return _URC_FATAL_PHASE1_ERROR;
1410 # else
1411 return _Unwind_SjLj_ForcedUnwind (e, handler, argument);
1412 # endif
1414 #else
1415 return _Unwind_ForcedUnwind (e, handler, argument);
1416 #endif
1419 #if defined (__SEH__) && !defined (__USING_SJLJ_EXCEPTIONS__)
1421 #define STATUS_USER_DEFINED (1U << 29)
1423 /* From unwind-seh.c. */
1424 #define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C')
1425 #define GCC_EXCEPTION(TYPE) \
1426 (STATUS_USER_DEFINED | ((TYPE) << 24) | GCC_MAGIC)
1427 #define STATUS_GCC_THROW GCC_EXCEPTION (0)
1429 EXCEPTION_DISPOSITION __gnat_SEH_error_handler
1430 (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
1432 struct Exception_Data *
1433 __gnat_map_SEH (EXCEPTION_RECORD* ExceptionRecord, const char **msg);
1435 struct _Unwind_Exception *
1436 __gnat_create_machine_occurrence_from_signal_handler (Exception_Id,
1437 const char *);
1439 /* Unwind opcodes. */
1440 #define UWOP_PUSH_NONVOL 0
1441 #define UWOP_ALLOC_LARGE 1
1442 #define UWOP_ALLOC_SMALL 2
1443 #define UWOP_SET_FPREG 3
1444 #define UWOP_SAVE_NONVOL 4
1445 #define UWOP_SAVE_NONVOL_FAR 5
1446 #define UWOP_SAVE_XMM128 8
1447 #define UWOP_SAVE_XMM128_FAR 9
1448 #define UWOP_PUSH_MACHFRAME 10
1450 /* Modify the IP value saved in the machine frame. This is really a kludge,
1451 that will be removed if we could propagate the Windows exception (and not
1452 the GCC one).
1453 What is very wrong is that the Windows unwinder will try to decode the
1454 instruction at IP, which isn't valid anymore after the adjust. */
1456 static void
1457 __gnat_adjust_context (unsigned char *unw, ULONG64 rsp)
1459 unsigned int len;
1461 /* Version = 1, no flags, no prologue. */
1462 if (unw[0] != 1 || unw[1] != 0)
1463 return;
1464 len = unw[2];
1465 /* No frame pointer. */
1466 if (unw[3] != 0)
1467 return;
1468 unw += 4;
1469 while (len > 0)
1471 /* Offset in prologue = 0. */
1472 if (unw[0] != 0)
1473 return;
1474 switch (unw[1] & 0xf)
1476 case UWOP_ALLOC_LARGE:
1477 /* Expect < 512KB. */
1478 if ((unw[1] & 0xf0) != 0)
1479 return;
1480 rsp += *(unsigned short *)(unw + 2) * 8;
1481 len--;
1482 unw += 2;
1483 break;
1484 case UWOP_SAVE_NONVOL:
1485 case UWOP_SAVE_XMM128:
1486 len--;
1487 unw += 2;
1488 break;
1489 case UWOP_PUSH_MACHFRAME:
1491 ULONG64 *rip;
1492 rip = (ULONG64 *)rsp;
1493 if ((unw[1] & 0xf0) == 0x10)
1494 rip++;
1495 /* Adjust rip. */
1496 (*rip)++;
1498 return;
1499 default:
1500 /* Unexpected. */
1501 return;
1503 unw += 2;
1504 len--;
1508 EXCEPTION_DISPOSITION
1509 __gnat_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
1510 PCONTEXT ms_orig_context,
1511 PDISPATCHER_CONTEXT ms_disp)
1513 /* Possibly transform run-time errors into Ada exceptions. As a small
1514 optimization, we call __gnat_SEH_error_handler only on non-user
1515 exceptions. */
1516 if (!(ms_exc->ExceptionCode & STATUS_USER_DEFINED))
1518 struct Exception_Data *exception;
1519 const char *msg;
1520 ULONG64 excpip = (ULONG64) ms_exc->ExceptionAddress;
1522 if (excpip != 0
1523 && excpip >= (ms_disp->ImageBase
1524 + ms_disp->FunctionEntry->BeginAddress)
1525 && excpip < (ms_disp->ImageBase
1526 + ms_disp->FunctionEntry->EndAddress))
1528 /* This is a fault in this function. We need to adjust the return
1529 address before raising the GCC exception. */
1530 CONTEXT context;
1531 PRUNTIME_FUNCTION mf_func = NULL;
1532 ULONG64 mf_imagebase;
1533 ULONG64 mf_rsp = 0;
1535 /* Get the context. */
1536 RtlCaptureContext (&context);
1538 while (1)
1540 PRUNTIME_FUNCTION RuntimeFunction;
1541 ULONG64 ImageBase;
1542 VOID *HandlerData;
1543 ULONG64 EstablisherFrame;
1545 /* Get function metadata. */
1546 RuntimeFunction = RtlLookupFunctionEntry
1547 (context.Rip, &ImageBase, ms_disp->HistoryTable);
1548 if (RuntimeFunction == ms_disp->FunctionEntry)
1549 break;
1550 mf_func = RuntimeFunction;
1551 mf_imagebase = ImageBase;
1552 mf_rsp = context.Rsp;
1554 if (!RuntimeFunction)
1556 /* In case of failure, assume this is a leaf function. */
1557 context.Rip = *(ULONG64 *) context.Rsp;
1558 context.Rsp += 8;
1560 else
1562 /* Unwind. */
1563 RtlVirtualUnwind (0, ImageBase, context.Rip, RuntimeFunction,
1564 &context, &HandlerData, &EstablisherFrame,
1565 NULL);
1568 /* 0 means bottom of the stack. */
1569 if (context.Rip == 0)
1571 mf_func = NULL;
1572 break;
1575 if (mf_func != NULL)
1576 __gnat_adjust_context
1577 ((unsigned char *)(mf_imagebase + mf_func->UnwindData), mf_rsp);
1580 exception = __gnat_map_SEH (ms_exc, &msg);
1581 if (exception != NULL)
1583 struct _Unwind_Exception *exc;
1585 /* Directly convert the system exception to a GCC one.
1586 This is really breaking the API, but is necessary for stack size
1587 reasons: the normal way is to call Raise_From_Signal_Handler,
1588 which build the exception and calls _Unwind_RaiseException, which
1589 unwinds the stack and will call this personality routine. But
1590 the Windows unwinder needs about 2KB of stack. */
1591 exc = __gnat_create_machine_occurrence_from_signal_handler
1592 (exception, msg);
1593 memset (exc->private_, 0, sizeof (exc->private_));
1594 ms_exc->ExceptionCode = STATUS_GCC_THROW;
1595 ms_exc->NumberParameters = 1;
1596 ms_exc->ExceptionInformation[0] = (ULONG_PTR)exc;
1601 return _GCC_specific_handler (ms_exc, this_frame, ms_orig_context,
1602 ms_disp, __gnat_personality_imp);
1604 #endif /* SEH */
1606 #if !defined (__USING_SJLJ_EXCEPTIONS__)
1607 /* Size of the _Unwind_Exception structure. This is used by g-cppexc to get
1608 the offset to the C++ object. */
1610 const int __gnat_unwind_exception_size = sizeof (_Unwind_Exception);
1611 #endif