mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +03:00
Tue Jun 4 02:25:44 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* elf/linux-compat.c (_init): Pass reloc_addr arg to _dl_lookup_symbol. * elf/dl-lookup.c (_dl_lookup_symbol): Use l_searchlist. * elf/dl-deps.c: New file. * elf/Makefile (rtld-routines): Add dl-deps. * elf/link.h: Declare _dl_map_object_deps, _dl_open. * elf/rtld.c (dl_main): Use _dl_map_object_deps. * elf/dlopen.c: Use _dl_open. * elf/rtld.c (dl_main): Remove BEFORE_RTLD variable and list frobnication based on its value. Detach RTLD_MAP from the chain if its l_opencount is zero after loading deps. * elf/dlfcn.h (RTLD_BINDING_MASK): New macro. * elf/link.h (struct link_map): Replace l_deps_loaded flag member with `struct link_map **l_searchlist' and `unsigned int l_nsearchlist'. * elf/dl-lookup.c (_dl_lookup_symbol): Make SYMBOL_SCOPE arg an array of two link_map ptrs. Search the maps in the l_searchlist of each elt that is not null. * elf/dl-reloc.c (_dl_relocate_object): Pass proper SCOPE array. * elf/dl-runtime.c: Likewise. * elf/dlsym.c: Likewise. * elf/rtld.c (dl_main): Likewise. * elf/dl-minimal.c (realloc): Support realloc of the block most recently returned by the minimal malloc. * intl/localealias.c, intl/dcgettext.c [_LIBC]: Define HAVE_ALLOCA.
This commit is contained in:
45
ChangeLog
45
ChangeLog
@ -1,9 +1,40 @@
|
||||
Tue Jun 4 02:25:44 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/linux-compat.c (_init): Pass reloc_addr arg to _dl_lookup_symbol.
|
||||
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Use l_searchlist.
|
||||
|
||||
* elf/dl-deps.c: New file.
|
||||
* elf/Makefile (rtld-routines): Add dl-deps.
|
||||
* elf/link.h: Declare _dl_map_object_deps, _dl_open.
|
||||
* elf/rtld.c (dl_main): Use _dl_map_object_deps.
|
||||
* elf/dlopen.c: Use _dl_open.
|
||||
|
||||
* elf/rtld.c (dl_main): Remove BEFORE_RTLD variable and list
|
||||
frobnication based on its value. Detach RTLD_MAP from the chain if
|
||||
its l_opencount is zero after loading deps.
|
||||
|
||||
* elf/dlfcn.h (RTLD_BINDING_MASK): New macro.
|
||||
|
||||
* elf/link.h (struct link_map): Replace l_deps_loaded flag member with
|
||||
`struct link_map **l_searchlist' and `unsigned int l_nsearchlist'.
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Make SYMBOL_SCOPE arg an array
|
||||
of two link_map ptrs. Search the maps in the l_searchlist of each
|
||||
elt that is not null.
|
||||
* elf/dl-reloc.c (_dl_relocate_object): Pass proper SCOPE array.
|
||||
* elf/dl-runtime.c: Likewise.
|
||||
* elf/dlsym.c: Likewise.
|
||||
* elf/rtld.c (dl_main): Likewise.
|
||||
|
||||
* elf/dl-minimal.c (realloc): Support realloc of the block most
|
||||
recently returned by the minimal malloc.
|
||||
|
||||
Tue Jun 4 00:16:03 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/gnu/errlist.awk: Produce N_("..."), not _N("...").
|
||||
|
||||
* intl: Updated from gettext-0.10.13.
|
||||
* intl/localealias.c intl/dcgettext.c [_LIBC]: Define HAVE_ALLOCA.
|
||||
* intl/localealias.c, intl/dcgettext.c [_LIBC]: Define HAVE_ALLOCA.
|
||||
|
||||
* signal/siggetmask.c: New file. Wrapper around sigblock with
|
||||
link_warning about obsolescence.
|
||||
@ -38,18 +69,6 @@ Mon Jun 3 15:58:22 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
|
||||
for a HANDLE signal to IGNORE because the signal is blocked, clean
|
||||
up any pending suspension left over from a call to resume.
|
||||
|
||||
Mon Jun 3 01:29:53 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/link.h (struct link_map): Replace l_deps_loaded flag member with
|
||||
`struct link_map **l_searchlist'.
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Make SYMBOL_SCOPE arg an array
|
||||
of two link_map ptrs. Search the maps in the l_searchlist of each
|
||||
of the two elts that is non-null.
|
||||
* elf/dl-reloc.c (_dl_relocate_object): Pass proper SCOPE array.
|
||||
* elf/dl-runtime.c: Likewise.
|
||||
* elf/dlsym.c: Likewise.
|
||||
* elf/rtld.c (dl_main): Likewise.
|
||||
|
||||
Mon Jun 3 00:30:35 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/dl-lookup.c (_dl_lookup_symbol): Take new arg RELOC_ADDR and
|
||||
|
@ -29,7 +29,7 @@ libdl-routines := dlopen dlclose dlsym dlerror
|
||||
libdl-inhibit-o = $(filter-out .so,$(object-suffixes)) # Build only shared.
|
||||
|
||||
rtld-routines := rtld $(addprefix dl-,minimal load lookup object reloc \
|
||||
runtime sysdep error init fini)
|
||||
deps runtime sysdep error init fini)
|
||||
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h \
|
||||
soinit.c sofini.c ldd.sh.in linux-compat.c
|
||||
|
||||
|
93
elf/dl-deps.c
Normal file
93
elf/dl-deps.c
Normal file
@ -0,0 +1,93 @@
|
||||
/* Load the dependencies of a mapped object.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <link.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
_dl_map_object_deps (struct link_map *map)
|
||||
{
|
||||
unsigned int nlist = 1;
|
||||
struct link_map **list = malloc (sizeof *list);
|
||||
unsigned int done;
|
||||
|
||||
/* Start the search list with one element: MAP itself. */
|
||||
list[0] = map;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct link_map *l = list[done];
|
||||
if (l->l_info[DT_NEEDED])
|
||||
{
|
||||
const char *strtab
|
||||
= ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
const Elf32_Dyn *d;
|
||||
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;
|
||||
else
|
||||
{
|
||||
free (list);
|
||||
_dl_signal_error (ENOMEM, map->l_name,
|
||||
"finding dependencies");
|
||||
}
|
||||
list[nlist++] = _dl_map_object (l, strtab + d->d_un.d_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map->l_searchlist = list;
|
||||
map->l_nsearchlist = nlist;
|
||||
}
|
||||
|
||||
|
||||
struct link_map *
|
||||
_dl_open (struct link_map *parent, const char *file, int mode)
|
||||
{
|
||||
struct link_map *new, *l;
|
||||
Elf32_Addr init;
|
||||
|
||||
/* Load the named object. */
|
||||
new = _dl_map_object (parent, file);
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
_dl_map_object_deps (new);
|
||||
|
||||
/* Relocate the objects loaded. */
|
||||
for (l = new; l; l = l->l_next)
|
||||
if (! l->l_relocated)
|
||||
_dl_relocate_object (l, (mode & RTLD_BINDING_MASK) == RTLD_LAZY);
|
||||
|
||||
/* Run the initializer functions of new objects. */
|
||||
while (init = _dl_init_next ())
|
||||
(*(void (*) (void)) init) ();
|
||||
|
||||
return new;
|
||||
}
|
@ -29,26 +29,31 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
Elf32_Addr
|
||||
_dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
struct link_map *symbol_scope,
|
||||
struct link_map *symbol_scope[2],
|
||||
const char *reference_name,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt)
|
||||
{
|
||||
unsigned long int hash = elf_hash (undef_name);
|
||||
struct link_map *map;
|
||||
struct
|
||||
{
|
||||
Elf32_Addr a;
|
||||
const Elf32_Sym *s;
|
||||
} weak_value = { 0, NULL };
|
||||
size_t i;
|
||||
struct link_map **scope, *map;
|
||||
|
||||
/* Search the relevant loaded objects for a definition. */
|
||||
for (map = symbol_scope; map; map = map->l_next)
|
||||
for (scope = symbol_scope; scope < &symbol_scope[2]; ++scope)
|
||||
if (*scope)
|
||||
for (i = 0; i < (*scope)->l_nsearchlist; ++i)
|
||||
{
|
||||
const Elf32_Sym *symtab;
|
||||
const char *strtab;
|
||||
Elf32_Word symidx;
|
||||
|
||||
map = (*scope)->l_searchlist[i];
|
||||
|
||||
symtab = ((void *) map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
|
||||
strtab = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
|
||||
@ -61,8 +66,9 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
const Elf32_Sym *sym = &symtab[symidx];
|
||||
|
||||
if (sym->st_value == 0 || /* No value. */
|
||||
reloc_addr == map->l_addr + sym->st_value || /* Self ref. */
|
||||
(noplt && sym->st_shndx == SHN_UNDEF)) /* Unwanted PLT entry. */
|
||||
/* Cannot resolve to the location being filled in. */
|
||||
reloc_addr == map->l_addr + sym->st_value ||
|
||||
(noplt && sym->st_shndx == SHN_UNDEF)) /* Reject PLT. */
|
||||
continue;
|
||||
|
||||
switch (ELF32_ST_TYPE (sym->st_info))
|
||||
@ -87,7 +93,8 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
|
||||
*ref = sym;
|
||||
return map->l_addr;
|
||||
case STB_WEAK:
|
||||
/* Weak definition. Use this value if we don't find another. */
|
||||
/* Weak definition. Use this value if we don't find
|
||||
another. */
|
||||
if (! weak_value.s)
|
||||
{
|
||||
weak_value.s = sym;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Minimal replacements for basic facilities used in the dynamic linker.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -84,10 +84,17 @@ free (void *ptr)
|
||||
}
|
||||
weak_symbol (free)
|
||||
|
||||
/* This is never called. */
|
||||
/* This is only called with the most recent block returned by malloc. */
|
||||
void *
|
||||
realloc (void *ptr, size_t n)
|
||||
{ ptr += n; abort (); }
|
||||
{
|
||||
void *new;
|
||||
assert (ptr == alloc_last_block);
|
||||
alloc_ptr = alloc_last_block;
|
||||
new = malloc (n);
|
||||
assert (new == ptr);
|
||||
return new;
|
||||
}
|
||||
weak_symbol (realloc)
|
||||
|
||||
/* Avoid signal frobnication in setjmp/longjmp. Keeps things smaller. */
|
||||
|
@ -54,12 +54,11 @@ _dl_relocate_object (struct link_map *l, int lazy)
|
||||
}
|
||||
|
||||
{
|
||||
struct link_map *real_next, *scope;
|
||||
struct link_map *scope[2];
|
||||
|
||||
const char *strtab
|
||||
= ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
|
||||
|
||||
Elf32_Addr resolve (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr, int noplt)
|
||||
{
|
||||
@ -67,16 +66,16 @@ _dl_relocate_object (struct link_map *l, int lazy)
|
||||
l->l_name, reloc_addr, noplt);
|
||||
}
|
||||
|
||||
real_next = l->l_next;
|
||||
if (l->l_info[DT_SYMBOLIC])
|
||||
{
|
||||
if (l->l_prev)
|
||||
l->l_prev->l_next = real_next;
|
||||
l->l_next = _dl_loaded;
|
||||
scope = l;
|
||||
scope[0] = l;
|
||||
scope[1] = _dl_loaded;
|
||||
}
|
||||
else
|
||||
scope = _dl_loaded;
|
||||
{
|
||||
scope[0] = _dl_loaded;
|
||||
scope[1] = l;
|
||||
}
|
||||
|
||||
if (l->l_type == lt_interpreter)
|
||||
/* We cannot be lazy when relocating the dynamic linker itself. It
|
||||
@ -87,11 +86,6 @@ _dl_relocate_object (struct link_map *l, int lazy)
|
||||
lazy = 0;
|
||||
|
||||
ELF_DYNAMIC_RELOCATE (l, lazy, resolve);
|
||||
|
||||
/* Restore list frobnication done above for DT_SYMBOLIC. */
|
||||
l->l_next = real_next;
|
||||
if (l->l_prev)
|
||||
l->l_prev->l_next = l;
|
||||
}
|
||||
|
||||
/* Set up the PLT so its unrelocated entries will
|
||||
|
@ -70,8 +70,9 @@ fixup (
|
||||
Elf32_Addr resolve (const Elf32_Sym **ref,
|
||||
Elf32_Addr reloc_addr, int noplt)
|
||||
{
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, _dl_loaded,
|
||||
l->l_name, reloc_addr, noplt);
|
||||
struct link_map *scope[2] = { _dl_loaded, NULL };
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref,
|
||||
scope, l->l_name, reloc_addr, noplt);
|
||||
}
|
||||
|
||||
/* Perform the specified relocation. */
|
||||
|
@ -24,6 +24,7 @@ Cambridge, MA 02139, USA. */
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
|
31
elf/dlopen.c
31
elf/dlopen.c
@ -24,38 +24,11 @@ Cambridge, MA 02139, USA. */
|
||||
void *
|
||||
dlopen (const char *file, int mode)
|
||||
{
|
||||
struct link_map *new, *l;
|
||||
struct link_map *new;
|
||||
|
||||
void doit (void)
|
||||
{
|
||||
Elf32_Addr init;
|
||||
|
||||
new = _dl_map_object (_dl_loaded, file);
|
||||
|
||||
/* Map in any dependencies. */
|
||||
for (l = new; l; l = l->l_next)
|
||||
if (! l->l_deps_loaded)
|
||||
{
|
||||
if (l->l_info[DT_NEEDED])
|
||||
{
|
||||
const char *strtab
|
||||
= (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
|
||||
const Elf32_Dyn *d;
|
||||
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
|
||||
if (d->d_tag == DT_NEEDED)
|
||||
_dl_map_object (l, strtab + d->d_un.d_val);
|
||||
}
|
||||
l->l_deps_loaded = 1;
|
||||
}
|
||||
|
||||
/* Relocate the objects loaded. */
|
||||
for (l = new; l; l = l->l_next)
|
||||
if (! l->l_relocated)
|
||||
_dl_relocate_object (l, mode == RTLD_LAZY);
|
||||
|
||||
/* Run the initializer functions of new objects. */
|
||||
while (init = _dl_init_next ())
|
||||
(*(void (*) (void)) init) ();
|
||||
new = _dl_open (_dl_loaded, file, mode);
|
||||
}
|
||||
|
||||
return _dlerror_run (doit) ? NULL : new;
|
||||
|
@ -33,7 +33,8 @@ dlsym (void *handle, const char *name)
|
||||
int lose;
|
||||
void doit (void)
|
||||
{
|
||||
loadbase = _dl_lookup_symbol (name, &ref, map, map->l_name, 0);
|
||||
struct link_map *scope[2] = { map, NULL };
|
||||
loadbase = _dl_lookup_symbol (name, &ref, scope, map->l_name, 0, 0);
|
||||
}
|
||||
|
||||
/* Confine the symbol scope to just this map. */
|
||||
|
35
elf/link.h
35
elf/link.h
@ -90,6 +90,12 @@ struct link_map
|
||||
Elf32_Word l_phnum; /* Number of program header entries. */
|
||||
Elf32_Addr l_entry; /* Entry point location. */
|
||||
|
||||
/* Array of DT_NEEDED dependencies and their dependencies, in
|
||||
dependency order for symbol lookup. This is null before the
|
||||
dependencies have been loaded. */
|
||||
struct link_map **l_searchlist;
|
||||
unsigned int l_nsearchlist;
|
||||
|
||||
/* Symbol hash table. */
|
||||
Elf32_Word l_nbuckets;
|
||||
const Elf32_Word *l_buckets, *l_chain;
|
||||
@ -102,7 +108,6 @@ struct link_map
|
||||
lt_library, /* Library needed by main executable. */
|
||||
lt_loaded, /* Extra run-time loaded shared object. */
|
||||
} l_type:2;
|
||||
unsigned int l_deps_loaded:1; /* Nonzero if DT_NEEDED items loaded. */
|
||||
unsigned int l_relocated:1; /* Nonzero if object's relocations done. */
|
||||
unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */
|
||||
unsigned int l_init_running:1; /* Nonzero while DT_INIT function runs. */
|
||||
@ -176,22 +181,36 @@ extern struct link_map *_dl_map_object (struct link_map *loader,
|
||||
extern struct link_map *_dl_map_object_from_fd (const char *name,
|
||||
int fd, char *realname);
|
||||
|
||||
/* Call _dl_map_object on the dependencies of MAP, and
|
||||
set up MAP->l_searchlist. */
|
||||
extern void _dl_map_object_deps (struct link_map *map);
|
||||
|
||||
/* Cache the locations of MAP's hash table. */
|
||||
extern void _dl_setup_hash (struct link_map *map);
|
||||
|
||||
|
||||
/* Open the shared object NAME, relocate it, and run its initializer if it
|
||||
hasn't already been run. LOADER's DT_RPATH is used in searching for
|
||||
NAME. MODE is as for `dlopen' (see <dlfcn.h>). If the object is
|
||||
already opened, returns its existing map. */
|
||||
extern struct link_map *_dl_open (struct link_map *loader,
|
||||
const char *name, int mode);
|
||||
|
||||
|
||||
|
||||
/* Search loaded objects' symbol tables for a definition of the symbol
|
||||
referred to by UNDEF. *SYM is the symbol table entry containing the
|
||||
reference; it is replaced with the defining symbol, and the base load
|
||||
address of the defining object is returned. SYMBOL_SCOPE is the head of
|
||||
the chain used for searching. REFERENCE_NAME should name the object
|
||||
containing the reference; it is used in error messages. RELOC_ADDR is
|
||||
the address being fixed up and the chosen symbol cannot be one with this
|
||||
value. If NOPLT is nonzero, then the reference must not be resolved to
|
||||
a PLT entry. */
|
||||
address of the defining object is returned. Each of SYMBOL_SCOPE[0] and
|
||||
SYMBOL_SCOPE[1] that is not null and their dependencies are searched to
|
||||
resolve the name. REFERENCE_NAME should name the object containing the
|
||||
reference; it is used in error messages. RELOC_ADDR is the address
|
||||
being fixed up and the chosen symbol cannot be one with this value. If
|
||||
NOPLT is nonzero, then the reference must not be resolved to a PLT
|
||||
entry. */
|
||||
extern Elf32_Addr _dl_lookup_symbol (const char *undef,
|
||||
const Elf32_Sym **sym,
|
||||
struct link_map *symbol_scope,
|
||||
struct link_map *symbol_scope[2],
|
||||
const char *reference_name,
|
||||
Elf32_Addr reloc_addr,
|
||||
int noplt);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Initializer for Linux-compatible dynamic linker `/lib/ld-linux.so.1'.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -33,8 +33,9 @@ void
|
||||
_init (void)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol ("atexit", &ref, _dl_loaded,
|
||||
struct link_map *scope[2] = { _dl_loaded, NULL };
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol ("atexit", &ref, scope,
|
||||
"<ld-linux.so.1 initialization>",
|
||||
1);
|
||||
0, 1);
|
||||
(*(__typeof (atexit) *) (loadbase + ref->st_value)) (&_dl_fini);
|
||||
}
|
||||
|
55
elf/rtld.c
55
elf/rtld.c
@ -124,7 +124,7 @@ dl_main (const Elf32_Phdr *phdr,
|
||||
Elf32_Addr *user_entry)
|
||||
{
|
||||
const Elf32_Phdr *ph;
|
||||
struct link_map *l, *last, *before_rtld;
|
||||
struct link_map *l;
|
||||
const char *interpreter_name;
|
||||
int lazy;
|
||||
int list_only = 0;
|
||||
@ -250,44 +250,19 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
l->l_next = &rtld_map;
|
||||
rtld_map.l_prev = l;
|
||||
|
||||
/* Now process all the DT_NEEDED entries and map in the objects.
|
||||
Each new link_map will go on the end of the chain, so we will
|
||||
come across it later in the loop to map in its dependencies. */
|
||||
before_rtld = NULL;
|
||||
for (l = _dl_loaded; l; l = l->l_next)
|
||||
{
|
||||
if (l->l_info[DT_NEEDED])
|
||||
{
|
||||
const char *strtab
|
||||
= (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
|
||||
const Elf32_Dyn *d;
|
||||
last = l;
|
||||
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
|
||||
if (d->d_tag == DT_NEEDED)
|
||||
{
|
||||
struct link_map *new;
|
||||
new = _dl_map_object (l, strtab + d->d_un.d_val);
|
||||
if (!before_rtld && new == &rtld_map)
|
||||
before_rtld = last;
|
||||
last = new;
|
||||
}
|
||||
}
|
||||
l->l_deps_loaded = 1;
|
||||
}
|
||||
/* Load all the libraries specified by DT_NEEDED entries. */
|
||||
_dl_map_object_deps (l);
|
||||
|
||||
/* If any DT_NEEDED entry referred to the interpreter object itself,
|
||||
reorder the list so it appears after its dependent. If not,
|
||||
remove it from the maps we will use for symbol resolution. */
|
||||
rtld_map.l_prev->l_next = rtld_map.l_next;
|
||||
if (rtld_map.l_next)
|
||||
rtld_map.l_next->l_prev = rtld_map.l_prev;
|
||||
if (before_rtld)
|
||||
/* XXX if kept, move it so l_next list is in dep order because
|
||||
it will determine gdb's search order.
|
||||
Perhaps do this always, so later dlopen by name finds it?
|
||||
XXX But then gdb always considers it present. */
|
||||
if (rtld_map.l_opencount == 0)
|
||||
{
|
||||
rtld_map.l_prev = before_rtld;
|
||||
rtld_map.l_next = before_rtld->l_next;
|
||||
before_rtld->l_next = &rtld_map;
|
||||
if (rtld_map.l_next)
|
||||
rtld_map.l_next->l_prev = &rtld_map;
|
||||
/* No DT_NEEDED entry referred to the interpreter object itself,
|
||||
so remove it from the list of visible objects. */
|
||||
rtld_map.l_prev->l_next = rtld_map.l_next;
|
||||
rtld_map.l_next->l_prev = rtld_map.l_prev;
|
||||
}
|
||||
|
||||
if (list_only)
|
||||
@ -316,9 +291,9 @@ of this helper program; chances are you did not intend to run this program.\n",
|
||||
for (i = 1; i < _dl_argc; ++i)
|
||||
{
|
||||
const Elf32_Sym *ref = NULL;
|
||||
Elf32_Addr loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
|
||||
_dl_loaded, "argument",
|
||||
0, 0);
|
||||
struct link_map *scope[2] ={ _dl_loaded, NULL };
|
||||
Elf32_Addr loadbase
|
||||
= _dl_lookup_symbol (_dl_argv[i], &ref, scope, "argument", 0, 0);
|
||||
char buf[20], *bp;
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
|
||||
|
Reference in New Issue
Block a user