1 /** 2 * Binding for libunwind/libgc's `unwind.h` 3 * 4 * Those bindings expose the `_Unwind_*` symbols used by druntime 5 * to do exception handling. 6 * 7 * See_Also: 8 * Itanium C++ ABI: Exception Handling ($Revision: 1.22 $) 9 * Source: $(DRUNTIMESRC core/internal/backtrace/_unwind.d) 10 */ 11 module core.internal.backtrace.unwind; 12 13 import core.stdc.stdint; 14 15 version (ARM) 16 { 17 version (iOS) {} else version = ARM_EABI_UNWINDER; 18 } 19 version (X86) version = X86_Any; 20 version (X86_64) version = X86_Any; 21 22 extern (C): 23 24 alias uintptr_t _Unwind_Word; 25 alias intptr_t _Unwind_Sword; 26 alias uintptr_t _Unwind_Ptr; 27 alias uintptr_t _Unwind_Internal_Ptr; 28 29 alias ulong _Unwind_Exception_Class; 30 31 alias uintptr_t _uleb128_t; 32 alias intptr_t _sleb128_t; 33 34 alias int _Unwind_Reason_Code; 35 enum 36 { 37 _URC_NO_REASON = 0, 38 _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 39 _URC_FATAL_PHASE2_ERROR = 2, 40 _URC_FATAL_PHASE1_ERROR = 3, 41 _URC_NORMAL_STOP = 4, 42 _URC_END_OF_STACK = 5, 43 _URC_HANDLER_FOUND = 6, 44 _URC_INSTALL_CONTEXT = 7, 45 _URC_CONTINUE_UNWIND = 8 46 } 47 version (ARM_EABI_UNWINDER) 48 enum _URC_FAILURE = 9; 49 50 alias int _Unwind_Action; 51 enum _Unwind_Action _UA_SEARCH_PHASE = 1; 52 enum _Unwind_Action _UA_CLEANUP_PHASE = 2; 53 enum _Unwind_Action _UA_HANDLER_FRAME = 4; 54 enum _Unwind_Action _UA_FORCE_UNWIND = 8; 55 enum _Unwind_Action _UA_END_OF_STACK = 16; 56 57 alias _Unwind_Exception_Cleanup_Fn = void function( 58 _Unwind_Reason_Code reason, 59 _Unwind_Exception *exc); 60 61 version (ARM_EABI_UNWINDER) 62 { 63 align(8) struct _Unwind_Control_Block 64 { 65 ulong exception_class; 66 void function(_Unwind_Reason_Code, _Unwind_Control_Block *) exception_cleanup; 67 68 /* Unwinder cache, private fields for the unwinder's use */ 69 struct unwinder_cache_t 70 { 71 uint reserved1; /* init reserved1 to 0, then don't touch */ 72 uint reserved2; 73 uint reserved3; 74 uint reserved4; 75 uint reserved5; 76 } 77 unwinder_cache_t unwinder_cache; 78 79 /* Propagation barrier cache (valid after phase 1): */ 80 struct barrier_cache_t 81 { 82 uint sp; 83 uint[5] bitpattern; 84 } 85 barrier_cache_t barrier_cache; 86 87 /* Cleanup cache (preserved over cleanup): */ 88 struct cleanup_cache_t 89 { 90 uint[4] bitpattern; 91 } 92 cleanup_cache_t cleanup_cache; 93 94 /* Pr cache (for pr's benefit): */ 95 struct pr_cache_t 96 { 97 uint fnstart; /* function start address */ 98 void* ehtp; /* pointer to EHT entry header word */ 99 uint additional; 100 uint reserved1; 101 } 102 pr_cache_t pr_cache; 103 } 104 105 alias _Unwind_Exception = _Unwind_Control_Block; 106 } 107 else version (X86_Any) 108 { 109 align(16) struct _Unwind_Exception 110 { 111 _Unwind_Exception_Class exception_class; 112 _Unwind_Exception_Cleanup_Fn exception_cleanup; 113 _Unwind_Word private_1; 114 _Unwind_Word private_2; 115 } 116 } 117 else 118 { 119 align(8) struct _Unwind_Exception 120 { 121 _Unwind_Exception_Class exception_class; 122 _Unwind_Exception_Cleanup_Fn exception_cleanup; 123 _Unwind_Word private_1; 124 _Unwind_Word private_2; 125 } 126 } 127 128 struct _Unwind_Context; 129 130 _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object); 131 132 alias _Unwind_Stop_Fn = _Unwind_Reason_Code function( 133 int _version, 134 _Unwind_Action actions, 135 _Unwind_Exception_Class exceptionClass, 136 _Unwind_Exception* exceptionObject, 137 _Unwind_Context* context, 138 void* stop_parameter); 139 140 _Unwind_Reason_Code _Unwind_ForcedUnwind( 141 _Unwind_Exception* exception_object, 142 _Unwind_Stop_Fn stop, 143 void* stop_parameter); 144 145 alias _Unwind_Trace_Fn = _Unwind_Reason_Code function(_Unwind_Context*, void*); 146 147 void _Unwind_DeleteException(_Unwind_Exception* exception_object); 148 void _Unwind_Resume(_Unwind_Exception* exception_object); 149 _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception* exception_object); 150 _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*); 151 152 version (ARM_EABI_UNWINDER) 153 { 154 _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception* exception_object, _Unwind_Context* context); 155 void _Unwind_Complete(_Unwind_Exception* exception_object); 156 } 157 158 _Unwind_Word _Unwind_GetGR(_Unwind_Context* context, int index); 159 void _Unwind_SetGR(_Unwind_Context* context, int index, _Unwind_Word new_value); 160 _Unwind_Ptr _Unwind_GetIP(_Unwind_Context* context); 161 _Unwind_Ptr _Unwind_GetIPInfo(_Unwind_Context* context, int*); 162 void _Unwind_SetIP(_Unwind_Context* context, _Unwind_Ptr new_value); 163 _Unwind_Word _Unwind_GetCFA(_Unwind_Context*); 164 _Unwind_Word _Unwind_GetBSP(_Unwind_Context*); 165 void* _Unwind_GetLanguageSpecificData(_Unwind_Context*); 166 _Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context* context); 167 void* _Unwind_FindEnclosingFunction(void* pc); 168 169 version (X68_64) 170 { 171 _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context* context) 172 { 173 return _Unwind_GetGR(context, 1); 174 } 175 176 _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context* context) 177 { 178 assert(0); 179 } 180 } 181 else 182 { 183 _Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context* context); 184 _Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context* context); 185 } 186 187 188 alias _Unwind_Personality_Fn = _Unwind_Reason_Code function( 189 int _version, 190 _Unwind_Action actions, 191 _Unwind_Exception_Class exceptionClass, 192 _Unwind_Exception* exceptionObject, 193 _Unwind_Context* context); 194 195 struct SjLj_Function_Context; 196 void _Unwind_SjLj_Register(SjLj_Function_Context *); 197 void _Unwind_SjLj_Unregister(SjLj_Function_Context *); 198 _Unwind_Reason_Code _Unwind_SjLj_RaiseException(_Unwind_Exception*); 199 _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(_Unwind_Exception , _Unwind_Stop_Fn, void*); 200 void _Unwind_SjLj_Resume(_Unwind_Exception*); 201 _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception*);