+2015-11-30 Antoine Tremblay <antoine.tremblay@ericsson.com>
+
+ * linux-aarch64-low.c (aarch64_supports_hardware_single_step):
+ New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * linux-arm-low.c (arm_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * linux-bfin-low.c (bfin_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <bfin_supports_hardware_single_step>:
+ Initialize.
+ * linux-crisv32-low.c (cris_supports_hardware_single_step):
+ New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * linux-low.c (can_hardware_single_step): Use
+ supports_hardware_single_step.
+ (can_software_single_step): New function.
+ (start_step_over): Call can_software_single_step.
+ (linux_supports_hardware_single_step): New function.
+ (struct target_ops) <supports_software_single_step>: Initialize.
+ * linux-low.h (struct linux_target_ops)
+ <supports_hardware_single_step>: Initialize.
+ * linux-m32r-low.c (m32r_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * linux-ppc-low.c (ppc_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <supports_hardware_single_step> Initialize.
+ * linux-s390-low.c (s390_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * linux-sh-low.c (sh_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * linux-tic6x-low.c (tic6x_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <tic6x_supports_hardware_single_step>:
+ Initialize.
+ * linux-tile-low.c (tile_supports_hardware_single_step): New function.
+ (struct linux_target_ops) <tile_supports_hardware_single_step>:
+ Initialize.
+ * linux-x86-low.c (x86_supports_hardware_single_step) New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * linux-xtensa-low.c (xtensa_supports_hardware_single_step):
+ New function.
+ (struct linux_target_ops) <supports_hardware_single_step>: Initialize.
+ * target.h (struct target_ops): <supports_software_single_step>:
+ New field.
+ (target_supports_software_single_step): New macro.
+
2015-11-30 Antoine Tremblay <antoine.tremblay@ericsson.com>
* linux-low.c (linux_wait_1): Fix pc advance condition.
return aarch64_breakpoint;
}
+/* Support for hardware single step. */
+
+static int
+aarch64_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
struct linux_target_ops the_low_target =
{
aarch64_arch_setup,
aarch64_emit_ops,
aarch64_get_min_fast_tracepoint_insn_len,
aarch64_supports_range_stepping,
+ NULL, /* breakpoint_kind_from_current_state */
+ aarch64_supports_hardware_single_step,
};
void
have_ptrace_getregset = 0;
}
+/* Support for hardware single step. */
+
+static int
+arm_supports_hardware_single_step (void)
+{
+ return 0;
+}
+
/* Register sets without using PTRACE_GETREGSET. */
static struct regset_info arm_regsets[] = {
NULL, /* emit_ops */
NULL, /* get_min_fast_tracepoint_insn_len */
NULL, /* supports_range_stepping */
- arm_breakpoint_kind_from_current_state
+ arm_breakpoint_kind_from_current_state,
+ arm_supports_hardware_single_step
};
void
current_process ()->tdesc = tdesc_bfin;
}
+/* Support for hardware single step. */
+
+static int
+bfin_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
static struct usrregs_info bfin_usrregs_info =
{
bfin_num_regs,
NULL, /* breakpoint_reinsert_addr */
2,
bfin_breakpoint_at,
+ NULL, /* supports_z_point_type */
+ NULL, /* insert_point */
+ NULL, /* remove_point */
+ NULL, /* stopped_by_watchpoint */
+ NULL, /* stopped_data_address */
+ NULL, /* collect_ptrace_register */
+ NULL, /* supply_ptrace_register */
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ bfin_supports_hardware_single_step,
};
current_process ()->tdesc = tdesc_crisv32;
}
+/* Support for hardware single step. */
+
+static int
+cris_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
static struct regset_info cris_regsets[] = {
{ PTRACE_GETREGS, PTRACE_SETREGS, 0, cris_num_regs * 4,
GENERAL_REGS, cris_fill_gregset, cris_store_gregset },
cris_remove_point,
cris_stopped_by_watchpoint,
cris_stopped_data_address,
+ NULL, /* collect_ptrace_register */
+ NULL, /* supply_ptrace_register */
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ cris_supports_hardware_single_step,
};
void
being stepped. */
ptid_t step_over_bkpt;
-/* True if the low target can hardware single-step. Such targets
- don't need a BREAKPOINT_REINSERT_ADDR callback. */
+/* True if the low target can hardware single-step. */
static int
can_hardware_single_step (void)
{
- return (the_low_target.breakpoint_reinsert_addr == NULL);
+ if (the_low_target.supports_hardware_single_step != NULL)
+ return the_low_target.supports_hardware_single_step ();
+ else
+ return 0;
+}
+
+/* True if the low target can software single-step. Such targets
+ implement the BREAKPOINT_REINSERT_ADDR callback. */
+
+static int
+can_software_single_step (void)
+{
+ return (the_low_target.breakpoint_reinsert_addr != NULL);
}
/* True if the low target supports memory breakpoints. If so, we'll
{
step = 1;
}
- else
+ else if (can_software_single_step ())
{
CORE_ADDR raddr = (*the_low_target.breakpoint_reinsert_addr) ();
set_reinsert_breakpoint (raddr);
step = 0;
}
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ "stepping is not implemented on this target");
+ }
current_thread = saved_thread;
return can_hardware_single_step ();
}
+static int
+linux_supports_software_single_step (void)
+{
+ return can_software_single_step ();
+}
+
static int
linux_stopped_by_watchpoint (void)
{
linux_breakpoint_kind_from_pc,
linux_sw_breakpoint_from_kind,
linux_proc_tid_get_name,
- linux_breakpoint_kind_from_current_state
+ linux_breakpoint_kind_from_current_state,
+ linux_supports_software_single_step
};
static void
/* See target.h. */
int (*breakpoint_kind_from_current_state) (CORE_ADDR *pcptr);
+
+ /* See target.h. */
+ int (*supports_hardware_single_step) (void);
};
extern struct linux_target_ops the_low_target;
current_process ()->tdesc = tdesc_m32r;
}
+/* Support for hardware single step. */
+
+static int
+m32r_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
static struct usrregs_info m32r_usrregs_info =
{
m32r_num_regs,
NULL,
0,
m32r_breakpoint_at,
+ NULL, /* supports_z_point_type */
+ NULL, /* insert_point */
+ NULL, /* remove_point */
+ NULL, /* stopped_by_watchpoint */
+ NULL, /* stopped_data_address */
+ NULL, /* collect_ptrace_register */
+ NULL, /* supply_ptrace_register */
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ m32r_supports_hardware_single_step,
};
void
supply_register_by_name (regcache, "spefscr", ®set->spefscr);
}
+/* Support for hardware single step. */
+
+static int
+ppc_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
static struct regset_info ppc_regsets[] = {
/* List the extra register sets before GENERAL_REGS. That way we will
fetch them every time, but still fall back to PTRACE_PEEKUSER for the
NULL,
ppc_collect_ptrace_register,
ppc_supply_ptrace_register,
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ ppc_supports_hardware_single_step,
};
void
return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
}
+/* Support for hardware single step. */
+
+static int
+s390_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
static struct usrregs_info s390_usrregs_info =
{
s390_num_regs,
NULL,
s390_collect_ptrace_register,
s390_supply_ptrace_register,
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ s390_supports_hardware_single_step,
};
void
return 0;
}
+/* Support for hardware single step. */
+
+static int
+sh_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
/* Provide only a fill function for the general register set. ps_lgetregs
will use this for NPTL support. */
NULL,
0,
sh_breakpoint_at,
+ NULL, /* supports_z_point_type */
+ NULL, /* insert_point */
+ NULL, /* remove_point */
+ NULL, /* stopped_by_watchpoint */
+ NULL, /* stopped_data_address */
+ NULL, /* collect_ptrace_register */
+ NULL, /* supply_ptrace_register */
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ sh_supports_hardware_single_step,
};
void
current_process ()->tdesc = tic6x_read_description ();
}
+/* Support for hardware single step. */
+
+static int
+tic6x_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
static struct regsets_info tic6x_regsets_info =
{
tic6x_regsets, /* regsets */
NULL,
0,
tic6x_breakpoint_at,
+ NULL, /* supports_z_point_type */
+ NULL, /* insert_point */
+ NULL, /* remove_point */
+ NULL, /* stopped_by_watchpoint */
+ NULL, /* stopped_data_address */
+ NULL, /* collect_ptrace_register */
+ NULL, /* supply_ptrace_register */
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ tic6x_supports_hardware_single_step,
};
void
current_process ()->tdesc = tdesc_tilegx;
}
+/* Support for hardware single step. */
+
+static int
+tile_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
struct linux_target_ops the_low_target =
{
NULL,
0,
tile_breakpoint_at,
+ NULL, /* supports_z_point_type */
+ NULL, /* insert_point */
+ NULL, /* remove_point */
+ NULL, /* stopped_by_watchpoint */
+ NULL, /* stopped_data_address */
+ NULL, /* collect_ptrace_register */
+ NULL, /* supply_ptrace_register */
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ tile_supports_hardware_single_step,
};
void
return 1;
}
+/* Implementation of linux_target_ops method "supports_hardware_single_step".
+ */
+
+static int
+x86_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
/* This is initialized assuming an amd64 target.
x86_arch_setup will correct it for i386 or amd64 targets. */
x86_emit_ops,
x86_get_min_fast_tracepoint_insn_len,
x86_supports_range_stepping,
+ NULL, /* breakpoint_kind_from_current_state */
+ x86_supports_hardware_single_step,
};
void
current_process ()->tdesc = tdesc_xtensa;
}
+/* Support for hardware single step. */
+
+static int
+xtensa_supports_hardware_single_step (void)
+{
+ return 1;
+}
+
static const struct regs_info *
xtensa_regs_info (void)
{
NULL,
0,
xtensa_breakpoint_at,
+ NULL, /* supports_z_point_type */
+ NULL, /* insert_point */
+ NULL, /* remove_point */
+ NULL, /* stopped_by_watchpoint */
+ NULL, /* stopped_data_address */
+ NULL, /* collect_ptrace_register */
+ NULL, /* supply_ptrace_register */
+ NULL, /* siginfo_fixup */
+ NULL, /* new_process */
+ NULL, /* new_thread */
+ NULL, /* new_fork */
+ NULL, /* prepare_to_resume */
+ NULL, /* process_qsupported */
+ NULL, /* supports_tracepoints */
+ NULL, /* get_thread_area */
+ NULL, /* install_fast_tracepoint_jump_pad */
+ NULL, /* emit_ops */
+ NULL, /* get_min_fast_tracepoint_insn_len */
+ NULL, /* supports_range_stepping */
+ NULL, /* breakpoint_kind_from_current_state */
+ xtensa_supports_hardware_single_step,
};
PC. The PCPTR is adjusted to the real memory location in case a flag
(e.g., the Thumb bit on ARM) is present in the PC. */
int (*breakpoint_kind_from_current_state) (CORE_ADDR *pcptr);
+
+ /* Returns true if the target can software single step. */
+ int (*supports_software_single_step) (void);
};
extern struct target_ops *the_target;
? (*the_target->breakpoint_kind_from_current_state) (pcptr) \
: target_breakpoint_kind_from_pc (pcptr))
+#define target_supports_software_single_step() \
+ (the_target->supports_software_single_step ? \
+ (*the_target->supports_software_single_step) () : 0)
+
/* Start non-stop mode, returns 0 on success, -1 on failure. */
int start_non_stop (int nonstop);