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); }
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_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info, void *arg) { # if defined(HAVE_DL_ITERATE_PHDR) unw_dyn_info_t di, *dip = &di; intrmask_t saved_mask; int ret; di.u.ti.segbase = ip; /* this is cheap... */ SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask); ret = dl_iterate_phdr (callback, &di); SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL); if (ret <= 0) { if (!kernel_table.u.ti.table_data) { if ((ret = get_kernel_table (&kernel_table)) < 0) return ret; } if (ip < kernel_table.start_ip || ip >= kernel_table.end_ip) return -UNW_ENOINFO; dip = &kernel_table; } # elif defined(HAVE_DLMODINFO) # define UNWIND_TBL_32BIT 0x8000000000000000 struct load_module_desc lmd; unw_dyn_info_t di, *dip = &di; struct unwind_header { uint64_t header_version; uint64_t start_offset; uint64_t end_offset; } *uhdr; if (!dlmodinfo (ip, &lmd, sizeof (lmd), NULL, 0, 0)) return -UNW_ENOINFO; di.format = UNW_INFO_FORMAT_TABLE; di.start_ip = lmd.text_base; di.end_ip = lmd.text_base + lmd.text_size; di.gp = lmd.linkage_ptr; di.u.ti.name_ptr = 0; /* no obvious table-name available */ di.u.ti.segbase = lmd.text_base; uhdr = (struct unwind_header *) lmd.unwind_base; if ((uhdr->header_version & ~UNWIND_TBL_32BIT) != 1 && (uhdr->header_version & ~UNWIND_TBL_32BIT) != 2) { Debug (1, "encountered unknown unwind header version %ld\n", (long) (uhdr->header_version & ~UNWIND_TBL_32BIT)); return -UNW_EBADVERSION; } if (uhdr->header_version & UNWIND_TBL_32BIT) { Debug (1, "32-bit unwind tables are not supported yet\n"); return -UNW_EINVAL; } di.u.ti.table_data = (unw_word_t *) (di.u.ti.segbase + uhdr->start_offset); di.u.ti.table_len = ((uhdr->end_offset - uhdr->start_offset) / sizeof (unw_word_t)); Debug (16, "found table `%s': segbase=%lx, len=%lu, gp=%lx, " "table_data=%p\n", (char *) di.u.ti.name_ptr, di.u.ti.segbase, di.u.ti.table_len, di.gp, di.u.ti.table_data); # endif /* now search the table: */ return tdep_search_unwind_table (as, ip, dip, pi, need_unwind_info, arg); }