// demand_interval: Given a PC 'pc', return an interval.  Note that
// 'pc' may be bogus (i.e, not even point to a text segment) and in this
// case UNW_INTERVAL_NULL should be returned.
UNW_INTERVAL_t
demand_interval(void* pc, bool isTopFrame)
{
#if (HPC_UNW_LITE)
  void* proc_beg = NULL, *mod_beg = NULL;
  dylib_find_proc(pc, &proc_beg, &mod_beg);

  if (!proc_beg && mod_beg && !isTopFrame) {
    // The procedure begin could not be found but pc is valid (since
    // the module begin was found).
    proc_beg = mips_find_proc(pc, mod_beg);
  }
  
  if (proc_beg) {
    uint32_t* beg = (uint32_t*)proc_beg; // [insn_beg, insn_end)
    uint32_t* end = (uint32_t*)pc; 
    return mips_build_intervals(beg, end, false/*retFirst*/, 0);
  }
  else {
    return UNW_INTERVAL_NULL;
  }
#else
  // N.B.: calls build_intervals() if necessary
  return (UNW_INTERVAL_t)hpcrun_addr_to_interval(pc, NULL, NULL);
#endif
}
Beispiel #2
0
static validation_status
validateTroll(void* addr, void* arg)
{
  bool isInCode = false;

#if (HPC_UNW_LITE)
  void *proc_beg = NULL, *mod_beg = NULL;
  dylib_find_proc(addr, &proc_beg, &mod_beg);
  isInCode = (mod_beg || proc_beg);
#else
  void* proc_beg = NULL;
  void* proc_end = NULL;
  bool ret = fnbounds_enclosing_addr(addr, &proc_beg, &proc_end, NULL);
  isInCode = ret && proc_beg;
#endif
  
  if (isInCode && isAfterCall(addr)) {
    return UNW_ADDR_CONFIRMED;
  }
  else {
    return UNW_ADDR_WRONG;
  }
}