diff options
Diffstat (limited to 'libexec/ld.so/resolve.c')
| -rw-r--r-- | libexec/ld.so/resolve.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c index c4bd6097f5d..c5bf588ade7 100644 --- a/libexec/ld.so/resolve.c +++ b/libexec/ld.so/resolve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.c,v 1.92 2019/08/04 23:51:45 guenther Exp $ */ +/* $OpenBSD: resolve.c,v 1.93 2019/10/03 06:10:54 guenther Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -53,7 +53,8 @@ struct symlookup { }; elf_object_t *_dl_objects; -elf_object_t *_dl_last_object; +int object_count; +static elf_object_t *_dl_last_object; elf_object_t *_dl_loading_object; /* @@ -87,10 +88,13 @@ _dl_add_object(elf_object_t *object) if (_dl_objects == NULL) { /* First object ? */ _dl_last_object = _dl_objects = object; + object_count = 2; /* count ld.so early */ } else { _dl_last_object->next = object; object->prev = _dl_last_object; _dl_last_object = object; + if (object->obj_type != OBJTYPE_LDR) /* see above */ + object_count++; } } @@ -434,7 +438,6 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, Elf_Phdr *phdrp, object->dev = 0; object->inode = 0; object->grpsym_gen = 0; - TAILQ_INIT(&object->grpsym_list); TAILQ_INIT(&object->grpref_list); if (object->dyn.runpath) @@ -492,7 +495,7 @@ _dl_cleanup_objects() _dl_free((char *)head->sod.sod_name); _dl_free_path(head->runpath); _dl_free_path(head->rpath); - _dl_tailq_free(TAILQ_FIRST(&head->grpsym_list)); + _dl_free(head->grpsym_vec.vec); _dl_tailq_free(TAILQ_FIRST(&head->child_list)); _dl_tailq_free(TAILQ_FIRST(&head->grpref_list)); nobj = head->next; @@ -510,6 +513,7 @@ _dl_remove_object(elf_object_t *object) if (_dl_last_object == object) _dl_last_object = object->prev; + object_count--; object->next = free_objects; free_objects = object; @@ -626,7 +630,6 @@ _dl_find_symbol(const char *name, int flags, const Elf_Sym *ref_sym, { const unsigned char *p; unsigned char c; - struct dep_node *n, *m; struct symlookup sl = { .sl_name = name, .sl_out = { .sym = NULL }, @@ -651,6 +654,9 @@ _dl_find_symbol(const char *name, int flags, const Elf_Sym *ref_sym, goto found; if (flags & SYM_DLSYM) { + struct object_vector vec; + int i; + if (_dl_find_symbol_obj(req_obj, &sl)) goto found; @@ -659,28 +665,34 @@ _dl_find_symbol(const char *name, int flags, const Elf_Sym *ref_sym, goto found; /* search dlopened obj and all children */ - TAILQ_FOREACH(n, &req_obj->load_object->grpsym_list, next_sib) { - if (_dl_find_symbol_obj(n->data, &sl)) + vec = req_obj->load_object->grpsym_vec; + for (i = 0; i < vec.len; i++) { + if (vec.vec[i] == req_obj) + continue; /* already searched */ + if (_dl_find_symbol_obj(vec.vec[i], &sl)) goto found; } } else { - int skip = 0; + struct dep_node *n; + struct object_vector vec; + int i, skip = 0; if ((flags & SYM_SEARCH_SELF) || (flags & SYM_SEARCH_NEXT)) skip = 1; /* * search dlopened objects: global or req_obj == dlopened_obj - * and and it's children + * and its children */ TAILQ_FOREACH(n, &_dlopened_child_list, next_sib) { if (((n->data->obj_flags & DF_1_GLOBAL) == 0) && (n->data != req_obj->load_object)) continue; - TAILQ_FOREACH(m, &n->data->grpsym_list, next_sib) { + vec = n->data->grpsym_vec; + for (i = 0; i < vec.len; i++) { if (skip == 1) { - if (m->data == req_obj) { + if (vec.vec[i] == req_obj) { skip = 0; if (flags & SYM_SEARCH_NEXT) continue; @@ -688,9 +700,9 @@ _dl_find_symbol(const char *name, int flags, const Elf_Sym *ref_sym, continue; } if ((flags & SYM_SEARCH_OTHER) && - (m->data == req_obj)) + (vec.vec[i] == req_obj)) continue; - if (_dl_find_symbol_obj(m->data, &sl)) + if (_dl_find_symbol_obj(vec.vec[i], &sl)) goto found; } } |
