1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-05 19:35:52 +03:00
2004-02-20  Ulrich Drepper  <drepper@redhat.com>

	* dlfcn/dlsym.c: Get ld.so loading lock before the call into ld.so.
	* dlfcn/dlvsym.c: Likewise.
	* elf/dl-addr.c: Get loading lock while using _dl_loaded data.
	* elf/dl-fini.c: Likewise.
	Patch by Shunichi Sagawa <s-sagawa@jp.fujitsu.com>.
This commit is contained in:
Ulrich Drepper
2004-02-21 01:06:02 +00:00
parent 5990e1fe12
commit a461b14777
5 changed files with 106 additions and 66 deletions

View File

@@ -1,3 +1,11 @@
2004-02-20 Ulrich Drepper <drepper@redhat.com>
* dlfcn/dlsym.c: Get ld.so loading lock before the call into ld.so.
* dlfcn/dlvsym.c: Likewise.
* elf/dl-addr.c: Get loading lock while using _dl_loaded data.
* elf/dl-fini.c: Likewise.
Patch by Shunichi Sagawa <s-sagawa@jp.fujitsu.com>.
2004-02-20 Jakub Jelinek <jakub@redhat.com> 2004-02-20 Jakub Jelinek <jakub@redhat.com>
* sysdeps/sparc/sparc32/fpu/libm-test-ulps: Add ulps for the * sysdeps/sparc/sparc32/fpu/libm-test-ulps: Add ulps for the

View File

@@ -1,5 +1,5 @@
/* Look up a symbol in a shared object loaded by `dlopen'. /* Look up a symbol in a shared object loaded by `dlopen'.
Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. Copyright (C) 1995-2000, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@@ -20,6 +20,8 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <stddef.h> #include <stddef.h>
#include <ldsodefs.h>
struct dlsym_args struct dlsym_args
{ {
/* The arguments to dlsym_doit. */ /* The arguments to dlsym_doit. */
@@ -48,5 +50,12 @@ dlsym (void *handle, const char *name)
args.handle = handle; args.handle = handle;
args.name = name; args.name = name;
return (_dlerror_run (dlsym_doit, &args) ? NULL : args.sym); /* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock));
void *result = (_dlerror_run (dlsym_doit, &args) ? NULL : args.sym);
__rtld_lock_unlock_recursive (GL(dl_load_lock));
return result;
} }

View File

@@ -1,5 +1,5 @@
/* Look up a versioned symbol in a shared object loaded by `dlopen'. /* Look up a versioned symbol in a shared object loaded by `dlopen'.
Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. Copyright (C) 1995-2000, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@@ -20,6 +20,8 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <stddef.h> #include <stddef.h>
#include <ldsodefs.h>
struct dlvsym_args struct dlvsym_args
{ {
/* The arguments to dlvsym_doit. */ /* The arguments to dlvsym_doit. */
@@ -51,6 +53,13 @@ __dlvsym (void *handle, const char *name, const char *version_str)
args.who = RETURN_ADDRESS (0); args.who = RETURN_ADDRESS (0);
args.version = version_str; args.version = version_str;
return (_dlerror_run (dlvsym_doit, &args) ? NULL : args.sym); /* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock));
void *result = (_dlerror_run (dlvsym_doit, &args) ? NULL : args.sym);
__rtld_lock_unlock_recursive (GL(dl_load_lock));
return result;
} }
weak_alias (__dlvsym, dlvsym) weak_alias (__dlvsym, dlvsym)

View File

@@ -1,5 +1,5 @@
/* Locate the shared object symbol nearest a given address. /* Locate the shared object symbol nearest a given address.
Copyright (C) 1996-2000,2001,2002,2003 Free Software Foundation, Inc. Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@@ -33,6 +33,9 @@ _dl_addr (const void *address, Dl_info *info,
const char *strtab; const char *strtab;
ElfW(Word) strtabsize; ElfW(Word) strtabsize;
/* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock));
/* Find the highest-addressed object that ADDRESS is not below. */ /* Find the highest-addressed object that ADDRESS is not below. */
match = NULL; match = NULL;
for (l = GL(dl_loaded); l; l = l->l_next) for (l = GL(dl_loaded); l; l = l->l_next)
@@ -56,9 +59,9 @@ _dl_addr (const void *address, Dl_info *info,
break; break;
} }
if (match == NULL) int result = 0;
return 0; if (match != NULL)
{
/* Now we know what object the address lies in. */ /* Now we know what object the address lies in. */
info->dli_fname = match->l_name; info->dli_fname = match->l_name;
info->dli_fbase = (void *) match->l_map_start; info->dli_fbase = (void *) match->l_map_start;
@@ -74,7 +77,8 @@ _dl_addr (const void *address, Dl_info *info,
strtabsize = match->l_info[DT_STRSZ]->d_un.d_val; strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
if (match->l_info[DT_HASH] != NULL) if (match->l_info[DT_HASH] != NULL)
symtabend = symtab + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]; symtabend = (symtab
+ ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
else else
/* There is no direct way to determine the number of symbols in the /* There is no direct way to determine the number of symbols in the
dynamic symbol table and no hash table is present. The ELF dynamic symbol table and no hash table is present. The ELF
@@ -82,11 +86,13 @@ _dl_addr (const void *address, Dl_info *info,
the string table which generally follows the symbol table. */ the string table which generally follows the symbol table. */
symtabend = (const ElfW(Sym) *) strtab; symtabend = (const ElfW(Sym) *) strtab;
/* We assume that the string table follows the symbol table, because /* We assume that the string table follows the symbol table,
there is no way in ELF to know the size of the dynamic symbol table!! */ because there is no way in ELF to know the size of the
dynamic symbol table!! */
for (matchsym = NULL; (void *) symtab < (void *) symtabend; ++symtab) for (matchsym = NULL; (void *) symtab < (void *) symtabend; ++symtab)
if (addr >= match->l_addr + symtab->st_value if (addr >= match->l_addr + symtab->st_value
&& ((symtab->st_size == 0 && addr == match->l_addr + symtab->st_value) && ((symtab->st_size == 0
&& addr == match->l_addr + symtab->st_value)
|| addr < match->l_addr + symtab->st_value + symtab->st_size) || addr < match->l_addr + symtab->st_value + symtab->st_size)
&& symtab->st_name < strtabsize && symtab->st_name < strtabsize
&& (matchsym == NULL || matchsym->st_value < symtab->st_value) && (matchsym == NULL || matchsym->st_value < symtab->st_value)
@@ -101,7 +107,8 @@ _dl_addr (const void *address, Dl_info *info,
if (matchsym) if (matchsym)
{ {
/* We found a symbol close by. Fill in its name and exact address. */ /* We found a symbol close by. Fill in its name and exact
address. */
info->dli_sname = strtab + matchsym->st_name; info->dli_sname = strtab + matchsym->st_name;
info->dli_saddr = (void *) (match->l_addr + matchsym->st_value); info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
} }
@@ -112,6 +119,11 @@ _dl_addr (const void *address, Dl_info *info,
info->dli_saddr = NULL; info->dli_saddr = NULL;
} }
return 1; result = 1;
}
__rtld_lock_unlock_recursive (GL(dl_load_lock));
return result;
} }
libc_hidden_def (_dl_addr) libc_hidden_def (_dl_addr)

View File

@@ -1,5 +1,5 @@
/* Call the termination functions of loaded shared objects. /* Call the termination functions of loaded shared objects.
Copyright (C) 1995,96,98,99,2000,2001,2002 Free Software Foundation, Inc. Copyright (C) 1995,96,1998-2002,2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@@ -46,6 +46,9 @@ _dl_fini (void)
struct link_map *l; struct link_map *l;
struct link_map **maps; struct link_map **maps;
/* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock));
/* XXX Could it be (in static binaries) that there is no object loaded? */ /* XXX Could it be (in static binaries) that there is no object loaded? */
assert (GL(dl_nloaded) > 0); assert (GL(dl_nloaded) > 0);
@@ -71,7 +74,7 @@ _dl_fini (void)
unsigned int j; unsigned int j;
unsigned int k; unsigned int k;
/* Find the place in the `maps' array. */ /* Find the place in the 'maps' array. */
for (j = 1; maps[j] != l; ++j) for (j = 1; maps[j] != l; ++j)
; ;
@@ -79,9 +82,7 @@ _dl_fini (void)
move the found object (if necessary) in front. */ move the found object (if necessary) in front. */
for (k = j + 1; k < GL(dl_nloaded); ++k) for (k = j + 1; k < GL(dl_nloaded); ++k)
{ {
struct link_map **runp; struct link_map **runp = maps[k]->l_initfini;
runp = maps[k]->l_initfini;
if (runp != NULL) if (runp != NULL)
{ {
while (*runp != NULL) while (*runp != NULL)
@@ -120,13 +121,12 @@ _dl_fini (void)
break; break;
} }
} }
} }
} }
} }
/* `maps' now contains the objects in the right order. Now call the /* 'maps' now contains the objects in the right order. Now call the
destructors. We have to process this array from the front. */ destructors. We have to process this array from the front. */
for (i = 0; i < GL(dl_nloaded); ++i) for (i = 0; i < GL(dl_nloaded); ++i)
{ {
@@ -172,6 +172,8 @@ _dl_fini (void)
--l->l_opencount; --l->l_opencount;
} }
__rtld_lock_unlock_recursive (GL(dl_load_lock));
if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_STATISTICS, 0)) if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
{ {
INTUSE(_dl_debug_printf) ("\nruntime linker statistics:\n"); INTUSE(_dl_debug_printf) ("\nruntime linker statistics:\n");