| 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
 | 
|---|