return 0;
}
-/* True if the low target can software single-step. Such targets
- implement the GET_NEXT_PCS callback. */
-
-static int
-can_software_single_step (void)
-{
- return (the_low_target.get_next_pcs != NULL);
-}
-
bool
linux_process_target::low_supports_breakpoints ()
{
gdb_assert_not_reached ("linux target op low_set_pc is not implemented");
}
+std::vector<CORE_ADDR>
+linux_process_target::low_get_next_pcs (regcache *regcache)
+{
+ 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
does not mean that the in-process agent has been loaded in the
inferior. */
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);
current_thread = saved_thread;
}
-static int check_stopped_by_watchpoint (struct lwp_info *child);
-
bool
linux_process_target::save_stop_reason (lwp_info *lwp)
{
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;
then the user inserts a breakpoint inside the range. In that
case we need to report the breakpoint PC. */
if ((!lwp->stepping || lwp->stop_pc == sw_breakpoint_pc)
- && (*the_low_target.breakpoint_at) (sw_breakpoint_pc))
+ && low_breakpoint_at (sw_breakpoint_pc))
lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
if (hardware_breakpoint_inserted_here (pc))
#if !USE_SIGTRAP_SIGINFO
else if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
- && !(*the_low_target.breakpoint_at) (pc))
+ && !low_breakpoint_at (pc))
{
if (debug_threads)
debug_printf ("previous SW breakpoint of %ld gone\n",
return 0;
}
-/* Fetch the possibly triggered data watchpoint info and store it in
- CHILD.
-
- On some archs, like x86, that use debug registers to set
- watchpoints, it's possible that the way to know which watched
- address trapped, is to check the register that is used to select
- which address to watch. Problem is, between setting the watchpoint
- and reading back which data address trapped, the user may change
- the set of watchpoints, and, as a consequence, GDB changes the
- debug registers in the inferior. To avoid reading back a stale
- stopped-data-address when that happens, we cache in LP the fact
- that a watchpoint trapped, and the corresponding data address, as
- soon as we see CHILD stop with a SIGTRAP. If GDB changes the debug
- registers meanwhile, we have the cached data we can rely on. */
-
-static int
-check_stopped_by_watchpoint (struct lwp_info *child)
+bool
+linux_process_target::check_stopped_by_watchpoint (lwp_info *child)
{
- if (the_low_target.stopped_by_watchpoint != NULL)
- {
- struct thread_info *saved_thread;
+ struct thread_info *saved_thread = current_thread;
+ current_thread = get_lwp_thread (child);
- saved_thread = current_thread;
- current_thread = get_lwp_thread (child);
+ if (low_stopped_by_watchpoint ())
+ {
+ child->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
+ child->stopped_data_address = low_stopped_data_address ();
+ }
- if (the_low_target.stopped_by_watchpoint ())
- {
- child->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
+ current_thread = saved_thread;
- if (the_low_target.stopped_data_address != NULL)
- child->stopped_data_address
- = the_low_target.stopped_data_address ();
- else
- child->stopped_data_address = 0;
- }
+ return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
+}
- current_thread = saved_thread;
- }
+bool
+linux_process_target::low_stopped_by_watchpoint ()
+{
+ return false;
+}
- return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
+CORE_ADDR
+linux_process_target::low_stopped_data_address ()
+{
+ return 0;
}
/* Return the ptrace options that we want to try to enable. */
event_child->stop_pc += increment_pc;
low_set_pc (regcache, event_child->stop_pc);
- if (!(*the_low_target.breakpoint_at) (event_child->stop_pc))
+ if (!low_breakpoint_at (event_child->stop_pc))
event_child->stop_reason = TARGET_STOPPED_BY_NO_REASON;
}
}
&& (WSTOPSIG (w) == SIGTRAP
|| ((WSTOPSIG (w) == SIGILL
|| WSTOPSIG (w) == SIGSEGV)
- && (*the_low_target.breakpoint_at) (event_child->stop_pc))));
+ && low_breakpoint_at (event_child->stop_pc))));
if (maybe_internal_trap)
{
/* 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)
{
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;
/* 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))
{
/* 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);
}
}
- if (the_low_target.supply_ptrace_register)
- the_low_target.supply_ptrace_register (regcache, regno, buf);
- else
- supply_register (regcache, regno, buf);
+ low_supply_ptrace_register (regcache, regno, buf);
}
void
buf = (char *) alloca (size);
memset (buf, 0, size);
- if (the_low_target.collect_ptrace_register)
- the_low_target.collect_ptrace_register (regcache, regno, buf);
- else
- collect_register (regcache, regno, buf);
+ low_collect_ptrace_register (regcache, regno, buf);
pid = lwpid_of (current_thread);
for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
}
#endif /* HAVE_LINUX_USRREGS */
+void
+linux_process_target::low_collect_ptrace_register (regcache *regcache,
+ int regno, char *buf)
+{
+ collect_register (regcache, regno, buf);
+}
+
+void
+linux_process_target::low_supply_ptrace_register (regcache *regcache,
+ int regno, const char *buf)
+{
+ supply_register (regcache, regno, buf);
+}
+
void
linux_process_target::usr_fetch_inferior_registers (const regs_info *regs_info,
regcache *regcache,
return n;
}
-/* These breakpoint and watchpoint related wrapper functions simply
- pass on the function call if the target has registered a
- corresponding function. */
-
-bool
-linux_process_target::supports_z_point_type (char z_type)
-{
- return (the_low_target.supports_z_point_type != NULL
- && the_low_target.supports_z_point_type (z_type));
-}
-
int
linux_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
int size, raw_breakpoint *bp)
{
if (type == raw_bkpt_type_sw)
return insert_memory_breakpoint (bp);
- else if (the_low_target.insert_point != NULL)
- return the_low_target.insert_point (type, addr, size, bp);
else
- /* Unsupported (see target.h). */
- return 1;
+ return low_insert_point (type, addr, size, bp);
+}
+
+int
+linux_process_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
+ int size, raw_breakpoint *bp)
+{
+ /* Unsupported (see target.h). */
+ return 1;
}
int
{
if (type == raw_bkpt_type_sw)
return remove_memory_breakpoint (bp);
- else if (the_low_target.remove_point != NULL)
- return the_low_target.remove_point (type, addr, size, bp);
else
- /* Unsupported (see target.h). */
- return 1;
+ return low_remove_point (type, addr, size, bp);
+}
+
+int
+linux_process_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
+ int size, raw_breakpoint *bp)
+{
+ /* Unsupported (see target.h). */
+ return 1;
}
/* Implement the stopped_by_sw_breakpoint target_ops
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;
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)
{