From: Rémi Bernon rbernon@codeweavers.com
--- loader/main.c | 14 ++++++++++++++ loader/preloader.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+)
diff --git a/loader/main.c b/loader/main.c index 9c364008cc6..6111fa65c87 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__
@@ -170,6 +174,9 @@ void wine_gdb_dll_loaded( const void *module, const char *unix_path, INT_PTR off else entry->map.l_addr = offset;
+ if (wine_rtld_map_start) wine_rtld_map_start(); + if (wine_rtld_map_complete) wine_rtld_map_complete(); + pthread_mutex_unlock( &link_map_lock ); }
@@ -193,6 +200,9 @@ void wine_gdb_dll_unload( const void *module ) if ((prev = entry->map.l_prev)) prev->l_next = entry->map.l_next; if ((next = entry->map.l_next)) next->l_prev = entry->map.l_prev;
+ if (wine_rtld_unmap_start) wine_rtld_unmap_start(); + if (wine_rtld_unmap_complete) wine_rtld_unmap_complete(); + pthread_mutex_unlock( &link_map_lock );
free( entry->map.l_name ); @@ -209,7 +219,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 );
@@ -226,7 +238,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 8e6575733ba..3a32a2ed8a0 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" @@ -1415,7 +1421,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(); }
@@ -1513,6 +1545,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)) );