示例#1
0
static struct value *
record_btrace_frame_prev_register (struct frame_info *this_frame,
				   void **this_cache,
				   int regnum)
{
  const struct btrace_frame_cache *cache;
  const struct btrace_function *bfun, *caller;
  const struct btrace_insn *insn;
  struct gdbarch *gdbarch;
  CORE_ADDR pc;
  int pcreg;

  gdbarch = get_frame_arch (this_frame);
  pcreg = gdbarch_pc_regnum (gdbarch);
  if (pcreg < 0 || regnum != pcreg)
    throw_error (NOT_AVAILABLE_ERROR,
		 _("Registers are not available in btrace record history"));

  cache = *this_cache;
  bfun = cache->bfun;
  gdb_assert (bfun != NULL);

  caller = bfun->up;
  if (caller == NULL)
    throw_error (NOT_AVAILABLE_ERROR,
		 _("No caller in btrace record history"));

  if ((bfun->flags & BFUN_UP_LINKS_TO_RET) != 0)
    {
      insn = VEC_index (btrace_insn_s, caller->insn, 0);
      pc = insn->pc;
    }
  else
    {
      insn = VEC_last (btrace_insn_s, caller->insn);
      pc = insn->pc;

      pc += gdb_insn_length (gdbarch, pc);
    }

  DEBUG ("[frame] unwound PC in %s on level %d: %s",
	 btrace_get_bfun_name (bfun), bfun->level,
	 core_addr_to_string_nz (pc));

  return frame_unwind_got_address (this_frame, regnum, pc);
}
struct value *
dwarf2_tailcall_prev_register_first (struct frame_info *this_frame,
				     void **tailcall_cachep, int regnum)
{
  struct gdbarch *this_gdbarch = get_frame_arch (this_frame);
  struct tailcall_cache *cache = *tailcall_cachep;
  CORE_ADDR addr;

  if (regnum == gdbarch_pc_regnum (this_gdbarch))
    addr = pretend_pc (this_frame, cache);
  else if (cache->prev_sp_p && regnum == gdbarch_sp_regnum (this_gdbarch))
    {
      int next_levels = existing_next_levels (this_frame, cache);

      if (next_levels == cache->chain_levels - 1)
	addr = cache->prev_sp;
      else
	addr = dwarf2_frame_cfa (this_frame) - cache->entry_cfa_sp_offset;
    }
  else
    return NULL;

  return frame_unwind_got_address (this_frame, regnum, addr);
}