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; }
/* ANDROID support update. */ HIDDEN struct map_info * map_create_list (pid_t pid) { struct map_iterator mi; unsigned long start, end, offset, flags; struct map_info *map_list = NULL; struct map_info *cur_map; if (maps_init (&mi, pid) < 0) return NULL; while (maps_next (&mi, &start, &end, &offset, &flags)) { cur_map = map_alloc_info (); if (cur_map == MAP_FAILED) break; cur_map->next = map_list; cur_map->start = start; cur_map->end = end; cur_map->offset = offset; cur_map->flags = flags; cur_map->path = strdup (mi.path); mutex_init (&cur_map->ei_lock); cur_map->ei.size = 0; cur_map->ei.image = NULL; map_list = cur_map; } maps_close (&mi); return map_list; }
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; }