Updated getElfEntries() to look for addresses in process address space in order to determine if a base address should be applied.
@@ -259,17 +259,35 @@ getElfEntries(struct link_map *lm, Elf64_Rela **rel, Elf64_Sym **sym, char **str
for (dyn = lm->l_ld; dyn->d_tag != DT_NULL; dyn++) {
if (dyn->d_tag == DT_SYMTAB) {
+ // Note: using osGetPageProt() to determine if the addr is present in the
+ // process address space. We don't need the prot value.
+ if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
+ *sym = (Elf64_Sym *)((char *)(dyn->d_un.d_ptr));
+ } else {
*sym = (Elf64_Sym *)((char *)(dyn->d_un.d_ptr + lm->l_addr));
+ }
} else if (dyn->d_tag == DT_STRTAB) {
+ if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
+ *str = (char *)(dyn->d_un.d_ptr);
+ } else {
*str = (char *)(dyn->d_un.d_ptr + lm->l_addr);
+ }
} else if (dyn->d_tag == DT_JMPREL) {
+ if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
+ *rel = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr));
+ } else {
*rel = (Elf64_Rela *)((char *)(dyn->d_un.d_ptr + lm->l_addr));
+ }
} else if (dyn->d_tag == DT_PLTRELSZ) {
*rsz = dyn->d_un.d_val;
} else if (dyn->d_tag == DT_PLTGOT) {
+ if (osGetPageProt((uint64_t)dyn->d_un.d_ptr) != -1) {
+ got = (char *)(dyn->d_un.d_ptr);
+ } else {
got = (char *)(dyn->d_un.d_ptr + lm->l_addr);
}
}
+ }
snprintf(buf, sizeof(buf), "%s:%d name: %s dyn %p sym %p rel %p str %p rsz %d got %p laddr 0x%lx\n",
__FUNCTION__, __LINE__, lm->l_name, dyn, *sym, *rel, *str, *rsz, got, lm->l_addr);
