Ignore:
Timestamp:
Feb 20, 2020, 4:15:51 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
6a490b2
Parents:
dca5802 (diff), 2cbfe92 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into relaxed_ready

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/exception.c

    rdca5802 rb7d6a36  
    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();
     
    246248}
    247249
    248 #if defined(PIC)
    249 #warning Exceptions not yet supported when using Position-Independent Code
    250 __attribute__((noinline))
    251 void __cfaabi_ehm__try_terminate(void (*try_block)(),
    252                 void (*catch_block)(int index, exception_t * except),
    253                 __attribute__((unused)) int (*match_block)(exception_t * except)) {
    254         abort();
    255 }
    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.
     250#pragma GCC push_options
     251#pragma GCC optimize("O0")
     252
     253// This is our personality routine. For every stack frame annotated with
     254// ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding.
     255//  Once in the search phase and once in the cleanup phase.
    259256_Unwind_Reason_Code __gcfa_personality_v0 (
    260257                int version, _Unwind_Action actions, unsigned long long exceptionClass,
     
    264261
    265262        //__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);
     263        __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):",
     264                        version, actions, exceptionClass, unwind_exception, context);
    267265
    268266        // If we've reached the end of the stack then there is nothing much we can do...
     
    291289        // Get the instuction pointer and a reading pointer into the exception table
    292290        lsda_header_info lsd_info;
    293         const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
     291        const unsigned char * cur_ptr = parse_lsda_header(context, lsd, &lsd_info);
    294292        _Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
    295293
     
    302300
    303301                // 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);
     302                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
     303                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
     304                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
     305                cur_ptr = read_uleb128(cur_ptr, &callsite_action);
    308306
    309307                // Have we reach the correct frame info yet?
     
    316314                        void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
    317315                        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);
     316                        __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n",
     317                                        bp, ep, ls, cs, cl, ip);
    319318#endif // __CFA_DEBUG_PRINT__
    320319                        continue;
    321320                }
    322321
    323                 // Have we gone too far
     322                // Have we gone too far?
    324323                if( lsd_info.Start + callsite_start > instruction_ptr ) {
    325324                        printf(" gone too far");
     
    331330                        // Which phase are we in
    332331                        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
     332                                // In search phase, these means we found a potential handler we must check.
     333
     334                                // We have arbitrarily decided that 0 means nothing to do and 1 means there is
     335                                // a potential handler. This doesn't seem to conflict the gcc default behavior.
    337336                                if (callsite_action != 0) {
    338337                                        // Now we want to run some code to see if the handler matches
     
    351350                                        // The current apprach uses one exception table entry per try block
    352351                                        _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;
     352                                        // Get the relative offset to the {...}?
     353                                        cur_ptr = read_uleb128(cur_ptr, &imatcher);
    358354
    359355                                        _Unwind_Reason_Code (*matcher)(exception_t *) =
     
    414410}
    415411
    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
     412// Try statements are hoisted out see comments for details. While this could probably be unique
     413// and simply linked from libcfa but there is one problem left, see the exception table for details
    418414__attribute__((noinline))
    419415void __cfaabi_ehm__try_terminate(void (*try_block)(),
     
    428424        // assembly works.
    429425
    430         // Setup the personality routine
     426        // Setup the personality routine and exception table.
     427#ifdef __PIC__
     428        asm volatile (".cfi_personality 0x9b,CFA.ref.__gcfa_personality_v0");
     429        asm volatile (".cfi_lsda 0x1b, .LLSDACFA2");
     430#else
    431431        asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
    432         // Setup the exception table
    433432        asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
     433#endif
    434434
    435435        // Label which defines the start of the area for which the handler is setup.
     
    442442        asm volatile goto ("" : : : : CATCH );
    443443
    444         // Normal return
     444        // Normal return for when there is no throw.
    445445        return;
    446446
     
    459459}
    460460
    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.
    463 
     461// Exception table data we need to generate. While this is almost generic, the custom data refers
     462// to {*}try_terminate, which is no way generic. Some more works need to be done if we want to
     463// have a single call to the try routine.
     464
     465#ifdef __PIC__
    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        // This uses language specific data and can be modified arbitrarily
     480        // We use handled area offset, handled area length,
     481        // handler landing pad offset and 1 (action code, gcc seems to use 0).
     482        ".LLSDACSBCFA2:\n"
     483        "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"
     484        "       .uleb128 .TRYEND-.TRYSTART\n"
     485        "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"
     486        "       .uleb128 1\n"
     487        ".LLSDACSECFA2:\n"
     488        // TABLE FOOTER
     489        "       .text\n"
     490        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
     491);
     492
     493// Somehow this piece of helps with the resolution of debug symbols.
     494__attribute__((unused)) static const int dummy = 0;
     495
     496asm (
     497        // Add a hidden symbol which points at the function.
     498        "       .hidden CFA.ref.__gcfa_personality_v0\n"
     499        "       .weak   CFA.ref.__gcfa_personality_v0\n"
     500        // No clue what this does specifically
     501        "       .section        .data.rel.local.CFA.ref.__gcfa_personality_v0,\"awG\",@progbits,CFA.ref.__gcfa_personality_v0,comdat\n"
     502        "       .align 8\n"
     503        "       .type CFA.ref.__gcfa_personality_v0, @object\n"
     504        "       .size CFA.ref.__gcfa_personality_v0, 8\n"
     505        "CFA.ref.__gcfa_personality_v0:\n"
     506#if defined( __x86_64 )
     507        "       .quad __gcfa_personality_v0\n"
     508#else // then __i386
     509        "   .long __gcfa_personality_v0\n"
     510#endif
     511);
     512#else
     513#error Exception Handling: unknown architecture for position independent code.
     514#endif // __i386 || __x86_64
     515#else // __PIC__
     516#if defined( __i386 ) || defined( __x86_64 )
     517asm (
     518        // HEADER
     519        ".LFECFA1:\n"
     520        "       .globl  __gcfa_personality_v0\n"
     521        "       .section        .gcc_except_table,\"a\",@progbits\n"
     522        // TABLE HEADER (important field is the BODY length at the end)
     523        ".LLSDACFA2:\n"
     524        "       .byte   0xff\n"
     525        "       .byte   0xff\n"
     526        "       .byte   0x1\n"
     527        "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"
     528        // BODY (language specific data)
     529        ".LLSDACSBCFA2:\n"
     530        //      Handled area start (relative to start of function)
     531        "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"
     532        //      Handled area length
     533        "       .uleb128 .TRYEND-.TRYSTART\n"
     534        //      Handler landing pad address (relative to start of function)
     535        "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"
     536        //      Action code, gcc seems to always use 0.
     537        "       .uleb128 1\n"
     538        // TABLE FOOTER
     539        ".LLSDACSECFA2:\n"
     540        "       .text\n"
    483541        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
    484542        "       .ident  \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
    485 //      "       .section        .note.GNU-stack,\"x\",@progbits\n"
     543        "       .section        .note.GNU-stack,\"x\",@progbits\n"
    486544);
     545#else
     546#error Exception Handling: unknown architecture for position dependent code.
    487547#endif // __i386 || __x86_64
    488 #endif //PIC
     548#endif // __PIC__
     549
     550#pragma GCC pop_options
Note: See TracChangeset for help on using the changeset viewer.