Skip to content

Commit

Permalink
* elf/dl-lookup.c (_dl_debug_bindings): Remove unised symbol_scope
Browse files Browse the repository at this point in the history
	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.
  • Loading branch information
Ulrich Drepper committed Oct 27, 2006
1 parent ee96ce2 commit c0a777e
Show file tree
Hide file tree
Showing 25 changed files with 229 additions and 201 deletions.
26 changes: 26 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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>

* sysdeps/gnu/netinet/tcp.h: Define TCP_CONGESTION.
Expand Down
67 changes: 28 additions & 39 deletions elf/dl-close.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,14 @@ _dl_close (void *_map)
one for the terminating NULL pointer. */
size_t remain = (new_list != NULL) + 1;
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
to its own l_symbolic_searchlist address, or some map's
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 *)
((char *) imap->l_scoperec->scope[cnt]
((char *) imap->l_scope[cnt]
- offsetof (struct link_map, l_searchlist));
assert (tmap->l_ns == ns);
if (tmap->l_idx == IDX_STILL_USED)
Expand All @@ -368,77 +368,66 @@ _dl_close (void *_map)
user of the current array. If possible use the link map's
memory. */
size_t new_size;
struct r_scoperec *newp;
if (imap->l_scoperec != &imap->l_scoperec_mem
&& remain < NINIT_SCOPE_ELEMS (imap)
&& imap->l_scoperec_mem.nusers == 0)
struct r_scope_elem **newp;

#define SCOPE_ELEMS(imap) \
(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);
newp = &imap->l_scoperec_mem;
new_size = SCOPE_ELEMS (imap);
newp = imap->l_scope_mem;
}
else
{
new_size = imap->l_scope_max;
newp = (struct r_scoperec *)
malloc (sizeof (struct r_scoperec)
+ new_size * sizeof (struct r_scope_elem *));
newp = (struct r_scope_elem **)
malloc (new_size * sizeof (struct r_scope_elem *));
if (newp == NULL)
_dl_signal_error (ENOMEM, "dlclose", NULL,
N_("cannot create scope list"));
}

newp->nusers = 0;
newp->remove_after_use = false;
newp->notify = false;

/* Copy over the remaining scope elements. */
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]
!= &imap->l_symbolic_searchlist)
if (imap->l_scope[cnt] != &imap->l_symbolic_searchlist)
{
struct link_map *tmap = (struct link_map *)
((char *) imap->l_scoperec->scope[cnt]
((char *) imap->l_scope[cnt]
- offsetof (struct link_map, l_searchlist));
if (tmap->l_idx != IDX_STILL_USED)
{
/* Remove the scope. Or replace with own map's
scope. */
if (new_list != NULL)
{
newp->scope[remain++] = new_list;
newp[remain++] = new_list;
new_list = NULL;
}
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)
imap->l_scoperec = newp;
imap->l_scope = newp;
else
{
__rtld_mrlock_change (imap->l_scoperec_lock);
imap->l_scoperec = newp;
__rtld_mrlock_done (imap->l_scoperec_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);
}
__rtld_mrlock_change (imap->l_scope_lock);
imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scope_lock);
}

/* No user anymore, we can free it now. */
if (old != &imap->l_scoperec_mem)
if (old != imap->l_scope_mem)
free (old);

imap->l_scope_max = new_size;
Expand Down Expand Up @@ -652,8 +641,8 @@ _dl_close (void *_map)
free (imap->l_initfini);

/* Remove the scope array if we allocated it. */
if (imap->l_scoperec != &imap->l_scoperec_mem)
free (imap->l_scoperec);
if (imap->l_scope != imap->l_scope_mem)
free (imap->l_scope);

if (imap->l_phdr_allocated)
free ((void *) imap->l_phdr);
Expand Down
3 changes: 1 addition & 2 deletions elf/dl-libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,7 @@ do_dlsym_private (void *ptr)
struct do_dlsym_args *args = (struct do_dlsym_args *) ptr;
args->ref = NULL;
l = GLRO(dl_lookup_symbol_x) (args->name, args->map, &args->ref,
args->map->l_scoperec->scope, &vers, 0, 0,
NULL);
args->map->l_scope, &vers, 0, 0, NULL);
args->loadbase = l;
}

Expand Down
8 changes: 4 additions & 4 deletions elf/dl-load.c
Original file line number Diff line number Diff line change
Expand Up @@ -1473,7 +1473,7 @@ cannot enable executable stack as shared object requires");
have to do this for the main map. */
if ((mode & RTLD_DEEPBIND) == 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.
This is the definition of DT_SYMBOLIC in SysVr4. */
Expand All @@ -1490,11 +1490,11 @@ cannot enable executable stack as shared object requires");
l->l_symbolic_searchlist.r_nlist = 1;

/* Now move the existing entries one back. */
memmove (&l->l_scoperec->scope[1], &l->l_scoperec->scope[0],
(l->l_scope_max - 1) * sizeof (l->l_scoperec->scope[0]));
memmove (&l->l_scope[1], &l->l_scope[0],
(l->l_scope_max - 1) * sizeof (l->l_scope[0]));

/* 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. */
Expand Down
8 changes: 3 additions & 5 deletions elf/dl-lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,7 @@ add_dependency (struct link_map *undef_map, struct link_map *map)
static void
internal_function
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
struct sym_val *value,
const ElfW(Sym) **ref, struct sym_val *value,
const struct r_found_version *version, int type_class,
int protected);

Expand Down Expand Up @@ -351,7 +350,7 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,

if (__builtin_expect (GLRO(dl_debug_mask)
& (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);

*ref = current_value.s;
Expand Down Expand Up @@ -408,8 +407,7 @@ _dl_setup_hash (struct link_map *map)
static void
internal_function
_dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[],
struct sym_val *value,
const ElfW(Sym) **ref, struct sym_val *value,
const struct r_found_version *version, int type_class,
int protected)
{
Expand Down
16 changes: 7 additions & 9 deletions elf/dl-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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'
information. If we need more entries we will allocate a large
array dynamically. */
new->l_scoperec = &new->l_scoperec_mem;
new->l_scope_max = (sizeof (new->l_scope_realmem.scope_elems)
/ sizeof (new->l_scope_realmem.scope_elems[0]));
new->l_scope = new->l_scope_mem;
new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);

/* No need to initialize the scope lock if the initializer is zero. */
#if _RTLD_MRLOCK_INITIALIZER != 0
__rtld_mrlock_initialize (new->l_scoperec_mem.lock);
__rtld_mrlock_initialize (new->l_scope_lock);
#endif

/* Counter for the scopes we have to handle. */
Expand All @@ -104,8 +103,7 @@ _dl_new_object (char *realname, const char *libname, int type,
l->l_next = new;

/* Add the global scope. */
new->l_scoperec->scope[idx++]
= &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
}
else
GL(dl_ns)[nsid]._ns_loaded = new;
Expand All @@ -121,15 +119,15 @@ _dl_new_object (char *realname, const char *libname, int type,
loader = loader->l_loader;

/* 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)
{
new->l_scoperec->scope[1] = new->l_scoperec->scope[0];
new->l_scope[1] = new->l_scope[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;
Expand Down
61 changes: 25 additions & 36 deletions elf/dl-open.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ dl_open_worker (void *a)
start the profiling. */
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)
{
Expand All @@ -357,7 +357,7 @@ dl_open_worker (void *a)
}
else
#endif
_dl_relocate_object (l, l->l_scoperec->scope, lazy, 0);
_dl_relocate_object (l, l->l_scope, lazy, 0);
}

if (l == new)
Expand All @@ -375,7 +375,7 @@ dl_open_worker (void *a)
not been loaded here and now. */
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;

while (*runp != NULL)
Expand All @@ -395,62 +395,51 @@ dl_open_worker (void *a)
/* The 'r_scope' array is too small. Allocate a new one
dynamically. */
size_t new_size;
struct r_scoperec *newp;
struct r_scope_elem **newp;

if (imap->l_scoperec != &imap->l_scoperec_mem
&& imap->l_scope_max < NINIT_SCOPE_ELEMS (imap)
&& imap->l_scoperec_mem.nusers == 0)
#define SCOPE_ELEMS(imap) \
(sizeof (imap->l_scope_mem) / sizeof (imap->l_scope_mem[0]))

if (imap->l_scope != imap->l_scope_mem
&& imap->l_scope_max < SCOPE_ELEMS (imap))
{
new_size = NINIT_SCOPE_ELEMS (imap);
newp = &imap->l_scoperec_mem;
new_size = SCOPE_ELEMS (imap);
newp = imap->l_scope_mem;
}
else
{
new_size = imap->l_scope_max * 2;
newp = (struct r_scoperec *)
malloc (sizeof (struct r_scoperec)
+ new_size * sizeof (struct r_scope_elem *));
newp = (struct r_scope_elem **)
malloc (new_size * sizeof (struct r_scope_elem *));
if (newp == NULL)
_dl_signal_error (ENOMEM, "dlopen", NULL,
N_("cannot create scope list"));
}

newp->nusers = 0;
newp->remove_after_use = false;
newp->notify = false;
memcpy (newp->scope, imap->l_scoperec->scope,
cnt * sizeof (imap->l_scoperec->scope[0]));
struct r_scoperec *old = imap->l_scoperec;
memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0]));
struct r_scope_elem **old = imap->l_scope;

if (old == &imap->l_scoperec_mem)
imap->l_scoperec = newp;
else if (SINGLE_THREAD_P)
{
imap->l_scoperec = newp;
free (old);
}
if (SINGLE_THREAD_P)
imap->l_scope = newp;
else
{
__rtld_mrlock_change (imap->l_scoperec_lock);
imap->l_scoperec = newp;
__rtld_mrlock_done (imap->l_scoperec_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);
__rtld_mrlock_change (imap->l_scope_lock);
imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scope_lock);
}

if (old != imap->l_scope_mem)
free (old);

imap->l_scope_max = new_size;
}

/* First terminate the extended list. Otherwise a thread
might use the new last element and then use the garbage
at offset IDX+1. */
imap->l_scoperec->scope[cnt + 1] = NULL;
imap->l_scope[cnt + 1] = NULL;
atomic_write_barrier ();
imap->l_scoperec->scope[cnt] = &new->l_searchlist;
imap->l_scope[cnt] = &new->l_searchlist;
}
#if USE_TLS
/* Only add TLS memory if this object is loaded now and
Expand Down
Loading

0 comments on commit c0a777e

Please sign in to comment.