// Reference to all sorts of information for exception handling. // C++ Interface to exception handlers. void * __cxa_allocate_exception(size_t thrown_size); // Creates space for the exception. void __cxa_free_exception(void * thrown_exception); void __cxa_throw(void * thrown_exception, struct type_info * tinfo, void (*dest)(void*)); // Throws the exception, is not supposed to return but ours should, // to handle resumption exceptions. void __cxa_begin_catch(); -> void * __cxa_begin_catch(void * exceptionObject); void __cxa_end_catch(); // Not sure, beginning and end of catch block maybe? /* Unwind Module * Full list: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html * Avaible at: /usr/lib/gcc/x86_64-linux-gnu/{5}/include/unwind.h */ typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn) (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, struct _Unwind_Context *); /* Type of the personality function, which does not have a set name. * So far `__gcfa_personality_v0` has been used. * Called by _Unwind_RaiseException (called by __cxa_throw) * or by _Unwind_ForcedUnwind's personality wrapper. * Params: * int version: Repersents unwind convention standard. * _Unwind_Action actions: Set of actions, used as instructions. * _Unwind_Exception_Class: 8-byte identifer: high 4 vendor, low 4 language. * _Unwind_Exception unwind_exception: Pointer to exception data. * _Unwind_Context context: Information on the current stack frame. * Return: * _Unwind_Reason_Code: Requests an action from the unwinder. */ // _Unwind_Action flags (multiple may be set): _UA_SEARCH_PHASE // Seaching for the handler _UA_CLEANUP_PHASE // Cleanup until handler found. _UA_HANDLER_FRAME // Previous search found handler here. _UA_FORCE_UNWIND // Unwind, do not decide if we have reached the handler. _UA_END_OF_STACK // We have reached the end of the stack. // _Unwind_Reason_Code values (one may be selected): _URC_NO_REASON // Containues force unwind. _URC_FOREIGN_EXCEPTION_CAUGHT // Cross between runtime environments. _URC_FATAL_PHASE2_ERROR // Error in cleanup, not otherwise defined. (Rare?) _URC_FATAL_PHASE1_ERROR // Error in search, not otherwise defined. _URC_NORMAL_STOP _URC_END_OF_STACK // eos found before a handler. _URC_HANDLER_FOUND // Just the signal (search?) _URC_INSTALL_CONTEXT // Handler found, resume execution (cleanup?) _URC_CONTINUE_UNWIND // No handler found (search&cleanup) // Exception Header: (?) typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code reason, struct _Unwind_Exception *exc); struct _Unwind_Exception { uint64 exception_class; _Unwind_Exception_Cleanup_Fn exception_cleanup; uint64 private_1; // Do not access. uint64 private_2; // Do not access. }; // There are two functions to access the unwind "operation". // The standard exception handler, uses the personality function. _Unwind_Reason_Code _Unwind_RaiseException( struct _Unwind_Exception * exception_object); // Helper for force unwind. typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)( int version, _Unwind_Action actions, uint64 exceptionClass, struct _Unwind_Exception * exceptionObject, struct _Unwind_Context * context, void * stop_parameter); // Special unwinder, wraps the personality function. _Unwind_Reason_Code _Unwind_ForcedUnwind( struct _Unwind_Exception * exception_object, _Unwind_Stop_Fn stop, void * stop_parameter); // Continues unwinding void _Unwind_Resume(struct _Unwind_Exception * exception_object); // Seems to be for finally and deconstrctors, not so much rethrow. // However I haven't figured out the difference. /* _Unwind Helper functions: * * _Unwind_GetLanguageSpecificData - LSDA (destructors and landing pads) * _Unwind_GetRegionStart - Function pointer to current stack frame. * _Unwind_GetIP - Get frame's instruction pointer * This might be the actual function pointer or the call site up stack. * * All three have the same signature. */ uint64 _Unwind_Get*(struct _Unwind_Context * context); void _Unwind_SetIP(struct _Unwind_Context * context, uint64 new_value); uint64 _Unwind_GetGR(struct _Unwind_Context * context, int index); void _Unwind_SetGR(struct _Unwind_Context * <>, int index, uint64 <>); // __builtin_eh_return_data_regno(^) ^=[0..3]? gives index. // Locally we also seem to have: _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); // GCC (Dwarf2 ?) Frame Layout Macros // See: https://gcc.gnu.org/onlinedocs/gccint/Frame-Layout.html // Include from: ??? FIRST_PARAM_OFFSET(fundecl) // Offset from argument pointer to first arguments address, or above that // address if ARGS_GROW_DOWNWARD. ARG_POINTER_CFA_OFFSET(fundecl) // Default: FIRST_PARM_OFFSET(fundecl) + crtl->args.pretend_args_size