]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ada/raise.c
2003-10-21 Arnaud Charlet <charlet@act-europe.fr>
[thirdparty/gcc.git] / gcc / ada / raise.c
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * R A I S E *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 1992-2003, Free Software Foundation, Inc. *
10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 2, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, USA. *
21 * *
22 * As a special exception, if you link this file with other files to *
23 * produce an executable, this file does not by itself cause the resulting *
24 * executable to be covered by the GNU General Public License. This except- *
25 * ion does not however invalidate any other reasons why the executable *
26 * file might be covered by the GNU Public License. *
27 * *
28 * GNAT was originally developed by the GNAT team at New York University. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
30 * *
31 ****************************************************************************/
32
33 /* Routines to support runtime exception handling */
34
35 #ifdef IN_RTS
36 #include "tconfig.h"
37 /* In the top-of-tree GCC, tconfig does not include tm.h, but in GCC 3.2
38 it does. To avoid branching raise.c just for that purpose, we kludge by
39 looking for a symbol always defined by tm.h and if it's not defined,
40 we include it. */
41 #ifndef FIRST_PSEUDO_REGISTER
42 #include "coretypes.h"
43 #include "tm.h"
44 #endif
45 #include "tsystem.h"
46 #include <sys/stat.h>
47 typedef char bool;
48 # define true 1
49 # define false 0
50 #else
51 #include "config.h"
52 #include "system.h"
53 #endif
54
55 #include "adaint.h"
56 #include "raise.h"
57
58 /* We have not yet figured out how to import this directly */
59
60 void
61 _gnat_builtin_longjmp (ptr, flag)
62 void *ptr;
63 int flag ATTRIBUTE_UNUSED;
64 {
65 __builtin_longjmp (ptr, 1);
66 }
67
68 /* When an exception is raised for which no handler exists, the procedure
69 Ada.Exceptions.Unhandled_Exception is called, which performs the call to
70 adafinal to complete finalization, and then prints out the error messages
71 for the unhandled exception. The final step is to call this routine, which
72 performs any system dependent cleanup required. */
73
74 void
75 __gnat_unhandled_terminate ()
76 {
77 /* Special termination handling for VMS */
78
79 #ifdef VMS
80 {
81 long prvhnd;
82
83 /* Remove the exception vector so it won't intercept any errors
84 in the call to exit, and go into and endless loop */
85
86 SYS$SETEXV (1, 0, 3, &prvhnd);
87 __gnat_os_exit (1);
88 }
89
90 /* Termination handling for all other systems. */
91
92 #elif !defined (__RT__)
93 __gnat_os_exit (1);
94 #endif
95 }
96
97 /* Below is the code related to the integration of the GCC mechanism for
98 exception handling. */
99
100 #include "unwind.h"
101
102 /* The names of a couple of "standard" routines for unwinding/propagation
103 actually vary depending on the underlying GCC scheme for exception handling
104 (SJLJ or DWARF). We need a consistently named interface to import from
105 a-except, so stubs are defined here. */
106
107 typedef struct _Unwind_Context _Unwind_Context;
108 typedef struct _Unwind_Exception _Unwind_Exception;
109
110 _Unwind_Reason_Code
111 __gnat_Unwind_RaiseException PARAMS ((_Unwind_Exception *));
112
113 _Unwind_Reason_Code
114 __gnat_Unwind_ForcedUnwind PARAMS ((_Unwind_Exception *, void *, void *));
115
116
117 #ifdef IN_RTS /* For eh personality routine */
118
119 #include "dwarf2.h"
120 #include "unwind-dw2-fde.h"
121 #include "unwind-pe.h"
122
123
124 /* --------------------------------------------------------------
125 -- The DB stuff below is there for debugging purposes only. --
126 -------------------------------------------------------------- */
127
128 #define DB_PHASES 0x1
129 #define DB_CSITE 0x2
130 #define DB_ACTIONS 0x4
131 #define DB_REGIONS 0x8
132
133 #define DB_ERR 0x1000
134
135 /* The "action" stuff below is also there for debugging purposes only. */
136
137 typedef struct
138 {
139 _Unwind_Action phase;
140 char * description;
141 } phase_descriptor;
142
143 static phase_descriptor phase_descriptors[]
144 = {{ _UA_SEARCH_PHASE, "SEARCH_PHASE" },
145 { _UA_CLEANUP_PHASE, "CLEANUP_PHASE" },
146 { _UA_HANDLER_FRAME, "HANDLER_FRAME" },
147 { _UA_FORCE_UNWIND, "FORCE_UNWIND" },
148 { -1, 0}};
149
150 static int
151 db_accepted_codes (void)
152 {
153 static int accepted_codes = -1;
154
155 if (accepted_codes == -1)
156 {
157 char * db_env = getenv ("EH_DEBUG");
158
159 accepted_codes = db_env ? (atoi (db_env) | DB_ERR) : 0;
160 /* Arranged for ERR stuff to always be visible when the variable
161 is defined. One may just set the variable to 0 to see the ERR
162 stuff only. */
163 }
164
165 return accepted_codes;
166 }
167
168 #define DB_INDENT_INCREASE 0x01
169 #define DB_INDENT_DECREASE 0x02
170 #define DB_INDENT_OUTPUT 0x04
171 #define DB_INDENT_NEWLINE 0x08
172 #define DB_INDENT_RESET 0x10
173
174 #define DB_INDENT_UNIT 8
175
176 static void
177 db_indent (int requests)
178 {
179 static int current_indentation_level = 0;
180
181 if (requests & DB_INDENT_RESET)
182 {
183 current_indentation_level = 0;
184 }
185
186 if (requests & DB_INDENT_INCREASE)
187 {
188 current_indentation_level ++;
189 }
190
191 if (requests & DB_INDENT_DECREASE)
192 {
193 current_indentation_level --;
194 }
195
196 if (requests & DB_INDENT_NEWLINE)
197 {
198 fprintf (stderr, "\n");
199 }
200
201 if (requests & DB_INDENT_OUTPUT)
202 {
203 fprintf (stderr, "%*s",
204 current_indentation_level * DB_INDENT_UNIT, " ");
205 }
206
207 }
208
209 static void
210 db (int db_code, char * msg_format, ...)
211 {
212 if (db_accepted_codes () & db_code)
213 {
214 va_list msg_args;
215
216 db_indent (DB_INDENT_OUTPUT);
217
218 va_start (msg_args, msg_format);
219 vfprintf (stderr, msg_format, msg_args);
220 va_end (msg_args);
221 }
222 }
223
224 static void
225 db_phases (int phases)
226 {
227 phase_descriptor *a = phase_descriptors;
228
229 if (! (db_accepted_codes() & DB_PHASES))
230 return;
231
232 db (DB_PHASES, "\n");
233
234 for (; a->description != 0; a++)
235 if (phases & a->phase)
236 db (DB_PHASES, "%s ", a->description);
237
238 db (DB_PHASES, " :\n");
239 }
240
241
242 /* ---------------------------------------------------------------
243 -- Now come a set of useful structures and helper routines. --
244 --------------------------------------------------------------- */
245
246 /* There are three major runtime tables involved, generated by the
247 GCC back-end. Contents slightly vary depending on the underlying
248 implementation scheme (dwarf zero cost / sjlj).
249
250 =======================================
251 * Tables for the dwarf zero cost case *
252 =======================================
253
254 call_site []
255 -------------------------------------------------------------------
256 * region-start | region-length | landing-pad | first-action-index *
257 -------------------------------------------------------------------
258
259 Identify possible actions to be taken and where to resume control
260 for that when an exception propagates through a pc inside the region
261 delimited by start and length.
262
263 A null landing-pad indicates that nothing is to be done.
264
265 Otherwise, first-action-index provides an entry into the action[]
266 table which heads a list of possible actions to be taken (see below).
267
268 If it is determined that indeed an action should be taken, that
269 is, if one action filter matches the exception beeing propagated,
270 then control should be transfered to landing-pad.
271
272 A null first-action-index indicates that there are only cleanups
273 to run there.
274
275 action []
276 -------------------------------
277 * action-filter | next-action *
278 -------------------------------
279
280 This table contains lists (called action chains) of possible actions
281 associated with call-site entries described in the call-site [] table.
282 There is at most one action list per call-site entry.
283
284 A null action-filter indicates a cleanup.
285
286 Non null action-filters provide an index into the ttypes [] table
287 (see below), from which information may be retrieved to check if it
288 matches the exception beeing propagated.
289
290 action-filter > 0 means there is a regular handler to be run,
291
292 action-filter < 0 means there is a some "exception_specification"
293 data to retrieve, which is only relevant for C++
294 and should never show up for Ada.
295
296 next-action indexes the next entry in the list. 0 indicates there is
297 no other entry.
298
299 ttypes []
300 ---------------
301 * ttype-value *
302 ---------------
303
304 A null value indicates a catch-all handler in C++, and an "others"
305 handler in Ada.
306
307 Non null values are used to match the exception beeing propagated:
308 In C++ this is a pointer to some rtti data, while in Ada this is an
309 exception id.
310
311 The special id value 1 indicates an "all_others" handler.
312
313 For C++, this table is actually also used to store "exception
314 specification" data. The differentiation between the two kinds
315 of entries is made by the sign of the associated action filter,
316 which translates into positive or negative offsets from the
317 so called base of the table:
318
319 Exception Specification data is stored at positive offsets from
320 the ttypes table base, which Exception Type data is stored at
321 negative offsets:
322
323 ---------------------------------------------------------------------------
324
325 Here is a quick summary of the tables organization:
326
327 +-- Unwind_Context (pc, ...)
328 |
329 |(pc)
330 |
331 | CALL-SITE[]
332 |
333 | +=============================================================+
334 | | region-start + length | landing-pad | first-action-index |
335 | +=============================================================+
336 +-> | pc range 0 => no-action 0 => cleanups only |
337 | !0 => jump @ N --+ |
338 +====================================================== | ====+
339 |
340 |
341 ACTION [] |
342 |
343 +==========================================================+ |
344 | action-filter | next-action | |
345 +==========================================================+ |
346 | 0 => cleanup | |
347 | >0 => ttype index for handler ------+ 0 => end of chain | <-+
348 | <0 => ttype index for spec data | |
349 +==================================== | ===================+
350 |
351 |
352 TTYPES [] |
353 | Offset negated from
354 +=====================+ | the actual base.
355 | ttype-value | |
356 +============+=====================+ |
357 | | 0 => "others" | |
358 | ... | 1 => "all others" | <---+
359 | | X => exception id |
360 | handlers +---------------------+
361 | | ... |
362 | ... | ... |
363 | | ... |
364 +============+=====================+ <<------ Table base
365 | ... | ... |
366 | specs | ... | (should not see negative filter
367 | ... | ... | values for Ada).
368 +============+=====================+
369
370
371 ============================
372 * Tables for the sjlj case *
373 ============================
374
375 So called "function contexts" are pushed on a context stack by calls to
376 _Unwind_SjLj_Register on function entry, and popped off at exit points by
377 calls to _Unwind_SjLj_Unregister. The current call_site for a function is
378 updated in the function context as the function's code runs along.
379
380 The generic unwinding engine in _Unwind_RaiseException walks the function
381 context stack and not the actual call chain.
382
383 The ACTION and TTYPES tables remain unchanged, which allows to search them
384 during the propagation phase to determine wether or not the propagated
385 exception is handled somewhere. When it is, we only "jump" up once directly
386 to the context where the handler will be found. Besides, this allows "break
387 exception unhandled" to work also
388
389 The CALL-SITE table is setup differently, though: the pc attached to the
390 unwind context is a direct index into the table, so the entries in this
391 table do not hold region bounds any more.
392
393 A special index (-1) is used to indicate that no action is possibly
394 connected with the context at hand, so null landing pads cannot appear
395 in the table.
396
397 Additionally, landing pad values in the table do not represent code address
398 to jump at, but so called "dispatch" indices used by a common landing pad
399 for the function to switch to the appropriate post-landing-pad.
400
401 +-- Unwind_Context (pc, ...)
402 |
403 | pc = call-site index
404 | 0 => terminate (should not see this for Ada)
405 | -1 => no-action
406 |
407 | CALL-SITE[]
408 |
409 | +=====================================+
410 | | landing-pad | first-action-index |
411 | +=====================================+
412 +-> | 0 => cleanups only |
413 | dispatch index N |
414 +=====================================+
415
416
417 ===================================
418 * Basic organization of this unit *
419 ===================================
420
421 The major point of this unit is to provide an exception propagation
422 personality routine for Ada. This is __gnat_eh_personality.
423
424 It is provided with a pointer to the propagated exception, an unwind
425 context describing a location the propagation is going through, and a
426 couple of other arguments including a description of the current
427 propagation phase.
428
429 It shall return to the generic propagation engine what is to be performed
430 next, after possible context adjustments, depending on what it finds in the
431 traversed context (a handler for the exception, a cleanup, nothing, ...),
432 and on the propagation phase.
433
434 A number of structures and subroutines are used for this purpose, as
435 sketched below:
436
437 o region_descriptor: General data associated with the context (base pc,
438 call-site table, action table, ttypes table, ...)
439
440 o action_descriptor: Data describing the action to be taken for the
441 propagated exception in the provided context (kind of action: nothing,
442 handler, cleanup; pointer to the action table entry, ...).
443
444 raise
445 |
446 ... (a-except.adb)
447 |
448 Propagate_Exception (a-exexpr.adb)
449 |
450 |
451 _Unwind_RaiseException (libgcc)
452 |
453 | (Ada frame)
454 |
455 +--> __gnat_eh_personality (context, exception)
456 |
457 +--> get_region_descriptor_for (context)
458 |
459 +--> get_action_descriptor_for (context, exception, region)
460 | |
461 | +--> get_call_site_action_for (context, region)
462 | (one version for each underlying scheme)
463 |
464 +--> setup_to_install (context)
465
466 This unit is inspired from the C++ version found in eh_personality.cc,
467 part of libstdc++-v3.
468
469 */
470
471
472 /* This is the structure of exception objects as built by the GNAT runtime
473 library (a-exexpr.adb). The layouts should exactly match, and the "common"
474 header is mandated by the exception handling ABI. */
475
476 typedef struct
477 {
478 _Unwind_Exception common;
479 /* ABI header, maximally aligned. */
480
481 _Unwind_Ptr id;
482 /* Id of the exception beeing propagated, filled by Propagate_Exception.
483
484 This is compared against the ttype entries associated with actions in the
485 examined context to see if one of these actions matches. */
486
487 bool handled_by_others;
488 /* Indicates wether a "when others" may catch this exception, also filled by
489 Propagate_Exception.
490
491 This is used to decide if a GNAT_OTHERS ttype entry matches. */
492
493 int n_cleanups_to_trigger;
494 /* Number of cleanups on the propagation way for the occurrence. This is
495 initialized to 0 by Propagate_Exception and computed by the personality
496 routine during the first phase of the propagation (incremented for each
497 context in which only cleanup actions match).
498
499 This is used by Propagate_Exception when the occurrence is not handled,
500 to control a forced unwinding phase aimed at triggering all the cleanups
501 before calling Unhandled_Exception_Terminate.
502
503 This is also used by __gnat_eh_personality to identify the point at which
504 the notification routine shall be called for a handled occurrence. */
505 } _GNAT_Exception;
506
507 /* The two constants below are specific ttype identifiers for special
508 exception ids. Their value is currently hardcoded at the gigi level
509 (see N_Exception_Handler). */
510
511 #define GNAT_OTHERS ((_Unwind_Ptr) 0x0)
512 #define GNAT_ALL_OTHERS ((_Unwind_Ptr) 0x1)
513
514 /* Describe the useful region data associated with an unwind context. */
515
516 typedef struct
517 {
518 /* The base pc of the region. */
519 _Unwind_Ptr base;
520
521 /* Pointer to the Language Specific Data for the region. */
522 _Unwind_Ptr lsda;
523
524 /* Call-Site data associated with this region. */
525 unsigned char call_site_encoding;
526 const unsigned char *call_site_table;
527
528 /* The base to which are relative landing pad offsets inside the call-site
529 entries . */
530 _Unwind_Ptr lp_base;
531
532 /* Action-Table associated with this region. */
533 const unsigned char *action_table;
534
535 /* Ttype data associated with this region. */
536 unsigned char ttype_encoding;
537 const unsigned char *ttype_table;
538 _Unwind_Ptr ttype_base;
539
540 } region_descriptor;
541
542 static void
543 db_region_for (region, uw_context)
544 region_descriptor *region;
545 _Unwind_Context *uw_context;
546 {
547 _Unwind_Ptr ip = _Unwind_GetIP (uw_context) - 1;
548
549 if (! (db_accepted_codes () & DB_REGIONS))
550 return;
551
552 db (DB_REGIONS, "For ip @ 0x%08x => ", ip);
553
554 if (region->lsda)
555 db (DB_REGIONS, "lsda @ 0x%x", region->lsda);
556 else
557 db (DB_REGIONS, "no lsda");
558
559 db (DB_REGIONS, "\n");
560 }
561
562 /* Retrieve the ttype entry associated with FILTER in the REGION's
563 ttype table. */
564
565 static const _Unwind_Ptr
566 get_ttype_entry_for (region, filter)
567 region_descriptor *region;
568 long filter;
569 {
570 _Unwind_Ptr ttype_entry;
571
572 filter *= size_of_encoded_value (region->ttype_encoding);
573 read_encoded_value_with_base
574 (region->ttype_encoding, region->ttype_base,
575 region->ttype_table - filter, &ttype_entry);
576
577 return ttype_entry;
578 }
579
580 /* Fill out the REGION descriptor for the provided UW_CONTEXT. */
581
582 static void
583 get_region_description_for (uw_context, region)
584 _Unwind_Context *uw_context;
585 region_descriptor *region;
586 {
587 const unsigned char * p;
588 _Unwind_Word tmp;
589 unsigned char lpbase_encoding;
590
591 /* Get the base address of the lsda information. If the provided context
592 is null or if there is no associated language specific data, there's
593 nothing we can/should do. */
594 region->lsda
595 = (_Unwind_Ptr) (uw_context
596 ? _Unwind_GetLanguageSpecificData (uw_context) : 0);
597
598 if (! region->lsda)
599 return;
600
601 /* Parse the lsda and fill the region descriptor. */
602 p = (char *)region->lsda;
603
604 region->base = _Unwind_GetRegionStart (uw_context);
605
606 /* Find @LPStart, the base to which landing pad offsets are relative. */
607 lpbase_encoding = *p++;
608 if (lpbase_encoding != DW_EH_PE_omit)
609 p = read_encoded_value
610 (uw_context, lpbase_encoding, p, &region->lp_base);
611 else
612 region->lp_base = region->base;
613
614 /* Find @TType, the base of the handler and exception spec type data. */
615 region->ttype_encoding = *p++;
616 if (region->ttype_encoding != DW_EH_PE_omit)
617 {
618 p = read_uleb128 (p, &tmp);
619 region->ttype_table = p + tmp;
620 }
621 else
622 region->ttype_table = 0;
623
624 region->ttype_base
625 = base_of_encoded_value (region->ttype_encoding, uw_context);
626
627 /* Get the encoding and length of the call-site table; the action table
628 immediately follows. */
629 region->call_site_encoding = *p++;
630 region->call_site_table = read_uleb128 (p, &tmp);
631
632 region->action_table = region->call_site_table + tmp;
633 }
634
635
636 /* Describe an action to be taken when propagating an exception up to
637 some context. */
638
639 typedef enum
640 {
641 /* Found some call site base data, but need to analyze further
642 before beeing able to decide. */
643 unknown,
644
645 /* There is nothing relevant in the context at hand. */
646 nothing,
647
648 /* There are only cleanups to run in this context. */
649 cleanup,
650
651 /* There is a handler for the exception in this context. */
652 handler
653 } action_kind;
654
655
656 typedef struct
657 {
658 /* The kind of action to be taken. */
659 action_kind kind;
660
661 /* A pointer to the action record entry. */
662 const unsigned char *table_entry;
663
664 /* Where we should jump to actually take an action (trigger a cleanup or an
665 exception handler). */
666 _Unwind_Ptr landing_pad;
667
668 /* If we have a handler matching our exception, these are the filter to
669 trigger it and the corresponding id. */
670 _Unwind_Sword ttype_filter;
671 _Unwind_Ptr ttype_entry;
672
673 } action_descriptor;
674
675
676 static void
677 db_action_for (action, uw_context)
678 action_descriptor *action;
679 _Unwind_Context *uw_context;
680 {
681 _Unwind_Ptr ip = _Unwind_GetIP (uw_context) - 1;
682
683 db (DB_ACTIONS, "For ip @ 0x%08x => ", ip);
684
685 switch (action->kind)
686 {
687 case unknown:
688 db (DB_ACTIONS, "lpad @ 0x%x, record @ 0x%x\n",
689 ip, action->landing_pad, action->table_entry);
690 break;
691
692 case nothing:
693 db (DB_ACTIONS, "Nothing\n");
694 break;
695
696 case cleanup:
697 db (DB_ACTIONS, "Cleanup\n");
698 break;
699
700 case handler:
701 db (DB_ACTIONS, "Handler, filter = %d\n", action->ttype_filter);
702 break;
703
704 default:
705 db (DB_ACTIONS, "Err? Unexpected action kind !\n");
706 break;
707 }
708
709 return;
710 }
711
712
713 /* Search the call_site_table of REGION for an entry appropriate for the
714 UW_CONTEXT's ip. If one is found, store the associated landing_pad and
715 action_table entry, and set the ACTION kind to unknown for further
716 analysis. Otherwise, set the ACTION kind to nothing.
717
718 There are two variants of this routine, depending on the underlying
719 mechanism (dwarf/sjlj), which account for differences in the tables
720 organization.
721 */
722
723 #ifdef __USING_SJLJ_EXCEPTIONS__
724
725 #define __builtin_eh_return_data_regno(x) x
726
727 static void
728 get_call_site_action_for (uw_context, region, action)
729 _Unwind_Context *uw_context;
730 region_descriptor *region;
731 action_descriptor *action;
732 {
733 _Unwind_Ptr call_site
734 = _Unwind_GetIP (uw_context) - 1;
735 /* Subtract 1 because GetIP returns the actual call_site value + 1. */
736
737 /* call_site is a direct index into the call-site table, with two special
738 values : -1 for no-action and 0 for "terminate". The latter should never
739 show up for Ada. To test for the former, beware that _Unwind_Ptr might be
740 unsigned. */
741
742 if ((int)call_site < 0)
743 {
744 action->kind = nothing;
745 return;
746 }
747 else if (call_site == 0)
748 {
749 db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n");
750 action->kind = nothing;
751 return;
752 }
753 else
754 {
755 _Unwind_Word cs_lp, cs_action;
756
757 /* Let the caller know there may be an action to take, but let it
758 determine the kind. */
759 action->kind = unknown;
760
761 /* We have a direct index into the call-site table, but this table is
762 made of leb128 values, the encoding length of which is variable. We
763 can't merely compute an offset from the index, then, but have to read
764 all the entries before the one of interest. */
765
766 const unsigned char * p = region->call_site_table;
767
768 do {
769 p = read_uleb128 (p, &cs_lp);
770 p = read_uleb128 (p, &cs_action);
771 } while (--call_site);
772
773
774 action->landing_pad = cs_lp + 1;
775
776 if (cs_action)
777 action->table_entry = region->action_table + cs_action - 1;
778 else
779 action->table_entry = 0;
780
781 return;
782 }
783 }
784
785 #else
786 /* ! __USING_SJLJ_EXCEPTIONS__ */
787
788 static void
789 get_call_site_action_for (uw_context, region, action)
790 _Unwind_Context *uw_context;
791 region_descriptor *region;
792 action_descriptor *action;
793 {
794 _Unwind_Ptr ip
795 = _Unwind_GetIP (uw_context) - 1;
796 /* Substract 1 because GetIP yields a call return address while we are
797 interested in information for the call point. This does not always yield
798 the exact call instruction address but always brings the ip back within
799 the corresponding region.
800
801 ??? When unwinding up from a signal handler triggered by a trap on some
802 instruction, we usually have the faulting instruction address here and
803 subtracting 1 might get us into the wrong region. */
804
805 const unsigned char * p
806 = region->call_site_table;
807
808 /* Unless we are able to determine otherwise ... */
809 action->kind = nothing;
810
811 db (DB_CSITE, "\n");
812
813 while (p < region->action_table)
814 {
815 _Unwind_Ptr cs_start, cs_len, cs_lp;
816 _Unwind_Word cs_action;
817
818 /* Note that all call-site encodings are "absolute" displacements. */
819 p = read_encoded_value (0, region->call_site_encoding, p, &cs_start);
820 p = read_encoded_value (0, region->call_site_encoding, p, &cs_len);
821 p = read_encoded_value (0, region->call_site_encoding, p, &cs_lp);
822 p = read_uleb128 (p, &cs_action);
823
824 db (DB_CSITE,
825 "c_site @ 0x%08x (+0x%03x), len = %3d, lpad @ 0x%08x (+0x%03x)\n",
826 region->base+cs_start, cs_start, cs_len,
827 region->lp_base+cs_lp, cs_lp);
828
829 /* The table is sorted, so if we've passed the ip, stop. */
830 if (ip < region->base + cs_start)
831 break;
832
833 /* If we have a match, fill the ACTION fields accordingly. */
834 else if (ip < region->base + cs_start + cs_len)
835 {
836 /* Let the caller know there may be an action to take, but let it
837 determine the kind. */
838 action->kind = unknown;
839
840 if (cs_lp)
841 action->landing_pad = region->lp_base + cs_lp;
842 else
843 action->landing_pad = 0;
844
845 if (cs_action)
846 action->table_entry = region->action_table + cs_action - 1;
847 else
848 action->table_entry = 0;
849
850 db (DB_CSITE, "+++\n");
851 return;
852 }
853 }
854
855 db (DB_CSITE, "---\n");
856 }
857
858 #endif
859
860 /* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
861 UW_CONTEXT in REGION. */
862
863 static void
864 get_action_description_for (uw_context, uw_exception, region, action)
865 _Unwind_Context *uw_context;
866 _Unwind_Exception *uw_exception;
867 region_descriptor *region;
868 action_descriptor *action;
869 {
870 _GNAT_Exception * gnat_exception = (_GNAT_Exception *) uw_exception;
871
872 /* Search the call site table first, which may get us a landing pad as well
873 as the head of an action record list. */
874 get_call_site_action_for (uw_context, region, action);
875 db_action_for (action, uw_context);
876
877 /* If there is not even a call_site entry, we are done. */
878 if (action->kind == nothing)
879 return;
880
881 /* Otherwise, check what we have at the place of the call site */
882
883 /* No landing pad => no cleanups or handlers. */
884 if (action->landing_pad == 0)
885 {
886 action->kind = nothing;
887 return;
888 }
889
890 /* Landing pad + null table entry => only cleanups. */
891 else if (action->table_entry == 0)
892 {
893 action->kind = cleanup;
894 return;
895 }
896
897 /* Landing pad + Table entry => handlers + possible cleanups. */
898 else
899 {
900 const unsigned char * p = action->table_entry;
901
902 _Unwind_Sword ar_filter, ar_disp;
903
904 action->kind = nothing;
905
906 while (1)
907 {
908 p = read_sleb128 (p, &ar_filter);
909 read_sleb128 (p, &ar_disp);
910 /* Don't assign p here, as it will be incremented by ar_disp
911 below. */
912
913 /* Null filters are for cleanups. */
914 if (ar_filter == 0)
915 action->kind = cleanup;
916
917 /* Positive filters are for regular handlers. */
918 else if (ar_filter > 0)
919 {
920 /* See if the filter we have is for an exception which matches
921 the one we are propagating. */
922 _Unwind_Ptr eid = get_ttype_entry_for (region, ar_filter);
923
924 if (eid == gnat_exception->id
925 || eid == GNAT_ALL_OTHERS
926 || (eid == GNAT_OTHERS && gnat_exception->handled_by_others))
927 {
928 action->ttype_filter = ar_filter;
929 action->ttype_entry = eid;
930 action->kind = handler;
931 return;
932 }
933 }
934
935 /* Negative filter values are for C++ exception specifications.
936 Should not be there for Ada :/ */
937 else
938 db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");
939
940 if (ar_disp == 0)
941 return;
942
943 p += ar_disp;
944 }
945 }
946 }
947
948 /* Setup in UW_CONTEXT the eh return target IP and data registers, which will
949 be restored with the others and retrieved by the landing pad once the jump
950 occured. */
951
952 static void
953 setup_to_install (uw_context, uw_exception, uw_landing_pad, uw_filter)
954 _Unwind_Context *uw_context;
955 _Unwind_Exception *uw_exception;
956 int uw_filter;
957 _Unwind_Ptr uw_landing_pad;
958 {
959 #ifndef EH_RETURN_DATA_REGNO
960 /* We should not be called if the appropriate underlying support is not
961 there. */
962 abort ();
963 #else
964 /* 1/ exception object pointer, which might be provided back to
965 _Unwind_Resume (and thus to this personality routine) if we are jumping
966 to a cleanup. */
967 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (0),
968 (_Unwind_Word)uw_exception);
969
970 /* 2/ handler switch value register, which will also be used by the target
971 landing pad to decide what action it shall take. */
972 _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (1),
973 (_Unwind_Word)uw_filter);
974
975 /* Setup the address we should jump at to reach the code where there is the
976 "something" we found. */
977 _Unwind_SetIP (uw_context, uw_landing_pad);
978 #endif
979 }
980
981 /* The following is defined from a-except.adb. Its purpose is to enable
982 automatic backtraces upon exception raise, as provided through the
983 GNAT.Traceback facilities. */
984 extern void __gnat_notify_handled_exception PARAMS ((void));
985 extern void __gnat_notify_unhandled_exception PARAMS ((void));
986
987 /* Below is the eh personality routine per se. We currently assume that only
988 GNU-Ada exceptions are met. */
989
990 _Unwind_Reason_Code
991 __gnat_eh_personality (uw_version, uw_phases,
992 uw_exception_class, uw_exception, uw_context)
993 int uw_version;
994 _Unwind_Action uw_phases;
995 _Unwind_Exception_Class uw_exception_class;
996 _Unwind_Exception *uw_exception;
997 _Unwind_Context *uw_context;
998 {
999 _GNAT_Exception * gnat_exception = (_GNAT_Exception *) uw_exception;
1000
1001 region_descriptor region;
1002 action_descriptor action;
1003
1004 if (uw_version != 1)
1005 return _URC_FATAL_PHASE1_ERROR;
1006
1007 db_indent (DB_INDENT_RESET);
1008 db_phases (uw_phases);
1009 db_indent (DB_INDENT_INCREASE);
1010
1011 /* Get the region description for the context we were provided with. This
1012 will tell us if there is some lsda, call_site, action and/or ttype data
1013 for the associated ip. */
1014 get_region_description_for (uw_context, &region);
1015 db_region_for (&region, uw_context);
1016
1017 /* No LSDA => no handlers or cleanups => we shall unwind further up. */
1018 if (! region.lsda)
1019 return _URC_CONTINUE_UNWIND;
1020
1021 /* Search the call-site and action-record tables for the action associated
1022 with this IP. */
1023 get_action_description_for (uw_context, uw_exception, &region, &action);
1024 db_action_for (&action, uw_context);
1025
1026 /* Whatever the phase, if there is nothing relevant in this frame,
1027 unwinding should just go on. */
1028 if (action.kind == nothing)
1029 return _URC_CONTINUE_UNWIND;
1030
1031 /* If we found something in search phase, we should return a code indicating
1032 what to do next depending on what we found. If we only have cleanups
1033 around, we shall try to unwind further up to find a handler, otherwise,
1034 tell we have a handler, which will trigger the second phase. */
1035 if (uw_phases & _UA_SEARCH_PHASE)
1036 {
1037 if (action.kind == cleanup)
1038 {
1039 gnat_exception->n_cleanups_to_trigger ++;
1040 return _URC_CONTINUE_UNWIND;
1041 }
1042 else
1043 {
1044 /* Trigger the appropriate notification routines before the second
1045 phase starts, which ensures the stack is still intact. */
1046 __gnat_notify_handled_exception ();
1047
1048 return _URC_HANDLER_FOUND;
1049 }
1050 }
1051
1052 /* We found something in cleanup/handler phase, which might be the handler
1053 or a cleanup for a handled occurrence, or a cleanup for an unhandled
1054 occurrence (we are in a FORCED_UNWIND phase in this case). Install the
1055 context to get there. */
1056
1057 /* If we are going to install a cleanup context, decrement the cleanup
1058 count. This is required in a FORCED_UNWINDing phase (for an unhandled
1059 exception), as this is used from the forced unwinding handler in
1060 Ada.Exceptions.Exception_Propagation to decide wether unwinding should
1061 proceed further or Unhandled_Exception_Terminate should be called. */
1062 if (action.kind == cleanup)
1063 gnat_exception->n_cleanups_to_trigger --;
1064
1065 setup_to_install
1066 (uw_context, uw_exception, action.landing_pad, action.ttype_filter);
1067
1068 return _URC_INSTALL_CONTEXT;
1069 }
1070
1071 /* Define the consistently named stubs imported by Propagate_Exception. */
1072
1073 #ifdef __USING_SJLJ_EXCEPTIONS__
1074
1075 #undef _Unwind_RaiseException
1076
1077 _Unwind_Reason_Code
1078 __gnat_Unwind_RaiseException (e)
1079 _Unwind_Exception *e;
1080 {
1081 return _Unwind_SjLj_RaiseException (e);
1082 }
1083
1084
1085 #undef _Unwind_ForcedUnwind
1086
1087 _Unwind_Reason_Code
1088 __gnat_Unwind_ForcedUnwind (e, handler, argument)
1089 _Unwind_Exception *e;
1090 void * handler;
1091 void * argument;
1092 {
1093 return _Unwind_SjLj_ForcedUnwind (e, handler, argument);
1094 }
1095
1096
1097 #else /* __USING_SJLJ_EXCEPTIONS__ */
1098
1099 _Unwind_Reason_Code
1100 __gnat_Unwind_RaiseException (e)
1101 _Unwind_Exception *e;
1102 {
1103 return _Unwind_RaiseException (e);
1104 }
1105
1106 _Unwind_Reason_Code
1107 __gnat_Unwind_ForcedUnwind (e, handler, argument)
1108 _Unwind_Exception *e;
1109 void * handler;
1110 void * argument;
1111 {
1112 return _Unwind_ForcedUnwind (e, handler, argument);
1113 }
1114
1115 #endif /* __USING_SJLJ_EXCEPTIONS__ */
1116
1117 #else
1118 /* ! IN_RTS */
1119
1120 /* The calls to the GCC runtime interface for exception raising are currently
1121 issued from a-exexpr.adb, which is used by both the runtime library and the
1122 compiler.
1123
1124 As the compiler binary is not linked against the GCC runtime library, we
1125 need also need stubs for this interface in the compiler case. We should not
1126 be using the GCC eh mechanism for the compiler, however, so expect these
1127 functions never to be called. */
1128
1129 _Unwind_Reason_Code
1130 __gnat_Unwind_RaiseException (e)
1131 _Unwind_Exception *e ATTRIBUTE_UNUSED;
1132 {
1133 abort ();
1134 }
1135
1136
1137 _Unwind_Reason_Code
1138 __gnat_Unwind_ForcedUnwind (e, handler, argument)
1139 _Unwind_Exception *e ATTRIBUTE_UNUSED;
1140 void * handler ATTRIBUTE_UNUSED;
1141 void * argument ATTRIBUTE_UNUSED;
1142 {
1143 abort ();
1144 }
1145
1146 #endif /* IN_RTS */