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 (); }
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; }