diff options
author | Ulrich Drepper <drepper@redhat.com> | 2001-05-22 23:42:35 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2001-05-22 23:42:35 +0000 |
commit | 80d9c5f0b121a46467a0fc4eab587c055d79e583 (patch) | |
tree | 1a511b043bd04d216fb732a3f131ab60c7d64ec8 /elf | |
parent | 2373b30ea829ad5dd9599b29902c80101deefc78 (diff) | |
download | glibc-80d9c5f0b121a46467a0fc4eab587c055d79e583.tar.gz glibc-80d9c5f0b121a46467a0fc4eab587c055d79e583.tar.xz glibc-80d9c5f0b121a46467a0fc4eab587c055d79e583.zip |
Update.
2001-05-18 Jakub Jelinek <jakub@redhat.com> * elf/dl-lookup.c (PROTECTED): Remove defines. (add_dependency): Mark it with internal_function. (_dl_do_lookup, _dl_do_lookup_versioned): New functions. (_dl_lookup_symbol, _dl_lookup_symbol_skip, _dl_lookup_versioned_symbol, _dl_lookup_versioned_symbol_skip): Use it if we don't want do_lookup* inlined. 2001-05-18 Jakub Jelinek <jakub@redhat.com> * include/link.h (struct r_scope_elem): Remove r_duplist and r_nduplist fields. * elf/dl-load.c (_dl_map_object_from_fd): Don't initialize them. * elf/dl-lookup.c (_dl_lookup_symbol_skip): Look in r_list, not r_duplist. (_dl_lookup_versioned_symbol_skip): Likewise. * elf/dl-deps.c (struct list): Remove dup field, rename unique to next. (_dl_map_object_deps): Don't compute duplicate list. * elf/dl-symbol.c: Removed. * elf/Makefile (routines): Remove dl-symbol. 2001-05-22 Ulrich Drepper <drepper@redhat.com> * po/el.po: Update from translation team. * po/sv.po: Likewise.
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 2 | ||||
-rw-r--r-- | elf/dl-deps.c | 119 | ||||
-rw-r--r-- | elf/dl-load.c | 2 | ||||
-rw-r--r-- | elf/dl-lookup.c | 93 | ||||
-rw-r--r-- | elf/dl-symbol.c | 33 |
5 files changed, 105 insertions, 144 deletions
diff --git a/elf/Makefile b/elf/Makefile index 8301683b80..39253e3709 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -21,7 +21,7 @@ subdir := elf headers = elf.h bits/elfclass.h link.h -routines = $(dl-routines) dl-open dl-close dl-symbol dl-support \ +routines = $(dl-routines) dl-open dl-close dl-support \ dl-addr enbl-secure dl-profstub dl-origin dl-libc dl-sym # The core dynamic linking functions are in libc for the static and diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 8313ae8a2d..8b9e1321ee 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -72,20 +72,15 @@ openaux (void *a) -/* We use a very special kind of list to track the two kinds paths +/* We use a very special kind of list to track the path through the list of loaded shared objects. We have to - - - produce a flat list with unique members of all involved objects - - - produce a flat list of all shared objects. + produce a flat list with unique members of all involved objects. */ struct list { int done; /* Nonzero if this map was processed. */ struct link_map *map; /* The data. */ - - struct list *unique; /* Elements for normal list. */ - struct list *dup; /* Elements in complete list. */ + struct list *next; /* Elements for normal list. */ }; @@ -139,8 +134,8 @@ _dl_map_object_deps (struct link_map *map, int trace_mode) { struct list known[1 + npreloads + 1]; - struct list *runp, *utail, *dtail; - unsigned int nlist, nduplist, i; + struct list *runp, *tail; + unsigned int nlist, i; /* Object name. */ const char *name; int errno_saved; @@ -153,9 +148,7 @@ _dl_map_object_deps (struct link_map *map, { known[nlist].done = 0; known[nlist].map = map; - - known[nlist].unique = &known[nlist + 1]; - known[nlist].dup = &known[nlist + 1]; + known[nlist].next = &known[nlist + 1]; ++nlist; /* We use `l_reserved' as a mark bit to detect objects we have @@ -175,17 +168,10 @@ _dl_map_object_deps (struct link_map *map, preload (preloads[i]); /* Terminate the lists. */ - known[nlist - 1].unique = NULL; - known[nlist - 1].dup = NULL; + known[nlist - 1].next = NULL; /* Pointer to last unique object. */ - utail = &known[nlist - 1]; - /* Pointer to last loaded object. */ - dtail = &known[nlist - 1]; - - /* Until now we have the same number of libraries in the normal and - the list with duplicates. */ - nduplist = nlist; + tail = &known[nlist - 1]; /* Process each element of the search list, loading each of its auxiliary objects and immediate dependencies. Auxiliary objects @@ -235,8 +221,6 @@ _dl_map_object_deps (struct link_map *map, { /* Map in the needed object. */ struct link_map *dep; - /* Allocate new entry. */ - struct list *newp; const char *objname; /* Recognize DSTs. */ @@ -255,21 +239,19 @@ _dl_map_object_deps (struct link_map *map, else dep = args.aux; - /* Add it in any case to the duplicate list. */ - newp = alloca (sizeof (struct list)); - newp->map = dep; - newp->dup = NULL; - dtail->dup = newp; - dtail = newp; - ++nduplist; - if (! dep->l_reserved) { - /* Append DEP to the unique list. */ + /* Allocate new entry. */ + struct list *newp; + + newp = alloca (sizeof (struct list)); + + /* Append DEP to the list. */ + newp->map = dep; newp->done = 0; - newp->unique = NULL; - utail->unique = newp; - utail = newp; + newp->next = NULL; + tail->next = newp; + tail = newp; ++nlist; /* Set the mark bit that says it's already in the list. */ dep->l_reserved = 1; @@ -343,7 +325,7 @@ _dl_map_object_deps (struct link_map *map, but we have no back links. So we copy the contents of the current entry over. Note that ORIG and NEWP now have switched their meanings. */ - orig->dup = memcpy (newp, orig, sizeof (*newp)); + memcpy (newp, orig, sizeof (*newp)); /* Initialize new entry. */ orig->done = 0; @@ -372,22 +354,22 @@ _dl_map_object_deps (struct link_map *map, /* This object is already in the search list we are building. Don't add a duplicate pointer. Just added by _dl_map_object. */ - for (late = newp; late->unique; late = late->unique) - if (late->unique->map == args.aux) + for (late = newp; late->next; late = late->next) + if (late->next->map == args.aux) break; - if (late->unique) + if (late->next) { /* The object is somewhere behind the current position in the search path. We have to move it to this earlier position. */ - orig->unique = newp; + orig->next = newp; - /* Now remove the later entry from the unique list + /* Now remove the later entry from the list and adjust the tail pointer. */ - if (utail == late->unique) - utail = late; - late->unique = late->unique->unique; + if (tail == late->next) + tail = late; + late->next = late->next->next; /* We must move the object earlier in the chain. */ if (args.aux->l_prev) @@ -406,25 +388,25 @@ _dl_map_object_deps (struct link_map *map, /* The object must be somewhere earlier in the list. That's good, we only have to insert an entry for the duplicate list. */ - orig->unique = NULL; /* Never used. */ + orig->next = NULL; /* Never used. */ /* Now we have a problem. The element - pointing to ORIG in the unique list must + pointing to ORIG in the list must point to NEWP now. This is the only place where we need this backreference and this situation is really not that frequent. So we don't use a double-linked list but instead search for the preceding element. */ late = known; - while (late->unique != orig) - late = late->unique; - late->unique = newp; + while (late->next != orig) + late = late->next; + late->next = newp; } } else { /* This is easy. We just add the symbol right here. */ - orig->unique = newp; + orig->next = newp; ++nlist; /* Set the mark bit that says it's already in the list. */ args.aux->l_reserved = 1; @@ -444,17 +426,12 @@ _dl_map_object_deps (struct link_map *map, args.aux->l_next = newp->map; } - /* Move the tail pointers if necessary. */ - if (orig == utail) - utail = newp; - if (orig == dtail) - dtail = newp; + /* Move the tail pointer if necessary. */ + if (orig == tail) + tail = newp; /* Move on the insert point. */ orig = newp; - - /* We always add an entry to the duplicate list. */ - ++nduplist; } } @@ -473,7 +450,7 @@ _dl_map_object_deps (struct link_map *map, /* If we have no auxiliary objects just go on to the next map. */ if (runp->done) do - runp = runp->unique; + runp = runp->next; while (runp != NULL && runp->done); } @@ -492,8 +469,7 @@ out: /* Store the search list we built in the object. It will be used for searches in the scope of this object. */ map->l_initfini = - (struct link_map **) malloc ((2 * nlist + 1 - + (nlist == nduplist ? 0 : nduplist)) + (struct link_map **) malloc ((2 * nlist + 1) * sizeof (struct link_map *)); if (map->l_initfini == NULL) _dl_signal_error (ENOMEM, map->l_name, @@ -503,7 +479,7 @@ out: map->l_searchlist.r_list = &map->l_initfini[nlist + 1]; map->l_searchlist.r_nlist = nlist; - for (nlist = 0, runp = known; runp; runp = runp->unique) + for (nlist = 0, runp = known; runp; runp = runp->next) { if (trace_mode && runp->map->l_faked) /* This can happen when we trace the loading. */ @@ -516,23 +492,6 @@ out: runp->map->l_reserved = 0; } - map->l_searchlist.r_nduplist = nduplist; - if (nlist == nduplist) - map->l_searchlist.r_duplist = map->l_searchlist.r_list; - else - { - unsigned int cnt; - - map->l_searchlist.r_duplist = map->l_searchlist.r_list + nlist; - - for (cnt = 0, runp = known; runp; runp = runp->dup) - if (trace_mode && runp->map->l_faked) - /* This can happen when we trace the loading. */ - --map->l_searchlist.r_nduplist; - else - map->l_searchlist.r_duplist[cnt++] = runp->map; - } - /* Now determine the order in which the initialization has to happen. */ memcpy (map->l_initfini, map->l_searchlist.r_list, nlist * sizeof (struct link_map *)); diff --git a/elf/dl-load.c b/elf/dl-load.c index 098da6c2c5..979177d3d1 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1126,8 +1126,6 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, l->l_symbolic_searchlist.r_list[0] = l; l->l_symbolic_searchlist.r_nlist = 1; - l->l_symbolic_searchlist.r_duplist = l->l_symbolic_searchlist.r_list; - l->l_symbolic_searchlist.r_nduplist = 1; /* Now move the existing entries one back. */ memmove (&l->l_scope[1], &l->l_scope[0], diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index f8bb9e17ca..3acd71f14c 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -75,16 +75,15 @@ __libc_lock_define (extern, _dl_load_lock) without versioning. gcc is not able to optimize a single function definition serving for both purposes so we define two functions. */ #define VERSIONED 0 -#define PROTECTED 0 #include "do-lookup.h" #define VERSIONED 1 -#define PROTECTED 0 #include "do-lookup.h" /* Add extra dependency on MAP to UNDEF_MAP. */ static int +internal_function add_dependency (struct link_map *undef_map, struct link_map *map) { struct link_map **list; @@ -180,6 +179,19 @@ add_dependency (struct link_map *undef_map, struct link_map *map) return result; } +static int +internal_function +_dl_do_lookup (const char *undef_name, unsigned long int hash, + const ElfW(Sym) *ref, struct sym_val *result, + struct r_scope_elem *scope, size_t i, + struct link_map *skip, int noexec, int noplt); +static int +internal_function +_dl_do_lookup_versioned (const char *undef_name, unsigned long int hash, + const ElfW(Sym) *ref, struct sym_val *result, + struct r_scope_elem *scope, size_t i, + const struct r_found_version *const version, + struct link_map *skip, int noexec, int noplt); /* Search loaded objects' symbol tables for a definition of the symbol UNDEF_NAME. */ @@ -261,8 +273,8 @@ _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, struct sym_val protected_value = { NULL, NULL }; for (scope = symbol_scope; *scope; ++scope) - if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0, - NULL, 0, 1)) + if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, + 0, NULL, 0, 1)) break; if (protected_value.s == NULL || protected_value.m == undef_map) @@ -299,15 +311,14 @@ _dl_lookup_symbol_skip (const char *undef_name, /* Search the relevant loaded objects for a definition. */ scope = symbol_scope; - for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i) - assert (i < (*scope)->r_nduplist); + for (i = 0; (*scope)->r_list[i] != skip_map; ++i) + assert (i < (*scope)->r_nlist); - if (i >= (*scope)->r_nlist - || ! do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i, - skip_map, 0, 0)) + if (! _dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i, + skip_map, 0, 0)) while (*++scope) - if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, - skip_map, 0, 0)) + if (_dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, + skip_map, 0, 0)) break; if (__builtin_expect (current_value.s == NULL, 0)) @@ -338,11 +349,11 @@ _dl_lookup_symbol_skip (const char *undef_name, struct sym_val protected_value = { NULL, NULL }; if (i >= (*scope)->r_nlist - || !do_lookup (undef_name, hash, *ref, &protected_value, *scope, i, - skip_map, 0, 1)) + || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, + i, skip_map, 0, 1)) while (*++scope) - if (do_lookup (undef_name, hash, *ref, &protected_value, *scope, 0, - skip_map, 0, 1)) + if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, + 0, skip_map, 0, 1)) break; if (protected_value.s == NULL || protected_value.m == undef_map) @@ -465,8 +476,8 @@ _dl_lookup_versioned_symbol (const char *undef_name, struct sym_val protected_value = { NULL, NULL }; for (scope = symbol_scope; *scope; ++scope) - if (do_lookup_versioned (undef_name, hash, *ref, &protected_value, - *scope, 0, version, NULL, 0, 1)) + if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value, + *scope, 0, version, NULL, 0, 1)) break; if (protected_value.s == NULL || protected_value.m == undef_map) @@ -502,15 +513,14 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name, /* Search the relevant loaded objects for a definition. */ scope = symbol_scope; - for (i = 0; (*scope)->r_duplist[i] != skip_map; ++i) - assert (i < (*scope)->r_nduplist); + for (i = 0; (*scope)->r_list[i] != skip_map; ++i) + assert (i < (*scope)->r_nlist); - if (i >= (*scope)->r_nlist - || ! do_lookup_versioned (undef_name, hash, *ref, ¤t_value, - *scope, i, version, skip_map, 0, 0)) + if (! _dl_do_lookup_versioned (undef_name, hash, *ref, ¤t_value, + *scope, i, version, skip_map, 0, 0)) while (*++scope) - if (do_lookup_versioned (undef_name, hash, *ref, ¤t_value, *scope, - 0, version, skip_map, 0, 0)) + if (_dl_do_lookup_versioned (undef_name, hash, *ref, ¤t_value, + *scope, 0, version, skip_map, 0, 0)) break; if (__builtin_expect (current_value.s == NULL, 0)) @@ -554,11 +564,13 @@ _dl_lookup_versioned_symbol_skip (const char *undef_name, struct sym_val protected_value = { NULL, NULL }; if (i >= (*scope)->r_nlist - || !do_lookup_versioned (undef_name, hash, *ref, &protected_value, - *scope, i, version, skip_map, 0, 1)) + || !_dl_do_lookup_versioned (undef_name, hash, *ref, + &protected_value, *scope, i, version, + skip_map, 0, 1)) while (*++scope) - if (do_lookup_versioned (undef_name, hash, *ref, &protected_value, - *scope, 0, version, skip_map, 0, 1)) + if (_dl_do_lookup_versioned (undef_name, hash, *ref, + &protected_value, *scope, 0, version, + skip_map, 0, 1)) break; if (protected_value.s == NULL || protected_value.m == undef_map) @@ -591,3 +603,28 @@ _dl_setup_hash (struct link_map *map) hash += map->l_nbuckets; map->l_chain = hash; } + +/* These are here so that we only inline do_lookup{,_versioned} in the common + case, not everywhere. */ +static int +internal_function +_dl_do_lookup (const char *undef_name, unsigned long int hash, + const ElfW(Sym) *ref, struct sym_val *result, + struct r_scope_elem *scope, size_t i, + struct link_map *skip, int noexec, int noplt) +{ + return do_lookup (undef_name, hash, ref, result, scope, i, skip, noexec, + noplt); +} + +static int +internal_function +_dl_do_lookup_versioned (const char *undef_name, unsigned long int hash, + const ElfW(Sym) *ref, struct sym_val *result, + struct r_scope_elem *scope, size_t i, + const struct r_found_version *const version, + struct link_map *skip, int noexec, int noplt) +{ + return do_lookup_versioned (undef_name, hash, ref, result, scope, i, + version, skip, noexec, noplt); +} diff --git a/elf/dl-symbol.c b/elf/dl-symbol.c deleted file mode 100644 index 5c12df7bff..0000000000 --- a/elf/dl-symbol.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Look up a symbol's run-time value in the scope of a loaded object. - Copyright (C) 1995, 96, 98, 99, 2000 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include <stddef.h> -#include <ldsodefs.h> - -/* Look up symbol NAME in MAP's scope and return its run-time address. */ - -ElfW(Addr) -internal_function -_dl_symbol_value (struct link_map *map, const char *name) -{ - const ElfW(Sym) *ref = NULL; - lookup_t result; - result = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0, 1); - return (result ? LOOKUP_VALUE_ADDRESS (result) : 0) + ref->st_value; -} |