comparison gcc/ada/raise-gcc.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
4 * * 4 * *
5 * R A I S E - G C C * 5 * R A I S E - G C C *
6 * * 6 * *
7 * C Implementation File * 7 * C Implementation File *
8 * * 8 * *
9 * Copyright (C) 1992-2018, Free Software Foundation, Inc. * 9 * Copyright (C) 1992-2019, Free Software Foundation, Inc. *
10 * * 10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under * 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- * 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- * 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- * 14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
37 # include "config.h" 37 # include "config.h"
38 # include "system.h" 38 # include "system.h"
39 /* Don't use fancy_abort. */ 39 /* Don't use fancy_abort. */
40 # undef abort 40 # undef abort
41 #else 41 #else
42 # ifndef CERT 42 # if !defined(CERT) && !defined(STANDALONE)
43 # include "tconfig.h" 43 # include "tconfig.h"
44 # include "tsystem.h" 44 # include "tsystem.h"
45 # else 45 # else
46 # define ATTRIBUTE_UNUSED __attribute__((unused)) 46 # include "runtime.h"
47 # define HAVE_GETIPINFO 1 47 # define HAVE_GETIPINFO 1
48 # endif 48 # endif
49 #endif 49 #endif
50 50
51 #include <stdarg.h> 51 #include <stdarg.h>
113 113
114 #ifdef CERT 114 #ifdef CERT
115 /* Called in case of error during propagation. */ 115 /* Called in case of error during propagation. */
116 extern void __gnat_raise_abort (void) __attribute__ ((noreturn)); 116 extern void __gnat_raise_abort (void) __attribute__ ((noreturn));
117 #define abort() __gnat_raise_abort() 117 #define abort() __gnat_raise_abort()
118
119 #elif defined(STANDALONE)
120 #include <stdlib.h>
121 #define inhibit_libc
118 #endif 122 #endif
119 123
120 #include "unwind-pe.h" 124 #include "unwind-pe.h"
121 125
122 #ifdef __ARM_EABI_UNWINDER__ 126 #ifdef __ARM_EABI_UNWINDER__
883 887
884 /* With CHOICE an exception choice representing an "exception - when" 888 /* With CHOICE an exception choice representing an "exception - when"
885 argument, and PROPAGATED_EXCEPTION a pointer to the currently propagated 889 argument, and PROPAGATED_EXCEPTION a pointer to the currently propagated
886 occurrence, return true if the latter matches the former, that is, if 890 occurrence, return true if the latter matches the former, that is, if
887 PROPAGATED_EXCEPTION is caught by the handling code controlled by CHOICE. 891 PROPAGATED_EXCEPTION is caught by the handling code controlled by CHOICE.
888 This takes care of the special Non_Ada_Error case on VMS. */ 892 */
889 893
890 #define Is_Handled_By_Others __gnat_is_handled_by_others 894 #define Is_Handled_By_Others __gnat_is_handled_by_others
891 #define Language_For __gnat_language_for 895 #define Language_For __gnat_language_for
892 #define Foreign_Data_For __gnat_foreign_data_for 896 #define Foreign_Data_For __gnat_foreign_data_for
893 #define EID_For __gnat_eid_for 897 #define EID_For __gnat_eid_for
899 903
900 extern Exception_Id EID_For (_GNAT_Exception * e); 904 extern Exception_Id EID_For (_GNAT_Exception * e);
901 905
902 #define Foreign_Exception system__exceptions__foreign_exception 906 #define Foreign_Exception system__exceptions__foreign_exception
903 extern struct Exception_Data Foreign_Exception; 907 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 908
910 /* Return true iff the exception class of EXCEPT is EC. */ 909 /* Return true iff the exception class of EXCEPT is EC. */
911 910
912 static int 911 static int
913 exception_class_eq (const _GNAT_Exception *except, 912 exception_class_eq (const _GNAT_Exception *except,
944 /* Base matching rules: An exception data (id) matches itself, "when 943 /* Base matching rules: An exception data (id) matches itself, "when
945 all_others" matches anything and "when others" matches anything 944 all_others" matches anything and "when others" matches anything
946 unless explicitly stated otherwise in the propagated occurrence. */ 945 unless explicitly stated otherwise in the propagated occurrence. */
947 if (choice == E || (choice == GNAT_OTHERS && Is_Handled_By_Others (E))) 946 if (choice == E || (choice == GNAT_OTHERS && Is_Handled_By_Others (E)))
948 return handler; 947 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 948
967 /* Otherwise, it doesn't match an Ada choice. */ 949 /* Otherwise, it doesn't match an Ada choice. */
968 return nothing; 950 return nothing;
969 } 951 }
970 952
1152 #define PERSONALITY_STORAGE static 1134 #define PERSONALITY_STORAGE static
1153 #else 1135 #else
1154 #define PERSONALITY_FUNCTION __gnat_personality_v0 1136 #define PERSONALITY_FUNCTION __gnat_personality_v0
1155 #endif 1137 #endif
1156 1138
1139 #if defined (__ARM_EABI_UNWINDER__) \
1140 && (defined (IN_RTS) || GCC_VERSION > 9000)
1141 #define TARGET_ATTRIBUTE __attribute__((target ("general-regs-only")))
1142 #else
1143 #define TARGET_ATTRIBUTE
1144 #endif
1145
1157 /* Code executed to continue unwinding. With the ARM unwinder, the 1146 /* Code executed to continue unwinding. With the ARM unwinder, the
1158 personality routine must unwind one frame (per EHABI 7.3 4.). */ 1147 personality routine must unwind one frame (per EHABI 7.3 4.). */
1159 1148
1160 static _Unwind_Reason_Code 1149 static _Unwind_Reason_Code
1150 TARGET_ATTRIBUTE
1161 continue_unwind (struct _Unwind_Exception* ue_header ATTRIBUTE_UNUSED, 1151 continue_unwind (struct _Unwind_Exception* ue_header ATTRIBUTE_UNUSED,
1162 struct _Unwind_Context* uw_context ATTRIBUTE_UNUSED) 1152 struct _Unwind_Context* uw_context ATTRIBUTE_UNUSED)
1163 { 1153 {
1164 #ifdef __ARM_EABI_UNWINDER__ 1154 #ifdef __ARM_EABI_UNWINDER__
1165 if (__gnu_unwind_frame (ue_header, uw_context) != _URC_OK) 1155 if (__gnu_unwind_frame (ue_header, uw_context) != _URC_OK)
1170 1160
1171 /* Common code for the body of GNAT personality routine. This code is shared 1161 /* Common code for the body of GNAT personality routine. This code is shared
1172 between all unwinders. */ 1162 between all unwinders. */
1173 1163
1174 static _Unwind_Reason_Code 1164 static _Unwind_Reason_Code
1165 TARGET_ATTRIBUTE
1175 personality_body (_Unwind_Action uw_phases, 1166 personality_body (_Unwind_Action uw_phases,
1176 _Unwind_Exception *uw_exception, 1167 _Unwind_Exception *uw_exception,
1177 _Unwind_Context *uw_context) 1168 _Unwind_Context *uw_context)
1178 { 1169 {
1179 region_descriptor region; 1170 region_descriptor region;
1218 { 1209 {
1219 return continue_unwind (uw_exception, uw_context); 1210 return continue_unwind (uw_exception, uw_context);
1220 } 1211 }
1221 else 1212 else
1222 { 1213 {
1214 #ifdef __ARM_EABI_UNWINDER__
1215 /* Though we do not use this field ourselves, initializing
1216 it is required by the ARM EH ABI before a personality
1217 function in phase1 returns _URC_HANDLER_FOUND, so that
1218 any personality function can use it in phase2 to test
1219 whether the handler frame was reached. */
1220 uw_exception->barrier_cache.sp
1221 = _Unwind_GetGR (uw_context, UNWIND_STACK_REG);
1222 #endif
1223
1223 #ifndef CERT 1224 #ifndef CERT
1224 /* Trigger the appropriate notification routines before the second 1225 /* Trigger the appropriate notification routines before the second
1225 phase starts, when the stack is still intact. First install what 1226 phase starts, when the stack is still intact. First install what
1226 needs to be installed in the current exception buffer and fetch 1227 needs to be installed in the current exception buffer and fetch
1227 the Ada occurrence pointer to use. */ 1228 the Ada occurrence pointer to use. */
1256 1257
1257 return _URC_INSTALL_CONTEXT; 1258 return _URC_INSTALL_CONTEXT;
1258 } 1259 }
1259 1260
1260 #ifndef __ARM_EABI_UNWINDER__ 1261 #ifndef __ARM_EABI_UNWINDER__
1261 /* Major tweak for ia64-vms : the CHF propagation phase calls this personality
1262 routine with sigargs/mechargs arguments and has very specific expectations
1263 on possible return values.
1264
1265 We handle this with a number of specific tricks:
1266
1267 1. We tweak the personality routine prototype to have the "version" and
1268 "phases" two first arguments be void * instead of int and _Unwind_Action
1269 as nominally expected in the GCC context.
1270
1271 This allows us to access the full range of bits passed in every case and
1272 has no impact on the callers side since each argument remains assigned
1273 the same single 64bit slot.
1274
1275 2. We retrieve the corresponding int and _Unwind_Action values within the
1276 routine for regular use with truncating conversions. This is a noop when
1277 called from the libgcc unwinder.
1278
1279 3. We assume we're called by the VMS CHF when unexpected bits are set in
1280 both those values. The incoming arguments are then real sigargs and
1281 mechargs pointers, which we then redirect to __gnat_handle_vms_condition
1282 for proper processing.
1283 */
1284 #if defined (VMS) && defined (__IA64)
1285 typedef void * version_arg_t;
1286 typedef void * phases_arg_t;
1287 #else
1288 typedef int version_arg_t; 1262 typedef int version_arg_t;
1289 typedef _Unwind_Action phases_arg_t; 1263 typedef _Unwind_Action phases_arg_t;
1290 #endif
1291 1264
1292 PERSONALITY_STORAGE _Unwind_Reason_Code 1265 PERSONALITY_STORAGE _Unwind_Reason_Code
1293 PERSONALITY_FUNCTION (version_arg_t, phases_arg_t, 1266 PERSONALITY_FUNCTION (version_arg_t, phases_arg_t,
1294 _Unwind_Exception_Class, _Unwind_Exception *, 1267 _Unwind_Exception_Class, _Unwind_Exception *,
1295 _Unwind_Context *); 1268 _Unwind_Context *);
1306 use. This is a noop everywhere except on ia64-vms when called from the 1279 use. This is a noop everywhere except on ia64-vms when called from the
1307 Condition Handling Facility. */ 1280 Condition Handling Facility. */
1308 int uw_version = (int) version_arg; 1281 int uw_version = (int) version_arg;
1309 _Unwind_Action uw_phases = (_Unwind_Action) phases_arg; 1282 _Unwind_Action uw_phases = (_Unwind_Action) phases_arg;
1310 1283
1311 /* Check that we're called from the ABI context we expect, with a major 1284 /* Check that we're called from the ABI context we expect. */
1312 possible variation on VMS for IA64. */
1313 if (uw_version != 1) 1285 if (uw_version != 1)
1314 { 1286 return _URC_FATAL_PHASE1_ERROR;
1315 #if defined (VMS) && defined (__IA64)
1316
1317 /* Assume we're called with sigargs/mechargs arguments if really
1318 unexpected bits are set in our first two formals. Redirect to the
1319 GNAT condition handling code in this case. */
1320
1321 extern long __gnat_handle_vms_condition (void *, void *);
1322
1323 unsigned int version_unexpected_bits_mask = 0xffffff00U;
1324 unsigned int phases_unexpected_bits_mask = 0xffffff00U;
1325
1326 if ((unsigned int)uw_version & version_unexpected_bits_mask
1327 && (unsigned int)uw_phases & phases_unexpected_bits_mask)
1328 return __gnat_handle_vms_condition (version_arg, phases_arg);
1329 #endif
1330
1331 return _URC_FATAL_PHASE1_ERROR;
1332 }
1333 1287
1334 return personality_body (uw_phases, uw_exception, uw_context); 1288 return personality_body (uw_phases, uw_exception, uw_context);
1335 } 1289 }
1336 1290
1337 #else /* __ARM_EABI_UNWINDER__ */ 1291 #else /* __ARM_EABI_UNWINDER__ */
1340 PERSONALITY_FUNCTION (_Unwind_State state, 1294 PERSONALITY_FUNCTION (_Unwind_State state,
1341 struct _Unwind_Exception* ue_header, 1295 struct _Unwind_Exception* ue_header,
1342 struct _Unwind_Context* uw_context); 1296 struct _Unwind_Context* uw_context);
1343 1297
1344 PERSONALITY_STORAGE _Unwind_Reason_Code 1298 PERSONALITY_STORAGE _Unwind_Reason_Code
1299 TARGET_ATTRIBUTE
1345 PERSONALITY_FUNCTION (_Unwind_State state, 1300 PERSONALITY_FUNCTION (_Unwind_State state,
1346 struct _Unwind_Exception* uw_exception, 1301 struct _Unwind_Exception* uw_exception,
1347 struct _Unwind_Context* uw_context) 1302 struct _Unwind_Context* uw_context)
1348 { 1303 {
1349 _Unwind_Action uw_phases; 1304 _Unwind_Action uw_phases;
1652 return 1607 return
1653 _GCC_specific_handler (ms_exc, this_frame, ms_orig_context, ms_disp, 1608 _GCC_specific_handler (ms_exc, this_frame, ms_orig_context, ms_disp,
1654 __gnat_personality_imp); 1609 __gnat_personality_imp);
1655 } 1610 }
1656 1611
1612 /* Define __gnat_personality_v0 for convenience */
1613
1614 PERSONALITY_STORAGE _Unwind_Reason_Code
1615 __gnat_personality_v0 (version_arg_t version_arg,
1616 phases_arg_t phases_arg,
1617 _Unwind_Exception_Class uw_exception_class,
1618 _Unwind_Exception *uw_exception,
1619 _Unwind_Context *uw_context)
1620 {
1621 return PERSONALITY_FUNCTION
1622 (version_arg, phases_arg, uw_exception_class, uw_exception, uw_context);
1623 }
1624
1657 #endif /* SEH */ 1625 #endif /* SEH */
1658 1626
1659 #if !defined (__USING_SJLJ_EXCEPTIONS__) 1627 #if !defined (__USING_SJLJ_EXCEPTIONS__)
1660 /* Size of the _Unwind_Exception structure. This is used by g-cppexc to get 1628 /* Size of the _Unwind_Exception structure. This is used by g-cppexc to get
1661 the offset to the C++ object. */ 1629 the offset to the C++ object. */