Changeset eb46fdf


Ignore:
Timestamp:
Dec 12, 2019, 4:06:18 PM (5 years ago)
Author:
Andrew Beach <ajbeach@…>
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
Message:

Clean up in exception.c. Should be no changes to code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/exception.c

    r737c98a reb46fdf  
    6969
    7070
    71 // This macro should be the only thing that needs to change across machines.  Used in the personality function, way down
    72 // 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.
    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?  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.
    106107
    107108void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node,
     
    212213        _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
    213214
    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.
    219221
    220222        if( ret == _URC_END_OF_STACK ) {
    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.
     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.
    223225                printf("Uncaught exception %p\n", &this_exception_storage);
    224226
     
    228230        }
    229231
    230         // We did not simply reach the end of the stack without finding a handler.  Something wen't wrong
     232        // We did not simply reach the end of the stack without finding a handler. This is an error.
    231233        printf("UNWIND ERROR %d after raise exception\n", ret);
    232234        abort();
     
    254256        abort();
    255257}
    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.
    259262_Unwind_Reason_Code __gcfa_personality_v0 (
    260263                int version, _Unwind_Action actions, unsigned long long exceptionClass,
     
    264267
    265268        //__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);
    267271
    268272        // If we've reached the end of the stack then there is nothing much we can do...
     
    291295        // Get the instuction pointer and a reading pointer into the exception table
    292296        lsda_header_info lsd_info;
    293         const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
     297        const unsigned char * cur_ptr = parse_lsda_header(context, lsd, &lsd_info);
    294298        _Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
    295299
     
    302306
    303307                // Decode the common stuff we have in here
    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);
     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);
    308312
    309313                // Have we reach the correct frame info yet?
     
    316320                        void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
    317321                        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);
    319324#endif // __CFA_DEBUG_PRINT__
    320325                        continue;
    321326                }
    322327
    323                 // Have we gone too far
     328                // Have we gone too far?
    324329                if( lsd_info.Start + callsite_start > instruction_ptr ) {
    325330                        printf(" gone too far");
     
    331336                        // Which phase are we in
    332337                        if (actions & _UA_SEARCH_PHASE) {
    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
     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.
    337342                                if (callsite_action != 0) {
    338343                                        // Now we want to run some code to see if the handler matches
     
    351356                                        // The current apprach uses one exception table entry per try block
    352357                                        _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);
    358360
    359361                                        _Unwind_Reason_Code (*matcher)(exception_t *) =
     
    414416}
    415417
    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
     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
    418420__attribute__((noinline))
    419421void __cfaabi_ehm__try_terminate(void (*try_block)(),
     
    428430        // assembly works.
    429431
    430         // Setup the personality routine
     432        // Setup the personality routine and exception table.
    431433        asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
    432         // Setup the exception table
    433434        asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
    434435
     
    442443        asm volatile goto ("" : : : : CATCH );
    443444
    444         // Normal return
     445        // Normal return for when there is no throw.
    445446        return;
    446447
     
    459460}
    460461
    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.
    463465
    464466#if defined( __i386 ) || defined( __x86_64 )
    465467asm (
    466         //HEADER
     468        // HEADER
    467469        ".LFECFA1:\n"
    468470        "       .globl  __gcfa_personality_v0\n"
    469471        "       .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"
    471474        "       .byte   0xff\n"
    472475        "       .byte   0xff\n"
    473476        "       .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"
    483491        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
    484492        "       .ident  \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
     
    486494);
    487495#endif // __i386 || __x86_64
    488 #endif //PIC
     496#endif // PIC
Note: See TracChangeset for help on using the changeset viewer.