PROTECTED int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen) { struct map_iterator mi; int found = 0, rc; unsigned long hi; if (maps_init (&mi, pid) < 0) return -1; while (maps_next (&mi, segbase, &hi, mapoff)) if (ip >= *segbase && ip < hi) { found = 1; break; } if (!found) { maps_close (&mi); return -1; } if (path) { strncpy(path, mi.path, pathlen); } rc = elf_map_image (ei, mi.path); maps_close (&mi); return rc; }
HIDDEN int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen) { struct load_module_desc lmd; const char *path2; if (pid != getpid ()) { printf ("%s: remote case not implemented yet\n", __FUNCTION__); return -UNW_ENOINFO; } if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) return -UNW_ENOINFO; *segbase = lmd.text_base; *mapoff = 0; /* XXX fix me? */ path2 = dlgetname (&lmd, sizeof (lmd), NULL, 0, 0); if (!path2) return -UNW_ENOINFO; if (path) { strncpy(path, path2, pathlen); path[pathlen - 1] = '\0'; if (strcmp(path, path2) != 0) Debug(1, "buffer size (%d) not big enough to hold path\n", pathlen); } Debug(1, "segbase=%lx, mapoff=%lx, path=%s\n", *segbase, *mapoff, path); return elf_map_image (ei, path); }
HIDDEN int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, unsigned long *segbase, unsigned long *mapoff) { struct load_module_desc lmd; const char *path; if (pid != getpid ()) { printf ("%s: remote case not implemented yet\n", __FUNCTION__); return -UNW_ENOINFO; } if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) return -UNW_ENOINFO; *segbase = lmd.text_base; *mapoff = 0; /* XXX fix me? */ path = dlgetname (&lmd, sizeof (lmd), NULL, 0, 0); if (!path) return -UNW_ENOINFO; Debug(1, "segbase=%lx, mapoff=%lx, path=%s\n", *segbase, *mapoff, path); return elf_map_image (ei, path); }
static int elf_lib_init(struct mt_elf *mte, struct task *task, struct libref *libref) { if (elf_map_image(mte, &libref->mmap_addr)) return -1; libref->entry = ARCH_ADDR_T(mte->entry_addr); libref->mmap_offset = mte->loadbase; libref->mmap_size = mte->loadsize; libref->txt_vaddr = mte->txt_hdr.p_vaddr - mte->vstart + mte->bias; libref->txt_size = mte->txt_hdr.p_filesz; libref->txt_offset = mte->txt_hdr.p_offset - mte->loadbase; libref->bias = mte->bias; libref->eh_hdr_offset = mte->eh_hdr.p_offset - mte->loadbase; libref->eh_hdr_vaddr = mte->eh_hdr.p_vaddr - mte->vstart + mte->bias; libref->pltgot = mte->pltgot - mte->vstart + mte->bias; libref->dyn = mte->dyn - mte->vstart + mte->bias; #ifdef __arm__ if (mte->exidx_hdr.p_filesz) { libref->exidx_data = libref->mmap_addr + mte->exidx_hdr.p_offset - mte->loadbase; libref->exidx_len = mte->exidx_hdr.p_filesz; } #endif if (mte->eh_hdr.p_filesz && mte->dyn) { if (dwarf_get_unwind_table(task, libref) < 0) return -1; } if (populate_symtab(mte, libref) < 0) return -1; return 0; }
PROTECTED int tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen) { int mib[4], error, ret; size_t len, len1; char *buf, *bp, *eb; struct kinfo_vmentry *kv; len = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_VMMAP; mib[3] = pid; error = sysctl(mib, 4, NULL, &len, NULL, 0); if (error == -1) { if (errno == ESRCH) { mib[3] = get_pid_by_tid(pid); if (mib[3] != -1) error = sysctl(mib, 4, NULL, &len, NULL, 0); if (error == -1) return (-UNW_EUNSPEC); } else return (-UNW_EUNSPEC); } len1 = len * 4 / 3; buf = get_mem(len1); if (buf == NULL) return (-UNW_EUNSPEC); len = len1; error = sysctl(mib, 4, buf, &len, NULL, 0); if (error == -1) { free_mem(buf, len1); return (-UNW_EUNSPEC); } ret = -UNW_EUNSPEC; for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { kv = (struct kinfo_vmentry *)(uintptr_t)bp; if (ip < kv->kve_start || ip >= kv->kve_end) continue; if (kv->kve_type != KVME_TYPE_VNODE) continue; *segbase = kv->kve_start; *mapoff = kv->kve_offset; if (path) { strncpy(path, kv->kve_path, pathlen); } ret = elf_map_image (ei, kv->kve_path); break; } free_mem(buf, len1); return (ret); }
static inline int get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg, int *countp) { unsigned long lo, hi, off; struct UPT_info *ui = arg; struct map_iterator mi; char path[PATH_MAX]; unw_dyn_info_t *di; unw_word_t res; int count = 0; maps_init (&mi, ui->pid); while (maps_next (&mi, &lo, &hi, &off)) { if (off) continue; if (ui->ei.image) { munmap (ui->ei.image, ui->ei.size); ui->ei.image = NULL; ui->ei.size = 0; /* invalidate the cache: */ ui->di_cache.start_ip = ui->di_cache.end_ip = 0; } if (elf_map_image (&ui->ei, path) < 0) /* ignore unmappable stuff like "/SYSV00001b58 (deleted)" */ continue; Debug (16, "checking object %s\n", path); di = _UPTi_find_unwind_table (ui, as, path, lo, off); if (di) { res = _Uia64_find_dyn_list (as, di, arg); if (res && count++ == 0) { Debug (12, "dyn_info_list_addr = 0x%lx\n", (long) res); *dil_addr = res; } } } maps_close (&mi); *countp = count; return 0; }