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