OSDN Git Service

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