| 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 | // Locally we also seem to have: | 
|---|
| 117 | _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); | 
|---|
| 118 |  | 
|---|
| 119 | // GCC (Dwarf2 ?) Frame Layout Macros | 
|---|
| 120 | // See: https://gcc.gnu.org/onlinedocs/gccint/Frame-Layout.html | 
|---|
| 121 | // Include from: ??? | 
|---|
| 122 |  | 
|---|
| 123 | FIRST_PARAM_OFFSET(fundecl) | 
|---|
| 124 | // Offset from argument pointer to first arguments address, or above that | 
|---|
| 125 | // address if ARGS_GROW_DOWNWARD. | 
|---|
| 126 |  | 
|---|
| 127 | ARG_POINTER_CFA_OFFSET(fundecl) | 
|---|
| 128 | // Default: FIRST_PARM_OFFSET(fundecl) + crtl->args.pretend_args_size | 
|---|