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-2019, 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 #ifndef IN_RTS
36   /* For gnat1/gnatbind compilation: use host headers.  */
37 # include "config.h"
38 # include "system.h"
39   /* Don't use fancy_abort.  */
40 # undef abort
41 #else
42 # ifndef CERT
43 #  include "tconfig.h"
44 #  include "tsystem.h"
45 # else
46 #  define ATTRIBUTE_UNUSED __attribute__((unused))
47 #  define HAVE_GETIPINFO 1
48 # endif
49 #endif
50 
51 #include <stdarg.h>
52 
53 #ifdef __cplusplus
54 # include <cstdlib>
55 #else
56 typedef char bool;
57 # define true 1
58 # define false 0
59 #endif
60 
61 #include "raise.h"
62 
63 #ifdef __APPLE__
64 /* On MacOS X, versions older than 10.5 don't export _Unwind_GetIPInfo.  */
65 #undef HAVE_GETIPINFO
66 #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
67 #define HAVE_GETIPINFO 1
68 #endif
69 #endif
70 
71 #if defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
72 /* HP-UX B.11.31 ia64 libunwind doesn't have _Unwind_GetIPInfo. */
73 #undef HAVE_GETIPINFO
74 #define _UA_END_OF_STACK 0
75 #endif
76 
77 /* The names of a couple of "standard" routines for unwinding/propagation
78    actually vary depending on the underlying GCC scheme for exception handling
79    (SJLJ or DWARF). We need a consistently named interface to import from
80    a-except, so wrappers are defined here.  */
81 
82 #ifndef IN_RTS
83   /* For gnat1/gnatbind compilation: cannot use unwind.h, as it is for the
84      target. So mimic configure...
85      This is a hack ???, the real fix is to link gnat1/gnatbind with the
86      runtime of the build compiler.  */
87 # ifdef EH_MECHANISM_arm
88 #   include "config/arm/unwind-arm.h"
89 # else
90 #   include "unwind-generic.h"
91 # endif
92 #else
93 # include "unwind.h"
94 #endif
95 
96 #ifdef __cplusplus
97 extern "C" {
98 #endif
99 
100 typedef struct _Unwind_Context _Unwind_Context;
101 typedef struct _Unwind_Exception _Unwind_Exception;
102 
103 _Unwind_Reason_Code
104 __gnat_Unwind_RaiseException (_Unwind_Exception *);
105 
106 _Unwind_Reason_Code
107 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *, _Unwind_Stop_Fn, void *);
108 
109 extern struct Exception_Occurrence *
110 __gnat_setup_current_excep (_Unwind_Exception *, _Unwind_Action);
111 
112 extern void __gnat_unhandled_except_handler (_Unwind_Exception *);
113 
114 #ifdef CERT
115 /* Called in case of error during propagation.  */
116 extern void __gnat_raise_abort (void) __attribute__ ((noreturn));
117 #define abort() __gnat_raise_abort()
118 #endif
119 
120 #include "unwind-pe.h"
121 
122 #ifdef __ARM_EABI_UNWINDER__
123 /* for memcmp */
124 #include <string.h>
125 #endif
126 
127 /* The known and handled exception classes.  */
128 
129 #ifdef __ARM_EABI_UNWINDER__
130 #define CXX_EXCEPTION_CLASS "GNUCC++"
131 #define GNAT_EXCEPTION_CLASS "GNU-Ada"
132 #else
133 #define CXX_EXCEPTION_CLASS 0x474e5543432b2b00ULL
134 #define GNAT_EXCEPTION_CLASS 0x474e552d41646100ULL
135 #endif
136 
137 /* Structure of a C++ exception, represented as a C structure...  See
138    unwind-cxx.h for the full definition.  */
139 
140 struct __cxa_exception
141 {
142   void *exceptionType;
143   void (*exceptionDestructor)(void *);
144 
145   void (*unexpectedHandler)();
146   void (*terminateHandler)();
147 
148   struct __cxa_exception *nextException;
149 
150   int handlerCount;
151 
152 #ifdef __ARM_EABI_UNWINDER__
153   struct __cxa_exception* nextPropagatingException;
154 
155   int propagationCount;
156 #else
157   int handlerSwitchValue;
158   const unsigned char *actionRecord;
159   const unsigned char *languageSpecificData;
160   _Unwind_Ptr catchTemp;
161   void *adjustedPtr;
162 #endif
163 
164   _Unwind_Exception unwindHeader;
165 };
166 
167 /* --------------------------------------------------------------
168    -- The DB stuff below is there for debugging purposes only. --
169    -------------------------------------------------------------- */
170 
171 #ifndef inhibit_libc
172 
173 #define DB_PHASES     0x1
174 #define DB_CSITE      0x2
175 #define DB_ACTIONS    0x4
176 #define DB_REGIONS    0x8
177 
178 #define DB_ERR        0x1000
179 
180 /* The "action" stuff below is also there for debugging purposes only.  */
181 
182 typedef struct
183 {
184   _Unwind_Action phase;
185   const char * description;
186 } phase_descriptor;
187 
188 static const phase_descriptor phase_descriptors[]
189   = {{ _UA_SEARCH_PHASE,  "SEARCH_PHASE" },
190      { _UA_CLEANUP_PHASE, "CLEANUP_PHASE" },
191      { _UA_HANDLER_FRAME, "HANDLER_FRAME" },
192      { _UA_FORCE_UNWIND,  "FORCE_UNWIND" },
193      { -1, 0}};
194 
195 static int
db_accepted_codes(void)196 db_accepted_codes (void)
197 {
198   static int accepted_codes = -1;
199 
200   if (accepted_codes == -1)
201     {
202       char * db_env = (char *) getenv ("EH_DEBUG");
203 
204       accepted_codes = db_env ? (atoi (db_env) | DB_ERR) : 0;
205       /* Arranged for ERR stuff to always be visible when the variable
206 	 is defined. One may just set the variable to 0 to see the ERR
207 	 stuff only.  */
208     }
209 
210   return accepted_codes;
211 }
212 
213 #define DB_INDENT_INCREASE 0x01
214 #define DB_INDENT_DECREASE 0x02
215 #define DB_INDENT_OUTPUT   0x04
216 #define DB_INDENT_NEWLINE  0x08
217 #define DB_INDENT_RESET    0x10
218 
219 #define DB_INDENT_UNIT     8
220 
221 static void
db_indent(int requests)222 db_indent (int requests)
223 {
224   static int current_indentation_level = 0;
225 
226   if (requests & DB_INDENT_RESET)
227     current_indentation_level = 0;
228 
229   if (requests & DB_INDENT_INCREASE)
230     current_indentation_level ++;
231 
232   if (requests & DB_INDENT_DECREASE)
233     current_indentation_level --;
234 
235   if (requests & DB_INDENT_NEWLINE)
236     fprintf (stderr, "\n");
237 
238   if (requests & DB_INDENT_OUTPUT)
239     fprintf (stderr, "%*s", current_indentation_level * DB_INDENT_UNIT, " ");
240 }
241 
242 static void ATTRIBUTE_PRINTF_2
db(int db_code,const char * msg_format,...)243 db (int db_code, const char * msg_format, ...)
244 {
245   if (db_accepted_codes () & db_code)
246     {
247       va_list msg_args;
248 
249       db_indent (DB_INDENT_OUTPUT);
250 
251       va_start (msg_args, msg_format);
252       vfprintf (stderr, msg_format, msg_args);
253       va_end (msg_args);
254     }
255 }
256 
257 static void
db_phases(int phases)258 db_phases (int phases)
259 {
260   const phase_descriptor *a = phase_descriptors;
261 
262   if (! (db_accepted_codes () & DB_PHASES))
263     return;
264 
265   db (DB_PHASES, "\n");
266 
267   for (; a->description != 0; a++)
268     if (phases & a->phase)
269       db (DB_PHASES, "%s ", a->description);
270 
271   db (DB_PHASES, " :\n");
272 }
273 #else /* !inhibit_libc */
274 #define db_phases(X)
275 #define db_indent(X)
276 #define db(X, ...)
277 #endif /* !inhibit_libc */
278 
279 /* ---------------------------------------------------------------
280    --  Now come a set of useful structures and helper routines. --
281    --------------------------------------------------------------- */
282 
283 /* There are three major runtime tables involved, generated by the
284    GCC back-end. Contents slightly vary depending on the underlying
285    implementation scheme (dwarf zero cost / sjlj).
286 
287    =======================================
288    * Tables for the dwarf zero cost case *
289    =======================================
290 
291    They are fully documented in:
292      http://sourcery.mentor.com/public/cxx-abi/exceptions.pdf
293    Here is a shorter presentation, with some specific comments for Ada.
294 
295    call_site []
296    -------------------------------------------------------------------
297    * region-start | region-length | landing-pad | first-action-index *
298    -------------------------------------------------------------------
299 
300    Identify possible actions to be taken and where to resume control
301    for that when an exception propagates through a pc inside the region
302    delimited by start and length.
303 
304    A null landing-pad indicates that nothing is to be done.
305 
306    Otherwise, first-action-index provides an entry into the action[]
307    table which heads a list of possible actions to be taken (see below).
308 
309    If it is determined that indeed an action should be taken, that
310    is, if one action filter matches the exception being propagated,
311    then control should be transferred to landing-pad.
312 
313    A null first-action-index indicates that there are only cleanups
314    to run there.
315 
316    action []
317    -------------------------------
318    * action-filter | next-action *
319    -------------------------------
320 
321    This table contains lists (called action chains) of possible actions
322    associated with call-site entries described in the call-site [] table.
323    There is at most one action list per call-site entry.  It is SLEB128
324    encoded.
325 
326    A null action-filter indicates a cleanup.
327 
328    Non null action-filters provide an index into the ttypes [] table
329    (see below), from which information may be retrieved to check if it
330    matches the exception being propagated.
331 
332    * action-filter > 0:
333    means there is a regular handler to be run The value is also passed
334    to the landing pad to dispatch the exception.
335 
336    * action-filter < 0:
337    means there is a some "exception_specification" data to retrieve,
338    which is only relevant for C++ and should never show up for Ada.
339    (Exception specification specifies which exceptions can be thrown
340    by a function. Such filter is emitted around the body of C++
341    functions defined like:
342      void foo ([...])  throw (A, B) { [...] }
343    These can be viewed as negativ filter: the landing pad is branched
344    to for exceptions that doesn't match the filter and usually aborts
345    the program).
346 
347    * next-action
348    points to the next entry in the list using a relative byte offset. 0
349    indicates there is no other entry.
350 
351    ttypes []
352    ---------------
353    * ttype-value *
354    ---------------
355 
356    This table is an array of addresses.
357 
358    A null value indicates a catch-all handler.  (Not used by Ada)
359 
360    Non null values are used to match the exception being propagated:
361    In C++ this is a pointer to some rtti data, while in Ada this is an
362    exception id (with a fake id for others).
363 
364    For C++, this table is actually also used to store "exception
365    specification" data. The differentiation between the two kinds
366    of entries is made by the sign of the associated action filter,
367    which translates into positive or negative offsets from the
368    so called base of the table:
369 
370    Exception Specification data is stored at positive offsets from
371    the ttypes table base, which Exception Type data is stored at
372    negative offsets:
373 
374    ---------------------------------------------------------------------------
375 
376    Here is a quick summary of the tables organization:
377 
378 	  +-- Unwind_Context (pc, ...)
379 	  |
380 	  |(pc)
381 	  |
382 	  |   CALL-SITE[]
383 	  |
384 	  |   +=============================================================+
385 	  |   | region-start + length |  landing-pad   | first-action-index |
386 	  |   +=============================================================+
387 	  +-> |       pc range          0 => no-action   0 => cleanups only |
388 	      |                         !0 => jump @              N --+     |
389 	      +====================================================== | ====+
390                                                                       |
391                                                                       |
392        ACTION []                                                      |
393                                                                       |
394        +==========================================================+   |
395        |              action-filter           |   next-action     |   |
396        +==========================================================+   |
397        |  0 => cleanup                                            |   |
398        | >0 => ttype index for handler ------+  0 => end of chain | <-+
399        | <0 => ttype index for spec data     |                    |
400        +==================================== | ===================+
401                                              |
402                                              |
403        TTYPES []                             |
404 					     |  Offset negated from
405 		 +=====================+     |  the actual base.
406 		 |     ttype-value     |     |
407     +============+=====================+     |
408     |            |        ...          |     |
409     |    ...     |     exception id    | <---+
410     |            |        ...          |
411     |  handlers	 +---------------------+
412     |            |        ...          |
413     |    ...     |        ...          |
414     |            |        ...          |
415     +============+=====================+ <<------ Table base
416     |    ...     |        ...          |
417     |   specs    |        ...          | (should not see negative filter
418     |    ...     |        ...          |  values for Ada).
419     +============+=====================+
420 
421 
422    ============================
423    * Tables for the sjlj case *
424    ============================
425 
426    So called "function contexts" are pushed on a context stack by calls to
427    _Unwind_SjLj_Register on function entry, and popped off at exit points by
428    calls to _Unwind_SjLj_Unregister. The current call_site for a function is
429    updated in the function context as the function's code runs along.
430 
431    The generic unwinding engine in _Unwind_RaiseException walks the function
432    context stack and not the actual call chain.
433 
434    The ACTION and TTYPES tables remain unchanged, which allows to search them
435    during the propagation phase to determine whether or not the propagated
436    exception is handled somewhere. When it is, we only "jump" up once directly
437    to the context where the handler will be found. Besides, this allows "break
438    exception unhandled" to work also
439 
440    The CALL-SITE table is setup differently, though: the pc attached to the
441    unwind context is a direct index into the table, so the entries in this
442    table do not hold region bounds any more.
443 
444    A special index (-1) is used to indicate that no action is possibly
445    connected with the context at hand, so null landing pads cannot appear
446    in the table.
447 
448    Additionally, landing pad values in the table do not represent code address
449    to jump at, but so called "dispatch" indices used by a common landing pad
450    for the function to switch to the appropriate post-landing-pad.
451 
452    +-- Unwind_Context (pc, ...)
453    |
454    | pc = call-site index
455    |  0 => terminate (should not see this for Ada)
456    | -1 => no-action
457    |
458    |   CALL-SITE[]
459    |
460    |   +=====================================+
461    |   |  landing-pad   | first-action-index |
462    |   +=====================================+
463    +-> |                  0 => cleanups only |
464        | dispatch index             N        |
465        +=====================================+
466 
467 
468    ===================================
469    * Basic organization of this unit *
470    ===================================
471 
472    The major point of this unit is to provide an exception propagation
473    personality routine for Ada. This is __gnat_personality_v0.
474 
475    It is provided with a pointer to the propagated exception, an unwind
476    context describing a location the propagation is going through, and a
477    couple of other arguments including a description of the current
478    propagation phase.
479 
480    It shall return to the generic propagation engine what is to be performed
481    next, after possible context adjustments, depending on what it finds in the
482    traversed context (a handler for the exception, a cleanup, nothing, ...),
483    and on the propagation phase.
484 
485    A number of structures and subroutines are used for this purpose, as
486    sketched below:
487 
488    o region_descriptor: General data associated with the context (base pc,
489      call-site table, action table, ttypes table, ...)
490 
491    o action_descriptor: Data describing the action to be taken for the
492      propagated exception in the provided context (kind of action: nothing,
493      handler, cleanup; pointer to the action table entry, ...).
494 
495    raise
496      |
497     ... (a-except.adb)
498      |
499    Propagate_Exception (a-exexpr.adb)
500      |
501      |
502    _Unwind_RaiseException (libgcc)
503      |
504      |   (Ada frame)
505      |
506      +--> __gnat_personality_v0 (context, exception)
507 	   |
508 	   +--> get_region_description_for (context)
509 	   |
510 	   +--> get_action_description_for (ip, exception, region)
511 	   |       |
512 	   |       +--> get_call_site_action_for (context, region)
513 	   |            (one version for each underlying scheme)
514            |
515 	   +--> setup_to_install (context)
516 
517    This unit is inspired from the C++ version found in eh_personality.cc,
518    part of libstdc++-v3.
519 
520 */
521 
522 
523 /* This is an incomplete "proxy" of the structure of exception objects as
524    built by the GNAT runtime library. Accesses to other fields than the common
525    header are performed through subprogram calls to alleviate the need of an
526    exact counterpart here and potential alignment/size issues for the common
527    header. See a-exexpr.adb.  */
528 
529 typedef struct
530 {
531   _Unwind_Exception common;
532   /* ABI header, maximally aligned. */
533 } _GNAT_Exception;
534 
535 /* The two constants below are specific ttype identifiers for special
536    exception ids.  Their type should match what a-exexpr exports.  */
537 
538 extern const int __gnat_others_value;
539 #define GNAT_OTHERS      ((_Unwind_Ptr) &__gnat_others_value)
540 
541 extern const int __gnat_all_others_value;
542 #define GNAT_ALL_OTHERS  ((_Unwind_Ptr) &__gnat_all_others_value)
543 
544 extern const int __gnat_unhandled_others_value;
545 #define GNAT_UNHANDLED_OTHERS  ((_Unwind_Ptr) &__gnat_unhandled_others_value)
546 
547 /* Describe the useful region data associated with an unwind context.  */
548 
549 typedef struct
550 {
551   /* The base pc of the region.  */
552   _Unwind_Ptr base;
553 
554   /* Pointer to the Language Specific Data for the region.  */
555   _Unwind_Ptr lsda;
556 
557   /* Call-Site data associated with this region.  */
558   unsigned char call_site_encoding;
559   const unsigned char *call_site_table;
560 
561   /* The base to which are relative landing pad offsets inside the call-site
562      entries .  */
563   _Unwind_Ptr lp_base;
564 
565   /* Action-Table associated with this region.  */
566   const unsigned char *action_table;
567 
568   /* Ttype data associated with this region.  */
569   unsigned char ttype_encoding;
570   const unsigned char *ttype_table;
571   _Unwind_Ptr ttype_base;
572 
573 } region_descriptor;
574 
575 /* Extract and adjust the IP (instruction pointer) from an exception
576    context.  */
577 
578 static _Unwind_Ptr
get_ip_from_context(_Unwind_Context * uw_context)579 get_ip_from_context (_Unwind_Context *uw_context)
580 {
581   int ip_before_insn = 0;
582 #ifdef HAVE_GETIPINFO
583   _Unwind_Ptr ip = _Unwind_GetIPInfo (uw_context, &ip_before_insn);
584 #else
585   _Unwind_Ptr ip = _Unwind_GetIP (uw_context);
586 #endif
587   /* Subtract 1 if necessary because GetIPInfo yields a call return address
588      in this case, while we are interested in information for the call point.
589      This does not always yield the exact call instruction address but always
590      brings the IP back within the corresponding region.  */
591   if (!ip_before_insn)
592     ip--;
593 
594   return ip;
595 }
596 
597 static void
db_region_for(region_descriptor * region,_Unwind_Ptr ip)598 db_region_for (region_descriptor *region, _Unwind_Ptr ip)
599 {
600 #ifndef inhibit_libc
601   if (! (db_accepted_codes () & DB_REGIONS))
602     return;
603 
604   db (DB_REGIONS, "For ip @ %p => ", (void *)ip);
605 
606   if (region->lsda)
607     db (DB_REGIONS, "lsda @ %p", (void *)region->lsda);
608   else
609     db (DB_REGIONS, "no lsda");
610 
611   db (DB_REGIONS, "\n");
612 #endif
613 }
614 
615 /* Retrieve the ttype entry associated with FILTER in the REGION's
616    ttype table.  */
617 
618 static _Unwind_Ptr
get_ttype_entry_for(region_descriptor * region,long filter)619 get_ttype_entry_for (region_descriptor *region, long filter)
620 {
621   _Unwind_Ptr ttype_entry;
622 
623   filter *= size_of_encoded_value (region->ttype_encoding);
624   read_encoded_value_with_base
625     (region->ttype_encoding, region->ttype_base,
626      region->ttype_table - filter, &ttype_entry);
627 
628   return ttype_entry;
629 }
630 
631 /* Fill out the REGION descriptor for the provided UW_CONTEXT.  */
632 
633 static void
get_region_description_for(_Unwind_Context * uw_context,region_descriptor * region)634 get_region_description_for (_Unwind_Context *uw_context,
635                             region_descriptor *region)
636 {
637   const unsigned char * p;
638   _uleb128_t tmp;
639   unsigned char lpbase_encoding;
640 
641   /* Get the base address of the lsda information. If the provided context
642      is null or if there is no associated language specific data, there's
643      nothing we can/should do.  */
644   region->lsda
645     = (_Unwind_Ptr) (uw_context
646 		     ? _Unwind_GetLanguageSpecificData (uw_context) : 0);
647 
648   if (! region->lsda)
649     return;
650 
651   /* Parse the lsda and fill the region descriptor.  */
652   p = (const unsigned char *)region->lsda;
653 
654   region->base = _Unwind_GetRegionStart (uw_context);
655 
656   /* Find @LPStart, the base to which landing pad offsets are relative.  */
657   lpbase_encoding = *p++;
658   if (lpbase_encoding != DW_EH_PE_omit)
659     p = read_encoded_value
660       (uw_context, lpbase_encoding, p, &region->lp_base);
661   else
662     region->lp_base = region->base;
663 
664   /* Find @TType, the base of the handler and exception spec type data.  */
665   region->ttype_encoding = *p++;
666   if (region->ttype_encoding != DW_EH_PE_omit)
667     {
668       p = read_uleb128 (p, &tmp);
669       region->ttype_table = p + tmp;
670     }
671    else
672      region->ttype_table = 0;
673 
674   region->ttype_base
675     = base_of_encoded_value (region->ttype_encoding, uw_context);
676 
677   /* Get the encoding and length of the call-site table; the action table
678      immediately follows.  */
679   region->call_site_encoding = *p++;
680   region->call_site_table = read_uleb128 (p, &tmp);
681 
682   region->action_table = region->call_site_table + tmp;
683 }
684 
685 
686 /* Describe an action to be taken when propagating an exception up to
687    some context.  */
688 
689 enum action_kind
690 {
691   /* Found some call site base data, but need to analyze further
692      before being able to decide.  */
693   unknown,
694 
695   /* There is nothing relevant in the context at hand. */
696   nothing,
697 
698   /* There are only cleanups to run in this context.  */
699   cleanup,
700 
701   /* There is a handler for the exception in this context.  */
702   handler,
703 
704   /* There is a handler for the exception, but it is only for catching
705      unhandled exceptions.  */
706   unhandler
707 };
708 
709 /* filter value for cleanup actions.  */
710 static const int cleanup_filter = 0;
711 
712 typedef struct
713 {
714   /* The kind of action to be taken.  */
715   enum action_kind kind;
716 
717   /* A pointer to the action record entry.  */
718   const unsigned char *table_entry;
719 
720   /* Where we should jump to actually take an action (trigger a cleanup or an
721      exception handler).  */
722   _Unwind_Ptr landing_pad;
723 
724   /* If we have a handler matching our exception, these are the filter to
725      trigger it and the corresponding id.  */
726   _Unwind_Sword ttype_filter;
727 
728 } action_descriptor;
729 
730 static void
db_action_for(action_descriptor * action,_Unwind_Ptr ip)731 db_action_for (action_descriptor *action, _Unwind_Ptr ip)
732 {
733 #ifndef inhibit_libc
734   db (DB_ACTIONS, "For ip @ %p => ", (void *)ip);
735 
736   switch (action->kind)
737      {
738      case unknown:
739        db (DB_ACTIONS, "lpad @ %p, record @ %p\n",
740 	   (void *) action->landing_pad, action->table_entry);
741        break;
742 
743      case nothing:
744        db (DB_ACTIONS, "Nothing\n");
745        break;
746 
747      case cleanup:
748        db (DB_ACTIONS, "Cleanup\n");
749        break;
750 
751      case handler:
752        db (DB_ACTIONS, "Handler, filter = %d\n", (int) action->ttype_filter);
753        break;
754 
755      default:
756        db (DB_ACTIONS, "Err? Unexpected action kind !\n");
757        break;
758     }
759 #endif
760 }
761 
762 /* Search the call_site_table of REGION for an entry appropriate for the
763    UW_CONTEXT's IP.  If one is found, store the associated landing_pad
764    and action_table entry, and set the ACTION kind to unknown for further
765    analysis.  Otherwise, set the ACTION kind to nothing.
766 
767    There are two variants of this routine, depending on the underlying
768    mechanism (DWARF/SJLJ), which account for differences in the tables.  */
769 
770 #ifdef __USING_SJLJ_EXCEPTIONS__
771 
772 #define __builtin_eh_return_data_regno(x) x
773 
774 static void
get_call_site_action_for(_Unwind_Ptr call_site,region_descriptor * region,action_descriptor * action)775 get_call_site_action_for (_Unwind_Ptr call_site,
776                           region_descriptor *region,
777                           action_descriptor *action)
778 {
779   /* call_site is a direct index into the call-site table, with two special
780      values : -1 for no-action and 0 for "terminate".  The latter should never
781      show up for Ada.  To test for the former, beware that _Unwind_Ptr might
782      be unsigned.  */
783 
784   if ((int)call_site < 0)
785     {
786       action->kind = nothing;
787     }
788   else if (call_site == 0)
789     {
790       db (DB_ERR, "========> Err, null call_site for Ada/sjlj\n");
791       action->kind = nothing;
792     }
793   else
794     {
795       _uleb128_t cs_lp, cs_action;
796       const unsigned char *p;
797 
798       /* Let the caller know there may be an action to take, but let it
799 	 determine the kind.  */
800       action->kind = unknown;
801 
802       /* We have a direct index into the call-site table, but this table is
803 	 made of leb128 values, the encoding length of which is variable.  We
804 	 can't merely compute an offset from the index, then, but have to read
805 	 all the entries before the one of interest.  */
806       p = region->call_site_table;
807       do
808 	{
809 	  p = read_uleb128 (p, &cs_lp);
810 	  p = read_uleb128 (p, &cs_action);
811 	}
812       while (--call_site);
813 
814       action->landing_pad = cs_lp + 1;
815 
816       if (cs_action)
817 	action->table_entry = region->action_table + cs_action - 1;
818       else
819 	action->table_entry = 0;
820     }
821 }
822 
823 #else /* !__USING_SJLJ_EXCEPTIONS__  */
824 
825 static void
get_call_site_action_for(_Unwind_Ptr ip,region_descriptor * region,action_descriptor * action)826 get_call_site_action_for (_Unwind_Ptr ip,
827                           region_descriptor *region,
828                           action_descriptor *action)
829 {
830   const unsigned char *p = region->call_site_table;
831 
832   /* Unless we are able to determine otherwise...  */
833   action->kind = nothing;
834 
835   db (DB_CSITE, "\n");
836 
837   while (p < region->action_table)
838     {
839       _Unwind_Ptr cs_start, cs_len, cs_lp;
840       _uleb128_t cs_action;
841 
842       /* Note that all call-site encodings are "absolute" displacements.  */
843       p = read_encoded_value (0, region->call_site_encoding, p, &cs_start);
844       p = read_encoded_value (0, region->call_site_encoding, p, &cs_len);
845       p = read_encoded_value (0, region->call_site_encoding, p, &cs_lp);
846       p = read_uleb128 (p, &cs_action);
847 
848       db (DB_CSITE,
849 	  "c_site @ %p (+%p), len = %p, lpad @ %p (+%p)\n",
850 	  (char *)region->base + cs_start, (void *)cs_start, (void *)cs_len,
851 	  (char *)region->lp_base + cs_lp, (void *)cs_lp);
852 
853       /* The table is sorted, so if we've passed the IP, stop.  */
854       if (ip < region->base + cs_start)
855  	break;
856 
857       /* If we have a match, fill the ACTION fields accordingly.  */
858       else if (ip < region->base + cs_start + cs_len)
859 	{
860 	  /* Let the caller know there may be an action to take, but let it
861 	     determine the kind.  */
862 	  action->kind = unknown;
863 
864 	  if (cs_lp)
865 	    action->landing_pad = region->lp_base + cs_lp;
866 	  else
867 	    action->landing_pad = 0;
868 
869 	  if (cs_action)
870 	    action->table_entry = region->action_table + cs_action - 1;
871 	  else
872 	    action->table_entry = 0;
873 
874 	  db (DB_CSITE, "+++\n");
875 	  return;
876 	}
877     }
878 
879   db (DB_CSITE, "---\n");
880 }
881 
882 #endif /* __USING_SJLJ_EXCEPTIONS__  */
883 
884 /* With CHOICE an exception choice representing an "exception - when"
885    argument, and PROPAGATED_EXCEPTION a pointer to the currently propagated
886    occurrence, return true if the latter matches the former, that is, if
887    PROPAGATED_EXCEPTION is caught by the handling code controlled by CHOICE.
888    This takes care of the special Non_Ada_Error case on VMS.  */
889 
890 #define Is_Handled_By_Others  __gnat_is_handled_by_others
891 #define Language_For          __gnat_language_for
892 #define Foreign_Data_For      __gnat_foreign_data_for
893 #define EID_For               __gnat_eid_for
894 
895 extern bool Is_Handled_By_Others (_Unwind_Ptr eid);
896 extern char Language_For (_Unwind_Ptr eid);
897 
898 extern void *Foreign_Data_For (_Unwind_Ptr eid);
899 
900 extern Exception_Id EID_For (_GNAT_Exception * e);
901 
902 #define Foreign_Exception system__exceptions__foreign_exception
903 extern struct Exception_Data Foreign_Exception;
904 
905 #ifdef VMS
906 #define Non_Ada_Error system__aux_dec__non_ada_error
907 extern struct Exception_Data Non_Ada_Error;
908 #endif
909 
910 /* Return true iff the exception class of EXCEPT is EC.  */
911 
912 static int
exception_class_eq(const _GNAT_Exception * except,const _Unwind_Exception_Class ec)913 exception_class_eq (const _GNAT_Exception *except,
914 		    const _Unwind_Exception_Class ec)
915 {
916 #ifdef __ARM_EABI_UNWINDER__
917   return memcmp (except->common.exception_class, ec, 8) == 0;
918 #else
919   return except->common.exception_class == ec;
920 #endif
921 }
922 
923 /* Return how CHOICE matches PROPAGATED_EXCEPTION.  */
924 
925 static enum action_kind
is_handled_by(_Unwind_Ptr choice,_GNAT_Exception * propagated_exception)926 is_handled_by (_Unwind_Ptr choice, _GNAT_Exception *propagated_exception)
927 {
928   /* All others choice match everything.  */
929   if (choice == GNAT_ALL_OTHERS)
930     return handler;
931 
932   /* GNAT exception occurrence.  */
933   if (exception_class_eq (propagated_exception, GNAT_EXCEPTION_CLASS))
934     {
935       /* Pointer to the GNAT exception data corresponding to the propagated
936          occurrence.  */
937       _Unwind_Ptr E = (_Unwind_Ptr) EID_For (propagated_exception);
938 
939       if (choice == GNAT_UNHANDLED_OTHERS)
940 	return unhandler;
941 
942       E = (_Unwind_Ptr) EID_For (propagated_exception);
943 
944       /* Base matching rules: An exception data (id) matches itself, "when
945          all_others" matches anything and "when others" matches anything
946          unless explicitly stated otherwise in the propagated occurrence.  */
947       if (choice == E || (choice == GNAT_OTHERS && Is_Handled_By_Others (E)))
948 	return handler;
949 
950 #ifdef VMS
951       /* In addition, on OpenVMS, Non_Ada_Error matches VMS exceptions, and we
952          may have different exception data pointers that should match for the
953          same condition code, if both an export and an import have been
954          registered.  The import code for both the choice and the propagated
955          occurrence are expected to have been masked off regarding severity
956          bits already (at registration time for the former and from within the
957          low level exception vector for the latter).  */
958       if ((Language_For (E) == 'V'
959 	   && choice != GNAT_OTHERS
960 	   && ((Language_For (choice) == 'V'
961 		&& Foreign_Data_For (choice) != 0
962 		&& Foreign_Data_For (choice) == Foreign_Data_For (E))
963 	       || choice == (_Unwind_Ptr)&Non_Ada_Error)))
964 	return handler;
965 #endif
966 
967       /* Otherwise, it doesn't match an Ada choice.  */
968       return nothing;
969     }
970 
971   /* All others and others choice match any foreign exception.  */
972   if (choice == GNAT_ALL_OTHERS
973       || choice == GNAT_OTHERS
974 #ifndef CERT
975       || choice == (_Unwind_Ptr) &Foreign_Exception
976 #endif
977       )
978     return handler;
979 
980 #ifndef CERT
981   /* C++ exception occurrences.  */
982   if (exception_class_eq (propagated_exception, CXX_EXCEPTION_CLASS)
983       && Language_For (choice) == 'C')
984     {
985       void *choice_typeinfo = Foreign_Data_For (choice);
986       void *except_typeinfo =
987 	(((struct __cxa_exception *)
988 	  ((_Unwind_Exception *)propagated_exception + 1)) - 1)
989 	->exceptionType;
990 
991       /* Typeinfo are directly compared, which might not be correct if they
992 	 aren't merged.  ??? We should call the == operator if this module is
993 	 compiled in C++.  */
994       if (choice_typeinfo == except_typeinfo)
995 	return handler;
996     }
997 #endif
998 
999   return nothing;
1000 }
1001 
1002 /* Fill out the ACTION to be taken from propagating UW_EXCEPTION up to
1003    UW_CONTEXT in REGION.  */
1004 
1005 static void
get_action_description_for(_Unwind_Ptr ip,_Unwind_Exception * uw_exception,_Unwind_Action uw_phase,region_descriptor * region,action_descriptor * action)1006 get_action_description_for (_Unwind_Ptr ip,
1007                             _Unwind_Exception *uw_exception,
1008                             _Unwind_Action uw_phase,
1009                             region_descriptor *region,
1010                             action_descriptor *action)
1011 {
1012   _GNAT_Exception *gnat_exception = (_GNAT_Exception *) uw_exception;
1013 
1014   /* Search the call site table first, which may get us a landing pad as well
1015      as the head of an action record list.  */
1016   get_call_site_action_for (ip, region, action);
1017   db_action_for (action, ip);
1018 
1019   /* If there is not even a call_site entry, we are done.  */
1020   if (action->kind == nothing)
1021     return;
1022 
1023   /* Otherwise, check what we have at the place of the call site.  */
1024 
1025   /* No landing pad => no cleanups or handlers.  */
1026   if (action->landing_pad == 0)
1027     {
1028       action->kind = nothing;
1029       return;
1030     }
1031 
1032   /* Landing pad + null table entry => only cleanups.  */
1033   else if (action->table_entry == 0)
1034     {
1035       action->kind = cleanup;
1036       action->ttype_filter = cleanup_filter;
1037       /* The filter initialization is not strictly necessary, as cleanup-only
1038 	 landing pads don't look at the filter value.  It is there to ensure
1039 	 we don't pass random values and so trigger potential confusion when
1040 	 installing the context later on.  */
1041       return;
1042     }
1043 
1044   /* Landing pad + Table entry => handlers + possible cleanups.  */
1045   else
1046     {
1047       const unsigned char * p = action->table_entry;
1048       _sleb128_t ar_filter, ar_disp;
1049 
1050       action->kind = nothing;
1051 
1052       while (1)
1053 	{
1054 	  p = read_sleb128 (p, &ar_filter);
1055 	  read_sleb128 (p, &ar_disp);
1056 	  /* Don't assign p here, as it will be incremented by ar_disp
1057 	     below.  */
1058 
1059 	  /* Null filters are for cleanups. */
1060 	  if (ar_filter == cleanup_filter)
1061 	    {
1062 	      action->kind = cleanup;
1063 	      action->ttype_filter = cleanup_filter;
1064 	      /* The filter initialization is required here, to ensure
1065 		 the target landing pad branches to the cleanup code if
1066 		 we happen not to find a matching handler.  */
1067 	    }
1068 
1069 	  /* Positive filters are for regular handlers.  */
1070 	  else if (ar_filter > 0)
1071 	    {
1072               /* Do not catch an exception if the _UA_FORCE_UNWIND flag is
1073                  passed (to follow the ABI).  */
1074               if (!(uw_phase & _UA_FORCE_UNWIND))
1075                 {
1076 		  enum action_kind act;
1077 
1078                   /* See if the filter we have is for an exception which
1079                      matches the one we are propagating.  */
1080                   _Unwind_Ptr choice =
1081 		    get_ttype_entry_for (region, ar_filter);
1082 
1083 		  act = is_handled_by (choice, gnat_exception);
1084                   if (act != nothing)
1085                     {
1086 		      action->kind = act;
1087                       action->ttype_filter = ar_filter;
1088                       return;
1089                     }
1090                 }
1091 	    }
1092 
1093 	  /* Negative filter values are for C++ exception specifications.
1094 	     Should not be there for Ada :/  */
1095 	  else
1096 	    db (DB_ERR, "========> Err, filter < 0 for Ada/dwarf\n");
1097 
1098 	  if (ar_disp == 0)
1099 	    return;
1100 
1101 	  p += ar_disp;
1102 	}
1103     }
1104 }
1105 
1106 /* Setup in UW_CONTEXT the eh return target IP and data registers, which will
1107    be restored with the others and retrieved by the landing pad once the jump
1108    occurred.  */
1109 
1110 static void
setup_to_install(_Unwind_Context * uw_context,_Unwind_Exception * uw_exception,_Unwind_Ptr uw_landing_pad,int uw_filter)1111 setup_to_install (_Unwind_Context *uw_context,
1112                   _Unwind_Exception *uw_exception,
1113                   _Unwind_Ptr uw_landing_pad,
1114                   int uw_filter)
1115 {
1116   /* 1/ exception object pointer, which might be provided back to
1117      _Unwind_Resume (and thus to this personality routine) if we are jumping
1118      to a cleanup.  */
1119   _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (0),
1120 		 (_Unwind_Word)uw_exception);
1121 
1122   /* 2/ handler switch value register, which will also be used by the target
1123      landing pad to decide what action it shall take.  */
1124   _Unwind_SetGR (uw_context, __builtin_eh_return_data_regno (1),
1125 		 (_Unwind_Word)uw_filter);
1126 
1127   /* Setup the address we should jump at to reach the code where there is the
1128      "something" we found.  */
1129   _Unwind_SetIP (uw_context, uw_landing_pad);
1130 }
1131 
1132 /* The following is defined from a-except.adb. Its purpose is to enable
1133    automatic backtraces upon exception raise, as provided through the
1134    GNAT.Traceback facilities.  */
1135 extern void __gnat_notify_handled_exception (struct Exception_Occurrence *);
1136 extern void __gnat_notify_unhandled_exception (struct Exception_Occurrence *);
1137 
1138 /* Below is the eh personality routine per se. We currently assume that only
1139    GNU-Ada exceptions are met.  */
1140 
1141 /* By default, the personality routine is public.  */
1142 #define PERSONALITY_STORAGE
1143 
1144 #ifdef __USING_SJLJ_EXCEPTIONS__
1145 #define PERSONALITY_FUNCTION    __gnat_personality_sj0
1146 #elif defined (__SEH__)
1147 #define PERSONALITY_FUNCTION    __gnat_personality_imp
1148 /* The public personality routine for seh is __gnat_personality_seh0, defined
1149    below using the SEH convention. This is a wrapper around the GNU routine,
1150    which is static.  */
1151 #undef PERSONALITY_STORAGE
1152 #define PERSONALITY_STORAGE static
1153 #else
1154 #define PERSONALITY_FUNCTION    __gnat_personality_v0
1155 #endif
1156 
1157 #if defined (__ARM_EABI_UNWINDER__) \
1158     && (defined (IN_RTS) || GCC_VERSION > 9000)
1159 #define TARGET_ATTRIBUTE __attribute__((target ("general-regs-only")))
1160 #else
1161 #define TARGET_ATTRIBUTE
1162 #endif
1163 
1164 /* Code executed to continue unwinding.  With the ARM unwinder, the
1165    personality routine must unwind one frame (per EHABI 7.3 4.).  */
1166 
1167 static _Unwind_Reason_Code
1168 TARGET_ATTRIBUTE
continue_unwind(struct _Unwind_Exception * ue_header ATTRIBUTE_UNUSED,struct _Unwind_Context * uw_context ATTRIBUTE_UNUSED)1169 continue_unwind (struct _Unwind_Exception* ue_header ATTRIBUTE_UNUSED,
1170 		 struct _Unwind_Context* uw_context ATTRIBUTE_UNUSED)
1171 {
1172 #ifdef __ARM_EABI_UNWINDER__
1173   if (__gnu_unwind_frame (ue_header, uw_context) != _URC_OK)
1174     return _URC_FAILURE;
1175 #endif
1176   return _URC_CONTINUE_UNWIND;
1177 }
1178 
1179 /* Common code for the body of GNAT personality routine.  This code is shared
1180    between all unwinders.  */
1181 
1182 static _Unwind_Reason_Code
1183 TARGET_ATTRIBUTE
personality_body(_Unwind_Action uw_phases,_Unwind_Exception * uw_exception,_Unwind_Context * uw_context)1184 personality_body (_Unwind_Action uw_phases,
1185 		  _Unwind_Exception *uw_exception,
1186 		  _Unwind_Context *uw_context)
1187 {
1188   region_descriptor region;
1189   action_descriptor action;
1190   _Unwind_Ptr ip;
1191 
1192   /* Debug traces.  */
1193   db_indent (DB_INDENT_RESET);
1194   db_phases (uw_phases);
1195   db_indent (DB_INDENT_INCREASE);
1196 
1197   /* Get the region description for the context we were provided with. This
1198      will tell us if there is some lsda, call_site, action and/or ttype data
1199      for the associated ip.  */
1200   get_region_description_for (uw_context, &region);
1201 
1202   /* No LSDA => no handlers or cleanups => we shall unwind further up.  */
1203   if (! region.lsda)
1204     return continue_unwind (uw_exception, uw_context);
1205 
1206   /* Get the instruction pointer.  */
1207   ip = get_ip_from_context (uw_context);
1208   db_region_for (&region, ip);
1209 
1210   /* Search the call-site and action-record tables for the action associated
1211      with this IP.  */
1212   get_action_description_for (ip, uw_exception, uw_phases, &region, &action);
1213   db_action_for (&action, ip);
1214 
1215   /* Whatever the phase, if there is nothing relevant in this frame,
1216      unwinding should just go on.  */
1217   if (action.kind == nothing)
1218     return continue_unwind (uw_exception, uw_context);
1219 
1220   /* If we found something in search phase, we should return a code indicating
1221      what to do next depending on what we found. If we only have cleanups
1222      around, we shall try to unwind further up to find a handler, otherwise,
1223      tell we have a handler, which will trigger the second phase.  */
1224   if (uw_phases & _UA_SEARCH_PHASE)
1225     {
1226       if (action.kind == cleanup)
1227 	{
1228 	  return continue_unwind (uw_exception, uw_context);
1229 	}
1230       else
1231 	{
1232 #ifndef CERT
1233 	  /* Trigger the appropriate notification routines before the second
1234 	     phase starts, when the stack is still intact.  First install what
1235 	     needs to be installed in the current exception buffer and fetch
1236 	     the Ada occurrence pointer to use.  */
1237 
1238 	  struct Exception_Occurrence *excep
1239 	    = __gnat_setup_current_excep (uw_exception, uw_phases);
1240 
1241 	  if (action.kind == unhandler)
1242 	    __gnat_notify_unhandled_exception (excep);
1243 	  else
1244 	    __gnat_notify_handled_exception (excep);
1245 #endif
1246 
1247 	  return _URC_HANDLER_FOUND;
1248 	}
1249     }
1250 
1251   /* We found something in cleanup/handler phase, which might be the handler
1252      or a cleanup for a handled occurrence, or a cleanup for an unhandled
1253      occurrence (we are in a FORCED_UNWIND phase in this case). Install the
1254      context to get there.  */
1255 
1256   setup_to_install
1257     (uw_context, uw_exception, action.landing_pad, action.ttype_filter);
1258 
1259 #ifndef CERT
1260   /* Write current exception so that it can be retrieved from Ada.  It was
1261      already done during phase 1, but one or several exceptions may have been
1262      raised in cleanup handlers in between.  */
1263   __gnat_setup_current_excep (uw_exception, uw_phases);
1264 #endif
1265 
1266   return _URC_INSTALL_CONTEXT;
1267 }
1268 
1269 #ifndef __ARM_EABI_UNWINDER__
1270 /* Major tweak for ia64-vms : the CHF propagation phase calls this personality
1271    routine with sigargs/mechargs arguments and has very specific expectations
1272    on possible return values.
1273 
1274    We handle this with a number of specific tricks:
1275 
1276    1. We tweak the personality routine prototype to have the "version" and
1277       "phases" two first arguments be void * instead of int and _Unwind_Action
1278       as nominally expected in the GCC context.
1279 
1280       This allows us to access the full range of bits passed in every case and
1281       has no impact on the callers side since each argument remains assigned
1282       the same single 64bit slot.
1283 
1284    2. We retrieve the corresponding int and _Unwind_Action values within the
1285       routine for regular use with truncating conversions. This is a noop when
1286       called from the libgcc unwinder.
1287 
1288    3. We assume we're called by the VMS CHF when unexpected bits are set in
1289       both those values. The incoming arguments are then real sigargs and
1290       mechargs pointers, which we then redirect to __gnat_handle_vms_condition
1291       for proper processing.
1292 */
1293 #if defined (VMS) && defined (__IA64)
1294 typedef void * version_arg_t;
1295 typedef void * phases_arg_t;
1296 #else
1297 typedef int version_arg_t;
1298 typedef _Unwind_Action phases_arg_t;
1299 #endif
1300 
1301 PERSONALITY_STORAGE _Unwind_Reason_Code
1302 PERSONALITY_FUNCTION (version_arg_t, phases_arg_t,
1303                       _Unwind_Exception_Class, _Unwind_Exception *,
1304                       _Unwind_Context *);
1305 
1306 PERSONALITY_STORAGE _Unwind_Reason_Code
PERSONALITY_FUNCTION(version_arg_t version_arg,phases_arg_t phases_arg,_Unwind_Exception_Class uw_exception_class ATTRIBUTE_UNUSED,_Unwind_Exception * uw_exception,_Unwind_Context * uw_context)1307 PERSONALITY_FUNCTION (version_arg_t version_arg,
1308                       phases_arg_t phases_arg,
1309                       _Unwind_Exception_Class uw_exception_class
1310 		         ATTRIBUTE_UNUSED,
1311                       _Unwind_Exception *uw_exception,
1312                       _Unwind_Context *uw_context)
1313 {
1314   /* Fetch the version and phases args with their nominal ABI types for later
1315      use. This is a noop everywhere except on ia64-vms when called from the
1316      Condition Handling Facility.  */
1317   int uw_version = (int) version_arg;
1318   _Unwind_Action uw_phases = (_Unwind_Action) phases_arg;
1319 
1320   /* Check that we're called from the ABI context we expect, with a major
1321      possible variation on VMS for IA64.  */
1322   if (uw_version != 1)
1323     {
1324 #if defined (VMS) && defined (__IA64)
1325 
1326       /* Assume we're called with sigargs/mechargs arguments if really
1327 	 unexpected bits are set in our first two formals.  Redirect to the
1328 	 GNAT condition handling code in this case.  */
1329 
1330       extern long __gnat_handle_vms_condition (void *, void *);
1331 
1332       unsigned int version_unexpected_bits_mask = 0xffffff00U;
1333       unsigned int phases_unexpected_bits_mask  = 0xffffff00U;
1334 
1335       if ((unsigned int)uw_version & version_unexpected_bits_mask
1336 	  && (unsigned int)uw_phases & phases_unexpected_bits_mask)
1337 	return __gnat_handle_vms_condition (version_arg, phases_arg);
1338 #endif
1339 
1340       return _URC_FATAL_PHASE1_ERROR;
1341     }
1342 
1343   return personality_body (uw_phases, uw_exception, uw_context);
1344 }
1345 
1346 #else /* __ARM_EABI_UNWINDER__ */
1347 
1348 PERSONALITY_STORAGE _Unwind_Reason_Code
1349 PERSONALITY_FUNCTION (_Unwind_State state,
1350 		      struct _Unwind_Exception* ue_header,
1351 		      struct _Unwind_Context* uw_context);
1352 
1353 PERSONALITY_STORAGE _Unwind_Reason_Code
1354 TARGET_ATTRIBUTE
PERSONALITY_FUNCTION(_Unwind_State state,struct _Unwind_Exception * uw_exception,struct _Unwind_Context * uw_context)1355 PERSONALITY_FUNCTION (_Unwind_State state,
1356 		      struct _Unwind_Exception* uw_exception,
1357 		      struct _Unwind_Context* uw_context)
1358 {
1359   _Unwind_Action uw_phases;
1360 
1361   switch (state & _US_ACTION_MASK)
1362     {
1363     case _US_VIRTUAL_UNWIND_FRAME:
1364       /* Phase 1.  */
1365       uw_phases = _UA_SEARCH_PHASE;
1366       break;
1367 
1368     case _US_UNWIND_FRAME_STARTING:
1369       /* Phase 2, to call a cleanup.  */
1370       uw_phases = _UA_CLEANUP_PHASE;
1371 #if 0
1372       /* ??? We don't use UA_HANDLER_FRAME (except to debug).  Futhermore,
1373 	 barrier_cache.sp isn't yet set.  */
1374       if (!(state & _US_FORCE_UNWIND)
1375 	  && (uw_exception->barrier_cache.sp
1376 	      == _Unwind_GetGR (uw_context, UNWIND_STACK_REG)))
1377 	uw_phases |= _UA_HANDLER_FRAME;
1378 #endif
1379       break;
1380 
1381     case _US_UNWIND_FRAME_RESUME:
1382       /* Phase 2, called at the return of a cleanup.  In the GNU
1383 	 implementation, there is nothing left to do, so we simply go on.  */
1384       return continue_unwind (uw_exception, uw_context);
1385 
1386     default:
1387       return _URC_FAILURE;
1388     }
1389   uw_phases |= (state & _US_FORCE_UNWIND);
1390 
1391   /* The dwarf unwinder assumes the context structure holds things like the
1392      function and LSDA pointers.  The ARM implementation caches these in
1393      the exception header (UCB).  To avoid rewriting everything we make a
1394      virtual scratch register point at the UCB.  This is a GNU specific
1395      requirement.  */
1396   _Unwind_SetGR (uw_context, UNWIND_POINTER_REG, (_Unwind_Ptr) uw_exception);
1397 
1398   return personality_body (uw_phases, uw_exception, uw_context);
1399 }
1400 #endif /* __ARM_EABI_UNWINDER__ */
1401 
1402 /* Callback routine called by Unwind_ForcedUnwind to execute all the cleanup
1403    before exiting the task.  */
1404 
1405 #ifndef CERT
1406 _Unwind_Reason_Code
__gnat_cleanupunwind_handler(int version ATTRIBUTE_UNUSED,_Unwind_Action phases,_Unwind_Exception_Class eclass ATTRIBUTE_UNUSED,struct _Unwind_Exception * exception,struct _Unwind_Context * context ATTRIBUTE_UNUSED,void * arg ATTRIBUTE_UNUSED)1407 __gnat_cleanupunwind_handler (int version ATTRIBUTE_UNUSED,
1408 			      _Unwind_Action phases,
1409 			      _Unwind_Exception_Class eclass ATTRIBUTE_UNUSED,
1410 			      struct _Unwind_Exception *exception,
1411 			      struct _Unwind_Context *context ATTRIBUTE_UNUSED,
1412 			      void *arg ATTRIBUTE_UNUSED)
1413 {
1414   /* Terminate when the end of the stack is reached.  */
1415   if ((phases & _UA_END_OF_STACK) != 0
1416 #if defined (__ia64__) && defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
1417       /* Strictely follow the ia64 ABI: when end of stack is reached,
1418 	 the callback will be called with a NULL stack pointer.
1419 	 No need for that when using libgcc unwinder.  */
1420       || _Unwind_GetGR (context, 12) == 0
1421 #endif
1422       )
1423     __gnat_unhandled_except_handler (exception);
1424 
1425   /* We know there is at least one cleanup further up. Return so that it
1426      is searched and entered, after which Unwind_Resume will be called
1427      and this hook will gain control again.  */
1428   return _URC_NO_REASON;
1429 }
1430 #endif
1431 
1432 /* Define the consistently named wrappers imported by Propagate_Exception.  */
1433 
1434 _Unwind_Reason_Code
__gnat_Unwind_RaiseException(_Unwind_Exception * e)1435 __gnat_Unwind_RaiseException (_Unwind_Exception *e)
1436 {
1437 #ifdef __USING_SJLJ_EXCEPTIONS__
1438   return _Unwind_SjLj_RaiseException (e);
1439 #else
1440   return _Unwind_RaiseException (e);
1441 #endif
1442 }
1443 
1444 _Unwind_Reason_Code
__gnat_Unwind_ForcedUnwind(_Unwind_Exception * e ATTRIBUTE_UNUSED,_Unwind_Stop_Fn handler ATTRIBUTE_UNUSED,void * argument ATTRIBUTE_UNUSED)1445 __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e ATTRIBUTE_UNUSED,
1446 			    _Unwind_Stop_Fn handler ATTRIBUTE_UNUSED,
1447 			    void *argument ATTRIBUTE_UNUSED)
1448 {
1449 #ifdef __USING_SJLJ_EXCEPTIONS__
1450 
1451 # if defined (__APPLE__) && defined (__arm__)
1452   /* There is not ForcedUnwind routine in arm-darwin system library.  */
1453   return _URC_FATAL_PHASE1_ERROR;
1454 # else
1455   return _Unwind_SjLj_ForcedUnwind (e, handler, argument);
1456 # endif
1457 
1458 #else
1459   return _Unwind_ForcedUnwind (e, handler, argument);
1460 #endif
1461 }
1462 
1463 #if defined (__SEH__) && !defined (__USING_SJLJ_EXCEPTIONS__)
1464 
1465 #define STATUS_USER_DEFINED		(1U << 29)
1466 
1467 /* From unwind-seh.c.  */
1468 #define GCC_MAGIC			(('G' << 16) | ('C' << 8) | 'C')
1469 #define GCC_EXCEPTION(TYPE)		\
1470        (STATUS_USER_DEFINED | ((TYPE) << 24) | GCC_MAGIC)
1471 #define STATUS_GCC_THROW		GCC_EXCEPTION (0)
1472 
1473 struct Exception_Data *
1474 __gnat_map_SEH (EXCEPTION_RECORD* ExceptionRecord, const char **msg);
1475 
1476 struct _Unwind_Exception *
1477 __gnat_create_machine_occurrence_from_signal_handler (Exception_Id,
1478 						      const char *);
1479 
1480 /* Unwind opcodes.  */
1481 #define UWOP_PUSH_NONVOL 0
1482 #define UWOP_ALLOC_LARGE 1
1483 #define UWOP_ALLOC_SMALL 2
1484 #define UWOP_SET_FPREG	 3
1485 #define UWOP_SAVE_NONVOL 4
1486 #define UWOP_SAVE_NONVOL_FAR 5
1487 #define UWOP_SAVE_XMM128 8
1488 #define UWOP_SAVE_XMM128_FAR 9
1489 #define UWOP_PUSH_MACHFRAME 10
1490 
1491 /* Modify the IP value saved in the machine frame.  This is really a kludge,
1492    that will be removed if we could propagate the Windows exception (and not
1493    the GCC one).
1494 
1495    What is very wrong is that the Windows unwinder will try to decode the
1496    instruction at IP, which isn't valid anymore after the adjustment.  */
1497 
1498 static void
__gnat_adjust_context(unsigned char * unw,ULONG64 rsp)1499 __gnat_adjust_context (unsigned char *unw, ULONG64 rsp)
1500 {
1501   unsigned int len;
1502 
1503   /* Version 1 or 2.  */
1504   if (unw[0] != 1 && unw[0] != 2)
1505     return;
1506   /* No flags, no prologue.  */
1507   if (unw[1] != 0)
1508     return;
1509   len = unw[2];
1510   /* No frame.  */
1511   if (unw[3] != 0)
1512     return;
1513   /* ??? Skip the first 2 undocumented opcodes for version 2.  */
1514   if (unw[0] == 2)
1515     unw += 8;
1516   else
1517     unw += 4;
1518   while (len > 0)
1519     {
1520       /* Offset in prologue = 0.  */
1521       if (unw[0] != 0)
1522 	return;
1523       switch (unw[1] & 0xf)
1524 	{
1525 	case UWOP_ALLOC_LARGE:
1526 	  /* Expect < 512KB.  */
1527 	  if ((unw[1] & 0xf0) != 0)
1528 	    return;
1529 	  rsp += *(unsigned short *)(unw + 2) * 8;
1530 	  len--;
1531 	  unw += 2;
1532 	  break;
1533 	case UWOP_SAVE_NONVOL:
1534 	case UWOP_SAVE_XMM128:
1535 	  len--;
1536 	  unw += 2;
1537 	  break;
1538 	case UWOP_PUSH_MACHFRAME:
1539 	  {
1540 	    ULONG64 *rip;
1541 	    rip = (ULONG64 *)rsp;
1542 	    if ((unw[1] & 0xf0) == 0x10)
1543 	      rip++;
1544 	    /* Adjust rip.  */
1545 	    (*rip)++;
1546 	  }
1547 	  return;
1548 	default:
1549 	  /* Unexpected.  */
1550 	  return;
1551 	}
1552       unw += 2;
1553       len--;
1554     }
1555 }
1556 
1557 EXCEPTION_DISPOSITION
__gnat_personality_seh0(PEXCEPTION_RECORD ms_exc,void * this_frame,PCONTEXT ms_orig_context,PDISPATCHER_CONTEXT ms_disp)1558 __gnat_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
1559 			 PCONTEXT ms_orig_context,
1560 			 PDISPATCHER_CONTEXT ms_disp)
1561 {
1562   /* Possibly transform run-time errors into Ada exceptions.  */
1563   if (!(ms_exc->ExceptionCode & STATUS_USER_DEFINED))
1564     {
1565       struct Exception_Data *exception;
1566       const char *msg;
1567       ULONG64 excpip = (ULONG64) ms_exc->ExceptionAddress;
1568 
1569       if (excpip != 0
1570 	  && excpip >= (ms_disp->ImageBase
1571 			+ ms_disp->FunctionEntry->BeginAddress)
1572 	  && excpip < (ms_disp->ImageBase
1573 		       + ms_disp->FunctionEntry->EndAddress))
1574 	{
1575 	  /* This is a fault in this function.  We need to adjust the return
1576 	     address before raising the GCC exception.  In order to do that,
1577 	     we need to locate the machine frame that has been pushed onto
1578 	     the stack in response to the hardware exception, so we will do
1579 	     a private unwinding from here, i.e. the frame of the personality
1580 	     routine, up to the frame immediately following the frame of this
1581 	     function.  This frame corresponds to a dummy prologue which is
1582 	     never actually executed but instead appears before the real entry
1583 	     point of an interrupt routine and exists only to provide a place
1584 	     to simulate the push of a machine frame.  */
1585 	  CONTEXT context;
1586 	  PRUNTIME_FUNCTION mf_func = NULL;
1587 	  ULONG64 mf_imagebase;
1588 	  ULONG64 mf_rsp = 0;
1589 
1590 	  /* Get the current context.  */
1591 	  RtlCaptureContext (&context);
1592 
1593 	  while (1)
1594 	    {
1595 	      PRUNTIME_FUNCTION RuntimeFunction;
1596 	      ULONG64 ImageBase;
1597 	      VOID *HandlerData;
1598 	      ULONG64 EstablisherFrame;
1599 
1600 	      /* Get function metadata.  */
1601 	      RuntimeFunction
1602 		= RtlLookupFunctionEntry (context.Rip, &ImageBase,
1603 					  ms_disp->HistoryTable);
1604 
1605 	      /* Stop once we reached the frame of this function.  */
1606 	      if (RuntimeFunction == ms_disp->FunctionEntry)
1607 		break;
1608 
1609 	      mf_func = RuntimeFunction;
1610 	      mf_imagebase = ImageBase;
1611 	      mf_rsp = context.Rsp;
1612 
1613 	      if (RuntimeFunction)
1614 		{
1615 		  /* Unwind.  */
1616 		  RtlVirtualUnwind (0, ImageBase, context.Rip, RuntimeFunction,
1617 				    &context, &HandlerData, &EstablisherFrame,
1618 				    NULL);
1619 		}
1620 	      else
1621 		{
1622 		  /* In case of failure, assume this is a leaf function.  */
1623 		  context.Rip = *(ULONG64 *) context.Rsp;
1624 		  context.Rsp += 8;
1625 		}
1626 
1627 	      /* 0 means bottom of the stack.  */
1628 	      if (context.Rip == 0)
1629 		{
1630 		  mf_func = NULL;
1631 		  break;
1632 		}
1633 	    }
1634 
1635 	  /* If we have found the machine frame, adjust the return address.  */
1636 	  if (mf_func != NULL)
1637 	    __gnat_adjust_context
1638 	      ((unsigned char *)(mf_imagebase + mf_func->UnwindData), mf_rsp);
1639 	}
1640 
1641       exception = __gnat_map_SEH (ms_exc, &msg);
1642       if (exception != NULL)
1643 	{
1644 	  /* Directly convert the system exception into a GCC one.
1645 
1646 	     This is really breaking the API, but is necessary for stack size
1647 	     reasons: the normal way is to call Raise_From_Signal_Handler,
1648 	     which builds the exception and calls _Unwind_RaiseException,
1649 	     which unwinds the stack and will call this personality routine.
1650 	     But the Windows unwinder needs about 2KB of stack.  */
1651 	  struct _Unwind_Exception *exc
1652 	    = __gnat_create_machine_occurrence_from_signal_handler (exception,
1653 								    msg);
1654 	  memset (exc->private_, 0, sizeof (exc->private_));
1655 	  ms_exc->ExceptionCode = STATUS_GCC_THROW;
1656 	  ms_exc->NumberParameters = 1;
1657 	  ms_exc->ExceptionInformation[0] = (ULONG_PTR)exc;
1658 	}
1659 
1660     }
1661 
1662   return
1663     _GCC_specific_handler (ms_exc, this_frame, ms_orig_context, ms_disp,
1664 			   __gnat_personality_imp);
1665 }
1666 
1667 #endif /* SEH */
1668 
1669 #if !defined (__USING_SJLJ_EXCEPTIONS__)
1670 /* Size of the _Unwind_Exception structure.  This is used by g-cppexc to get
1671    the offset to the C++ object.  */
1672 
1673 const int __gnat_unwind_exception_size = sizeof (_Unwind_Exception);
1674 #endif
1675 
1676 #ifdef __cplusplus
1677 }
1678 #endif
1679