OSDN Git Service

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