diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ldso/dynlink.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 8e1d94f3..4b52a5a6 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -704,6 +704,25 @@ static void decode_dyn(struct dso *p) p->versym = laddr(p, *dyn); } +static size_t count_syms(struct dso *p) +{ + if (p->hashtab) return p->hashtab[1]; + + size_t nsym, i; + uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4); + uint32_t *hashval; + for (i = nsym = 0; i < p->ghashtab[0]; i++) { + if (buckets[i] > nsym) + nsym = buckets[i]; + } + if (nsym) { + hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]); + do nsym++; + while (!(*hashval++ & 1)); + } + return nsym; +} + static struct dso *load_library(const char *name, struct dso *needed_by) { char buf[2*NAME_MAX+2]; @@ -1613,7 +1632,6 @@ int __dladdr(const void *addr, Dl_info *info) Sym *sym; uint32_t nsym; char *strings; - size_t i; void *best = 0; char *bestname; @@ -1625,24 +1643,7 @@ int __dladdr(const void *addr, Dl_info *info) sym = p->syms; strings = p->strings; - if (p->hashtab) { - nsym = p->hashtab[1]; - } else { - uint32_t *buckets; - uint32_t *hashval; - buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4); - sym += p->ghashtab[1]; - for (i = nsym = 0; i < p->ghashtab[0]; i++) { - if (buckets[i] > nsym) - nsym = buckets[i]; - } - if (nsym) { - nsym -= p->ghashtab[1]; - hashval = buckets + p->ghashtab[0] + nsym; - do nsym++; - while (!(*hashval++ & 1)); - } - } + nsym = count_syms(p); for (; nsym; nsym--, sym++) { if (sym->st_value |