]> gcc.gnu.org Git - gcc.git/blob - gcc/ada/raise-gcc.c
0074ad53fbc0def9a9bc9e7f2bfb3503cc10e574
[gcc.git] / gcc / ada / raise-gcc.c
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 ****************************************************************************/
31
32 /* Code related to the integration of the GCC mechanism for exception
33 handling. */
34
35 #ifndef IN_RTS
36 #error "RTS unit only"
37 #endif
38
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
46
47 #include <stdarg.h>
48 typedef char bool;
49 # define true 1
50 # define false 0
51
52 #include "raise.h"
53
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
61
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
67
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. */
72
73 #include "unwind.h"
74
75 typedef struct _Unwind_Context _Unwind_Context;
76 typedef struct _Unwind_Exception _Unwind_Exception;
77
78 _Unwind_Reason_Code
79 __gnat_Unwind_RaiseException (_Unwind_Exception *);
80
81 _Unwind_Reason_Code
82 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *, void *, void *);
83
84 extern struct Exception_Occurrence *__gnat_setup_current_excep
85 (_Unwind_Exception *);
86 extern void __gnat_unhandled_except_handler (_Unwind_Exception *);
87
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
93
94 #include "unwind-pe.h"
95
96 /* The known and handled exception classes. */
97
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
105
106 /* Structure of a C++ exception, represented as a C structure... See
107 unwind-cxx.h for the full definition. */
108
109 struct __cxa_exception
110 {
111 void *exceptionType;
112 void (*exceptionDestructor)(void *);
113
114 void (*unexpectedHandler)();
115 void (*terminateHandler)();
116
117 struct __cxa_exception *nextException;
118
119 int handlerCount;
120
121 #ifdef __ARM_EABI_UNWINDER__
122 struct __cxa_exception* nextPropagatingException;
123
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
132
133 _Unwind_Exception unwindHeader;
134 };
135
136 /* --------------------------------------------------------------
137 -- The DB stuff below is there for debugging purposes only. --
138 -------------------------------------------------------------- */
139
140 #ifndef inhibit_libc
141
142 #define DB_PHASES 0x1
143 #define DB_CSITE 0x2
144 #define DB_ACTIONS 0x4
145 #define DB_REGIONS 0x8
146
147 #define DB_ERR 0x1000
148
149 /* The "action" stuff below is also there for debugging purposes only. */
150
151 typedef struct
152 {
153 _Unwind_Action phase;
154 const char * description;
155 } phase_descriptor;
156
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}};
163
164 static int
165 db_accepted_codes (void)
166 {
167 static int accepted_codes = -1;
168
169 if (accepted_codes == -1)
170 {
171 char * db_env = (char *) getenv ("EH_DEBUG");
172
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. */
177 }
178
179 return accepted_codes;
180 }
181
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
187
188 #define DB_INDENT_UNIT 8
189
190 static void
191 db_indent (int requests)
192 {
193 static int current_indentation_level = 0;
194
195 if (requests & DB_INDENT_RESET)
196 current_indentation_level = 0;
197
198 if (requests & DB_INDENT_INCREASE)
199 current_indentation_level ++;
200
201 if (requests & DB_INDENT_DECREASE)
202 current_indentation_level --;
203
204 if (requests & DB_INDENT_NEWLINE)
205 fprintf (stderr, "\n");
206
207 if (requests & DB_INDENT_OUTPUT)
208 fprintf (stderr, "%*s", current_indentation_level * DB_INDENT_UNIT, " ");
209 }
210
211 static void ATTRIBUTE_PRINTF_2
212 db (int db_code, char * msg_format, ...)
213 {
214 if (db_accepted_codes () & db_code)
215 {
216 va_list msg_args;
217
218 db_indent (DB_INDENT_OUTPUT);
219
220 va_start (msg_args, msg_format);
221 vfprintf (stderr, msg_format, msg_args);
222 va_end (msg_args);
223 }
224 }
225
226 static void
227 db_phases (int phases)
228 {
229 const phase_descriptor *a = phase_descriptors;
230
231 if (! (db_accepted_codes () & DB_PHASES))
232 return;
233
234 db (DB_PHASES, "\n");
235
236 for (; a->description != 0; a++)
237 if (phases & a->phase)
238 db (DB_PHASES, "%s ", a->description);
239
240 db (DB_PHASES, " :\n");
241 }
242 #else /* !inhibit_libc */
243 #define db_phases(X)
244 #define db_indent(X)
245 #define db(X, ...)
246 #endif /* !inhibit_libc */
247
248 /* ---------------------------------------------------------------
249 -- Now come a set of useful structures and helper routines. --
250 --------------------------------------------------------------- */
251
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).
255
256 =======================================
257 * Tables for the dwarf zero cost case *
258 =======================================
259
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.
263
264 call_site []
265 -------------------------------------------------------------------
266 * region-start | region-length | landing-pad | first-action-index *
267 -------------------------------------------------------------------
268
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.
272
273 A null landing-pad indicates that nothing is to be done.
274
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).
277
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.
281
282 A null first-action-index indicates that there are only cleanups
283 to run there.
284
285 action []
286 -------------------------------
287 * action-filter | next-action *
288 -------------------------------
289
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.
294
295 A null action-filter indicates a cleanup.
296
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.
300
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.
304
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).
315
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.
319
320 ttypes []
321 ---------------
322 * ttype-value *
323 ---------------
324
325 This table is an array of addresses.
326
327 A null value indicates a catch-all handler. (Not used by Ada)
328
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).
332
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:
338
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:
342
343 ---------------------------------------------------------------------------
344
345 Here is a quick summary of the tables organization:
346
347 +-- Unwind_Context (pc, ...)
348 |
349 |(pc)
350 |
351 | CALL-SITE[]
352 |
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 +====================================================== | ====+
359 |
360 |
361 ACTION [] |
362 |
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 +==================================== | ===================+
370 |
371 |
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 +============+=====================+
389
390
391 ============================
392 * Tables for the sjlj case *
393 ============================
394
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.
399
400 The generic unwinding engine in _Unwind_RaiseException walks the function
401 context stack and not the actual call chain.
402
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
408
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.
412
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.
416
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.
420
421 +-- Unwind_Context (pc, ...)
422 |
423 | pc = call-site index
424 | 0 => terminate (should not see this for Ada)
425 | -1 => no-action
426 |
427 | CALL-SITE[]
428 |
429 | +=====================================+
430 | | landing-pad | first-action-index |
431 | +=====================================+
432 +-> | 0 => cleanups only |
433 | dispatch index N |
434 +=====================================+
435
436
437 ===================================
438 * Basic organization of this unit *
439 ===================================
440
441 The major point of this unit is to provide an exception propagation
442 personality routine for Ada. This is __gnat_personality_v0.
443
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.
448
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.
453
454 A number of structures and subroutines are used for this purpose, as
455 sketched below:
456
457 o region_descriptor: General data associated with the context (base pc,
458 call-site table, action table, ttypes table, ...)
459
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, ...).
463
464 raise
465 |
466 ... (a-except.adb)
467 |
468 Propagate_Exception (a-exexpr.adb)
469 |
470 |
471 _Unwind_RaiseException (libgcc)
472 |
473 | (Ada frame)
474 |
475 +--> __gnat_personality_v0 (context, exception)
476 |
477 +--> get_region_description_for (context)
478 |
479 +--> get_action_description_for (ip, exception, region)
480 | |
481 | +--> get_call_site_action_for (context, region)
482 | (one version for each underlying scheme)
483 |
484 +--> setup_to_install (context)
485
486 This unit is inspired from the C++ version found in eh_personality.cc,
487 part of libstdc++-v3.
488
489 */
490
491
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. */
497
498 typedef struct
499 {
500 _Unwind_Exception common;
501 /* ABI header, maximally aligned. */
502 } _GNAT_Exception;
503
504 /* The two constants below are specific ttype identifiers for special
505 exception ids. Their type should match what a-exexpr exports. */
506
507 extern const int __gnat_others_value;
508 #define GNAT_OTHERS ((_Unwind_Ptr) &__gnat_others_value)
509
510 extern const int __gnat_all_others_value;
511 #define GNAT_ALL_OTHERS ((_Unwind_Ptr) &__gnat_all_others_value)
512
513 extern const int __gnat_unhandled_others_value;
514 #define GNAT_UNHANDLED_OTHERS ((_Unwind_Ptr) &__gnat_unhandled_others_value)
515
516 /* Describe the useful region data associated with an unwind context. */
517
518 typedef struct
519 {
520 /* The base pc of the region. */
521 _Unwind_Ptr base;
522
523 /* Pointer to the Language Specific Data for the region. */
524 _Unwind_Ptr lsda;
525
526 /* Call-Site data associated with this region. */
527 unsigned char call_site_encoding;
528 const unsigned char *call_site_table;
529
530 /* The base to which are relative landing pad offsets inside the call-site
531 entries . */
532 _Unwind_Ptr lp_base;
533
534 /* Action-Table associated with this region. */
535 const unsigned char *action_table;
536
537 /* Ttype data associated with this region. */
538 unsigned char ttype_encoding;
539 const unsigned char *ttype_table;
540 _Unwind_Ptr ttype_base;
541
542 } region_descriptor;
543
544 /* Extract and adjust the IP (instruction pointer) from an exception
545 context. */
546
547 static _Unwind_Ptr
548 get_ip_from_context (_Unwind_Context *uw_context)
549 {
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--;
562
563 return ip;
564 }
565
566 static void
567 db_region_for (region_descriptor *region, _Unwind_Ptr ip)
568 {
569 #ifndef inhibit_libc
570 if (! (db_accepted_codes () & DB_REGIONS))
571 return;
572
573 db (DB_REGIONS, "For ip @ %p => ", (void *)ip);
574
575 if (region->lsda)
576 db (DB_REGIONS, "lsda @ %p", (void *)region->lsda);
577 else
578 db (DB_REGIONS, "no lsda");
579
580 db (DB_REGIONS, "\n");
581 #endif
582 }
583
584 /* Retrieve the ttype entry associated with FILTER in the REGION's
585 ttype table. */
586
587 static _Unwind_Ptr
588 get_ttype_entry_for (region_descriptor *region, long filter)
589 {
590 _Unwind_Ptr ttype_entry;
591
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);
596
597 return ttype_entry;
598 }
599
600 /* Fill out the REGION descriptor for the provided UW_CONTEXT. */
601
602 static void
603 get_region_description_for (_Unwind_Context *uw_context,
604 region_descriptor *region)
605 {
606 const unsigned char * p;
607 _uleb128_t tmp;
608 unsigned char lpbase_encoding;
609
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);
616
617 if (! region->lsda)
618 return;
619
620 /* Parse the lsda and fill the region descriptor. */
621 p = (const unsigned char *)region->lsda;
622
623 region->base = _Unwind_GetRegionStart (uw_context);
624
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;
632
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)
636 {
637 p = read_uleb128 (p, &tmp);
638 region->ttype_table = p + tmp;
639 }
640 else
641 region->ttype_table = 0;
642
643 region->ttype_base
644 = base_of_encoded_value (region->ttype_encoding, uw_context);
645
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);
650
651 region->action_table = region->call_site_table + tmp;
652 }
653
654
655 /* Describe an action to be taken when propagating an exception up to
656 some context. */
657
658 enum action_kind
659 {
660 /* Found some call site base data, but need to analyze further
661 before being able to decide. */
662 unknown,
663
664 /* There is nothing relevant in the context at hand. */
665 nothing,
666
667 /* There are only cleanups to run in this context. */
668 cleanup,
669
670 /* There is a handler for the exception in this context. */
671 handler,
672
673 /* There is a handler for the exception, but it is only for catching
674 unhandled exceptions. */
675 unhandler
676 };
677
678 /* filter value for cleanup actions. */
679 static const int cleanup_filter = 0;
680
681 typedef struct
682 {
683 /* The kind of action to be taken. */
684 enum action_kind kind;
685
686 /* A pointer to the action record entry. */
687 const unsigned char *table_entry;
688
689 /* Where we should jump to actually take an action (trigger a cleanup or an
690 exception handler). */
691 _Unwind_Ptr landing_pad;
692
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;
696
697 } action_descriptor;
698
699 static void
700 db_action_for (action_descriptor *action, _Unwind_Ptr ip)
701 {
702 #ifndef inhibit_libc
703 db (DB_ACTIONS, "For ip @ %p => ", (void *)ip);
704
705 switch (action->kind)
706 {
707 case unknown:
708 db (DB_ACTIONS, "lpad @ %p, record @ %p\n",
709 (void *) action->landing_pad, action->table_entry);
710 break;
711
712 case nothing:
713 db (DB_ACTIONS, "Nothing\n");
714 break;
715
716 case cleanup:
717 db (DB_ACTIONS, "Cleanup\n");
718 break;
719
720 case handler:
721 db (DB_ACTIONS, "Handler, filter = %d\n", (int) action->ttype_filter);
722 break;
723
724 default:
725 db (DB_ACTIONS, "Err? Unexpected action kind !\n");
726 break;
727 }
728 #endif
729 }
730
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.
735
736 There are two variants of this routine, depending on the underlying
737 mechanism (DWARF/SJLJ), which account for differences in the tables. */
738
739 #ifdef __USING_SJLJ_EXCEPTIONS__
740
741 #define __builtin_eh_return_data_regno(x) x
742
743 static void
744 get_call_site_action_for (_Unwind_Ptr call_site,
745 region_descriptor *region,
746 action_descriptor *action)
747 {
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. */
752
753 if ((int)call_site < 0)
754 {
755 action->kind = nothing;
756 }
757 else if (call_site == 0)
758 {
759 db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n");
760 action->kind = nothing;
761 }
762 else
763 {
764 _uleb128_t cs_lp, cs_action;
765 const unsigned char *p;
766
767 /* Let the caller know there may be an action to take, but let it
768 determine the kind. */
769 action->kind = unknown;
770
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;
776 do
777 {
778 p = read_uleb128 (p, &cs_lp);
779 p = read_uleb128 (p, &cs_action);
780 }
781 while (--call_site);
782
783 action->landing_pad = cs_lp + 1;
784
785 if (cs_action)
786 action->table_entry = region->action_table + cs_action - 1;
787 else
788 action->table_entry = 0;
789 }
790 }
791
792 #else /* !__USING_SJLJ_EXCEPTIONS__ */
793
794 static void
795 get_call_site_action_for (_Unwind_Ptr ip,
796 region_descriptor *region,
797 action_descriptor *action)
798 {
799 const unsigned char *p = region->call_site_table;
800
801 /* Unless we are able to determine otherwise... */
802 action->kind = nothing;
803
804 db (DB_CSITE, "\n");
805
806 while (p < region->action_table)
807 {
808 _Unwind_Ptr cs_start, cs_len, cs_lp;
809 _uleb128_t cs_action;
810
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);
816
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);
821
822 /* The table is sorted, so if we've passed the IP, stop. */
823 if (ip < region->base + cs_start)
824 break;
825
826 /* If we have a match, fill the ACTION fields accordingly. */
827 else if (ip < region->base + cs_start + cs_len)
828 {
829 /* Let the caller know there may be an action to take, but let it
830 determine the kind. */
831 action->kind = unknown;
832
833 if (cs_lp)
834 action->landing_pad = region->lp_base + cs_lp;
835 else
836 action->landing_pad = 0;
837
838 if (cs_action)
839 action->table_entry = region->action_table + cs_action - 1;
840 else
841 action->table_entry = 0;
842
843 db (DB_CSITE, "+++\n");
844 return;
845 }
846 }
847
848 db (DB_CSITE, "---\n");
849 }
850
851 #endif /* __USING_SJLJ_EXCEPTIONS__ */
852
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. */
858
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
863
864 extern bool Is_Handled_By_Others (_Unwind_Ptr eid);
865 extern char Language_For (_Unwind_Ptr eid);
866
867 extern void *Foreign_Data_For (_Unwind_Ptr eid);
868
869 extern Exception_Id EID_For (_GNAT_Exception * e);
870
871 #define Foreign_Exception system__exceptions__foreign_exception
872 extern struct Exception_Data Foreign_Exception;
873
874 #ifdef VMS
875 #define Non_Ada_Error system__aux_dec__non_ada_error
876 extern struct Exception_Data Non_Ada_Error;
877 #endif
878
879 /* Return true iff the exception class of EXCEPT is EC. */
880
881 static int
882 exception_class_eq (const _GNAT_Exception *except, _Unwind_Exception_Class ec)
883 {
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
889 }
890
891 /* Return how CHOICE matches PROPAGATED_EXCEPTION. */
892
893 static enum action_kind
894 is_handled_by (_Unwind_Ptr choice, _GNAT_Exception *propagated_exception)
895 {
896 /* All others choice match everything. */
897 if (choice == GNAT_ALL_OTHERS)
898 return handler;
899
900 /* GNAT exception occurrence. */
901 if (exception_class_eq (propagated_exception, GNAT_EXCEPTION_CLASS))
902 {
903 /* Pointer to the GNAT exception data corresponding to the propagated
904 occurrence. */
905 _Unwind_Ptr E = (_Unwind_Ptr) EID_For (propagated_exception);
906
907 if (choice == GNAT_UNHANDLED_OTHERS)
908 return unhandler;
909
910 E = (_Unwind_Ptr) EID_For (propagated_exception);
911
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;
917
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
934
935 /* Otherwise, it doesn't match an Ada choice. */
936 return nothing;
937 }
938
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
945 )
946 return handler;
947
948 #ifndef CERT
949 /* C++ exception occurrences. */
950 if (exception_class_eq (propagated_exception, CXX_EXCEPTION_CLASS)
951 && Language_For (choice) == 'C')
952 {
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;
958
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;
964 }
965 #endif
966
967 return nothing;
968 }
969
970 /* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
971 UW_CONTEXT in REGION. */
972
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)
979 {
980 _GNAT_Exception *gnat_exception = (_GNAT_Exception *) uw_exception;
981
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);
986
987 /* If there is not even a call_site entry, we are done. */
988 if (action->kind == nothing)
989 return;
990
991 /* Otherwise, check what we have at the place of the call site. */
992
993 /* No landing pad => no cleanups or handlers. */
994 if (action->landing_pad == 0)
995 {
996 action->kind = nothing;
997 return;
998 }
999
1000 /* Landing pad + null table entry => only cleanups. */
1001 else if (action->table_entry == 0)
1002 {
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;
1010 }
1011
1012 /* Landing pad + Table entry => handlers + possible cleanups. */
1013 else
1014 {
1015 const unsigned char * p = action->table_entry;
1016 _sleb128_t ar_filter, ar_disp;
1017
1018 action->kind = nothing;
1019
1020 while (1)
1021 {
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. */
1026
1027 /* Null filters are for cleanups. */
1028 if (ar_filter == cleanup_filter)
1029 {
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. */
1035 }
1036
1037 /* Positive filters are for regular handlers. */
1038 else if (ar_filter > 0)
1039 {
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))
1043 {
1044 enum action_kind act;
1045
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);
1050
1051 act = is_handled_by (choice, gnat_exception);
1052 if (act != nothing)
1053 {
1054 action->kind = act;
1055 action->ttype_filter = ar_filter;
1056 return;
1057 }
1058 }
1059 }
1060
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");
1065
1066 if (ar_disp == 0)
1067 return;
1068
1069 p += ar_disp;
1070 }
1071 }
1072 }
1073
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. */
1077
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)
1083 {
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);
1089
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);
1094
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);
1098 }
1099
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 *);
1105
1106 /* Below is the eh personality routine per se. We currently assume that only
1107 GNU-Ada exceptions are met. */
1108
1109 /* By default, the personality routine is public. */
1110 #define PERSONALITY_STORAGE
1111
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
1124
1125 /* Code executed to continue unwinding. With the ARM unwinder, the
1126 personality routine must unwind one frame (per EHABI 7.3 4.). */
1127
1128 static _Unwind_Reason_Code
1129 continue_unwind (struct _Unwind_Exception* ue_header ATTRIBUTE_UNUSED,
1130 struct _Unwind_Context* uw_context ATTRIBUTE_UNUSED)
1131 {
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;
1137 }
1138
1139 /* Common code for the body of GNAT personality routine. This code is shared
1140 between all unwinders. */
1141
1142 static _Unwind_Reason_Code
1143 personality_body (_Unwind_Action uw_phases,
1144 _Unwind_Exception *uw_exception,
1145 _Unwind_Context *uw_context)
1146 {
1147 region_descriptor region;
1148 action_descriptor action;
1149 _Unwind_Ptr ip;
1150
1151 /* Debug traces. */
1152 db_indent (DB_INDENT_RESET);
1153 db_phases (uw_phases);
1154 db_indent (DB_INDENT_INCREASE);
1155
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);
1160
1161 /* No LSDA => no handlers or cleanups => we shall unwind further up. */
1162 if (! region.lsda)
1163 return continue_unwind (uw_exception, uw_context);
1164
1165 /* Get the instruction pointer. */
1166 ip = get_ip_from_context (uw_context);
1167 db_region_for (&region, ip);
1168
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);
1173
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);
1178
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)
1184 {
1185 if (action.kind == cleanup)
1186 {
1187 return continue_unwind (uw_exception, uw_context);
1188 }
1189 else
1190 {
1191 #ifndef CERT
1192 struct Exception_Occurrence *excep;
1193
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
1203
1204 return _URC_HANDLER_FOUND;
1205 }
1206 }
1207
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. */
1212
1213 setup_to_install
1214 (uw_context, uw_exception, action.landing_pad, action.ttype_filter);
1215
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
1222
1223 return _URC_INSTALL_CONTEXT;
1224 }
1225
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.
1230
1231 We handle this with a number of specific tricks:
1232
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.
1236
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.
1240
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.
1244
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.
1249 */
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
1257
1258 PERSONALITY_STORAGE _Unwind_Reason_Code
1259 PERSONALITY_FUNCTION (version_arg_t, phases_arg_t,
1260 _Unwind_Exception_Class, _Unwind_Exception *,
1261 _Unwind_Context *);
1262
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)
1270 {
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;
1276
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)
1280 {
1281 #if defined (VMS) && defined (__IA64)
1282
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. */
1286
1287 extern long __gnat_handle_vms_condition (void *, void *);
1288
1289 unsigned int version_unexpected_bits_mask = 0xffffff00U;
1290 unsigned int phases_unexpected_bits_mask = 0xffffff00U;
1291
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
1296
1297 return _URC_FATAL_PHASE1_ERROR;
1298 }
1299
1300 return personality_body (uw_phases, uw_exception, uw_context);
1301 }
1302
1303 #else /* __ARM_EABI_UNWINDER__ */
1304
1305 PERSONALITY_STORAGE _Unwind_Reason_Code
1306 PERSONALITY_FUNCTION (_Unwind_State state,
1307 struct _Unwind_Exception* ue_header,
1308 struct _Unwind_Context* uw_context);
1309
1310 PERSONALITY_STORAGE _Unwind_Reason_Code
1311 PERSONALITY_FUNCTION (_Unwind_State state,
1312 struct _Unwind_Exception* uw_exception,
1313 struct _Unwind_Context* uw_context)
1314 {
1315 _Unwind_Action uw_phases;
1316
1317 switch (state & _US_ACTION_MASK)
1318 {
1319 case _US_VIRTUAL_UNWIND_FRAME:
1320 /* Phase 1. */
1321 uw_phases = _UA_SEARCH_PHASE;
1322 break;
1323
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;
1336
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);
1341
1342 default:
1343 return _URC_FAILURE;
1344 }
1345 uw_phases |= (state & _US_FORCE_UNWIND);
1346
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);
1353
1354 return personality_body (uw_phases, uw_exception, uw_context);
1355 }
1356 #endif /* __ARM_EABI_UNWINDER__ */
1357
1358 /* Callback routine called by Unwind_ForcedUnwind to execute all the cleanup
1359 before exiting the task. */
1360
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)
1369 {
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
1378 )
1379 __gnat_unhandled_except_handler (exception);
1380
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;
1385 }
1386 #endif
1387
1388 /* Define the consistently named wrappers imported by Propagate_Exception. */
1389
1390 _Unwind_Reason_Code
1391 __gnat_Unwind_RaiseException (_Unwind_Exception *e)
1392 {
1393 #ifdef __USING_SJLJ_EXCEPTIONS__
1394 return _Unwind_SjLj_RaiseException (e);
1395 #else
1396 return _Unwind_RaiseException (e);
1397 #endif
1398 }
1399
1400 _Unwind_Reason_Code
1401 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e ATTRIBUTE_UNUSED,
1402 void *handler ATTRIBUTE_UNUSED,
1403 void *argument ATTRIBUTE_UNUSED)
1404 {
1405 #ifdef __USING_SJLJ_EXCEPTIONS__
1406
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
1413
1414 #else
1415 return _Unwind_ForcedUnwind (e, handler, argument);
1416 #endif
1417 }
1418
1419 #if defined (__SEH__) && !defined (__USING_SJLJ_EXCEPTIONS__)
1420
1421 #define STATUS_USER_DEFINED (1U << 29)
1422
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)
1428
1429 EXCEPTION_DISPOSITION __gnat_SEH_error_handler
1430 (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
1431
1432 struct Exception_Data *
1433 __gnat_map_SEH (EXCEPTION_RECORD* ExceptionRecord, const char **msg);
1434
1435 struct _Unwind_Exception *
1436 __gnat_create_machine_occurrence_from_signal_handler (Exception_Id,
1437 const char *);
1438
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
1449
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. */
1455
1456 static void
1457 __gnat_adjust_context (unsigned char *unw, ULONG64 rsp)
1458 {
1459 unsigned int len;
1460
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)
1470 {
1471 /* Offset in prologue = 0. */
1472 if (unw[0] != 0)
1473 return;
1474 switch (unw[1] & 0xf)
1475 {
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:
1490 {
1491 ULONG64 *rip;
1492 rip = (ULONG64 *)rsp;
1493 if ((unw[1] & 0xf0) == 0x10)
1494 rip++;
1495 /* Adjust rip. */
1496 (*rip)++;
1497 }
1498 return;
1499 default:
1500 /* Unexpected. */
1501 return;
1502 }
1503 unw += 2;
1504 len--;
1505 }
1506 }
1507
1508 EXCEPTION_DISPOSITION
1509 __gnat_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
1510 PCONTEXT ms_orig_context,
1511 PDISPATCHER_CONTEXT ms_disp)
1512 {
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))
1517 {
1518 struct Exception_Data *exception;
1519 const char *msg;
1520 ULONG64 excpip = (ULONG64) ms_exc->ExceptionAddress;
1521
1522 if (excpip != 0
1523 && excpip >= (ms_disp->ImageBase
1524 + ms_disp->FunctionEntry->BeginAddress)
1525 && excpip < (ms_disp->ImageBase
1526 + ms_disp->FunctionEntry->EndAddress))
1527 {
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;
1534
1535 /* Get the context. */
1536 RtlCaptureContext (&context);
1537
1538 while (1)
1539 {
1540 PRUNTIME_FUNCTION RuntimeFunction;
1541 ULONG64 ImageBase;
1542 VOID *HandlerData;
1543 ULONG64 EstablisherFrame;
1544
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;
1553
1554 if (!RuntimeFunction)
1555 {
1556 /* In case of failure, assume this is a leaf function. */
1557 context.Rip = *(ULONG64 *) context.Rsp;
1558 context.Rsp += 8;
1559 }
1560 else
1561 {
1562 /* Unwind. */
1563 RtlVirtualUnwind (0, ImageBase, context.Rip, RuntimeFunction,
1564 &context, &HandlerData, &EstablisherFrame,
1565 NULL);
1566 }
1567
1568 /* 0 means bottom of the stack. */
1569 if (context.Rip == 0)
1570 {
1571 mf_func = NULL;
1572 break;
1573 }
1574 }
1575 if (mf_func != NULL)
1576 __gnat_adjust_context
1577 ((unsigned char *)(mf_imagebase + mf_func->UnwindData), mf_rsp);
1578 }
1579
1580 exception = __gnat_map_SEH (ms_exc, &msg);
1581 if (exception != NULL)
1582 {
1583 struct _Unwind_Exception *exc;
1584
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;
1597 }
1598
1599 }
1600
1601 return _GCC_specific_handler (ms_exc, this_frame, ms_orig_context,
1602 ms_disp, __gnat_personality_imp);
1603 }
1604 #endif /* SEH */
1605
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. */
1609
1610 const int __gnat_unwind_exception_size = sizeof (_Unwind_Exception);
1611 #endif
This page took 0.104453 seconds and 4 git commands to generate.