From: Rémi Bernon rbernon@codeweavers.com
--- loader/main.c | 10 ++++++++++ loader/preloader.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
diff --git a/loader/main.c b/loader/main.c index e82ff7e0060..152f4bf4e0d 100644 --- a/loader/main.c +++ b/loader/main.c @@ -56,6 +56,10 @@ extern char **environ; /* the preloader will set these variables */ const struct wine_preload_info *wine_main_preload_info = NULL; void (*wine_rtld_init)( struct link_map *map ) = NULL; +void (*wine_rtld_map_start)(void) = NULL; +void (*wine_rtld_map_complete)(void) = NULL; +void (*wine_rtld_unmap_start)(void) = NULL; +void (*wine_rtld_unmap_complete)(void) = NULL;
#ifdef __linux__
@@ -175,6 +179,7 @@ void wine_gdb_dll_loaded( const void *module, const char *unix_path ) entry->map.l_addr = (char *)module - (char *)nt->OptionalHeader.ImageBase; }
+ if (wine_rtld_map_start) wine_rtld_map_start(); sync_wine_link_map(); if (wine_rtld_map_complete) wine_rtld_map_complete();
@@ -201,6 +206,7 @@ void wine_gdb_dll_unload( const void *module ) if (entry->map.l_prev) entry->map.l_prev->l_next = entry->map.l_next; if (entry->map.l_next) entry->map.l_next->l_prev = entry->map.l_prev;
+ if (wine_rtld_unmap_start) wine_rtld_unmap_start(); sync_wine_link_map(); if (wine_rtld_unmap_complete) wine_rtld_unmap_complete();
@@ -220,7 +226,9 @@ void *dlopen( const char *file, int mode ) if (!rtld_dlopen) rtld_dlopen = dlsym( RTLD_NEXT, "dlopen" ); ret = rtld_dlopen( file, mode );
+ if (wine_rtld_map_start) wine_rtld_map_start(); sync_wine_link_map(); + if (wine_rtld_map_complete) wine_rtld_map_complete();
pthread_mutex_unlock( &link_map_lock );
@@ -237,7 +245,9 @@ int dlclose( void *handle ) if (!rtld_dlclose) rtld_dlclose = dlsym( RTLD_NEXT, "dlclose" ); ret = rtld_dlclose( handle );
+ if (wine_rtld_unmap_start) wine_rtld_unmap_start(); sync_wine_link_map(); + if (wine_rtld_unmap_complete) wine_rtld_unmap_complete();
pthread_mutex_unlock( &link_map_lock );
diff --git a/loader/preloader.c b/loader/preloader.c index ba146fc712d..3c52a3ebbde 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -85,6 +85,12 @@ #ifdef HAVE_SYS_LINK_H # include <sys/link.h> #endif +#ifdef HAVE_SYS_SDT_H +# include <sys/sdt.h> +#else +# define STAP_PROBE2(a,b,c,d) +# define STAP_PROBE3(a,b,c,d,e) +#endif
#include "wine/asm.h" #include "main.h" @@ -1393,7 +1399,33 @@ static void init_r_debug( struct wld_auxv *av )
void rtld_init( struct link_map *map ) { + STAP_PROBE2( rtld, init_start, LM_ID_BASE, &_r_debug ); _r_debug.r_map = map; + STAP_PROBE2( rtld, init_complete, LM_ID_BASE, &_r_debug ); + _dl_debug_state(); +} + +void rtld_map_start(void) +{ + STAP_PROBE2( rtld, map_start, LM_ID_BASE, &_r_debug ); +} + +void rtld_map_complete(void) +{ + STAP_PROBE3( rtld, map_complete, LM_ID_BASE, &_r_debug, NULL ); + STAP_PROBE2( rtld, reloc_start, LM_ID_BASE, &_r_debug ); + STAP_PROBE3( rtld, reloc_complete, LM_ID_BASE, &_r_debug, NULL ); + _dl_debug_state(); +} + +void rtld_unmap_start(void) +{ + STAP_PROBE2( rtld, unmap_start, LM_ID_BASE, &_r_debug ); +} + +void rtld_unmap_complete(void) +{ + STAP_PROBE2( rtld, unmap_complete, LM_ID_BASE, &_r_debug ); _dl_debug_state(); }
@@ -1491,6 +1523,20 @@ void* wld_start( void **stack ) if (rtld_probe) *rtld_probe = rtld_init; else wld_printf( "wine_rtld_init not found\n" );
+ rtld_probe = find_symbol( &main_binary_map, "wine_rtld_map_start", STT_OBJECT ); + if (rtld_probe) *rtld_probe = rtld_map_start; + else wld_printf( "wine_rtld_map_start not found\n" ); + rtld_probe = find_symbol( &main_binary_map, "wine_rtld_map_complete", STT_OBJECT ); + if (rtld_probe) *rtld_probe = rtld_map_complete; + else wld_printf( "wine_rtld_map_complete not found\n" ); + + rtld_probe = find_symbol( &main_binary_map, "wine_rtld_unmap_start", STT_OBJECT ); + if (rtld_probe) *rtld_probe = rtld_unmap_start; + else wld_printf( "wine_rtld_unmap_start not found\n" ); + rtld_probe = find_symbol( &main_binary_map, "wine_rtld_unmap_complete", STT_OBJECT ); + if (rtld_probe) *rtld_probe = rtld_unmap_complete; + else wld_printf( "wine_rtld_unmap_complete not found\n" ); + #define SET_NEW_AV(n,type,val) new_av[n].a_type = (type); new_av[n].a_un.a_val = (val); SET_NEW_AV( 0, AT_PHDR, (unsigned long)main_binary_map.l_phdr ); SET_NEW_AV( 1, AT_PHENT, sizeof(ElfW(Phdr)) );