Changeset eb46fdf
- Timestamp:
- Dec 12, 2019, 4:06:18 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 332bd33
- Parents:
- 737c98a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/exception.c
r737c98a reb46fdf 69 69 70 70 71 // This macro should be the only thing that needs to change across machines. Used in the personality function, way down72 // in termination.71 // This macro should be the only thing that needs to change across machines. 72 // Used in the personality function, way down in termination. 73 73 // struct _Unwind_Context * -> _Unwind_Reason_Code(*)(exception_t *) 74 74 #define MATCHER_FROM_CONTEXT(ptr_to_context) \ … … 102 102 } 103 103 104 // Do we control where exceptions get thrown even with concurency? If not these are not quite thread safe, the cleanup 105 // hook has to be added after the node is built but before it is made the top node. 104 // Do we control where exceptions get thrown even with concurency? 105 // If not these are not quite thread safe, the cleanup hook has to 106 // be added after the node is built but before it is made the top node. 106 107 107 108 void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node, … … 212 213 _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage ); 213 214 214 // If we reach here it means something happened. For resumption to work we need to find a way to return back to 215 // here. Most of them will probably boil down to setting a global flag and making the phase 1 either stop or 216 // fail. Causing an error on purpose may help avoiding unnecessary work but it might have some weird side 217 // effects. If we just pretend no handler was found that would work but may be expensive for no reason since we 218 // will always search the whole stack. 215 // If we reach here it means something happened. For resumption to work we need to find a way 216 // to return back to here. Most of them will probably boil down to setting a global flag and 217 // making the phase 1 either stop or fail. Causing an error on purpose may help avoiding 218 // unnecessary work but it might have some weird side effects. If we just pretend no handler 219 // was found that would work but may be expensive for no reason since we will always search 220 // the whole stack. 219 221 220 222 if( ret == _URC_END_OF_STACK ) { 221 // No proper handler was found. This can be handled in several way. C++ calls std::terminate Here we222 // force unwind the stack, basically raising a cancellation.223 // No proper handler was found. This can be handled in many ways, C++ calls std::terminate. 224 // Here we force unwind the stack, basically raising a cancellation. 223 225 printf("Uncaught exception %p\n", &this_exception_storage); 224 226 … … 228 230 } 229 231 230 // We did not simply reach the end of the stack without finding a handler. Something wen't wrong232 // We did not simply reach the end of the stack without finding a handler. This is an error. 231 233 printf("UNWIND ERROR %d after raise exception\n", ret); 232 234 abort(); … … 254 256 abort(); 255 257 } 256 #else 257 // This is our personality routine. For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0". 258 // This function will be called twice when unwinding. Once in the search phased and once in the cleanup phase. 258 #else // PIC 259 // This is our personality routine. For every stack frame annotated with 260 // ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding. 261 // Once in the search phase and once in the cleanup phase. 259 262 _Unwind_Reason_Code __gcfa_personality_v0 ( 260 263 int version, _Unwind_Action actions, unsigned long long exceptionClass, … … 264 267 265 268 //__cfaabi_dbg_print_safe("CFA: 0x%lx\n", _Unwind_GetCFA(context)); 266 __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context); 269 __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", 270 version, actions, exceptionClass, unwind_exception, context); 267 271 268 272 // If we've reached the end of the stack then there is nothing much we can do... … … 291 295 // Get the instuction pointer and a reading pointer into the exception table 292 296 lsda_header_info lsd_info; 293 const unsigned char * cur_ptr = parse_lsda_header( 297 const unsigned char * cur_ptr = parse_lsda_header(context, lsd, &lsd_info); 294 298 _Unwind_Ptr instruction_ptr = _Unwind_GetIP( context ); 295 299 … … 302 306 303 307 // Decode the common stuff we have in here 304 cur_ptr = read_encoded_value 305 cur_ptr = read_encoded_value 306 cur_ptr = read_encoded_value 307 cur_ptr = read_uleb128 308 cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_start); 309 cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_len); 310 cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad); 311 cur_ptr = read_uleb128(cur_ptr, &callsite_action); 308 312 309 313 // Have we reach the correct frame info yet? … … 316 320 void * ep = (void*)lsd_info.Start + callsite_start + callsite_len; 317 321 void * ip = (void*)instruction_ptr; 318 __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip); 322 __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", 323 bp, ep, ls, cs, cl, ip); 319 324 #endif // __CFA_DEBUG_PRINT__ 320 325 continue; 321 326 } 322 327 323 // Have we gone too far 328 // Have we gone too far? 324 329 if( lsd_info.Start + callsite_start > instruction_ptr ) { 325 330 printf(" gone too far"); … … 331 336 // Which phase are we in 332 337 if (actions & _UA_SEARCH_PHASE) { 333 // Search phase, this means we probably found a potential handler and must check if it is a match334 335 // If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler336 // This doesn't seem to conflict the gcc default behavior338 // In search phase, these means we found a potential handler we must check. 339 340 // We have arbitrarily decided that 0 means nothing to do and 1 means there is 341 // a potential handler. This doesn't seem to conflict the gcc default behavior. 337 342 if (callsite_action != 0) { 338 343 // Now we want to run some code to see if the handler matches … … 351 356 // The current apprach uses one exception table entry per try block 352 357 _uleb128_t imatcher; 353 // Get the relative offset to the 354 cur_ptr = read_uleb128 (cur_ptr, &imatcher); 355 356 // Get a function pointer from the relative offset and call it 357 // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher; 358 // Get the relative offset to the {...}? 359 cur_ptr = read_uleb128(cur_ptr, &imatcher); 358 360 359 361 _Unwind_Reason_Code (*matcher)(exception_t *) = … … 414 416 } 415 417 416 // Try statements are hoisted out see comments for details. With this could probably be unique and simply linked from417 // libcfa but there is one problem left, see the exception table for details418 // Try statements are hoisted out see comments for details. While this could probably be unique 419 // and simply linked from libcfa but there is one problem left, see the exception table for details 418 420 __attribute__((noinline)) 419 421 void __cfaabi_ehm__try_terminate(void (*try_block)(), … … 428 430 // assembly works. 429 431 430 // Setup the personality routine 432 // Setup the personality routine and exception table. 431 433 asm volatile (".cfi_personality 0x3,__gcfa_personality_v0"); 432 // Setup the exception table433 434 asm volatile (".cfi_lsda 0x3, .LLSDACFA2"); 434 435 … … 442 443 asm volatile goto ("" : : : : CATCH ); 443 444 444 // Normal return 445 // Normal return for when there is no throw. 445 446 return; 446 447 … … 459 460 } 460 461 461 // Exception table data we need to generate. While this is almost generic, the custom data refers to foo_try_match try 462 // match, which is no way generic. Some more works need to be done if we want to have a single call to the try routine. 462 // Exception table data we need to generate. While this is almost generic, the custom data refers 463 // to {*}try_terminate, which is no way generic. Some more works need to be done if we want to 464 // have a single call to the try routine. 463 465 464 466 #if defined( __i386 ) || defined( __x86_64 ) 465 467 asm ( 466 // HEADER468 // HEADER 467 469 ".LFECFA1:\n" 468 470 " .globl __gcfa_personality_v0\n" 469 471 " .section .gcc_except_table,\"a\",@progbits\n" 470 ".LLSDACFA2:\n" //TABLE header 472 // TABLE HEADER (important field is the BODY length at the end) 473 ".LLSDACFA2:\n" 471 474 " .byte 0xff\n" 472 475 " .byte 0xff\n" 473 476 " .byte 0x1\n" 474 " .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n" // BODY length 475 // Body uses language specific data and therefore could be modified arbitrarily 476 ".LLSDACSBCFA2:\n" // BODY start 477 " .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n" // Handled area start (relative to start of function) 478 " .uleb128 .TRYEND-.TRYSTART\n" // Handled area length 479 " .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n" // Hanlder landing pad adress (relative to start of function) 480 " .uleb128 1\n" // Action code, gcc seems to use always 0 481 ".LLSDACSECFA2:\n" // BODY end 482 " .text\n" // TABLE footer 477 " .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n" 478 // BODY (language specific data) 479 ".LLSDACSBCFA2:\n" 480 // Handled area start (relative to start of function) 481 " .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n" 482 // Handled area length 483 " .uleb128 .TRYEND-.TRYSTART\n" 484 // Handler landing pad address (relative to start of function) 485 " .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n" 486 // Action code, gcc seems to always use 0. 487 " .uleb128 1\n" 488 // TABLE FOOTER 489 ".LLSDACSECFA2:\n" 490 " .text\n" 483 491 " .size __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n" 484 492 " .ident \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n" … … 486 494 ); 487 495 #endif // __i386 || __x86_64 488 #endif // PIC496 #endif // PIC
Note: See TracChangeset
for help on using the changeset viewer.