Esempio n. 1
0
void
sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p)
{
  struct gdbarch *arch = current_gdbarch;
  struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
  CORE_ADDR npc, nnpc;

  if (insert_breakpoints_p)
    {
      CORE_ADDR pc, orig_npc;

      pc = sparc_address_from_register (tdep->pc_regnum);
      orig_npc = npc = sparc_address_from_register (tdep->npc_regnum);

      /* Analyze the instruction at PC.  */
      nnpc = sparc_analyze_control_transfer (arch, pc, &npc);
      if (npc != 0)
	insert_single_step_breakpoint (npc);

      if (nnpc != 0)
	insert_single_step_breakpoint (nnpc);

      /* Assert that we have set at least one breakpoint, and that
	 they're not set at the same spot - unless we're going
	 from here straight to NULL, i.e. a call or jump to 0.  */
      gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
      gdb_assert (nnpc != npc || orig_npc == 0);
    }
  else
    remove_single_step_breakpoints ();
}
Esempio n. 2
0
static int
arm_linux_software_single_step (struct frame_info *frame)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct address_space *aspace = get_frame_address_space (frame);
  CORE_ADDR next_pc = arm_get_next_pc (frame, get_frame_pc (frame));

  /* The Linux kernel offers some user-mode helpers in a high page.  We can
     not read this page (as of 2.6.23), and even if we could then we couldn't
     set breakpoints in it, and even if we could then the atomic operations
     would fail when interrupted.  They are all called as functions and return
     to the address in LR, so step to there instead.  */
  if (next_pc > 0xffff0000)
    next_pc = get_frame_register_unsigned (frame, ARM_LR_REGNUM);

  insert_single_step_breakpoint (gdbarch, aspace, next_pc);

  return 1;
}