예제 #1
0
static int
get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_word_t ip)
{
  unsigned long segbase, mapoff;
  char path[PATH_MAX];

#if UNW_TARGET_IA64 && defined(__linux)
  if (!edi->ktab.start_ip && _Uia64_get_kernel_table (&edi->ktab) < 0)
    return -UNW_ENOINFO;

  if (edi->ktab.format != -1 && ip >= edi->ktab.start_ip && ip < edi->ktab.end_ip)
    return 0;
#endif

  if ((edi->di_cache.format != -1
       && ip >= edi->di_cache.start_ip && ip < edi->di_cache.end_ip)
#if UNW_TARGET_ARM
      || (edi->di_debug.format != -1
       && ip >= edi->di_arm.start_ip && ip < edi->di_arm.end_ip)
#endif
      || (edi->di_debug.format != -1
       && ip >= edi->di_debug.start_ip && ip < edi->di_debug.end_ip))
    return 0;

  invalidate_edi(edi);

  if (tdep_get_elf_image (&edi->ei, pid, ip, &segbase, &mapoff, path,
                          sizeof(path)) < 0)
    return -UNW_ENOINFO;

  /* Here, SEGBASE is the starting-address of the (mmap'ped) segment
     which covers the IP we're looking for.  */
  if (tdep_find_unwind_table (edi, as, path, segbase, mapoff, ip) < 0)
    return -UNW_ENOINFO;

  /* This can happen in corner cases where dynamically generated
     code falls into the same page that contains the data-segment
     and the page-offset of the code is within the first page of
     the executable.  */
  if (edi->di_cache.format != -1
      && (ip < edi->di_cache.start_ip || ip >= edi->di_cache.end_ip))
     edi->di_cache.format = -1;

  if (edi->di_debug.format != -1
      && (ip < edi->di_debug.start_ip || ip >= edi->di_debug.end_ip))
     edi->di_debug.format = -1;

  if (edi->di_cache.format == -1
#if UNW_TARGET_ARM
      && edi->di_arm.format == -1
#endif
      && edi->di_debug.format == -1)
    return -UNW_ENOINFO;

  return 0;
}
예제 #2
0
static int
get_unwind_info (struct elf_dyn_info *edi, pid_t pid, unw_addr_space_t as, unw_word_t ip, void *as_arg)
{
  /* ANDROID support update. */
  unsigned long segbase, mapoff;
  struct elf_image ei;
  int ret;
  char *path = NULL;
  /* End of ANDROID update. */

#if UNW_TARGET_IA64 && defined(__linux)
  if (!edi->ktab.start_ip && _Uia64_get_kernel_table (&edi->ktab) < 0)
    return -UNW_ENOINFO;

  if (edi->ktab.format != -1 && ip >= edi->ktab.start_ip && ip < edi->ktab.end_ip)
    return 0;
#endif

  if ((edi->di_cache.format != -1
       && ip >= edi->di_cache.start_ip && ip < edi->di_cache.end_ip)
#if UNW_TARGET_ARM
      || (edi->di_debug.format != -1
       && ip >= edi->di_arm.start_ip && ip < edi->di_arm.end_ip)
#endif
      || (edi->di_debug.format != -1
       && ip >= edi->di_debug.start_ip && ip < edi->di_debug.end_ip))
    return 0;

  invalidate_edi(edi);

  /* ANDROID support update. */
  if (tdep_get_elf_image (as, &ei, pid, ip, &segbase, &mapoff, &path, as_arg) < 0)
    return -UNW_ENOINFO;

  ret = tdep_find_unwind_table (edi, &ei, as, path, segbase, mapoff, ip);
  free(path);
  if (ret < 0)
    return ret;
  /* End of ANDROID update. */

  /* This can happen in corner cases where dynamically generated
     code falls into the same page that contains the data-segment
     and the page-offset of the code is within the first page of
     the executable.  */
  if (edi->di_cache.format != -1
      && (ip < edi->di_cache.start_ip || ip >= edi->di_cache.end_ip))
     edi->di_cache.format = -1;

  if (edi->di_debug.format != -1
      && (ip < edi->di_debug.start_ip || ip >= edi->di_debug.end_ip))
     edi->di_debug.format = -1;

  if (edi->di_cache.format == -1
#if UNW_TARGET_ARM
      && edi->di_arm.format == -1
#endif
      && edi->di_debug.format == -1)
    return -UNW_ENOINFO;

  return 0;
}