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