mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +03:00
Tue Jun 4 18:57:57 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* elf/dladdr.c: Remove #include <setjmp.h>, we don't use it. * shlib-versions: Set libdl=2. * elf/dl-deps.c (_dl_map_object_deps): Use a linked list of alloca'd elements and then scan it to fill the single malloc'd array, instead of using realloc to grow the array in the first pass. _dl_map_object may do some mallocs that break our stream of reallocs, and the minimal realloc can't handle that. * elf/dl-init.c (_dl_init_next): Take argument, link_map whose searchlist describes the piece of the DT_NEEDED graph to be initialized. * elf/link.h: Update prototype. * sysdeps/i386/dl-machine.h (RTLD_START): Pass _dl_loaded as argument to _dl_init_next. * sysdeps/m68k/dl-machine.h: Likewise. * elf/dl-deps.c (_dl_open): Pass new object as arg to _dl_init_next. * elf/link.h (struct link_map): Add `l_reserved' member, soaking up extra bits in last byte. * elf/dl-deps.c (_dl_map_object_deps): Use that for mark bit to avoid putting dup elts in search list. * elf/dlclose.c: Use MAP->l_searchlist to find deps to close. * elf/dlsym.c: Don't tweak linked list. Scope array given to _dl_lookup_symbol does the right thing. Tue Jun 4 02:25:44 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
This commit is contained in:
@ -25,20 +25,33 @@ Cambridge, MA 02139, USA. */
|
||||
void
|
||||
_dl_map_object_deps (struct link_map *map)
|
||||
{
|
||||
unsigned int nlist = 1;
|
||||
struct link_map **list = malloc (sizeof *list);
|
||||
unsigned int done;
|
||||
struct list
|
||||
{
|
||||
struct link_map *map;
|
||||
struct list *next;
|
||||
};
|
||||
struct list head, *tailp, *scanp;
|
||||
unsigned int nlist;
|
||||
|
||||
/* Start the search list with one element: MAP itself. */
|
||||
list[0] = map;
|
||||
head.map = map;
|
||||
head.next = NULL;
|
||||
nlist = 1;
|
||||
|
||||
|
||||
/* Process each element of the search list, loading each of its immediate
|
||||
dependencies and appending them to the list as we step through it.
|
||||
This produces a flat, ordered list that represents a breadth-first
|
||||
search of the dependency tree. */
|
||||
for (done = 0; done < nlist; ++done)
|
||||
for (scanp = tailp = &head; scanp; scanp = scanp->next)
|
||||
{
|
||||
struct link_map *l = list[done];
|
||||
struct link_map *l = scanp->map;
|
||||
|
||||
/* We use `l_reserved' as a mark bit to detect objects we have
|
||||
already put in the search list and avoid adding duplicate elements
|
||||
later in the list. */
|
||||
l->l_reserved = 1;
|
||||
|
||||
if (l->l_info[DT_NEEDED])
|
||||
{
|
||||
const char *strtab
|
||||
@ -47,24 +60,42 @@ _dl_map_object_deps (struct link_map *map)
|
||||
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
|
||||
if (d->d_tag == DT_NEEDED)
|
||||
{
|
||||
/* Extend the list and put this object on the end. */
|
||||
struct link_map **n
|
||||
= realloc (list, (nlist + 1) * sizeof *list);
|
||||
if (n)
|
||||
list = n;
|
||||
/* Map in the needed object. */
|
||||
struct link_map *dep
|
||||
= _dl_map_object (l, strtab + d->d_un.d_val);
|
||||
|
||||
if (dep->l_reserved)
|
||||
/* This object is already in the search list we are
|
||||
building. Don't add a duplicate pointer. Release the
|
||||
reference just added by _dl_map_object. */
|
||||
--dep->l_opencount;
|
||||
else
|
||||
{
|
||||
free (list);
|
||||
_dl_signal_error (ENOMEM, map->l_name,
|
||||
"finding dependencies");
|
||||
/* Append DEP to the search list. */
|
||||
tailp->next = alloca (sizeof *tailp);
|
||||
tailp = tailp->next;
|
||||
tailp->map = dep;
|
||||
tailp->next = NULL;
|
||||
++nlist;
|
||||
}
|
||||
list[nlist++] = _dl_map_object (l, strtab + d->d_un.d_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map->l_searchlist = list;
|
||||
/* Store the search list we built in the object. It will be used for
|
||||
searches in the scope of this object. */
|
||||
map->l_searchlist = malloc (nlist * sizeof (struct link_map *));
|
||||
map->l_nsearchlist = nlist;
|
||||
|
||||
nlist = 0;
|
||||
for (scanp = &head; scanp; scanp = scanp->next)
|
||||
{
|
||||
map->l_searchlist[nlist++] = scanp->map;
|
||||
|
||||
/* Now clear all the mark bits we set in the objects on the search list
|
||||
to avoid duplicates, so the next call starts fresh. */
|
||||
scanp->map->l_reserved = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -86,7 +117,7 @@ _dl_open (struct link_map *parent, const char *file, int mode)
|
||||
_dl_relocate_object (l, (mode & RTLD_BINDING_MASK) == RTLD_LAZY);
|
||||
|
||||
/* Run the initializer functions of new objects. */
|
||||
while (init = _dl_init_next ())
|
||||
while (init = _dl_init_next (new))
|
||||
(*(void (*) (void)) init) ();
|
||||
|
||||
return new;
|
||||
|
Reference in New Issue
Block a user