summaryrefslogtreecommitdiff
path: root/src/ldso/dynlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldso/dynlink.c')
-rw-r--r--src/ldso/dynlink.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index fa5ad004..ad987b8f 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -63,6 +63,7 @@ struct dso {
Sym *syms;
uint32_t *hashtab;
uint32_t *ghashtab;
+ int16_t *versym;
char *strings;
unsigned char *map;
size_t map_len;
@@ -156,7 +157,8 @@ static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
uint32_t *hashtab = dso->hashtab;
char *strings = dso->strings;
for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
- if (!strcmp(s, strings+syms[i].st_name))
+ if ((!dso->versym || dso->versym[i] >= 0)
+ && (!strcmp(s, strings+syms[i].st_name)))
return syms+i;
}
return 0;
@@ -164,25 +166,24 @@ static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
{
- Sym *sym;
- char *strings;
+ Sym *syms = dso->syms;
+ char *strings = dso->strings;
uint32_t *hashtab = dso->ghashtab;
uint32_t nbuckets = hashtab[0];
uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
uint32_t h2;
uint32_t *hashval;
- uint32_t n = buckets[h1 % nbuckets];
+ uint32_t i = buckets[h1 % nbuckets];
- if (!n) return 0;
+ if (!i) return 0;
- strings = dso->strings;
- sym = dso->syms + n;
- hashval = buckets + nbuckets + (n - hashtab[1]);
+ hashval = buckets + nbuckets + (i - hashtab[1]);
- for (h1 |= 1; ; sym++) {
+ for (h1 |= 1; ; i++) {
h2 = *hashval++;
- if ((h1 == (h2|1)) && !strcmp(s, strings + sym->st_name))
- return sym;
+ if ((!dso->versym || dso->versym[i] >= 0)
+ && (h1 == (h2|1)) && !strcmp(s, strings + syms[i].st_name))
+ return syms+i;
if (h2 & 1) break;
}
@@ -456,6 +457,8 @@ static void decode_dyn(struct dso *p)
p->hashtab = (void *)(p->base + dyn[DT_HASH]);
if (search_vec(p->dynv, dyn, DT_GNU_HASH))
p->ghashtab = (void *)(p->base + *dyn);
+ if (search_vec(p->dynv, dyn, DT_VERSYM))
+ p->versym = (void *)(p->base + *dyn);
}
static struct dso *load_library(const char *name)