diff options
Diffstat (limited to 'elf')
-rw-r--r-- | elf/dl-deps.c | 74 | ||||
-rw-r--r-- | elf/dl-error.c | 9 | ||||
-rw-r--r-- | elf/dynamic-link.h | 9 | ||||
-rw-r--r-- | elf/elf.h | 10 | ||||
-rw-r--r-- | elf/ldd.bash.in | 6 | ||||
-rw-r--r-- | elf/ldd.sh.in | 8 | ||||
-rw-r--r-- | elf/link.h | 9 |
7 files changed, 89 insertions, 36 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 01e4f19..f034196 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -1,5 +1,5 @@ /* Load the dependencies of a mapped object. - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996, 1997 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 @@ -32,33 +32,65 @@ _dl_map_object_deps (struct link_map *map, struct link_map *map; struct list *next; }; - struct list head[1 + npreloads], *tailp, *scanp; + struct list head[2 + npreloads], *tailp, *scanp; struct list duphead, *duptailp; - unsigned int nlist; unsigned int nduplist; + unsigned int nlist, naux, i; + inline void preload (struct link_map *map) + { + head[nlist].next = &head[nlist + 1]; + head[nlist++].map = map; - /* Start the search list with one element: MAP itself. */ - head[0].map = 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. */ + map->l_reserved = 1; + } - /* 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. */ - map->l_reserved = 1; + naux = nlist = 0; - /* Add the preloaded items after MAP but before any of its dependencies. */ - for (nlist = 0; nlist < npreloads; ++nlist) +#define AUXTAG (DT_NUM + DT_PROCNUM + DT_EXTRATAGIDX (DT_AUXILIARY)) + + if (map->l_info[AUXTAG]) { - head[nlist].next = &head[nlist + 1]; - head[nlist + 1].map = preloads[nlist]; - preloads[nlist]->l_reserved = 1; + /* There is an auxiliary library specified. We try to load it, + and if we can, use its symbols in preference to our own. + But if we can't load it, we just silently ignore it. + XXX support multiple DT_AUXILIARYs? + */ + struct link_map *aux; + void openaux (void) + { + const char *strtab + = ((void *) map->l_addr + map->l_info[DT_STRTAB]->d_un.d_ptr); + aux = _dl_map_object (map, strtab + map->l_info[AUXTAG]->d_un.d_val, + map->l_type == lt_executable ? lt_library : + map->l_type, trace_mode); + } + char *errstring; + const char *objname; + if (! _dl_catch_error (&errstring, &objname, &openaux)) + { + /* The auxiliary object is actually there. Use it + as the first search element, even before MAP itself. */ + preload (aux); + naux = 1; + } } + /* Start the search list with one element: MAP itself. */ + preload (map); + + /* Add the preloaded items after MAP but before any of its dependencies. */ + for (i = 0; i < npreloads; ++i) + preload (preloads[i]); + /* Terminate the lists. */ - head[nlist].next = NULL; + head[nlist - 1].next = NULL; duphead.next = NULL; /* Start here for adding dependencies to the list. */ - tailp = &head[nlist++]; + tailp = &head[nlist - 1]; /* Until now we have the same number of libraries in the normal and the list with duplicates. */ @@ -104,7 +136,7 @@ _dl_map_object_deps (struct link_map *map, dep->l_reserved = 1; } - /* In any case Append DEP to the duplicates search list. */ + /* In any case append DEP to the duplicates search list. */ duptailp->next = alloca (sizeof *duptailp); duptailp = duptailp->next; duptailp->map = dep; @@ -117,6 +149,9 @@ _dl_map_object_deps (struct link_map *map, /* 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 *)); + if (map->l_searchlist == NULL) + _dl_signal_error (ENOMEM, map->l_name, + "cannot allocate symbol search list"); map->l_nsearchlist = nlist; nlist = 0; @@ -130,9 +165,12 @@ _dl_map_object_deps (struct link_map *map, } map->l_dupsearchlist = malloc (nduplist * sizeof (struct link_map *)); + if (map->l_dupsearchlist == NULL) + _dl_signal_error (ENOMEM, map->l_name, + "cannot allocate symbol search list"); map->l_ndupsearchlist = nduplist; - for (nlist = 0; nlist < npreloads + 1; ++nlist) + for (nlist = 0; nlist < naux + 1 + npreloads; ++nlist) map->l_dupsearchlist[nlist] = head[nlist].map; for (scanp = duphead.next; scanp; scanp = scanp->next) map->l_dupsearchlist[nlist++] = scanp->map; diff --git a/elf/dl-error.c b/elf/dl-error.c index 55d9c2f..52eb577 100644 --- a/elf/dl-error.c +++ b/elf/dl-error.c @@ -1,5 +1,5 @@ /* Error handling for runtime dynamic linker. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 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 @@ -76,21 +76,22 @@ _dl_catch_error (char **errstring, void (*operate) (void)) { int errcode; - struct catch c = { errstring: NULL, objname: NULL }; + struct catch *old, c = { errstring: NULL, objname: NULL }; + old = catch; errcode = setjmp (c.env); if (errcode == 0) { catch = &c; (*operate) (); - catch = NULL; + catch = old; *errstring = NULL; *objname = NULL; return 0; } /* We get here only if we longjmp'd out of OPERATE. */ - catch = NULL; + catch = old; *errstring = c.errstring; *objname = c.objname; return errcode == -1 ? 0 : errcode; diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 97eb6a5..c613f82 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -1,5 +1,5 @@ /* Inline functions for dynamic linking. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 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 @@ -25,11 +25,12 @@ /* Read the dynamic section at DYN and fill in INFO with indices DT_*. */ static inline void __attribute__ ((unused)) -elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM]) +elf_get_dynamic_info (ElfW(Dyn) *dyn, + ElfW(Dyn) *info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]) { unsigned int i; - for (i = 0; i < DT_NUM + DT_PROCNUM; ++i) + for (i = 0; i < DT_NUM + DT_PROCNUM + DT_EXTRANUM; ++i) info[i] = NULL; if (! dyn) @@ -42,6 +43,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM]) else if (dyn->d_tag >= DT_LOPROC && dyn->d_tag < DT_LOPROC + DT_PROCNUM) info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; + else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) + info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_PROCNUM] = dyn; else assert (! "bad dynamic tag"); dyn++; @@ -1,5 +1,5 @@ /* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ian Lance Taylor <ian@cygnus.com>. @@ -464,6 +464,14 @@ typedef struct #define DT_HIPROC 0x7fffffff /* End of processor-specific */ #define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + + /* Auxiliary vector. */ /* This vector is normally only used by the program interpreter. The diff --git a/elf/ldd.bash.in b/elf/ldd.bash.in index 311ef82..6e2b515 100644 --- a/elf/ldd.bash.in +++ b/elf/ldd.bash.in @@ -1,6 +1,6 @@ #! @BASH@ -# Copyright (C) 1996 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997 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 @@ -34,7 +34,7 @@ while test $# -gt 0; do case "$1" in --v*) echo $"ldd (GNU libc) @VERSION@ -Copyright (C) 1996 Free Software Foundation, Inc. +Copyright (C) 1996, 1997 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." exit 0 ;; @@ -42,7 +42,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." echo $"ldd [OPTION]... FILE... --help print this help and exit --version print version information and exit -Report bugs to <bug-glibc@prep.ai.mit.edu>." +Report bugs using the \`glibcbug' script to <bugs@gnu.ai.mit.edu>." exit 0 ;; --) # Stop option processing. shift; break ;; diff --git a/elf/ldd.sh.in b/elf/ldd.sh.in index 7b7276f..5b6cc3a 100644 --- a/elf/ldd.sh.in +++ b/elf/ldd.sh.in @@ -1,6 +1,6 @@ #! /bin/sh -# Copyright (C) 1996 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997 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 @@ -30,15 +30,15 @@ while test $# -gt 0; do case "$1" in --v*) echo 'ldd (GNU libc) @VERSION@ -Copyright (C) 1996 Free Software Foundation, Inc. +Copyright (C) 1996, 1997 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.' exit 0 ;; --h*) - echo 'ldd [OPTION]... FILE... + echo "ldd [OPTION]... FILE... --help print this help and exit --version print version information and exit -Report bugs to <bug-glibc@prep.ai.mit.edu>.' +Report bugs using the \`glibcbug' script to <bugs@gnu.ai.mit.edu>." exit 0 ;; --) # Stop option processing. shift; break ;; @@ -1,5 +1,5 @@ /* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 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 @@ -97,8 +97,11 @@ struct link_map const char *l_libname; /* Name requested (before search). */ /* Indexed pointers to dynamic section. [0,DT_NUM) are indexed by the processor-independent tags. - [DT_NUM,DT_NUM+DT_PROCNUM] are indexed by the tag minus DT_LOPROC. */ - ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM]; + [DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC. + [DT_NUM+DT_PROCNUM,DT_NUM+DT_PROCNUM+DT_EXTRANUM) are indexed + by DT_EXTRATAGIDX(tagvalue) (see <elf.h>). */ + + ElfW(Dyn) *l_info[DT_NUM + DT_PROCNUM + DT_EXTRANUM]; const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */ ElfW(Addr) l_entry; /* Entry point location. */ ElfW(Half) l_phnum; /* Number of program header entries. */ |