Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/exception.c

    reb46fdf rd43ed2c  
    6969
    7070
    71 // This macro should be the only thing that needs to change across machines.
    72 // Used in the personality function, way down in termination.
     71// This macro should be the only thing that needs to change across machines.  Used in the personality function, way down
     72// in termination.
    7373// struct _Unwind_Context * -> _Unwind_Reason_Code(*)(exception_t *)
    7474#define MATCHER_FROM_CONTEXT(ptr_to_context) \
     
    102102}
    103103
    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.
     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.
    107106
    108107void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node,
     
    213212        _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
    214213
    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.
     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.
    221219
    222220        if( ret == _URC_END_OF_STACK ) {
    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.
     221                // No proper handler was found.  This can be handled in several way.  C++ calls std::terminate Here we
     222                // force unwind the stack, basically raising a cancellation.
    225223                printf("Uncaught exception %p\n", &this_exception_storage);
    226224
     
    230228        }
    231229
    232         // We did not simply reach the end of the stack without finding a handler. This is an error.
     230        // We did not simply reach the end of the stack without finding a handler.  Something wen't wrong
    233231        printf("UNWIND ERROR %d after raise exception\n", ret);
    234232        abort();
     
    256254        abort();
    257255}
    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.
     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.
    262259_Unwind_Reason_Code __gcfa_personality_v0 (
    263260                int version, _Unwind_Action actions, unsigned long long exceptionClass,
     
    267264
    268265        //__cfaabi_dbg_print_safe("CFA: 0x%lx\n", _Unwind_GetCFA(context));
    269         __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):",
    270                         version, actions, exceptionClass, unwind_exception, context);
     266        __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
    271267
    272268        // If we've reached the end of the stack then there is nothing much we can do...
     
    295291        // Get the instuction pointer and a reading pointer into the exception table
    296292        lsda_header_info lsd_info;
    297         const unsigned char * cur_ptr = parse_lsda_header(context, lsd, &lsd_info);
     293        const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
    298294        _Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
    299295
     
    306302
    307303                // Decode the common stuff we have in here
    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);
     304                cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
     305                cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
     306                cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
     307                cur_ptr = read_uleb128 (cur_ptr, &callsite_action);
    312308
    313309                // Have we reach the correct frame info yet?
     
    320316                        void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
    321317                        void * ip = (void*)instruction_ptr;
    322                         __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n",
    323                                         bp, ep, ls, cs, cl, ip);
     318                        __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
    324319#endif // __CFA_DEBUG_PRINT__
    325320                        continue;
    326321                }
    327322
    328                 // Have we gone too far?
     323                // Have we gone too far
    329324                if( lsd_info.Start + callsite_start > instruction_ptr ) {
    330325                        printf(" gone too far");
     
    336331                        // Which phase are we in
    337332                        if (actions & _UA_SEARCH_PHASE) {
    338                                 // 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.
     333                                // Search phase, this means we probably found a potential handler and must check if it is a match
     334
     335                                // If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler
     336                                // This doesn't seem to conflict the gcc default behavior
    342337                                if (callsite_action != 0) {
    343338                                        // Now we want to run some code to see if the handler matches
     
    356351                                        // The current apprach uses one exception table entry per try block
    357352                                        _uleb128_t imatcher;
    358                                         // Get the relative offset to the {...}?
    359                                         cur_ptr = read_uleb128(cur_ptr, &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;
    360358
    361359                                        _Unwind_Reason_Code (*matcher)(exception_t *) =
     
    416414}
    417415
    418 // 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
     416// Try statements are hoisted out see comments for details.  With this could probably be unique and simply linked from
     417// libcfa but there is one problem left, see the exception table for details
    420418__attribute__((noinline))
    421419void __cfaabi_ehm__try_terminate(void (*try_block)(),
     
    430428        // assembly works.
    431429
    432         // Setup the personality routine and exception table.
     430        // Setup the personality routine
    433431        asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
     432        // Setup the exception table
    434433        asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
    435434
     
    443442        asm volatile goto ("" : : : : CATCH );
    444443
    445         // Normal return for when there is no throw.
     444        // Normal return
    446445        return;
    447446
     
    460459}
    461460
    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.
     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.
    465463
    466464#if defined( __i386 ) || defined( __x86_64 )
    467465asm (
    468         // HEADER
     466        //HEADER
    469467        ".LFECFA1:\n"
    470468        "       .globl  __gcfa_personality_v0\n"
    471469        "       .section        .gcc_except_table,\"a\",@progbits\n"
    472         // TABLE HEADER (important field is the BODY length at the end)
    473         ".LLSDACFA2:\n"
     470        ".LLSDACFA2:\n"                                                 //TABLE header
    474471        "       .byte   0xff\n"
    475472        "       .byte   0xff\n"
    476473        "       .byte   0x1\n"
    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"
     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
    491483        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
    492484        "       .ident  \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
     
    494486);
    495487#endif // __i386 || __x86_64
    496 #endif // PIC
     488#endif //PIC
Note: See TracChangeset for help on using the changeset viewer.