From 60fb3d4b64c3d53101243e81b26ca98bf4d469d9 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 27 Apr 2017 15:04:34 +0200 Subject: [PATCH] preloader: Fix symbol lookup for dynamic libraries. Signed-off-by: Alexandre Julliard --- loader/preloader.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/loader/preloader.c b/loader/preloader.c index 903061e874e..a21efc95e88 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -945,7 +945,7 @@ static unsigned int gnu_hash( const char *name ) /* * Find a symbol in the symbol table of the executable loaded */ -static void *find_symbol( const ElfW(Phdr) *phdr, int num, const char *var, int type ) +static void *find_symbol( const struct wld_link_map *map, const char *var, int type ) { const ElfW(Dyn) *dyn = NULL; const ElfW(Phdr) *ph; @@ -957,21 +957,14 @@ static void *find_symbol( const ElfW(Phdr) *phdr, int num, const char *var, int /* check the values */ #ifdef DUMP_SYMS - wld_printf("%p %x\n", phdr, num ); + wld_printf("%p %x\n", map->l_phdr, map->l_phnum ); #endif - if( ( phdr == NULL ) || ( num == 0 ) ) - { - wld_printf("could not find PT_DYNAMIC header entry\n"); - return NULL; - } - /* parse the (already loaded) ELF executable's header */ - for (ph = phdr; ph < &phdr[num]; ++ph) + for (ph = map->l_phdr; ph < &map->l_phdr[map->l_phnum]; ++ph) { if( PT_DYNAMIC == ph->p_type ) { - dyn = (void *) ph->p_vaddr; - num = ph->p_memsz / sizeof (*dyn); + dyn = (void *)(ph->p_vaddr + map->l_addr); break; } } @@ -980,13 +973,13 @@ static void *find_symbol( const ElfW(Phdr) *phdr, int num, const char *var, int while( dyn->d_tag ) { if( dyn->d_tag == DT_STRTAB ) - strings = (const char*) dyn->d_un.d_ptr; + strings = (const char*)(dyn->d_un.d_ptr + map->l_addr); if( dyn->d_tag == DT_SYMTAB ) - symtab = (const ElfW(Sym) *)dyn->d_un.d_ptr; + symtab = (const ElfW(Sym) *)(dyn->d_un.d_ptr + map->l_addr); if( dyn->d_tag == DT_HASH ) - hashtab = (const Elf32_Word *)dyn->d_un.d_ptr; + hashtab = (const Elf32_Word *)(dyn->d_un.d_ptr + map->l_addr); if( dyn->d_tag == DT_GNU_HASH ) - gnu_hashtab = (const Elf32_Word *)dyn->d_un.d_ptr; + gnu_hashtab = (const Elf32_Word *)(dyn->d_un.d_ptr + map->l_addr); #ifdef DUMP_SYMS wld_printf("%lx %p\n", (unsigned long)dyn->d_tag, (void *)dyn->d_un.d_ptr ); #endif @@ -1036,7 +1029,7 @@ found: #ifdef DUMP_SYMS wld_printf("Found %s -> %p\n", strings + symtab[idx].st_name, (void *)symtab[idx].st_value ); #endif - return (void *)symtab[idx].st_value; + return (void *)(symtab[idx].st_value + map->l_addr); } /* @@ -1240,8 +1233,7 @@ void* wld_start( void **stack ) map_so_lib( interp, &ld_so_map ); /* store pointer to the preload info into the appropriate main binary variable */ - wine_main_preload_info = find_symbol( main_binary_map.l_phdr, main_binary_map.l_phnum, - "wine_main_preload_info", STT_OBJECT ); + wine_main_preload_info = find_symbol( &main_binary_map, "wine_main_preload_info", STT_OBJECT ); if (wine_main_preload_info) *wine_main_preload_info = preload_info; else wld_printf( "wine_main_preload_info not found\n" );