}
#define strcmp(l,r) dl_strcmp(l,r)
+/* Compute load address for a virtual address in a given dso. */
+#define laddr(p, v) (void *)((p)->base + (v))
+
static void decode_vec(size_t *v, size_t *a, size_t cnt)
{
size_t i;
start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t);
end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t);
if (start>end || end-start < 4*sizeof(size_t)) return;
- a = (size_t *)(dso->base + start);
- z = (size_t *)(dso->base + end);
+ a = laddr(dso, start);
+ z = laddr(dso, end);
a[-2] = 1;
a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1;
z[1] = 1;
{
size_t dyn[DYN_CNT];
decode_vec(p->dynv, dyn, DYN_CNT);
- p->syms = (void *)(p->base + dyn[DT_SYMTAB]);
- p->strings = (void *)(p->base + dyn[DT_STRTAB]);
+ p->syms = laddr(p, dyn[DT_SYMTAB]);
+ p->strings = laddr(p, dyn[DT_STRTAB]);
if (dyn[0]&(1<<DT_HASH))
- p->hashtab = (void *)(p->base + dyn[DT_HASH]);
+ p->hashtab = laddr(p, dyn[DT_HASH]);
if (dyn[0]&(1<<DT_RPATH))
p->rpath_orig = (void *)(p->strings + dyn[DT_RPATH]);
if (dyn[0]&(1<<DT_RUNPATH))
p->rpath_orig = (void *)(p->strings + dyn[DT_RUNPATH]);
if (search_vec(p->dynv, dyn, DT_GNU_HASH))
- p->ghashtab = (void *)(p->base + *dyn);
+ p->ghashtab = laddr(p, *dyn);
if (search_vec(p->dynv, dyn, DT_VERSYM))
- p->versym = (void *)(p->base + *dyn);
+ p->versym = laddr(p, *dyn);
}
static struct dso *load_library(const char *name, struct dso *needed_by)
Phdr *ph = p->phdr;
for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
if (ph->p_type == PT_DYNAMIC) {
- p->dynv = (void *)(p->base + ph->p_vaddr);
+ p->dynv = laddr(p, ph->p_vaddr);
} else if (ph->p_type == PT_GNU_RELRO) {
p->relro_start = ph->p_vaddr & -PAGE_SIZE;
p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
decode_vec(p->dynv, dyn, DYN_CNT);
if (dyn[0] & (1<<DT_FINI_ARRAY)) {
size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
- size_t *fn = (size_t *)(p->base + dyn[DT_FINI_ARRAY])+n;
+ size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;
while (n--) ((void (*)(void))*--fn)();
}
#ifndef NO_LEGACY_INITFINI
if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
- ((void (*)(void))(p->base + dyn[DT_FINI]))();
+ ((void (*)(void))laddr(p, dyn[DT_FINI]))();
#endif
}
}
}
#ifndef NO_LEGACY_INITFINI
if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
- ((void (*)(void))(p->base + dyn[DT_INIT]))();
+ ((void (*)(void))laddr(p, dyn[DT_INIT]))();
#endif
if (dyn[0] & (1<<DT_INIT_ARRAY)) {
size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
- size_t *fn = (void *)(p->base + dyn[DT_INIT_ARRAY]);
+ size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);
while (n--) ((void (*)(void))*fn++)();
}
if (!need_locking && libc.threads_minus_1) {
app.tls_align = phdr->p_align;
}
}
- if (app.tls_size) app.tls_image = (char *)app.base + tls_image;
- if (interp_off) ldso.name = (char *)app.base + interp_off;
+ if (app.tls_size) app.tls_image = laddr(&app, tls_image);
+ if (interp_off) ldso.name = laddr(&app, interp_off);
if ((aux[0] & (1UL<<AT_EXECFN))
&& strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
app.name = (char *)aux[AT_EXECFN];
close(fd);
ldso.name = ldname;
app.name = argv[0];
- aux[AT_ENTRY] = (size_t)app.base + ehdr->e_entry;
+ aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);
/* Find the name that would have been used for the dynamic
* linker had ldd not taken its place. */
if (ldd_mode) {
if (!def.sym) goto failed;
if ((def.sym->st_info&0xf) == STT_TLS)
return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value});
- return def.dso->base + def.sym->st_value;
+ return laddr(def.dso, def.sym->st_value);
}
if (invalid_dso_handle(p))
return 0;
if (sym && (sym->st_info&0xf) == STT_TLS)
return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
- return p->base + sym->st_value;
+ return laddr(p, sym->st_value);
if (p->deps) for (i=0; p->deps[i]; i++) {
if ((ght = p->deps[i]->ghashtab)) {
if (!gh) gh = gnu_hash(s);
if (sym && (sym->st_info&0xf) == STT_TLS)
return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
- return p->deps[i]->base + sym->st_value;
+ return laddr(p->deps[i], sym->st_value);
}
failed:
error("Symbol not found: %s", s);
if (sym->st_value
&& (1<<(sym->st_info&0xf) & OK_TYPES)
&& (1<<(sym->st_info>>4) & OK_BINDS)) {
- void *symaddr = p->base + sym->st_value;
+ void *symaddr = laddr(p, sym->st_value);
if (symaddr > addr || symaddr < best)
continue;
best = symaddr;