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