1 // Exception handling and frame unwind runtime interface routines. 2 // Copyright (C) 2011-2020 Free Software Foundation, Inc. 3 4 // GCC is free software; you can redistribute it and/or modify it under 5 // the terms of the GNU General Public License as published by the Free 6 // Software Foundation; either version 3, or (at your option) any later 7 // version. 8 9 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY 10 // WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // for more details. 13 14 // Under Section 7 of GPL version 3, you are granted additional 15 // permissions described in the GCC Runtime Library Exception, version 16 // 3.1, as published by the Free Software Foundation. 17 18 // You should have received a copy of the GNU General Public License and 19 // a copy of the GCC Runtime Library Exception along with this program; 20 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 21 // <http://www.gnu.org/licenses/>. 22 23 // extern(C) interface for the ARM EABI and C6X unwinders. 24 // This corresponds to unwind-arm-common.h 25 26 module gcc.unwind.arm_common; 27 28 import gcc.config; 29 30 static if (GNU_ARM_EABI_Unwinder): 31 32 import gcc.builtins; 33 34 extern (C): 35 36 // Placed outside @nogc in order to not constrain what the callback does. 37 // ??? Does this really need to be extern(C) alias? 38 extern(C) alias _Unwind_Exception_Cleanup_Fn 39 = void function(_Unwind_Reason_Code, _Unwind_Exception*); 40 41 extern(C) alias personality_routine 42 = _Unwind_Reason_Code function(_Unwind_State, 43 _Unwind_Control_Block*, 44 _Unwind_Context*); 45 46 extern(C) alias _Unwind_Stop_Fn 47 =_Unwind_Reason_Code function(int, _Unwind_Action, 48 _Unwind_Exception_Class, 49 _Unwind_Control_Block*, 50 _Unwind_Context*, void*); 51 52 extern(C) alias _Unwind_Trace_Fn 53 = _Unwind_Reason_Code function(_Unwind_Context*, void*); 54 55 @nogc: 56 57 alias _Unwind_Word = __builtin_machine_uint; 58 alias _Unwind_Sword = __builtin_machine_int; 59 alias _Unwind_Ptr = __builtin_pointer_uint; 60 alias _Unwind_Internal_Ptr =__builtin_pointer_uint; 61 alias _uw = _Unwind_Word; 62 alias _uw64 = ulong; 63 alias _uw16 = ushort; 64 alias _uw8 = ubyte; 65 66 alias _Unwind_Reason_Code = uint; 67 enum : _Unwind_Reason_Code 68 { 69 _URC_OK = 0, // operation completed successfully 70 _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 71 _URC_END_OF_STACK = 5, 72 _URC_HANDLER_FOUND = 6, 73 _URC_INSTALL_CONTEXT = 7, 74 _URC_CONTINUE_UNWIND = 8, 75 _URC_FAILURE = 9 // unspecified failure of some kind 76 } 77 78 alias _Unwind_State = int; 79 enum : _Unwind_State 80 { 81 _US_VIRTUAL_UNWIND_FRAME = 0, 82 _US_UNWIND_FRAME_STARTING = 1, 83 _US_UNWIND_FRAME_RESUME = 2, 84 _US_ACTION_MASK = 3, 85 _US_FORCE_UNWIND = 8, 86 _US_END_OF_STACK = 16 87 } 88 89 // Provided only for for compatibility with existing code. 90 alias _Unwind_Action = int; 91 enum : _Unwind_Action 92 { 93 _UA_SEARCH_PHASE = 1, 94 _UA_CLEANUP_PHASE = 2, 95 _UA_HANDLER_FRAME = 4, 96 _UA_FORCE_UNWIND = 8, 97 _UA_END_OF_STACK = 16, 98 _URC_NO_REASON = _URC_OK 99 } 100 101 struct _Unwind_Context; 102 alias _Unwind_EHT_Header = _uw; 103 104 struct _Unwind_Control_Block 105 { 106 _Unwind_Exception_Class exception_class = '\0'; 107 _Unwind_Exception_Cleanup_Fn exception_cleanup; 108 // Unwinder cache, private fields for the unwinder's use 109 struct _unwinder_cache 110 { 111 _uw reserved1; // Forced unwind stop fn, 0 if not forced 112 _uw reserved2; // Personality routine address 113 _uw reserved3; // Saved callsite address 114 _uw reserved4; // Forced unwind stop arg 115 _uw reserved5; 116 } 117 _unwinder_cache unwinder_cache; 118 // Propagation barrier cache (valid after phase 1): 119 struct _barrier_cache 120 { 121 _uw sp; 122 _uw[5] bitpattern; 123 } 124 _barrier_cache barrier_cache; 125 // Cleanup cache (preserved over cleanup): 126 struct _cleanup_cache 127 { 128 _uw[4] bitpattern; 129 } 130 _cleanup_cache cleanup_cache; 131 // Pr cache (for pr's benefit): 132 struct _pr_cache 133 { 134 _uw fnstart; // function start address */ 135 _Unwind_EHT_Header* ehtp; // pointer to EHT entry header word 136 _uw additional; // additional data 137 _uw reserved1; 138 } 139 _pr_cache pr_cache; 140 long[0] _force_alignment; // Force alignment to 8-byte boundary 141 } 142 143 // Virtual Register Set 144 alias _Unwind_VRS_RegClass = int; 145 enum : _Unwind_VRS_RegClass 146 { 147 _UVRSC_CORE = 0, // integer register 148 _UVRSC_VFP = 1, // vfp 149 _UVRSC_FPA = 2, // fpa 150 _UVRSC_WMMXD = 3, // Intel WMMX data register 151 _UVRSC_WMMXC = 4 // Intel WMMX control register 152 } 153 154 alias _Unwind_VRS_DataRepresentation = int; 155 enum : _Unwind_VRS_DataRepresentation 156 { 157 _UVRSD_UINT32 = 0, 158 _UVRSD_VFPX = 1, 159 _UVRSD_FPAX = 2, 160 _UVRSD_UINT64 = 3, 161 _UVRSD_FLOAT = 4, 162 _UVRSD_DOUBLE = 5 163 } 164 165 alias _Unwind_VRS_Result = int; 166 enum : _Unwind_VRS_Result 167 { 168 _UVRSR_OK = 0, 169 _UVRSR_NOT_IMPLEMENTED = 1, 170 _UVRSR_FAILED = 2 171 } 172 173 // Frame unwinding state. 174 struct __gnu_unwind_state 175 { 176 _uw data; // The current word (bytes packed msb first). 177 _uw* next; // Pointer to the next word of data. 178 _uw8 bytes_left; // The number of bytes left in this word. 179 _uw8 words_left; // The number of words pointed to by ptr. 180 } 181 182 _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context*, _Unwind_VRS_RegClass, 183 _uw, _Unwind_VRS_DataRepresentation, 184 void*); 185 186 _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context*, _Unwind_VRS_RegClass, 187 _uw, _Unwind_VRS_DataRepresentation, 188 void*); 189 190 _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context*, _Unwind_VRS_RegClass, 191 _uw, _Unwind_VRS_DataRepresentation); 192 193 194 // Support functions for the PR. 195 alias _Unwind_Exception = _Unwind_Control_Block; 196 alias _Unwind_Exception_Class = char[8]; 197 198 void* _Unwind_GetLanguageSpecificData(_Unwind_Context*); 199 _Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context*); 200 201 _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context*); 202 // This should never be used. 203 _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context*); 204 205 // Interface functions: 206 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block*); 207 void _Unwind_Resume(_Unwind_Control_Block*); 208 _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Control_Block*); 209 210 _Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Control_Block*, 211 _Unwind_Stop_Fn, void*); 212 213 // @@@ Use unwind data to perform a stack backtrace. The trace callback 214 // is called for every stack frame in the call chain, but no cleanup 215 // actions are performed. 216 _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*); 217 218 _Unwind_Word _Unwind_GetCFA(_Unwind_Context*); 219 void _Unwind_Complete(_Unwind_Control_Block*); 220 void _Unwind_DeleteException(_Unwind_Exception*); 221 222 _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Control_Block*, 223 _Unwind_Context*); 224 _Unwind_Reason_Code __gnu_unwind_execute(_Unwind_Context*, 225 __gnu_unwind_state*); 226 227 _Unwind_Word _Unwind_GetGR(_Unwind_Context* context, int regno) 228 { 229 _uw val; 230 _Unwind_VRS_Get(context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); 231 return val; 232 } 233 234 void _Unwind_SetGR(_Unwind_Context* context, int regno, _Unwind_Word val) 235 { 236 _Unwind_VRS_Set(context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); 237 } 238 239 // leb128 type numbers have a potentially unlimited size. 240 // The target of the following definitions of _sleb128_t and _uleb128_t 241 // is to have efficient data types large enough to hold the leb128 type 242 // numbers used in the unwind code. 243 alias _sleb128_t = __builtin_clong; 244 alias _uleb128_t = __builtin_culong; 245