Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/interpose.cfa

    r032234bd r9cd5bd2  
    4242
    4343typedef void (* generic_fptr_t)(void);
     44static generic_fptr_t do_interpose_symbol( void * library, const char symbol[], const char version[] ) {
     45        const char * error;
     46
     47        union { generic_fptr_t fptr; void * ptr; } originalFunc;
     48
     49        #if defined( _GNU_SOURCE )
     50                if ( version ) {
     51                        originalFunc.ptr = dlvsym( library, symbol, version );
     52                } else {
     53                        originalFunc.ptr = dlsym( library, symbol );
     54                }
     55        #else
     56                originalFunc.ptr = dlsym( library, symbol );
     57        #endif // _GNU_SOURCE
     58
     59        error = dlerror();
     60        if ( error ) abort( "interpose_symbol : internal error, %s\n", error );
     61
     62        return originalFunc.fptr;
     63}
     64
    4465static generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) {
    4566        const char * error;
    4667
    4768        static void * library;
     69        static void * pthread_library;
    4870        if ( ! library ) {
    4971                #if defined( RTLD_NEXT )
     
    5880                #endif
    5981        } // if
    60 
    61         union { generic_fptr_t fptr; void * ptr; } originalFunc;
    62 
    63         #if defined( _GNU_SOURCE )
    64                 if ( version ) {
    65                         originalFunc.ptr = dlvsym( library, symbol, version );
    66                 } else {
    67                         originalFunc.ptr = dlsym( library, symbol );
    68                 }
    69         #else
    70                 originalFunc.ptr = dlsym( library, symbol );
    71         #endif // _GNU_SOURCE
    72 
    73         error = dlerror();
    74         if ( error ) abort( "interpose_symbol : internal error, %s\n", error );
    75 
    76         return originalFunc.fptr;
     82        if ( ! pthread_library ) {
     83                #if defined( RTLD_NEXT )
     84                        pthread_library = RTLD_NEXT;
     85                #else
     86                        // missing RTLD_NEXT => must hard-code library name, assuming libstdc++
     87                        pthread_library = dlopen( "libpthread.so", RTLD_LAZY );
     88                        error = dlerror();
     89                        if ( error ) {
     90                                abort( "interpose_symbol : failed to open libpthread, %s\n", error );
     91                        }
     92                #endif
     93        } // if
     94
     95        return do_interpose_symbol(library, symbol, version);
    7796}
    7897
     
    97116
    98117extern "C" {
     118        void __cfathreadabi_interpose_startup( generic_fptr_t (*do_interpose_symbol)( void * library, const char symbol[], const char version[] ) ) __attribute__((weak));
    99119        void __cfaabi_interpose_startup( void ) {
    100120                const char *version = 0p;
     
    108128                INTERPOSE_LIBC( exit , version );
    109129#pragma GCC diagnostic pop
     130
     131                if(__cfathreadabi_interpose_startup) __cfathreadabi_interpose_startup( do_interpose_symbol );
    110132
    111133                // As a precaution (and necessity), errors that result in termination are delivered on a separate stack because
Note: See TracChangeset for help on using the changeset viewer.