From c0a777e8d01ab40dd9c0ce95328430a4ce7299e3 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 27 Oct 2006 15:54:20 +0000 Subject: * 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. --- elf/dl-close.c | 67 +++++++++++++++++++++++--------------------------------- elf/dl-libc.c | 3 +-- elf/dl-load.c | 8 +++---- elf/dl-lookup.c | 8 +++---- elf/dl-object.c | 16 ++++++-------- elf/dl-open.c | 61 +++++++++++++++++++++------------------------------ elf/dl-runtime.c | 43 +++++++----------------------------- elf/dl-sym.c | 20 ++++------------- elf/rtld.c | 12 +++++----- 9 files changed, 85 insertions(+), 153 deletions(-) (limited to 'elf') diff --git a/elf/dl-close.c b/elf/dl-close.c index bfcceea4bc..31bc80b935 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -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) @@ -368,38 +368,35 @@ _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) { @@ -407,38 +404,30 @@ _dl_close (void *_map) 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; @@ -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); diff --git a/elf/dl-libc.c b/elf/dl-libc.c index 8b78a7a388..a6d0d1fcef 100644 --- a/elf/dl-libc.c +++ b/elf/dl-libc.c @@ -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; } diff --git a/elf/dl-load.c b/elf/dl-load.c index 172fb2fc35..36dc123c01 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -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. */ @@ -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. */ diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 72381698db..29a52165ce 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -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); @@ -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, ¤t_value, version, type_class, protected); *ref = current_value.s; @@ -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) { diff --git a/elf/dl-object.c b/elf/dl-object.c index c5dae9ef11..29f44bfd55 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -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. */ @@ -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; @@ -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; diff --git a/elf/dl-open.c b/elf/dl-open.c index 85b9637305..2ae861f9cc 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -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) { @@ -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) @@ -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) @@ -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 diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 8bf5b89eb6..0488fab8d0 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -93,29 +93,15 @@ _dl_fixup ( version = NULL; } - struct r_scoperec *scoperec = l->l_scoperec; if (l->l_type == lt_loaded && !SINGLE_THREAD_P) - { - __rtld_mrlock_lock (l->l_scoperec_lock); - scoperec = l->l_scoperec; - atomic_increment (&scoperec->nusers); - __rtld_mrlock_unlock (l->l_scoperec_lock); - } + __rtld_mrlock_lock (l->l_scope_lock); result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, - scoperec->scope, version, - ELF_RTYPE_CLASS_PLT, + l->l_scope, version, ELF_RTYPE_CLASS_PLT, DL_LOOKUP_ADD_DEPENDENCY, NULL); - if (l->l_type == lt_loaded && !SINGLE_THREAD_P - && atomic_decrement_val (&scoperec->nusers) == 0 - && __builtin_expect (scoperec->remove_after_use, 0)) - { - if (scoperec->notify) - __rtld_notify (scoperec->nusers); - else - free (scoperec); - } + if (l->l_type == lt_loaded && !SINGLE_THREAD_P) + __rtld_mrlock_unlock (l->l_scope_lock); /* Currently result contains the base load address (or link map) of the object that defines sym. Now add in the symbol @@ -195,29 +181,16 @@ _dl_profile_fixup ( version = NULL; } - struct r_scoperec *scoperec = l->l_scoperec; if (l->l_type == lt_loaded && !SINGLE_THREAD_P) - { - __rtld_mrlock_lock (l->l_scoperec_lock); - scoperec = l->l_scoperec; - atomic_increment (&scoperec->nusers); - __rtld_mrlock_unlock (l->l_scoperec_lock); - } + __rtld_mrlock_lock (l->l_scope_lock); result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym, - scoperec->scope, version, + l->l_scope, version, ELF_RTYPE_CLASS_PLT, DL_LOOKUP_ADD_DEPENDENCY, NULL); - if (l->l_type == lt_loaded && !SINGLE_THREAD_P - && atomic_decrement_val (&scoperec->nusers) == 0 - && __builtin_expect (scoperec->remove_after_use, 0)) - { - if (scoperec->notify) - __rtld_notify (scoperec->nusers); - else - free (scoperec); - } + if (l->l_type == lt_loaded && !SINGLE_THREAD_P) + __rtld_mrlock_unlock (l->l_scope_lock); /* Currently result contains the base load address (or link map) of the object that defines sym. Now add in the symbol diff --git a/elf/dl-sym.c b/elf/dl-sym.c index 34d75a1a67..8bb564c2fe 100644 --- a/elf/dl-sym.c +++ b/elf/dl-sym.c @@ -65,7 +65,6 @@ struct call_dl_lookup_args /* Arguments to do_dlsym. */ struct link_map *map; const char *name; - struct r_scope_elem **scope; struct r_found_version *vers; int flags; @@ -79,7 +78,7 @@ call_dl_lookup (void *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->scope, args->vers, 0, + args->map->l_scope, args->vers, 0, args->flags, NULL); } @@ -118,20 +117,16 @@ do_sym (void *handle, const char *name, void *who, array can change. */ if (match->l_type != lt_loaded || SINGLE_THREAD_P) 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, NULL); else { - __rtld_mrlock_lock (match->l_scoperec_lock); - struct r_scoperec *scoperec = match->l_scoperec; - atomic_increment (&scoperec->nusers); - __rtld_mrlock_unlock (match->l_scoperec_lock); + __rtld_mrlock_lock (match->l_scope_lock); struct call_dl_lookup_args args; args.name = name; args.map = match; - args.scope = scoperec->scope; args.vers = vers; args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY; 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, call_dl_lookup, &args); - if (atomic_decrement_val (&scoperec->nusers) == 0 - && __builtin_expect (scoperec->remove_after_use, 0)) - { - if (scoperec->notify) - __rtld_notify (scoperec->nusers); - else - free (scoperec); - } + __rtld_mrlock_unlock (match->l_scope_lock); if (__builtin_expect (errstring != NULL, 0)) { diff --git a/elf/rtld.c b/elf/rtld.c index ace3a3099d..8f0b0703a7 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -609,7 +609,7 @@ relocate_doit (void *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 @@ -1963,7 +1963,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", lookup_t result; 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, 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. */ GL(dl_rtld_map).l_relocated = 0; _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)) @@ -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. */ 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 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)) - _dl_relocate_object (l, l->l_scoperec->scope, GLRO(dl_lazy), + _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy), consider_profiling); #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); /* Mark the link map as not yet relocated again. */ GL(dl_rtld_map).l_relocated = 0; - _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scoperec->scope, - 0, 0); + _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); HP_TIMING_NOW (stop); HP_TIMING_DIFF (add, start, stop); HP_TIMING_ACCUM_NT (relocate_time, add); -- cgit 1.4.1