if (!app.loadmap) {
app.loadmap = (void *)&app_dummy_loadmap;
app.loadmap->nsegs = 1;
- app.loadmap->segs[0].addr = (size_t)app.base;
- app.loadmap->segs[0].p_memsz = -1;
+ app.loadmap->segs[0].addr = (size_t)app.map;
+ app.loadmap->segs[0].p_vaddr = (size_t)app.map
+ - (size_t)app.base;
+ app.loadmap->segs[0].p_memsz = app.map_len;
}
argv[-3] = (void *)app.loadmap;
}
return 1;
}
+static void *addr2dso(size_t a)
+{
+ struct dso *p;
+ for (p=head; p; p=p->next) {
+ if (DL_FDPIC && p->loadmap) {
+ size_t i;
+ for (i=0; i<p->loadmap->nsegs; i++) {
+ if (a-p->loadmap->segs[i].p_vaddr
+ < p->loadmap->segs[i].p_memsz)
+ return p;
+ }
+ i = count_syms(p);
+ if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
+ return p;
+ } else {
+ if (a-(size_t)p->map < p->map_len)
+ return p;
+ }
+ }
+ return 0;
+}
+
void *__tls_get_addr(size_t *);
static void *do_dlsym(struct dso *p, const char *s, void *ra)
if (p == RTLD_DEFAULT) {
p = head;
} else if (p == RTLD_NEXT) {
- for (p=head; p && (unsigned char *)ra-p->map>p->map_len; p=p->next);
+ p = addr2dso((size_t)ra);
if (!p) p=head;
p = p->next;
}
char *bestname;
pthread_rwlock_rdlock(&lock);
- for (p=head; p && (unsigned char *)addr-p->map>p->map_len; p=p->next);
+ p = addr2dso((size_t)addr);
pthread_rwlock_unlock(&lock);
if (!p) return 0;