[4a58895] | 1 | // Reference to all sorts of information for exception handling. |
---|
| 2 | |
---|
| 3 | // C++ Interface to exception handlers. |
---|
| 4 | |
---|
| 5 | void * __cxa_allocate_exception(size_t thrown_size); |
---|
| 6 | // Creates space for the exception. |
---|
| 7 | |
---|
| 8 | void __cxa_free_exception(void * thrown_exception); |
---|
| 9 | |
---|
| 10 | void __cxa_throw(void * thrown_exception, struct type_info * tinfo, |
---|
| 11 | void (*dest)(void*)); |
---|
| 12 | // Throws the exception, is not supposed to return but ours should, |
---|
| 13 | // to handle resumption exceptions. |
---|
| 14 | |
---|
| 15 | void __cxa_begin_catch(); -> void * __cxa_begin_catch(void * exceptionObject); |
---|
| 16 | void __cxa_end_catch(); |
---|
| 17 | // Not sure, beginning and end of catch block maybe? |
---|
| 18 | |
---|
| 19 | |
---|
| 20 | /* Unwind Module |
---|
| 21 | * Full list: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html |
---|
| 22 | * Avaible at: /usr/lib/gcc/x86_64-linux-gnu/{5}/include/unwind.h |
---|
| 23 | */ |
---|
| 24 | |
---|
| 25 | typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) |
---|
| 26 | (int, _Unwind_Action, _Unwind_Exception_Class, |
---|
| 27 | struct _Unwind_Exception *, struct _Unwind_Context *); |
---|
| 28 | /* Type of the personality function, which does not have a set name. |
---|
| 29 | * So far `__gcfa_personality_v0` has been used. |
---|
| 30 | * Called by _Unwind_RaiseException (called by __cxa_throw) |
---|
| 31 | * or by _Unwind_ForcedUnwind's personality wrapper. |
---|
| 32 | * Params: |
---|
| 33 | * int version: Repersents unwind convention standard. |
---|
| 34 | * _Unwind_Action actions: Set of actions, used as instructions. |
---|
| 35 | * _Unwind_Exception_Class: 8-byte identifer: high 4 vendor, low 4 language. |
---|
| 36 | * _Unwind_Exception unwind_exception: Pointer to exception data. |
---|
| 37 | * _Unwind_Context context: Information on the current stack frame. |
---|
| 38 | * Return: |
---|
| 39 | * _Unwind_Reason_Code: Requests an action from the unwinder. |
---|
| 40 | */ |
---|
| 41 | |
---|
| 42 | |
---|
| 43 | // _Unwind_Action flags (multiple may be set): |
---|
| 44 | _UA_SEARCH_PHASE // Seaching for the handler |
---|
| 45 | _UA_CLEANUP_PHASE // Cleanup until handler found. |
---|
| 46 | _UA_HANDLER_FRAME // Previous search found handler here. |
---|
| 47 | _UA_FORCE_UNWIND // Unwind, do not decide if we have reached the handler. |
---|
| 48 | _UA_END_OF_STACK // We have reached the end of the stack. |
---|
| 49 | |
---|
| 50 | |
---|
| 51 | // _Unwind_Reason_Code values (one may be selected): |
---|
| 52 | _URC_NO_REASON // Containues force unwind. |
---|
| 53 | _URC_FOREIGN_EXCEPTION_CAUGHT // Cross between runtime environments. |
---|
| 54 | _URC_FATAL_PHASE2_ERROR // Error in cleanup, not otherwise defined. (Rare?) |
---|
| 55 | _URC_FATAL_PHASE1_ERROR // Error in search, not otherwise defined. |
---|
| 56 | _URC_NORMAL_STOP |
---|
| 57 | _URC_END_OF_STACK // eos found before a handler. |
---|
| 58 | _URC_HANDLER_FOUND // Just the signal (search?) |
---|
| 59 | _URC_INSTALL_CONTEXT // Handler found, resume execution (cleanup?) |
---|
| 60 | _URC_CONTINUE_UNWIND // No handler found (search&cleanup) |
---|
| 61 | |
---|
| 62 | |
---|
| 63 | // Exception Header: (?) |
---|
| 64 | typedef void (*_Unwind_Exception_Cleanup_Fn) |
---|
| 65 | (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc); |
---|
| 66 | |
---|
| 67 | struct _Unwind_Exception { |
---|
| 68 | uint64 exception_class; |
---|
| 69 | _Unwind_Exception_Cleanup_Fn exception_cleanup; |
---|
| 70 | uint64 private_1; // Do not access. |
---|
| 71 | uint64 private_2; // Do not access. |
---|
| 72 | }; |
---|
| 73 | |
---|
| 74 | |
---|
| 75 | // There are two functions to access the unwind "operation". |
---|
| 76 | // The standard exception handler, uses the personality function. |
---|
| 77 | _Unwind_Reason_Code _Unwind_RaiseException( |
---|
| 78 | struct _Unwind_Exception * exception_object); |
---|
| 79 | |
---|
| 80 | // Helper for force unwind. |
---|
| 81 | typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)( |
---|
| 82 | int version, |
---|
| 83 | _Unwind_Action actions, |
---|
| 84 | uint64 exceptionClass, |
---|
| 85 | struct _Unwind_Exception * exceptionObject, |
---|
| 86 | struct _Unwind_Context * context, |
---|
| 87 | void * stop_parameter); |
---|
| 88 | |
---|
| 89 | // Special unwinder, wraps the personality function. |
---|
| 90 | _Unwind_Reason_Code _Unwind_ForcedUnwind( |
---|
| 91 | struct _Unwind_Exception * exception_object, |
---|
| 92 | _Unwind_Stop_Fn stop, |
---|
| 93 | void * stop_parameter); |
---|
| 94 | |
---|
| 95 | // Continues unwinding |
---|
| 96 | void _Unwind_Resume(struct _Unwind_Exception * exception_object); |
---|
| 97 | // Seems to be for finally and deconstrctors, not so much rethrow. |
---|
| 98 | // However I haven't figured out the difference. |
---|
| 99 | |
---|
| 100 | |
---|
| 101 | /* _Unwind Helper functions: |
---|
| 102 | * |
---|
| 103 | * _Unwind_GetLanguageSpecificData - LSDA (destructors and landing pads) |
---|
| 104 | * _Unwind_GetRegionStart - Function pointer to current stack frame. |
---|
| 105 | * _Unwind_GetIP - Get frame's instruction pointer |
---|
| 106 | * This might be the actual function pointer or the call site up stack. |
---|
| 107 | * |
---|
| 108 | * All three have the same signature. */ |
---|
| 109 | uint64 _Unwind_Get*(struct _Unwind_Context * context); |
---|
| 110 | |
---|
| 111 | void _Unwind_SetIP(struct _Unwind_Context * context, uint64 new_value); |
---|
| 112 | uint64 _Unwind_GetGR(struct _Unwind_Context * context, int index); |
---|
| 113 | void _Unwind_SetGR(struct _Unwind_Context * <>, int index, uint64 <>); |
---|
| 114 | // __builtin_eh_return_data_regno(^) ^=[0..3]? gives index. |
---|
| 115 | |
---|
| 116 | |
---|
| 117 | // GCC (Dwarf2 ?) Frame Layout Macros |
---|
| 118 | // https://gcc.gnu.org/onlinedocs/gccint/Frame-Layout.html |
---|
| 119 | |
---|
| 120 | FIRST_PARAM_OFFSET(fundecl) |
---|
| 121 | // Offset from argument pointer to first arguments address, or above that |
---|
| 122 | // address if ARGS_GROW_DOWNWARD. |
---|
| 123 | |
---|
| 124 | ARG_POINTER_CFA_OFFSET(fundecl) |
---|
| 125 | // Default: FIRST_PARM_OFFSET(fundecl) + crtl->args.pretend_args_size |
---|