OSDN Git Service

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