Alexandre Julliard : preloader: Fix symbol lookup for dynamic libraries.

Alexandre Julliard julliard at winehq.org
Thu Apr 27 15:49:10 CDT 2017


Module: wine
Branch: master
Commit: 60fb3d4b64c3d53101243e81b26ca98bf4d469d9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=60fb3d4b64c3d53101243e81b26ca98bf4d469d9

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Apr 27 15:04:34 2017 +0200

preloader: Fix symbol lookup for dynamic libraries.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 loader/preloader.c | 28 ++++++++++------------------
 1 file changed, 10 insertions(+), 18 deletions(-)

diff --git a/loader/preloader.c b/loader/preloader.c
index 903061e..a21efc9 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" );
 




More information about the wine-cvs mailing list