summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-11-08 05:29:49 +0000
committermarcel <marcel@FreeBSD.org>2003-11-08 05:29:49 +0000
commit6ae3d37f99625464fbfb4d3c6fadb4a61c4bd333 (patch)
tree5894fbde5a1c97d5b7ddc717ae6c691a2dda261a /lib/libc
parenta9efed458bca1d3b746b4a2791f1bb5c63633fea (diff)
downloadFreeBSD-src-6ae3d37f99625464fbfb4d3c6fadb4a61c4bd333.zip
FreeBSD-src-6ae3d37f99625464fbfb4d3c6fadb4a61c4bd333.tar.gz
Virtual addresses in headers of ELF files for dynamic objects need
to be relocated before they can be used as pointers.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/ia64/gen/unwind.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/lib/libc/ia64/gen/unwind.c b/lib/libc/ia64/gen/unwind.c
index 566d113..7afd0ef 100644
--- a/lib/libc/ia64/gen/unwind.c
+++ b/lib/libc/ia64/gen/unwind.c
@@ -57,6 +57,7 @@ _Unwind_FindTableEntry(const void *pc, unsigned long *pseg, unsigned long *pgp)
char *p, *p_top;
struct ia64_unwind_entry *unw, *res;
register unsigned long gp __asm__("gp"); /* XXX assumes gcc */
+ unsigned long reloc, vaddr;
size_t l, m, r;
if (!dladdr(pc, &info))
@@ -71,6 +72,7 @@ _Unwind_FindTableEntry(const void *pc, unsigned long *pseg, unsigned long *pgp)
assert(ehdr->e_machine == EM_IA_64);
#endif
+ reloc = (ehdr->e_type == ET_DYN) ? (uintptr_t)info.dli_fbase : 0;
*pgp = gp;
*pseg = 0UL;
res = NULL;
@@ -79,29 +81,30 @@ _Unwind_FindTableEntry(const void *pc, unsigned long *pseg, unsigned long *pgp)
p_top = p + ehdr->e_phnum * ehdr->e_phentsize;
while (p < p_top) {
phdr = (Elf_Phdr*)p;
+ vaddr = phdr->p_vaddr + reloc;
switch (phdr->p_type) {
case PT_DYNAMIC:
- dyn = (Elf_Dyn*)phdr->p_vaddr;
+ dyn = (Elf_Dyn*)vaddr;
while (dyn->d_tag != DT_NULL) {
if (dyn->d_tag == DT_PLTGOT) {
- *pgp = dyn->d_un.d_ptr;
+ *pgp = dyn->d_un.d_ptr + reloc;
break;
}
dyn++;
}
break;
case PT_LOAD:
- if (pc >= (void*)phdr->p_vaddr &&
- pc < (void*)(phdr->p_vaddr + phdr->p_memsz))
- *pseg = phdr->p_vaddr;
+ if (pc >= (void*)vaddr &&
+ pc < (void*)(vaddr + phdr->p_memsz))
+ *pseg = vaddr;
break;
case PT_IA_64_UNWIND:
#if SANITY
assert(*pseg != 0UL);
assert(res == NULL);
#endif
- unw = (struct ia64_unwind_entry*)phdr->p_vaddr;
+ unw = (struct ia64_unwind_entry*)vaddr;
l = 0;
r = phdr->p_memsz / sizeof(struct ia64_unwind_entry);
while (l < r) {
OpenPOWER on IntegriCloud