]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/raise.c
3psoccon.ads, [...]: Files added.
[gcc.git] / gcc / ada / raise.c
CommitLineData
19235870
RK
1/****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * R A I S E *
6 * *
7 * C Implementation File *
8 * *
fbf5a39b 9 * Copyright (C) 1992-2003, Free Software Foundation, Inc. *
19235870
RK
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. *
71ff80dc 29 * Extensive contributions were provided by Ada Core Technologies Inc. *
19235870
RK
30 * *
31 ****************************************************************************/
32
33/* Routines to support runtime exception handling */
34
35#ifdef IN_RTS
36#include "tconfig.h"
fbf5a39b
AC
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
19235870
RK
45#include "tsystem.h"
46#include <sys/stat.h>
07fc65c4
GB
47typedef char bool;
48# define true 1
49# define false 0
19235870
RK
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
60void
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
74void
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}
17c5c8a5 96
07fc65c4 97/* Below is the code related to the integration of the GCC mechanism for
fbf5a39b 98 exception handling. */
07fc65c4
GB
99
100#include "unwind.h"
101
fbf5a39b
AC
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. */
3d713bb8 106
fbf5a39b
AC
107typedef struct _Unwind_Context _Unwind_Context;
108typedef struct _Unwind_Exception _Unwind_Exception;
3d713bb8 109
fbf5a39b
AC
110_Unwind_Reason_Code
111__gnat_Unwind_RaiseException PARAMS ((_Unwind_Exception *));
3d713bb8 112
fbf5a39b
AC
113_Unwind_Reason_Code
114__gnat_Unwind_ForcedUnwind PARAMS ((_Unwind_Exception *, void *, void *));
17c5c8a5 115
17c5c8a5
GB
116
117#ifdef IN_RTS /* For eh personality routine */
118
17c5c8a5 119#include "dwarf2.h"
17c5c8a5
GB
120#include "unwind-dw2-fde.h"
121#include "unwind-pe.h"
122
17c5c8a5 123
fbf5a39b
AC
124/* --------------------------------------------------------------
125 -- The DB stuff below is there for debugging purposes only. --
126 -------------------------------------------------------------- */
17c5c8a5 127
fbf5a39b
AC
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
137typedef struct
17c5c8a5 138{
fbf5a39b
AC
139 _Unwind_Action phase;
140 char * description;
141} phase_descriptor;
17c5c8a5 142
fbf5a39b
AC
143static 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}};
17c5c8a5 149
fbf5a39b
AC
150static int
151db_accepted_codes (void)
17c5c8a5 152{
fbf5a39b 153 static int accepted_codes = -1;
17c5c8a5 154
fbf5a39b
AC
155 if (accepted_codes == -1)
156 {
157 char * db_env = getenv ("EH_DEBUG");
17c5c8a5 158
fbf5a39b
AC
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 }
07fc65c4 164
fbf5a39b
AC
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
176static void
177db_indent (int requests)
178{
179 static int current_indentation_level = 0;
180
181 if (requests & DB_INDENT_RESET)
17c5c8a5 182 {
fbf5a39b 183 current_indentation_level = 0;
17c5c8a5 184 }
17c5c8a5 185
fbf5a39b
AC
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 }
17c5c8a5 206
17c5c8a5
GB
207}
208
fbf5a39b
AC
209static void
210db (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
224static void
225db_phases (int phases)
17c5c8a5 226{
fbf5a39b
AC
227 phase_descriptor *a = phase_descriptors;
228
229 if (! (db_accepted_codes() & DB_PHASES))
230 return;
17c5c8a5 231
fbf5a39b
AC
232 db (DB_PHASES, "\n");
233
234 for (; a->description != 0; a++)
235 if (phases & a->phase)
236 db (DB_PHASES, "%s ", a->description);
17c5c8a5 237
fbf5a39b 238 db (DB_PHASES, " :\n");
17c5c8a5
GB
239}
240
fbf5a39b
AC
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
17c5c8a5 472/* This is the structure of exception objects as built by the GNAT runtime
fbf5a39b 473 library (a-exexpr.adb). The layouts should exactly match, and the "common"
17c5c8a5
GB
474 header is mandated by the exception handling ABI. */
475
fbf5a39b 476typedef struct
07fc65c4 477{
fbf5a39b
AC
478 _Unwind_Exception common;
479 /* ABI header, maximally aligned. */
480
17c5c8a5 481 _Unwind_Ptr id;
fbf5a39b
AC
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. */
17c5c8a5 492
fbf5a39b
AC
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;
17c5c8a5
GB
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
fbf5a39b
AC
511#define GNAT_OTHERS ((_Unwind_Ptr) 0x0)
512#define GNAT_ALL_OTHERS ((_Unwind_Ptr) 0x1)
17c5c8a5 513
fbf5a39b 514/* Describe the useful region data associated with an unwind context. */
17c5c8a5 515
fbf5a39b
AC
516typedef struct
517{
518 /* The base pc of the region. */
519 _Unwind_Ptr base;
17c5c8a5 520
fbf5a39b
AC
521 /* Pointer to the Language Specific Data for the region. */
522 _Unwind_Ptr lsda;
17c5c8a5 523
fbf5a39b
AC
524 /* Call-Site data associated with this region. */
525 unsigned char call_site_encoding;
526 const unsigned char *call_site_table;
17c5c8a5 527
fbf5a39b
AC
528 /* The base to which are relative landing pad offsets inside the call-site
529 entries . */
530 _Unwind_Ptr lp_base;
17c5c8a5 531
fbf5a39b
AC
532 /* Action-Table associated with this region. */
533 const unsigned char *action_table;
17c5c8a5 534
fbf5a39b
AC
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
542static void
543db_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
565static const _Unwind_Ptr
566get_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
582static void
583get_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
639typedef 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;
17c5c8a5 654
17c5c8a5 655
07fc65c4
GB
656typedef struct
657{
fbf5a39b
AC
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;
07fc65c4 674
17c5c8a5
GB
675
676static void
fbf5a39b
AC
677db_action_for (action, uw_context)
678 action_descriptor *action;
679 _Unwind_Context *uw_context;
17c5c8a5 680{
fbf5a39b 681 _Unwind_Ptr ip = _Unwind_GetIP (uw_context) - 1;
17c5c8a5 682
fbf5a39b 683 db (DB_ACTIONS, "For ip @ 0x%08x => ", ip);
17c5c8a5 684
fbf5a39b
AC
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 }
17c5c8a5 708
fbf5a39b 709 return;
17c5c8a5
GB
710}
711
17c5c8a5 712
fbf5a39b
AC
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.
17c5c8a5 717
fbf5a39b
AC
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
727static void
728get_call_site_action_for (uw_context, region, action)
729 _Unwind_Context *uw_context;
730 region_descriptor *region;
731 action_descriptor *action;
17c5c8a5 732{
fbf5a39b
AC
733 _Unwind_Ptr call_site
734 = _Unwind_GetIP (uw_context) - 1;
735 /* Subtract 1 because GetIP returns the actual call_site value + 1. */
17c5c8a5 736
fbf5a39b
AC
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. */
07fc65c4 741
fbf5a39b 742 if ((int)call_site < 0)
17c5c8a5 743 {
fbf5a39b
AC
744 action->kind = nothing;
745 return;
17c5c8a5 746 }
fbf5a39b
AC
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;
17c5c8a5 756
fbf5a39b
AC
757 /* Let the caller know there may be an action to take, but let it
758 determine the kind. */
759 action->kind = unknown;
17c5c8a5 760
fbf5a39b
AC
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. */
17c5c8a5 765
fbf5a39b 766 const unsigned char * p = region->call_site_table;
17c5c8a5 767
fbf5a39b
AC
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;
17c5c8a5 782 }
fbf5a39b
AC
783}
784
785#else
786/* ! __USING_SJLJ_EXCEPTIONS__ */
787
788static void
789get_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. */
07fc65c4 804
fbf5a39b
AC
805 const unsigned char * p
806 = region->call_site_table;
17c5c8a5 807
fbf5a39b
AC
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)
17c5c8a5 814 {
07fc65c4
GB
815 _Unwind_Ptr cs_start, cs_len, cs_lp;
816 _Unwind_Word cs_action;
17c5c8a5
GB
817
818 /* Note that all call-site encodings are "absolute" displacements. */
fbf5a39b
AC
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);
17c5c8a5
GB
822 p = read_uleb128 (p, &cs_action);
823
fbf5a39b
AC
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
17c5c8a5 829 /* The table is sorted, so if we've passed the ip, stop. */
fbf5a39b
AC
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)
17c5c8a5 835 {
fbf5a39b
AC
836 /* Let the caller know there may be an action to take, but let it
837 determine the kind. */
838 action->kind = unknown;
839
17c5c8a5 840 if (cs_lp)
fbf5a39b
AC
841 action->landing_pad = region->lp_base + cs_lp;
842 else
843 action->landing_pad = 0;
844
17c5c8a5 845 if (cs_action)
fbf5a39b
AC
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;
17c5c8a5
GB
852 }
853 }
854
fbf5a39b
AC
855 db (DB_CSITE, "---\n");
856}
17c5c8a5 857
fbf5a39b 858#endif
07fc65c4 859
fbf5a39b
AC
860/* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
861 UW_CONTEXT in REGION. */
07fc65c4 862
fbf5a39b
AC
863static void
864get_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;
17c5c8a5 871
fbf5a39b
AC
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);
17c5c8a5 876
fbf5a39b
AC
877 /* If there is not even a call_site entry, we are done. */
878 if (action->kind == nothing)
879 return;
17c5c8a5 880
fbf5a39b 881 /* Otherwise, check what we have at the place of the call site */
07fc65c4 882
fbf5a39b
AC
883 /* No landing pad => no cleanups or handlers. */
884 if (action->landing_pad == 0)
17c5c8a5 885 {
fbf5a39b
AC
886 action->kind = nothing;
887 return;
17c5c8a5 888 }
fbf5a39b
AC
889
890 /* Landing pad + null table entry => only cleanups. */
891 else if (action->table_entry == 0)
17c5c8a5 892 {
fbf5a39b
AC
893 action->kind = cleanup;
894 return;
17c5c8a5 895 }
fbf5a39b
AC
896
897 /* Landing pad + Table entry => handlers + possible cleanups. */
17c5c8a5
GB
898 else
899 {
fbf5a39b 900 const unsigned char * p = action->table_entry;
17c5c8a5 901
fbf5a39b 902 _Unwind_Sword ar_filter, ar_disp;
17c5c8a5 903
fbf5a39b 904 action->kind = nothing;
17c5c8a5
GB
905
906 while (1)
907 {
fbf5a39b
AC
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. */
17c5c8a5 912
fbf5a39b 913 /* Null filters are for cleanups. */
17c5c8a5 914 if (ar_filter == 0)
fbf5a39b
AC
915 action->kind = cleanup;
916
917 /* Positive filters are for regular handlers. */
17c5c8a5
GB
918 else if (ar_filter > 0)
919 {
fbf5a39b
AC
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);
17c5c8a5 923
fbf5a39b
AC
924 if (eid == gnat_exception->id
925 || eid == GNAT_ALL_OTHERS
926 || (eid == GNAT_OTHERS && gnat_exception->handled_by_others))
17c5c8a5 927 {
fbf5a39b
AC
928 action->ttype_filter = ar_filter;
929 action->ttype_entry = eid;
930 action->kind = handler;
931 return;
17c5c8a5
GB
932 }
933 }
fbf5a39b
AC
934
935 /* Negative filter values are for C++ exception specifications.
936 Should not be there for Ada :/ */
17c5c8a5 937 else
fbf5a39b 938 db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");
17c5c8a5 939
fbf5a39b
AC
940 if (ar_disp == 0)
941 return;
17c5c8a5 942
fbf5a39b
AC
943 p += ar_disp;
944 }
945 }
946}
17c5c8a5 947
fbf5a39b
AC
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. */
07fc65c4 951
fbf5a39b
AC
952static void
953setup_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}
17c5c8a5 980
fbf5a39b
AC
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. */
984extern void __gnat_notify_handled_exception PARAMS ((void));
985extern void __gnat_notify_unhandled_exception PARAMS ((void));
07fc65c4 986
fbf5a39b
AC
987/* Below is the eh personality routine per se. We currently assume that only
988 GNU-Ada exceptions are met. */
17c5c8a5 989
fbf5a39b
AC
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;
17c5c8a5 1000
fbf5a39b
AC
1001 region_descriptor region;
1002 action_descriptor action;
17c5c8a5 1003
fbf5a39b
AC
1004 if (uw_version != 1)
1005 return _URC_FATAL_PHASE1_ERROR;
17c5c8a5 1006
fbf5a39b
AC
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)
17c5c8a5 1038 {
fbf5a39b 1039 gnat_exception->n_cleanups_to_trigger ++;
17c5c8a5
GB
1040 return _URC_CONTINUE_UNWIND;
1041 }
fbf5a39b
AC
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 ();
17c5c8a5 1047
fbf5a39b
AC
1048 return _URC_HANDLER_FOUND;
1049 }
17c5c8a5
GB
1050 }
1051
fbf5a39b
AC
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. */
07fc65c4 1056
fbf5a39b
AC
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 --;
17c5c8a5 1064
fbf5a39b
AC
1065 setup_to_install
1066 (uw_context, uw_exception, action.landing_pad, action.ttype_filter);
17c5c8a5 1067
fbf5a39b
AC
1068 return _URC_INSTALL_CONTEXT;
1069}
07fc65c4 1070
fbf5a39b 1071/* Define the consistently named stubs imported by Propagate_Exception. */
17c5c8a5 1072
fbf5a39b 1073#ifdef __USING_SJLJ_EXCEPTIONS__
07fc65c4 1074
fbf5a39b 1075#undef _Unwind_RaiseException
17c5c8a5 1076
fbf5a39b
AC
1077_Unwind_Reason_Code
1078__gnat_Unwind_RaiseException (e)
1079 _Unwind_Exception *e;
1080{
1081 return _Unwind_SjLj_RaiseException (e);
1082}
17c5c8a5 1083
17c5c8a5 1084
fbf5a39b 1085#undef _Unwind_ForcedUnwind
17c5c8a5 1086
fbf5a39b
AC
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);
17c5c8a5
GB
1094}
1095
1096
fbf5a39b 1097#else /* __USING_SJLJ_EXCEPTIONS__ */
23cae84f
OH
1098
1099_Unwind_Reason_Code
1100__gnat_Unwind_RaiseException (e)
fbf5a39b 1101 _Unwind_Exception *e;
23cae84f 1102{
fbf5a39b 1103 return _Unwind_RaiseException (e);
23cae84f
OH
1104}
1105
3d713bb8 1106_Unwind_Reason_Code
fbf5a39b
AC
1107__gnat_Unwind_ForcedUnwind (e, handler, argument)
1108 _Unwind_Exception *e;
1109 void * handler;
1110 void * argument;
23cae84f 1111{
fbf5a39b 1112 return _Unwind_ForcedUnwind (e, handler, argument);
23cae84f 1113}
fbf5a39b
AC
1114
1115#endif /* __USING_SJLJ_EXCEPTIONS__ */
23cae84f
OH
1116
1117#else
fbf5a39b 1118/* ! IN_RTS */
07fc65c4
GB
1119
1120/* The calls to the GCC runtime interface for exception raising are currently
fbf5a39b
AC
1121 issued from a-exexpr.adb, which is used by both the runtime library and the
1122 compiler.
07fc65c4 1123
fbf5a39b
AC
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. */
07fc65c4
GB
1128
1129_Unwind_Reason_Code
23cae84f 1130__gnat_Unwind_RaiseException (e)
fbf5a39b 1131 _Unwind_Exception *e ATTRIBUTE_UNUSED;
07fc65c4 1132{
07fc65c4
GB
1133 abort ();
1134}
1135
fbf5a39b
AC
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 */
This page took 1.287591 seconds and 5 git commands to generate.