Changes in libcfa/src/exception.c [5715d43:67ca73e]
- File:
-
- 1 edited
-
libcfa/src/exception.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/exception.c
r5715d43 r67ca73e 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Aug 12 13:55:00202013 // Update Count : 2 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 15 07:17:19 2020 13 // Update Count : 26 14 14 // 15 15 … … 21 21 // Implementation of the secret header is hardware dependent. 22 22 #if !( defined( __x86_64 ) || defined( __i386 ) ) 23 #error Exception Handling: No known architecture detected. 23 #elif defined( __ARM_ARCH ) 24 #warning FIX ME: check if anything needed for ARM 25 #else 26 #warning Exception Handling: No known architecture detected. 24 27 #endif 25 28 … … 28 31 #include <unwind.h> 29 32 #include <bits/debug.hfa> 30 #include "concurrency/invoke.h"31 33 #include "stdhdr/assert.h" 32 34 … … 59 61 60 62 63 // Temperary global exception context. Does not work with concurency. 64 struct exception_context_t { 65 struct __cfaehm_try_resume_node * top_resume; 66 67 exception_t * current_exception; 68 int current_handler_index; 69 } static shared_stack = {NULL, NULL, 0}; 70 61 71 // Get the current exception context. 62 72 // There can be a single global until multithreading occurs, then each stack 63 // needs its own. We get this from libcfathreads (no weak attribute). 64 __attribute__((weak)) struct exception_context_t * this_exception_context() { 65 static struct exception_context_t shared_stack = {NULL, NULL}; 73 // needs its own. It will have to be updated to handle that. 74 struct exception_context_t * this_exception_context() { 66 75 return &shared_stack; 67 76 } … … 116 125 117 126 // MEMORY MANAGEMENT ========================================================= 118 119 struct __cfaehm_node {120 struct _Unwind_Exception unwind_exception;121 struct __cfaehm_node * next;122 int handler_index;123 };124 125 #define NODE_TO_EXCEPT(node) ((exception_t *)(1 + (node)))126 #define EXCEPT_TO_NODE(except) ((struct __cfaehm_node *)(except) - 1)127 #define UNWIND_TO_NODE(unwind) ((struct __cfaehm_node *)(unwind))128 #define NULL_MAP(map, ptr) ((ptr) ? (map(ptr)) : NULL)129 127 130 128 // How to clean up an exception in various situations. … … 142 140 } 143 141 142 // We need a piece of storage to raise the exception, for now its a single 143 // piece. 144 static struct _Unwind_Exception this_exception_storage; 145 146 struct __cfaehm_node { 147 struct __cfaehm_node * next; 148 }; 149 150 #define NODE_TO_EXCEPT(node) ((exception_t *)(1 + (node))) 151 #define EXCEPT_TO_NODE(except) ((struct __cfaehm_node *)(except) - 1) 152 144 153 // Creates a copy of the indicated exception and sets current_exception to it. 145 154 static void __cfaehm_allocate_exception( exception_t * except ) { … … 155 164 } 156 165 157 // Initialize the node:158 exception_t * except_store = NODE_TO_EXCEPT(store);159 store->unwind_exception.exception_class = __cfaehm_exception_class;160 store->unwind_exception.exception_cleanup = __cfaehm_exception_cleanup;161 store->handler_index = 0;162 except->virtual_table->copy( except_store, except );163 164 166 // Add the node to the list: 165 store->next = NULL_MAP(EXCEPT_TO_NODE, context->current_exception); 166 context->current_exception = except_store; 167 store->next = EXCEPT_TO_NODE(context->current_exception); 168 context->current_exception = NODE_TO_EXCEPT(store); 169 170 // Copy the exception to storage. 171 except->virtual_table->copy( context->current_exception, except ); 172 173 // Set up the exception storage. 174 this_exception_storage.exception_class = __cfaehm_exception_class; 175 this_exception_storage.exception_cleanup = __cfaehm_exception_cleanup; 167 176 } 168 177 … … 179 188 if ( context->current_exception == except ) { 180 189 node = to_free->next; 181 context->current_exception = NULL_MAP(NODE_TO_EXCEPT, node);190 context->current_exception = (node) ? NODE_TO_EXCEPT(node) : 0; 182 191 } else { 183 192 node = EXCEPT_TO_NODE(context->current_exception); … … 207 216 // Verify actions follow the rules we expect. 208 217 verify((actions & _UA_CLEANUP_PHASE) && (actions & _UA_FORCE_UNWIND)); 209 verify(!(actions & (_UA_SEARCH_PHASE | _UA_HAND LER_FRAME)));218 verify(!(actions & (_UA_SEARCH_PHASE | _UA_HANDER_FRAME))); 210 219 211 220 if ( actions & _UA_END_OF_STACK ) { … … 216 225 } 217 226 218 static struct _Unwind_Exception cancel_exception_storage;219 220 227 // Cancel the current stack, prefroming approprate clean-up and messaging. 221 228 void __cfaehm_cancel_stack( exception_t * exception ) { 222 229 // TODO: Detect current stack and pick a particular stop-function. 223 230 _Unwind_Reason_Code ret; 224 ret = _Unwind_ForcedUnwind( & cancel_exception_storage, _Stop_Fn, (void*)0x22 );231 ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 ); 225 232 printf("UNWIND ERROR %d after force unwind\n", ret); 226 233 abort(); … … 243 250 static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) { 244 251 struct exception_context_t * context = this_exception_context(); 252 struct _Unwind_Exception * storage = &this_exception_storage; 245 253 if ( NULL == context->current_exception ) { 246 254 printf("UNWIND ERROR missing exception in begin unwind\n"); 247 255 abort(); 248 256 } 249 struct _Unwind_Exception * storage =250 &EXCEPT_TO_NODE(context->current_exception)->unwind_exception;251 257 252 258 // Call stdlibc to raise the exception … … 294 300 abort(); 295 301 } 296 302 #if 0 297 303 // This is our personality routine. For every stack frame annotated with 298 304 // ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding. … … 406 412 cur_ptr = read_uleb128(cur_ptr, &imatcher); 407 413 414 _Unwind_Word match_pos = 408 415 # if defined( __x86_64 ) 409 _Unwind_Word match_pos =_Unwind_GetCFA(unwind_context) + 8;416 _Unwind_GetCFA(unwind_context) + 8; 410 417 # elif defined( __i386 ) 411 _Unwind_Word match_pos = _Unwind_GetCFA(unwind_context) + 24; 418 _Unwind_GetCFA(unwind_context) + 24; 419 # elif defined( __ARM_ARCH ) 420 # warning FIX ME: check if anything needed for ARM 421 42; 412 422 # endif 413 423 int (*matcher)(exception_t *) = *(int(**)(exception_t *))match_pos; … … 416 426 _Unwind_Reason_Code ret = (0 == index) 417 427 ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND; 418 UNWIND_TO_NODE(unwind_exception)->handler_index = index;428 context->current_handler_index = index; 419 429 420 430 // Based on the return value, check if we matched the exception … … 422 432 __cfadbg_print_safe(exception, " handler found\n"); 423 433 } else { 424 // TODO: Continue the search if there is more in the table.425 434 __cfadbg_print_safe(exception, " no handler\n"); 426 435 } … … 514 523 // Exception handler 515 524 // Note: Saving the exception context on the stack breaks termination exceptions. 516 catch_block( EXCEPT_TO_NODE( this_exception_context()->current_exception )->handler_index,525 catch_block( this_exception_context()->current_handler_index, 517 526 this_exception_context()->current_exception ); 518 527 } … … 600 609 601 610 #pragma GCC pop_options 611 #endif // 0
Note:
See TracChangeset
for help on using the changeset viewer.