1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

* elf/dl-lookup.c (_dl_debug_bindings): Remove unised symbol_scope

argument.
	(_dl_lookup_symbol_x): Adjust caller.

	* sysdeps/generic/ldsodefs.h (struct link_namespaces): Remove
	_ns_global_scope.
	* elf/rtld.c (dl_main): Don't initialize _ns_global_scope.

	* elf/dl-libc.c: Revert l_scope name changes.
	* elf/dl-load.c: Likewise.
	* elf/dl-object.c: Likewise.
	* elf/rtld.c: Likewise.
	* elf/dl-close.c (_dl_close): Likewise.
	* elf/dl-open.c (dl_open_worker): Likewise.  If not SINGLE_THREAD_P,
	always use __rtld_mrlock_{change,done}.  Always free old scope list
	here if not l_scope_mem.
	* elf/dl-runtime.c (_dl_fixup, _dl_profile_fixup): Revert l_scope name
	change.  Never free scope list here.  Just __rtld_mrlock_lock before
	the lookup and __rtld_mrlock_unlock it after the lookup.
	* elf/dl-sym.c: Likewise.
	* include/link.h (struct r_scoperec): Remove.
	(struct link_map): Replace l_scoperec with l_scope, l_scoperec_mem
	with l_scope_mem and l_scoperec_lock with l_scope_lock.
This commit is contained in:
Ulrich Drepper
2006-10-27 15:54:20 +00:00
parent ee96ce2fca
commit c0a777e8d0
25 changed files with 229 additions and 201 deletions

View File

@ -1,3 +1,29 @@
2006-10-27 Jakub Jelinek <jakub@redhat.com>
* elf/dl-lookup.c (_dl_debug_bindings): Remove unised symbol_scope
argument.
(_dl_lookup_symbol_x): Adjust caller.
* sysdeps/generic/ldsodefs.h (struct link_namespaces): Remove
_ns_global_scope.
* elf/rtld.c (dl_main): Don't initialize _ns_global_scope.
* elf/dl-libc.c: Revert l_scope name changes.
* elf/dl-load.c: Likewise.
* elf/dl-object.c: Likewise.
* elf/rtld.c: Likewise.
* elf/dl-close.c (_dl_close): Likewise.
* elf/dl-open.c (dl_open_worker): Likewise. If not SINGLE_THREAD_P,
always use __rtld_mrlock_{change,done}. Always free old scope list
here if not l_scope_mem.
* elf/dl-runtime.c (_dl_fixup, _dl_profile_fixup): Revert l_scope name
change. Never free scope list here. Just __rtld_mrlock_lock before
the lookup and __rtld_mrlock_unlock it after the lookup.
* elf/dl-sym.c: Likewise.
* include/link.h (struct r_scoperec): Remove.
(struct link_map): Replace l_scoperec with l_scope, l_scoperec_mem
with l_scope_mem and l_scoperec_lock with l_scope_lock.
2006-10-25 Ulrich Drepper <drepper@redhat.com> 2006-10-25 Ulrich Drepper <drepper@redhat.com>
* sysdeps/gnu/netinet/tcp.h: Define TCP_CONGESTION. * sysdeps/gnu/netinet/tcp.h: Define TCP_CONGESTION.

View File

@ -343,14 +343,14 @@ _dl_close (void *_map)
one for the terminating NULL pointer. */ one for the terminating NULL pointer. */
size_t remain = (new_list != NULL) + 1; size_t remain = (new_list != NULL) + 1;
bool removed_any = false; bool removed_any = false;
for (size_t cnt = 0; imap->l_scoperec->scope[cnt] != NULL; ++cnt) for (size_t cnt = 0; imap->l_scope[cnt] != NULL; ++cnt)
/* This relies on l_scope[] entries being always set either /* This relies on l_scope[] entries being always set either
to its own l_symbolic_searchlist address, or some map's to its own l_symbolic_searchlist address, or some map's
l_searchlist address. */ l_searchlist address. */
if (imap->l_scoperec->scope[cnt] != &imap->l_symbolic_searchlist) if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
{ {
struct link_map *tmap = (struct link_map *) struct link_map *tmap = (struct link_map *)
((char *) imap->l_scoperec->scope[cnt] ((char *) imap->l_scope[cnt]
- offsetof (struct link_map, l_searchlist)); - offsetof (struct link_map, l_searchlist));
assert (tmap->l_ns == ns); assert (tmap->l_ns == ns);
if (tmap->l_idx == IDX_STILL_USED) if (tmap->l_idx == IDX_STILL_USED)
@ -368,38 +368,35 @@ _dl_close (void *_map)
user of the current array. If possible use the link map's user of the current array. If possible use the link map's
memory. */ memory. */
size_t new_size; size_t new_size;
struct r_scoperec *newp; struct r_scope_elem **newp;
if (imap->l_scoperec != &imap->l_scoperec_mem
&& remain < NINIT_SCOPE_ELEMS (imap) #define SCOPE_ELEMS(imap) \
&& imap->l_scoperec_mem.nusers == 0) (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))
if (imap->l_scope != imap->l_scope_mem
&& remain < SCOPE_ELEMS (imap))
{ {
new_size = NINIT_SCOPE_ELEMS (imap); new_size = SCOPE_ELEMS (imap);
newp = &imap->l_scoperec_mem; newp = imap->l_scope_mem;
} }
else else
{ {
new_size = imap->l_scope_max; new_size = imap->l_scope_max;
newp = (struct r_scoperec *) newp = (struct r_scope_elem **)
malloc (sizeof (struct r_scoperec) malloc (new_size * sizeof (struct r_scope_elem *));
+ new_size * sizeof (struct r_scope_elem *));
if (newp == NULL) if (newp == NULL)
_dl_signal_error (ENOMEM, "dlclose", NULL, _dl_signal_error (ENOMEM, "dlclose", NULL,
N_("cannot create scope list")); N_("cannot create scope list"));
} }
newp->nusers = 0;
newp->remove_after_use = false;
newp->notify = false;
/* Copy over the remaining scope elements. */ /* Copy over the remaining scope elements. */
remain = 0; remain = 0;
for (size_t cnt = 0; imap->l_scoperec->scope[cnt] != NULL; ++cnt) for (size_t cnt = 0; imap->l_scope[cnt] != NULL; ++cnt)
{ {
if (imap->l_scoperec->scope[cnt] if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
!= &imap->l_symbolic_searchlist)
{ {
struct link_map *tmap = (struct link_map *) struct link_map *tmap = (struct link_map *)
((char *) imap->l_scoperec->scope[cnt] ((char *) imap->l_scope[cnt]
- offsetof (struct link_map, l_searchlist)); - offsetof (struct link_map, l_searchlist));
if (tmap->l_idx != IDX_STILL_USED) if (tmap->l_idx != IDX_STILL_USED)
{ {
@ -407,38 +404,30 @@ _dl_close (void *_map)
scope. */ scope. */
if (new_list != NULL) if (new_list != NULL)
{ {
newp->scope[remain++] = new_list; newp[remain++] = new_list;
new_list = NULL; new_list = NULL;
} }
continue; continue;
} }
} }
newp->scope[remain++] = imap->l_scoperec->scope[cnt]; newp[remain++] = imap->l_scope[cnt];
} }
newp->scope[remain] = NULL; newp[remain] = NULL;
struct r_scoperec *old = imap->l_scoperec; struct r_scope_elem **old = imap->l_scope;
if (SINGLE_THREAD_P) if (SINGLE_THREAD_P)
imap->l_scoperec = newp; imap->l_scope = newp;
else else
{ {
__rtld_mrlock_change (imap->l_scoperec_lock); __rtld_mrlock_change (imap->l_scope_lock);
imap->l_scoperec = newp; imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scoperec_lock); __rtld_mrlock_done (imap->l_scope_lock);
if (atomic_increment_val (&old->nusers) != 1)
{
old->remove_after_use = true;
old->notify = true;
if (atomic_decrement_val (&old->nusers) != 0)
__rtld_waitzero (old->nusers);
}
} }
/* No user anymore, we can free it now. */ /* No user anymore, we can free it now. */
if (old != &imap->l_scoperec_mem) if (old != imap->l_scope_mem)
free (old); free (old);
imap->l_scope_max = new_size; imap->l_scope_max = new_size;
@ -652,8 +641,8 @@ _dl_close (void *_map)
free (imap->l_initfini); free (imap->l_initfini);
/* Remove the scope array if we allocated it. */ /* Remove the scope array if we allocated it. */
if (imap->l_scoperec != &imap->l_scoperec_mem) if (imap->l_scope != imap->l_scope_mem)
free (imap->l_scoperec); free (imap->l_scope);
if (imap->l_phdr_allocated) if (imap->l_phdr_allocated)
free ((void *) imap->l_phdr); free ((void *) imap->l_phdr);

View File

@ -133,8 +133,7 @@ do_dlsym_private (void *ptr)
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr; struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
args->ref = NULL; args->ref = NULL;
l = GLRO(dl_lookup_symbol_x) (args->name, args->map, &args->ref, l = GLRO(dl_lookup_symbol_x) (args->name, args->map, &args->ref,
args->map->l_scoperec->scope, &vers, 0, 0, args->map->l_scope, &vers, 0, 0, NULL);
NULL);
args->loadbase = l; args->loadbase = l;
} }

View File

@ -1473,7 +1473,7 @@ cannot enable executable stack as shared object requires");
have to do this for the main map. */ have to do this for the main map. */
if ((mode & RTLD_DEEPBIND) == 0 if ((mode & RTLD_DEEPBIND) == 0
&& __builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0) && __builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
&& &l->l_searchlist != l->l_scoperec->scope[0]) && &l->l_searchlist != l->l_scope[0])
{ {
/* Create an appropriate searchlist. It contains only this map. /* Create an appropriate searchlist. It contains only this map.
This is the definition of DT_SYMBOLIC in SysVr4. */ This is the definition of DT_SYMBOLIC in SysVr4. */
@ -1490,11 +1490,11 @@ cannot enable executable stack as shared object requires");
l->l_symbolic_searchlist.r_nlist = 1; l->l_symbolic_searchlist.r_nlist = 1;
/* Now move the existing entries one back. */ /* Now move the existing entries one back. */
memmove (&l->l_scoperec->scope[1], &l->l_scoperec->scope[0], memmove (&l->l_scope[1], &l->l_scope[0],
(l->l_scope_max - 1) * sizeof (l->l_scoperec->scope[0])); (l->l_scope_max - 1) * sizeof (l->l_scope[0]));
/* Now add the new entry. */ /* Now add the new entry. */
l->l_scoperec->scope[0] = &l->l_symbolic_searchlist; l->l_scope[0] = &l->l_symbolic_searchlist;
} }
/* Remember whether this object must be initialized first. */ /* Remember whether this object must be initialized first. */

View File

@ -200,8 +200,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
static void static void
internal_function internal_function
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map, _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], const ElfW(Sym) **ref, struct sym_val *value,
struct sym_val *value,
const struct r_found_version *version, int type_class, const struct r_found_version *version, int type_class,
int protected); int protected);
@ -351,7 +350,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
if (__builtin_expect (GLRO(dl_debug_mask) if (__builtin_expect (GLRO(dl_debug_mask)
& (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0)) & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
_dl_debug_bindings (undef_name, undef_map, ref, symbol_scope, _dl_debug_bindings (undef_name, undef_map, ref,
&current_value, version, type_class, protected); &current_value, version, type_class, protected);
*ref = current_value.s; *ref = current_value.s;
@ -408,8 +407,7 @@ _dl_setup_hash (struct link_map *map)
static void static void
internal_function internal_function
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map, _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], const ElfW(Sym) **ref, struct sym_val *value,
struct sym_val *value,
const struct r_found_version *version, int type_class, const struct r_found_version *version, int type_class,
int protected) int protected)
{ {

View File

@ -82,13 +82,12 @@ _dl_new_object (char *realname, const char *libname, int type,
/* Use the 'l_scope_mem' array by default for the the 'l_scope' /* Use the 'l_scope_mem' array by default for the the 'l_scope'
information. If we need more entries we will allocate a large information. If we need more entries we will allocate a large
array dynamically. */ array dynamically. */
new->l_scoperec = &new->l_scoperec_mem; new->l_scope = new->l_scope_mem;
new->l_scope_max = (sizeof (new->l_scope_realmem.scope_elems) new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
/ sizeof (new->l_scope_realmem.scope_elems[0]));
/* No need to initialize the scope lock if the initializer is zero. */ /* No need to initialize the scope lock if the initializer is zero. */
#if _RTLD_MRLOCK_INITIALIZER != 0 #if _RTLD_MRLOCK_INITIALIZER != 0
__rtld_mrlock_initialize (new->l_scoperec_mem.lock); __rtld_mrlock_initialize (new->l_scope_lock);
#endif #endif
/* Counter for the scopes we have to handle. */ /* Counter for the scopes we have to handle. */
@ -104,8 +103,7 @@ _dl_new_object (char *realname, const char *libname, int type,
l->l_next = new; l->l_next = new;
/* Add the global scope. */ /* Add the global scope. */
new->l_scoperec->scope[idx++] new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
= &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
} }
else else
GL(dl_ns)[nsid]._ns_loaded = new; GL(dl_ns)[nsid]._ns_loaded = new;
@ -121,15 +119,15 @@ _dl_new_object (char *realname, const char *libname, int type,
loader = loader->l_loader; loader = loader->l_loader;
/* Insert the scope if it isn't the global scope we already added. */ /* Insert the scope if it isn't the global scope we already added. */
if (idx == 0 || &loader->l_searchlist != new->l_scoperec->scope[0]) if (idx == 0 || &loader->l_searchlist != new->l_scope[0])
{ {
if ((mode & RTLD_DEEPBIND) != 0 && idx != 0) if ((mode & RTLD_DEEPBIND) != 0 && idx != 0)
{ {
new->l_scoperec->scope[1] = new->l_scoperec->scope[0]; new->l_scope[1] = new->l_scope[0];
idx = 0; idx = 0;
} }
new->l_scoperec->scope[idx] = &loader->l_searchlist; new->l_scope[idx] = &loader->l_searchlist;
} }
new->l_local_scope[0] = &new->l_searchlist; new->l_local_scope[0] = &new->l_searchlist;

View File

@ -344,7 +344,7 @@ dl_open_worker (void *a)
start the profiling. */ start the profiling. */
struct link_map *old_profile_map = GL(dl_profile_map); struct link_map *old_profile_map = GL(dl_profile_map);
_dl_relocate_object (l, l->l_scoperec->scope, 1, 1); _dl_relocate_object (l, l->l_scope, 1, 1);
if (old_profile_map == NULL && GL(dl_profile_map) != NULL) if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
{ {
@ -357,7 +357,7 @@ dl_open_worker (void *a)
} }
else else
#endif #endif
_dl_relocate_object (l, l->l_scoperec->scope, lazy, 0); _dl_relocate_object (l, l->l_scope, lazy, 0);
} }
if (l == new) if (l == new)
@ -375,7 +375,7 @@ dl_open_worker (void *a)
not been loaded here and now. */ not been loaded here and now. */
if (imap->l_init_called && imap->l_type == lt_loaded) if (imap->l_init_called && imap->l_type == lt_loaded)
{ {
struct r_scope_elem **runp = imap->l_scoperec->scope; struct r_scope_elem **runp = imap->l_scope;
size_t cnt = 0; size_t cnt = 0;
while (*runp != NULL) while (*runp != NULL)
@ -395,62 +395,51 @@ dl_open_worker (void *a)
/* The 'r_scope' array is too small. Allocate a new one /* The 'r_scope' array is too small. Allocate a new one
dynamically. */ dynamically. */
size_t new_size; size_t new_size;
struct r_scoperec *newp; struct r_scope_elem **newp;
if (imap->l_scoperec != &imap->l_scoperec_mem #define SCOPE_ELEMS(imap) \
&& imap->l_scope_max < NINIT_SCOPE_ELEMS (imap) (sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))
&& imap->l_scoperec_mem.nusers == 0)
if (imap->l_scope != imap->l_scope_mem
&& imap->l_scope_max < SCOPE_ELEMS (imap))
{ {
new_size = NINIT_SCOPE_ELEMS (imap); new_size = SCOPE_ELEMS (imap);
newp = &imap->l_scoperec_mem; newp = imap->l_scope_mem;
} }
else else
{ {
new_size = imap->l_scope_max * 2; new_size = imap->l_scope_max * 2;
newp = (struct r_scoperec *) newp = (struct r_scope_elem **)
malloc (sizeof (struct r_scoperec) malloc (new_size * sizeof (struct r_scope_elem *));
+ new_size * sizeof (struct r_scope_elem *));
if (newp == NULL) if (newp == NULL)
_dl_signal_error (ENOMEM, "dlopen", NULL, _dl_signal_error (ENOMEM, "dlopen", NULL,
N_("cannot create scope list")); N_("cannot create scope list"));
} }
newp->nusers = 0; memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0]));
newp->remove_after_use = false; struct r_scope_elem **old = imap->l_scope;
newp->notify = false;
memcpy (newp->scope, imap->l_scoperec->scope,
cnt * sizeof (imap->l_scoperec->scope[0]));
struct r_scoperec *old = imap->l_scoperec;
if (old == &imap->l_scoperec_mem) if (SINGLE_THREAD_P)
imap->l_scoperec = newp; imap->l_scope = newp;
else if (SINGLE_THREAD_P)
{
imap->l_scoperec = newp;
free (old);
}
else else
{ {
__rtld_mrlock_change (imap->l_scoperec_lock); __rtld_mrlock_change (imap->l_scope_lock);
imap->l_scoperec = newp; imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scoperec_lock); __rtld_mrlock_done (imap->l_scope_lock);
atomic_increment (&old->nusers);
old->remove_after_use = true;
if (atomic_decrement_val (&old->nusers) == 0)
/* No user, we can free it here and now. */
free (old);
} }
if (old != imap->l_scope_mem)
free (old);
imap->l_scope_max = new_size; imap->l_scope_max = new_size;
} }
/* First terminate the extended list. Otherwise a thread /* First terminate the extended list. Otherwise a thread
might use the new last element and then use the garbage might use the new last element and then use the garbage
at offset IDX+1. */ at offset IDX+1. */
imap->l_scoperec->scope[cnt + 1] = NULL; imap->l_scope[cnt + 1] = NULL;
atomic_write_barrier (); atomic_write_barrier ();
imap->l_scoperec->scope[cnt] = &new->l_searchlist; imap->l_scope[cnt] = &new->l_searchlist;
} }
#if USE_TLS #if USE_TLS
/* Only add TLS memory if this object is loaded now and /* Only add TLS memory if this object is loaded now and

View File

@ -93,29 +93,15 @@ _dl_fixup (
version = NULL; version = NULL;
} }
struct r_scoperec *scoperec = l->l_scoperec;
if (l->l_type == lt_loaded && !SINGLE_THREAD_P) if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
{ __rtld_mrlock_lock (l->l_scope_lock);
__rtld_mrlock_lock (l->l_scoperec_lock);
scoperec = l->l_scoperec;
atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (l->l_scoperec_lock);
}
result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
scoperec->scope, version, l->l_scope, version, ELF_RTYPE_CLASS_PLT,
ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL); DL_LOOKUP_ADD_DEPENDENCY, NULL);
if (l->l_type == lt_loaded && !SINGLE_THREAD_P if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
&& atomic_decrement_val (&scoperec->nusers) == 0 __rtld_mrlock_unlock (l->l_scope_lock);
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)
__rtld_notify (scoperec->nusers);
else
free (scoperec);
}
/* Currently result contains the base load address (or link map) /* Currently result contains the base load address (or link map)
of the object that defines sym. Now add in the symbol of the object that defines sym. Now add in the symbol
@ -195,29 +181,16 @@ _dl_profile_fixup (
version = NULL; version = NULL;
} }
struct r_scoperec *scoperec = l->l_scoperec;
if (l->l_type == lt_loaded && !SINGLE_THREAD_P) if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
{ __rtld_mrlock_lock (l->l_scope_lock);
__rtld_mrlock_lock (l->l_scoperec_lock);
scoperec = l->l_scoperec;
atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (l->l_scoperec_lock);
}
result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym, result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym,
scoperec->scope, version, l->l_scope, version,
ELF_RTYPE_CLASS_PLT, ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL); DL_LOOKUP_ADD_DEPENDENCY, NULL);
if (l->l_type == lt_loaded && !SINGLE_THREAD_P if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
&& atomic_decrement_val (&scoperec->nusers) == 0 __rtld_mrlock_unlock (l->l_scope_lock);
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)
__rtld_notify (scoperec->nusers);
else
free (scoperec);
}
/* Currently result contains the base load address (or link map) /* Currently result contains the base load address (or link map)
of the object that defines sym. Now add in the symbol of the object that defines sym. Now add in the symbol

View File

@ -65,7 +65,6 @@ struct call_dl_lookup_args
/* Arguments to do_dlsym. */ /* Arguments to do_dlsym. */
struct link_map *map; struct link_map *map;
const char *name; const char *name;
struct r_scope_elem **scope;
struct r_found_version *vers; struct r_found_version *vers;
int flags; int flags;
@ -79,7 +78,7 @@ call_dl_lookup (void *ptr)
{ {
struct call_dl_lookup_args *args = (struct call_dl_lookup_args *) ptr; struct call_dl_lookup_args *args = (struct call_dl_lookup_args *) ptr;
args->map = GLRO(dl_lookup_symbol_x) (args->name, args->map, args->refp, args->map = GLRO(dl_lookup_symbol_x) (args->name, args->map, args->refp,
args->scope, args->vers, 0, args->map->l_scope, args->vers, 0,
args->flags, NULL); args->flags, NULL);
} }
@ -118,20 +117,16 @@ do_sym (void *handle, const char *name, void *who,
array can change. */ array can change. */
if (match->l_type != lt_loaded || SINGLE_THREAD_P) if (match->l_type != lt_loaded || SINGLE_THREAD_P)
result = GLRO(dl_lookup_symbol_x) (name, match, &ref, result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
match->l_scoperec->scope, vers, 0, match->l_scope, vers, 0,
flags | DL_LOOKUP_ADD_DEPENDENCY, flags | DL_LOOKUP_ADD_DEPENDENCY,
NULL); NULL);
else else
{ {
__rtld_mrlock_lock (match->l_scoperec_lock); __rtld_mrlock_lock (match->l_scope_lock);
struct r_scoperec *scoperec = match->l_scoperec;
atomic_increment (&scoperec->nusers);
__rtld_mrlock_unlock (match->l_scoperec_lock);
struct call_dl_lookup_args args; struct call_dl_lookup_args args;
args.name = name; args.name = name;
args.map = match; args.map = match;
args.scope = scoperec->scope;
args.vers = vers; args.vers = vers;
args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY; args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY;
args.refp = &ref; args.refp = &ref;
@ -142,14 +137,7 @@ do_sym (void *handle, const char *name, void *who,
int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced, int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
call_dl_lookup, &args); call_dl_lookup, &args);
if (atomic_decrement_val (&scoperec->nusers) == 0 __rtld_mrlock_unlock (match->l_scope_lock);
&& __builtin_expect (scoperec->remove_after_use, 0))
{
if (scoperec->notify)
__rtld_notify (scoperec->nusers);
else
free (scoperec);
}
if (__builtin_expect (errstring != NULL, 0)) if (__builtin_expect (errstring != NULL, 0))
{ {

View File

@ -609,7 +609,7 @@ relocate_doit (void *a)
{ {
struct relocate_args *args = (struct relocate_args *) a; struct relocate_args *args = (struct relocate_args *) a;
_dl_relocate_object (args->l, args->l->l_scoperec->scope, args->lazy, 0); _dl_relocate_object (args->l, args->l->l_scope, args->lazy, 0);
} }
static void static void
@ -1963,7 +1963,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
lookup_t result; lookup_t result;
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map, result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map,
&ref, main_map->l_scoperec->scope, &ref, main_map->l_scope,
NULL, ELF_RTYPE_CLASS_PLT, NULL, ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL); DL_LOOKUP_ADD_DEPENDENCY, NULL);
@ -2007,7 +2007,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
/* Mark the link map as not yet relocated again. */ /* Mark the link map as not yet relocated again. */
GL(dl_rtld_map).l_relocated = 0; GL(dl_rtld_map).l_relocated = 0;
_dl_relocate_object (&GL(dl_rtld_map), _dl_relocate_object (&GL(dl_rtld_map),
main_map->l_scoperec->scope, 0, 0); main_map->l_scope, 0, 0);
} }
} }
#define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
@ -2143,7 +2143,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
/* Now set up the variable which helps the assembler startup code. */ /* Now set up the variable which helps the assembler startup code. */
GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist; GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist;
GL(dl_ns)[LM_ID_BASE]._ns_global_scope[0] = &main_map->l_searchlist;
/* Save the information about the original global scope list since /* Save the information about the original global scope list since
we need it in the memory handling later. */ we need it in the memory handling later. */
@ -2227,7 +2226,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
} }
if (l != &GL(dl_rtld_map)) if (l != &GL(dl_rtld_map))
_dl_relocate_object (l, l->l_scoperec->scope, GLRO(dl_lazy), _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy),
consider_profiling); consider_profiling);
#ifdef USE_TLS #ifdef USE_TLS
@ -2303,8 +2302,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
HP_TIMING_NOW (start); HP_TIMING_NOW (start);
/* Mark the link map as not yet relocated again. */ /* Mark the link map as not yet relocated again. */
GL(dl_rtld_map).l_relocated = 0; GL(dl_rtld_map).l_relocated = 0;
_dl_relocate_object (&GL(dl_rtld_map), main_map->l_scoperec->scope, _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
0, 0);
HP_TIMING_NOW (stop); HP_TIMING_NOW (stop);
HP_TIMING_DIFF (add, start, stop); HP_TIMING_DIFF (add, start, stop);
HP_TIMING_ACCUM_NT (relocate_time, add); HP_TIMING_ACCUM_NT (relocate_time, add);

View File

@ -75,18 +75,6 @@ struct r_search_path_struct
}; };
/* Structure for a scope. Each such data structure has a lock. The
lock allows many readers. It can be invalidated by setting bit 31
which means that no more lockers are allowe */
struct r_scoperec
{
bool remove_after_use;
bool notify;
int nusers;
struct r_scope_elem *scope[0];
};
/* Structure describing a loaded shared object. The `l_next' and `l_prev' /* Structure describing a loaded shared object. The `l_next' and `l_prev'
members form a chain of all the shared objects loaded at startup. members form a chain of all the shared objects loaded at startup.
@ -226,27 +214,14 @@ struct link_map
ElfW(Addr) l_text_end; ElfW(Addr) l_text_end;
/* Default array for 'l_scope'. */ /* Default array for 'l_scope'. */
union struct r_scope_elem *l_scope_mem[4];
{
struct r_scoperec l_scoperec_mem;
struct
{
struct r_scoperec scoperec_struct;
/* XXX This number should be increased once the scope memory
handling has been tested. */
struct r_scope_elem *scope_elems[4];
#define NINIT_SCOPE_ELEMS(map) \
(sizeof ((map)->l_scope_realmem.scope_elems) \
/ sizeof ((map)->l_scope_realmem.scope_elems[0]))
} l_scope_realmem;
};
/* Size of array allocated for 'l_scope'. */ /* Size of array allocated for 'l_scope'. */
size_t l_scope_max; size_t l_scope_max;
/* This is an array defining the lookup scope for this link map. /* This is an array defining the lookup scope for this link map.
There are initially at most three different scope lists. */ There are initially at most three different scope lists. */
struct r_scoperec *l_scoperec; struct r_scope_elem **l_scope;
/* We need to protect using the SCOPEREC. */ /* We need to protect using the SCOPEREC. */
__rtld_mrlock_define (, l_scoperec_lock) __rtld_mrlock_define (, l_scope_lock)
/* A similar array, this time only with the local scope. This is /* A similar array, this time only with the local scope. This is
used occasionally. */ used occasionally. */

View File

@ -1,3 +1,32 @@
2006-10-27 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_mrlock_lock,
__rtld_mrlock_change): Update oldval if atomic compare and exchange
failed.
* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (SINGLE_THREAD_P):
Define to THREAD_SELF->header.multiple_threads.
* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (SINGLE_THREAD_P):
Likewise.
* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (SINGLE_THREAD_P):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (SINGLE_THREAD_P):
Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (SINGLE_THREAD_P):
Likewise.
2006-10-26 Jakub Jelinek <jakub@redhat.com> 2006-10-26 Jakub Jelinek <jakub@redhat.com>
* pthread_attr_setstacksize.c (NEW_VERNUM): Define to GLIBC_2_3_3 * pthread_attr_setstacksize.c (NEW_VERNUM): Define to GLIBC_2_3_3

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2003 Free Software Foundation, Inc. /* Copyright (C) 2003, 2006 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
@ -163,7 +163,13 @@ extern int __local_multiple_threads attribute_hidden;
#else #else
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -143,7 +143,13 @@
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
@ -216,7 +216,13 @@ __GC_##name: \
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -124,7 +124,13 @@
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -113,7 +113,13 @@
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -67,6 +67,7 @@ typedef int __rtld_mrlock_t;
oldval); \ oldval); \
if (__builtin_expect (ret == oldval, 1)) \ if (__builtin_expect (ret == oldval, 1)) \
goto out; \ goto out; \
oldval = ret; \
} \ } \
atomic_delay (); \ atomic_delay (); \
} \ } \
@ -112,6 +113,7 @@ typedef int __rtld_mrlock_t;
oldval); \ oldval); \
if (__builtin_expect (ret == oldval, 1)) \ if (__builtin_expect (ret == oldval, 1)) \
goto out; \ goto out; \
oldval = ret; \
} \ } \
atomic_delay (); \ atomic_delay (); \
} \ } \

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. /* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -109,7 +109,13 @@ L(pseudo_end):
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. /* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -122,7 +122,13 @@ extern int __local_multiple_threads attribute_hidden;
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. /* Copyright (C) 2003, 2004, 2005, 2006 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
@ -157,7 +157,13 @@
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
@ -100,7 +100,13 @@ __##syscall_name##_nocancel: \
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -98,7 +98,13 @@ __##syscall_name##_nocancel: \
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. /* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
@ -132,7 +132,13 @@ extern int __local_multiple_threads attribute_hidden;
#elif !defined __ASSEMBLER__ #elif !defined __ASSEMBLER__
# define SINGLE_THREAD_P (1) # ifdef IS_IN_rtld
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P (1)
# endif
# define NO_CANCELLATION 1 # define NO_CANCELLATION 1
#endif #endif

View File

@ -377,8 +377,6 @@ struct rtld_global
struct link_map *_ns_loaded; struct link_map *_ns_loaded;
/* Number of object in the _dl_loaded list. */ /* Number of object in the _dl_loaded list. */
unsigned int _ns_nloaded; unsigned int _ns_nloaded;
/* Array representing global scope. */
struct r_scope_elem *_ns_global_scope[2];
/* Direct pointer to the searchlist of the main object. */ /* Direct pointer to the searchlist of the main object. */
struct r_scope_elem *_ns_main_searchlist; struct r_scope_elem *_ns_main_searchlist;
/* This is zero at program start to signal that the global scope map is /* This is zero at program start to signal that the global scope map is