Changeset b947fb2
- Timestamp:
- Jul 26, 2017, 12:35:39 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 15d1cc3, a5f0529, d746bc8
- Parents:
- 33218c6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/exception.c
r33218c6 rb947fb2 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 : Tus Jul 11 16:36:00201713 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 26 10:37:51 2017 13 // Update Count : 2 14 14 // 15 15 … … 21 21 #include <stdio.h> 22 22 #include <unwind.h> 23 24 // FIX ME: temporary hack to keep ARM build working 25 #ifndef _URC_FATAL_PHASE1_ERROR 26 #define _URC_FATAL_PHASE1_ERROR 2 27 #endif // ! _URC_FATAL_PHASE1_ERROR 28 #ifndef _URC_FATAL_PHASE2_ERROR 29 #define _URC_FATAL_PHASE2_ERROR 2 30 #endif // ! _URC_FATAL_PHASE2_ERROR 23 31 24 32 #include "lsda.h" … … 35 43 36 44 37 // This macro should be the only thing that needs to change across machines. 38 // Used in the personality function, way downin termination.45 // This macro should be the only thing that needs to change across machines. Used in the personality function, way down 46 // in termination. 39 47 // struct _Unwind_Context * -> _Unwind_Reason_Code(*)(exception *) 40 48 #define MATCHER_FROM_CONTEXT(ptr_to_context) \ … … 69 77 } 70 78 71 /* Do we control where exceptions get thrown even with concurency? 72 * If not these are not quite thread safe, the cleanup hook has to be added 73 * after the node is built but before it is made the top node. 74 */ 79 // Do we control where exceptions get thrown even with concurency? If not these are not quite thread safe, the cleanup 80 // hook has to be added after the node is built but before it is made the top node. 81 75 82 void __cfaehm__try_resume_setup(struct __cfaehm__try_resume_node * node, 76 83 int (*handler)(exception * except)) { … … 89 96 // Requires -fexceptions to work. 90 97 91 // Global which defines the current exception 92 // Currently an int just to make matching easier 98 // Global which defines the current exception. Currently an int just to make matching easier. 93 99 //int this_exception; (became shared_stack.current_exception) 94 100 … … 121 127 _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage ); 122 128 123 // If we reach here it means something happened 124 // For resumption to work we need to find a way to return back to here 125 // Most of them will probably boil down to setting a global flag and making the phase 1 either stop or fail. 126 // Causing an error on purpose may help avoiding unnecessary work but it might have some weird side effects. 127 // If we just pretend no handler was found that would work but may be expensive for no reason since we will always 128 // search the whole stack 129 // If we reach here it means something happened. For resumption to work we need to find a way to return back to 130 // here. Most of them will probably boil down to setting a global flag and making the phase 1 either stop or 131 // fail. Causing an error on purpose may help avoiding unnecessary work but it might have some weird side 132 // effects. If we just pretend no handler was found that would work but may be expensive for no reason since we 133 // will always search the whole stack. 129 134 130 135 if( ret == _URC_END_OF_STACK ) { 131 // No proper handler was found 132 // This can be handled in several way 133 // C++ calls std::terminate 134 // Here we force unwind the stack, basically raising a cancellation 136 // No proper handler was found. This can be handled in several way. C++ calls std::terminate Here we 137 // force unwind the stack, basically raising a cancellation. 135 138 printf("Uncaught exception %p\n", &this_exception_storage); 136 139 … … 140 143 } 141 144 142 // We did not simply reach the end of the stack without finding a handler, 143 // Something wen't wrong 145 // We did not simply reach the end of the stack without finding a handler. Something wen't wrong 144 146 printf("UNWIND ERROR %d after raise exception\n", ret); 145 147 abort(); … … 154 156 } 155 157 156 // This is our personality routine 157 // For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0" 158 // This function will be called twice when unwinding 159 // Once in the search phased and once in the cleanup phase 158 // This is our personality routine. For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0". 159 // This function will be called twice when unwinding. Once in the search phased and once in the cleanup phase. 160 160 _Unwind_Reason_Code __gcfa_personality_v0 ( 161 161 int version, _Unwind_Action actions, unsigned long long exceptionClass, … … 293 293 // I assume this sets the instruction pointer to the adress of the landing pad 294 294 // It doesn't actually set it, it only state the value that needs to be set once we return _URC_INSTALL_CONTEXT 295 _Unwind_SetIP( context, lsd_info.LPStart + callsite_landing_pad);295 _Unwind_SetIP( context, ((lsd_info.LPStart) + (callsite_landing_pad)) ); 296 296 297 297 // DEBUG … … 317 317 } 318 318 319 // Try statements are hoisted out see comments for details 320 // With this could probably be unique and simply linked from 321 // libcfa but there is one problem left, see the exception table 322 // for details 319 // Try statements are hoisted out see comments for details. With this could probably be unique and simply linked from 320 // libcfa but there is one problem left, see the exception table for details 323 321 __attribute__((noinline)) 324 322 void __cfaehm__try_terminate(void (*try_block)(), … … 328 326 //! printf("%p %p %p %p\n", &try_block, &catch_block, &match_block, &xy); 329 327 330 // Setup statments 331 // These 2 statments won't actually result in any code, 332 // they only setup global tables. 333 // However, they clobber gcc cancellation support from gcc. 334 // We can replace the personality routine but replacing the exception 335 // table gcc generates is not really doable, it generates labels based 336 // on how the assembly works. 328 // Setup statments: These 2 statments won't actually result in any code, they only setup global tables. 329 // However, they clobber gcc cancellation support from gcc. We can replace the personality routine but 330 // replacing the exception table gcc generates is not really doable, it generates labels based on how the 331 // assembly works. 332 337 333 // Setup the personality routine 338 334 asm volatile (".cfi_personality 0x3,__gcfa_personality_v0"); … … 340 336 asm volatile (".cfi_lsda 0x3, .LLSDACFA2"); 341 337 342 // Label which defines the start of the area for which the handler is setup 338 // Label which defines the start of the area for which the handler is setup. 343 339 asm volatile (".TRYSTART:"); 344 340 … … 354 350 // Exceptionnal path 355 351 CATCH : __attribute__(( unused )); 356 // Label which defines the end of the area for which the handler is setup 352 // Label which defines the end of the area for which the handler is setup. 357 353 asm volatile (".TRYEND:"); 358 // Label which defines the start of the exception landing pad 359 // basically what will be called when the exception is caught 360 // Note, if multiple handlers are given, the multiplexing should be done 361 // by the generated code, not the exception runtime 354 // Label which defines the start of the exception landing pad. Basically what is called when the exception is 355 // caught. Note, if multiple handlers are given, the multiplexing should be done by the generated code, not the 356 // exception runtime. 362 357 asm volatile (".CATCH:"); 363 358 364 359 // Exception handler 365 catch_block(shared_stack.current_handler_index, 366 &shared_stack.current_exception); 367 } 368 369 // Exception table data we need to generate 370 // While this is almost generic, the custom data refers to 371 // foo_try_match try match, which is no way generic 372 // Some more works need to be done if we want to have a single 373 // call to the try routine 360 catch_block( shared_stack.current_handler_index, 361 &shared_stack.current_exception ); 362 } 363 364 // Exception table data we need to generate. While this is almost generic, the custom data refers to foo_try_match try 365 // 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. 366 367 #if defined( __x86_64__ ) || defined( __i386__ ) 374 368 asm ( 375 369 //HEADER … … 394 388 // " .section .note.GNU-stack,\"x\",@progbits\n" 395 389 ); 390 #endif // __x86_64__ || __i386__
Note: See TracChangeset
for help on using the changeset viewer.