preloader: Fix symbol lookup for dynamic libraries.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
45a632ee81
commit
60fb3d4b64
|
@ -945,7 +945,7 @@ static unsigned int gnu_hash( const char *name )
|
||||||
/*
|
/*
|
||||||
* Find a symbol in the symbol table of the executable loaded
|
* 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(Dyn) *dyn = NULL;
|
||||||
const ElfW(Phdr) *ph;
|
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 */
|
/* check the values */
|
||||||
#ifdef DUMP_SYMS
|
#ifdef DUMP_SYMS
|
||||||
wld_printf("%p %x\n", phdr, num );
|
wld_printf("%p %x\n", map->l_phdr, map->l_phnum );
|
||||||
#endif
|
#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 */
|
/* 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 )
|
if( PT_DYNAMIC == ph->p_type )
|
||||||
{
|
{
|
||||||
dyn = (void *) ph->p_vaddr;
|
dyn = (void *)(ph->p_vaddr + map->l_addr);
|
||||||
num = ph->p_memsz / sizeof (*dyn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -980,13 +973,13 @@ static void *find_symbol( const ElfW(Phdr) *phdr, int num, const char *var, int
|
||||||
while( dyn->d_tag )
|
while( dyn->d_tag )
|
||||||
{
|
{
|
||||||
if( dyn->d_tag == DT_STRTAB )
|
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 )
|
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 )
|
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 )
|
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
|
#ifdef DUMP_SYMS
|
||||||
wld_printf("%lx %p\n", (unsigned long)dyn->d_tag, (void *)dyn->d_un.d_ptr );
|
wld_printf("%lx %p\n", (unsigned long)dyn->d_tag, (void *)dyn->d_un.d_ptr );
|
||||||
#endif
|
#endif
|
||||||
|
@ -1036,7 +1029,7 @@ found:
|
||||||
#ifdef DUMP_SYMS
|
#ifdef DUMP_SYMS
|
||||||
wld_printf("Found %s -> %p\n", strings + symtab[idx].st_name, (void *)symtab[idx].st_value );
|
wld_printf("Found %s -> %p\n", strings + symtab[idx].st_name, (void *)symtab[idx].st_value );
|
||||||
#endif
|
#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 );
|
map_so_lib( interp, &ld_so_map );
|
||||||
|
|
||||||
/* store pointer to the preload info into the appropriate main binary variable */
|
/* 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 = find_symbol( &main_binary_map, "wine_main_preload_info", STT_OBJECT );
|
||||||
"wine_main_preload_info", STT_OBJECT );
|
|
||||||
if (wine_main_preload_info) *wine_main_preload_info = preload_info;
|
if (wine_main_preload_info) *wine_main_preload_info = preload_info;
|
||||||
else wld_printf( "wine_main_preload_info not found\n" );
|
else wld_printf( "wine_main_preload_info not found\n" );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue