return 0;
}
-/* True if the low target can software single-step. Such targets
- implement the GET_NEXT_PCS callback. */
+bool
+linux_process_target::low_supports_breakpoints ()
+{
+ return false;
+}
-static int
-can_software_single_step (void)
+CORE_ADDR
+linux_process_target::low_get_pc (regcache *regcache)
{
- return (the_low_target.get_next_pcs != NULL);
+ return 0;
}
-/* True if the low target supports memory breakpoints. If so, we'll
- have a GET_PC implementation. */
+void
+linux_process_target::low_set_pc (regcache *regcache, CORE_ADDR newpc)
+{
+ gdb_assert_not_reached ("linux target op low_set_pc is not implemented");
+}
-static int
-supports_breakpoints (void)
+std::vector<CORE_ADDR>
+linux_process_target::low_get_next_pcs (regcache *regcache)
{
- return (the_low_target.get_pc != NULL);
+ gdb_assert_not_reached ("linux target op low_get_next_pcs is not "
+ "implemented");
+}
+
+int
+linux_process_target::low_decr_pc_after_break ()
+{
+ return 0;
}
/* Returns true if this target can support fast tracepoints. This
child_proc->attached = parent_proc->attached;
if (event_lwp->bp_reinsert != 0
- && can_software_single_step ()
+ && supports_software_single_step ()
&& event == PTRACE_EVENT_VFORK)
{
/* If we leave single-step breakpoints there, child will
In case of vfork, we'll reinsert them back once vforked
child is done. */
if (event_lwp->bp_reinsert != 0
- && can_software_single_step ())
+ && supports_software_single_step ())
{
/* The child process is forked and stopped, so it is safe
to access its memory without stopping all other threads
{
event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORK_DONE;
- if (event_lwp->bp_reinsert != 0 && can_software_single_step ())
+ if (event_lwp->bp_reinsert != 0 && supports_software_single_step ())
{
reinsert_single_step_breakpoints (event_thr);
struct regcache *regcache;
CORE_ADDR pc;
- if (the_low_target.get_pc == NULL)
+ if (!low_supports_breakpoints ())
return 0;
saved_thread = current_thread;
current_thread = get_lwp_thread (lwp);
regcache = get_thread_regcache (current_thread, 1);
- pc = (*the_low_target.get_pc) (regcache);
+ pc = low_get_pc (regcache);
if (debug_threads)
debug_printf ("pc is 0x%lx\n", (long) pc);
siginfo_t siginfo;
#endif
- if (the_low_target.get_pc == NULL)
+ if (!low_supports_breakpoints ())
return false;
pc = get_pc (lwp);
- sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break;
+ sw_breakpoint_pc = pc - low_decr_pc_after_break ();
/* breakpoint_at reads from the current thread. */
saved_thread = current_thread;
{
struct regcache *regcache
= get_thread_regcache (current_thread, 1);
- (*the_low_target.set_pc) (regcache, sw_breakpoint_pc);
+ low_set_pc (regcache, sw_breakpoint_pc);
}
/* Update this so we record the correct stop PC below. */
}
regcache = get_thread_regcache (current_thread, 1);
- (*the_low_target.set_pc) (regcache, status.tpoint_addr);
+ low_set_pc (regcache, status.tpoint_addr);
lwp->stop_pc = status.tpoint_addr;
/* Cancel any fast tracepoint lock this thread was
= get_thread_regcache (current_thread, 1);
event_child->stop_pc += increment_pc;
- (*the_low_target.set_pc) (regcache, event_child->stop_pc);
+ low_set_pc (regcache, event_child->stop_pc);
if (!(*the_low_target.breakpoint_at) (event_child->stop_pc))
event_child->stop_reason = TARGET_STOPPED_BY_NO_REASON;
not support internal breakpoints at all, we also report the
SIGTRAP without further processing; it's of no concern to us. */
maybe_internal_trap
- = (supports_breakpoints ()
+ = (low_supports_breakpoints ()
&& (WSTOPSIG (w) == SIGTRAP
|| ((WSTOPSIG (w) == SIGILL
|| WSTOPSIG (w) == SIGSEGV)
decr_pc_after_break adjustment to the inferior's regcache
ourselves. */
- if (the_low_target.set_pc != NULL)
+ if (low_supports_breakpoints ())
{
struct regcache *regcache
= get_thread_regcache (current_thread, 1);
- (*the_low_target.set_pc) (regcache, event_child->stop_pc);
+ low_set_pc (regcache, event_child->stop_pc);
}
if (step_over_finished)
/* Remove the single-step breakpoints if any. Note that
there isn't single-step breakpoint if we finished stepping
over. */
- if (can_software_single_step ()
+ if (supports_software_single_step ()
&& has_single_step_breakpoints (current_thread))
{
stop_all_lwps (0, event_child);
/* Alright, we're going to report a stop. */
/* Remove single-step breakpoints. */
- if (can_software_single_step ())
+ if (supports_software_single_step ())
{
/* Remove single-step breakpoints or not. It it is true, stop all
lwps, so that other threads won't hit the breakpoint in the
if (event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
&& !cs.swbreak_feature)
{
- int decr_pc = the_low_target.decr_pc_after_break;
+ int decr_pc = low_decr_pc_after_break ();
if (decr_pc != 0)
{
struct regcache *regcache
= get_thread_regcache (current_thread, 1);
- (*the_low_target.set_pc) (regcache, event_child->stop_pc + decr_pc);
+ low_set_pc (regcache, event_child->stop_pc + decr_pc);
}
}
scoped_restore save_current_thread = make_scoped_restore (¤t_thread);
current_thread = thread;
- std::vector<CORE_ADDR> next_pcs = the_low_target.get_next_pcs (regcache);
+ std::vector<CORE_ADDR> next_pcs = low_get_next_pcs (regcache);
for (CORE_ADDR pc : next_pcs)
set_single_step_breakpoint (pc, current_ptid);
{
step = 1;
}
- else if (can_software_single_step ())
+ else if (supports_software_single_step ())
{
install_software_single_step_breakpoints (lwp);
step = 0;
step = single_step (lwp);
}
- if (proc->tdesc != NULL && the_low_target.get_pc != NULL)
+ if (proc->tdesc != NULL && low_supports_breakpoints ())
{
struct regcache *regcache = get_thread_regcache (current_thread, 1);
- lwp->stop_pc = (*the_low_target.get_pc) (regcache);
+ lwp->stop_pc = low_get_pc (regcache);
if (debug_threads)
{
/* On software single step target, resume the inferior with signal
rather than stepping over. */
- if (can_software_single_step ()
+ if (supports_software_single_step ()
&& lwp->pending_signals != NULL
&& lwp_signal_can_be_delivered (lwp))
{
other threads stopped, then resume all threads again. Make sure
to queue any signals that would otherwise be delivered or
queued. */
- if (!any_pending && supports_breakpoints ())
+ if (!any_pending && low_supports_breakpoints ())
need_step_over = find_thread ([this] (thread_info *thread)
{
return thread_needs_step_over (thread);
/* If resume_step is requested by GDB, install single-step
breakpoints when the thread is about to be actually resumed if
the single-step breakpoints weren't removed. */
- if (can_software_single_step ()
+ if (supports_software_single_step ()
&& !has_single_step_breakpoints (thread))
install_software_single_step_breakpoints (lwp);
resume any threads - have it step over the breakpoint with all
other threads stopped, then resume all threads again. */
- if (supports_breakpoints ())
+ if (low_supports_breakpoints ())
{
need_step_over = find_thread ([this] (thread_info *thread)
{
return can_hardware_single_step ();
}
-bool
-linux_process_target::supports_software_single_step ()
-{
- return can_software_single_step ();
-}
-
bool
linux_process_target::stopped_by_watchpoint ()
{
bool
linux_process_target::supports_range_stepping ()
{
- if (can_software_single_step ())
+ if (supports_software_single_step ())
return true;
if (*the_low_target.supports_range_stepping == NULL)
return false;
CORE_ADDR
linux_process_target::read_pc (regcache *regcache)
{
- if (the_low_target.get_pc == NULL)
+ if (!low_supports_breakpoints ())
return 0;
- return (*the_low_target.get_pc) (regcache);
+ return low_get_pc (regcache);
}
void
linux_process_target::write_pc (regcache *regcache, CORE_ADDR pc)
{
- gdb_assert (the_low_target.set_pc != NULL);
+ gdb_assert (low_supports_breakpoints ());
- (*the_low_target.set_pc) (regcache, pc);
+ low_set_pc (regcache, pc);
}
bool
return ptid_of (current_thread);
}
-/* Implementation of the target_ops method "breakpoint_kind_from_pc". */
-
-int
-linux_process_target::breakpoint_kind_from_pc (CORE_ADDR *pcptr)
-{
- if (the_low_target.breakpoint_kind_from_pc != NULL)
- return (*the_low_target.breakpoint_kind_from_pc) (pcptr);
- else
- return process_stratum_target::breakpoint_kind_from_pc (pcptr);
-}
-
-/* Implementation of the target_ops method "sw_breakpoint_from_kind". */
-
-const gdb_byte *
-linux_process_target::sw_breakpoint_from_kind (int kind, int *size)
-{
- gdb_assert (the_low_target.sw_breakpoint_from_kind != NULL);
-
- return (*the_low_target.sw_breakpoint_from_kind) (kind, size);
-}
-
-/* Implementation of the target_ops method
- "breakpoint_kind_from_current_state". */
-
-int
-linux_process_target::breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
-{
- if (the_low_target.breakpoint_kind_from_current_state != NULL)
- return (*the_low_target.breakpoint_kind_from_current_state) (pcptr);
- else
- return breakpoint_kind_from_pc (pcptr);
-}
-
const char *
linux_process_target::thread_name (ptid_t thread)
{