OSDN Git Service

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