Ejemplo n.º 1
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)
{
  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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
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;
}