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