of variables any more (the file target is handling them and they
never get to the process target). So when you push a file target,
it goes into the file stratum, which is always below the process
- stratum. */
+ stratum.
+
+ Note that rather than allow an empty stack, we always have the
+ dummy target at the bottom stratum, so we can call the target
+ methods without checking them. */
#include "target/target.h"
#include "target/resume.h"
#define TARGET_DEFAULT_RETURN(ARG)
#define TARGET_DEFAULT_FUNC(ARG)
+/* Each target that can be activated with "target TARGET_NAME" passes
+ the address of one of these objects to add_target, which uses the
+ object's address as unique identifier, and registers the "target
+ TARGET_NAME" command using SHORTNAME as target name. */
+
+struct target_info
+{
+ /* Name of this target. */
+ const char *shortname;
+
+ /* Name for printing. */
+ const char *longname;
+
+ /* Documentation. Does not include trailing newline, and starts
+ with a one-line description (probably similar to longname). */
+ const char *doc;
+};
+
struct target_ops
{
- struct target_ops *beneath; /* To the target under this one. */
+ /* To the target under this one. */
+ target_ops *beneath () const;
+ /* Free resources associated with the target. Note that singleton
+ targets, like e.g., native targets, are global objects, not
+ heap allocated, and are thus only deleted on GDB exit. The
+ main teardown entry point is the "close" method, below. */
virtual ~target_ops () {}
- /* Name this target type. */
- virtual const char *shortname () = 0;
-
- /* Name for printing. */
- virtual const char *longname () = 0;
+ /* Return a reference to this target's unique target_info
+ object. */
+ virtual const target_info &info () const = 0;
- /* Documentation. Does not include trailing newline, and starts
- ith a one-line description (probably similar to longname). */
- virtual const char *doc () = 0;
+ /* Name this target type. */
+ const char *shortname ()
+ { return info ().shortname; }
- /* The open routine takes the rest of the parameters from the
- command, and (if successful) pushes a new target onto the
- stack. Targets should supply this routine, if only to provide
- an error message. */
- virtual void open (const char *, int);
+ const char *longname ()
+ { return info ().longname; }
/* Close the target. This is where the target can handle
teardown. Heap-allocated targets should delete themselves
done from the target, so GDB needs to be able to tell whether
it should ignore the event and whether it should adjust the PC.
See adjust_pc_after_break. */
- virtual int stopped_by_sw_breakpoint ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool stopped_by_sw_breakpoint ()
+ TARGET_DEFAULT_RETURN (false);
/* Returns true if the above method is supported. */
- virtual int supports_stopped_by_sw_breakpoint ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool supports_stopped_by_sw_breakpoint ()
+ TARGET_DEFAULT_RETURN (false);
/* Returns true if the target stopped for a hardware breakpoint.
Likewise, if the target supports hardware breakpoints, this
require PC adjustment, GDB needs to be able to tell whether the
hardware breakpoint event is a delayed event for a breakpoint
that is already gone and should thus be ignored. */
- virtual int stopped_by_hw_breakpoint ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool stopped_by_hw_breakpoint ()
+ TARGET_DEFAULT_RETURN (false);
/* Returns true if the above method is supported. */
- virtual int supports_stopped_by_hw_breakpoint ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool supports_stopped_by_hw_breakpoint ()
+ TARGET_DEFAULT_RETURN (false);
virtual int can_use_hw_breakpoint (enum bptype, int, int)
TARGET_DEFAULT_RETURN (0);
virtual int remove_mask_watchpoint (CORE_ADDR, CORE_ADDR,
enum target_hw_bp_type)
TARGET_DEFAULT_RETURN (1);
- virtual int stopped_by_watchpoint ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool stopped_by_watchpoint ()
+ TARGET_DEFAULT_RETURN (false);
virtual int have_steppable_watchpoint ()
- TARGET_DEFAULT_RETURN (0);
+ TARGET_DEFAULT_RETURN (false);
virtual bool have_continuable_watchpoint ()
- TARGET_DEFAULT_RETURN (0);
- virtual int stopped_data_address (CORE_ADDR *)
- TARGET_DEFAULT_RETURN (0);
- virtual int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int)
+ TARGET_DEFAULT_RETURN (false);
+ virtual bool stopped_data_address (CORE_ADDR *)
+ TARGET_DEFAULT_RETURN (false);
+ virtual bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int)
TARGET_DEFAULT_FUNC (default_watchpoint_addr_within_range);
/* Documentation of this routine is provided with the corresponding
virtual int region_ok_for_hw_watchpoint (CORE_ADDR, int)
TARGET_DEFAULT_FUNC (default_region_ok_for_hw_watchpoint);
- virtual int can_accel_watchpoint_condition (CORE_ADDR, int, int,
- struct expression *)
- TARGET_DEFAULT_RETURN (0);
+ virtual bool can_accel_watchpoint_condition (CORE_ADDR, int, int,
+ struct expression *)
+ TARGET_DEFAULT_RETURN (false);
virtual int masked_watch_num_registers (CORE_ADDR, CORE_ADDR)
TARGET_DEFAULT_RETURN (-1);
TARGET_DEFAULT_RETURN (-1);
virtual bool supports_terminal_ours ()
- TARGET_DEFAULT_RETURN (0);
+ TARGET_DEFAULT_RETURN (false);
virtual void terminal_init ()
TARGET_DEFAULT_IGNORE ();
virtual void terminal_inferior ()
/* Note that can_run is special and can be invoked on an unpushed
target. Targets defining this method must also define
to_can_async_p and to_supports_non_stop. */
- virtual int can_run ();
+ virtual bool can_run ();
/* Documentation of this routine is provided with the corresponding
target_* macro. */
unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
TARGET_DEFAULT_IGNORE ();
- virtual int thread_alive (ptid_t ptid)
- TARGET_DEFAULT_RETURN (0);
+ virtual bool thread_alive (ptid_t ptid)
+ TARGET_DEFAULT_RETURN (false);
virtual void update_thread_list ()
TARGET_DEFAULT_IGNORE ();
virtual const char *pid_to_str (ptid_t)
enum strata to_stratum;
/* Provide default values for all "must have" methods. */
- virtual int has_all_memory () { return 0; }
- virtual int has_memory () { return 0; }
- virtual int has_stack () { return 0; }
- virtual int has_registers () { return 0; }
- virtual int has_execution (ptid_t) { return 0; }
+ virtual bool has_all_memory () { return false; }
+ virtual bool has_memory () { return false; }
+ virtual bool has_stack () { return false; }
+ virtual bool has_registers () { return false; }
+ virtual bool has_execution (ptid_t) { return false; }
/* Control thread execution. */
virtual thread_control_capabilities get_thread_control_capabilities ()
TARGET_DEFAULT_RETURN (0);
/* This method must be implemented in some situations. See the
comment on 'can_run'. */
- virtual int can_async_p ()
- TARGET_DEFAULT_RETURN (0);
- virtual int is_async_p ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool can_async_p ()
+ TARGET_DEFAULT_RETURN (false);
+ virtual bool is_async_p ()
+ TARGET_DEFAULT_RETURN (false);
virtual void async (int)
TARGET_DEFAULT_NORETURN (tcomplain ());
virtual void thread_events (int)
TARGET_DEFAULT_IGNORE ();
/* This method must be implemented in some situations. See the
comment on 'can_run'. */
- virtual int supports_non_stop ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool supports_non_stop ()
+ TARGET_DEFAULT_RETURN (false);
/* Return true if the target operates in non-stop mode even with
"set non-stop off". */
- virtual int always_non_stop_p ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool always_non_stop_p ()
+ TARGET_DEFAULT_RETURN (false);
/* find_memory_regions support method for gcore */
virtual int find_memory_regions (find_memory_region_ftype func, void *data)
TARGET_DEFAULT_FUNC (dummy_find_memory_regions);
TARGET_DEFAULT_FUNC (default_search_memory);
/* Can target execute in reverse? */
- virtual int can_execute_reverse ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool can_execute_reverse ()
+ TARGET_DEFAULT_RETURN (false);
/* The direction the target is currently executing. Must be
implemented on targets that support reverse execution and async
/* Does this target support debugging multiple processes
simultaneously? */
- virtual int supports_multi_process ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool supports_multi_process ()
+ TARGET_DEFAULT_RETURN (false);
/* Does this target support enabling and disabling tracepoints while a trace
experiment is running? */
- virtual int supports_enable_disable_tracepoint ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool supports_enable_disable_tracepoint ()
+ TARGET_DEFAULT_RETURN (false);
/* Does this target support disabling address space randomization? */
- virtual int supports_disable_randomization ()
+ virtual bool supports_disable_randomization ()
TARGET_DEFAULT_FUNC (find_default_supports_disable_randomization);
/* Does this target support the tracenz bytecode for string collection? */
- virtual int supports_string_tracing ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool supports_string_tracing ()
+ TARGET_DEFAULT_RETURN (false);
/* Does this target support evaluation of breakpoint conditions on its
end? */
- virtual int supports_evaluation_of_breakpoint_conditions ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool supports_evaluation_of_breakpoint_conditions ()
+ TARGET_DEFAULT_RETURN (false);
/* Does this target support evaluation of breakpoint commands on its
end? */
- virtual int can_run_breakpoint_commands ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool can_run_breakpoint_commands ()
+ TARGET_DEFAULT_RETURN (false);
/* Determine current architecture of thread PTID.
/* Return nonzero if the filesystem seen by the current inferior
is the local filesystem, zero otherwise. */
- virtual int filesystem_is_local ()
- TARGET_DEFAULT_RETURN (1);
+ virtual bool filesystem_is_local ()
+ TARGET_DEFAULT_RETURN (true);
/* Open FILENAME on the target, in the filesystem as seen by INF,
using FLAGS and MODE. If INF is NULL, use the filesystem seen
/* Is the target able to download tracepoint locations in current
state? */
- virtual int can_download_tracepoint ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool can_download_tracepoint ()
+ TARGET_DEFAULT_RETURN (false);
/* Send full details of a trace state variable to the target. */
virtual void download_trace_state_variable (const trace_state_variable &tsv)
/* Get the value of the trace state variable number TSV, returning
1 if the value is known and writing the value itself into the
location pointed to by VAL, else returning 0. */
- virtual int get_trace_state_variable_value (int tsv, LONGEST *val)
- TARGET_DEFAULT_RETURN (0);
+ virtual bool get_trace_state_variable_value (int tsv, LONGEST *val)
+ TARGET_DEFAULT_RETURN (false);
virtual int save_trace_data (const char *filename)
TARGET_DEFAULT_NORETURN (tcomplain ());
/* Add/change textual notes about the trace run, returning 1 if
successful, 0 otherwise. */
- virtual int set_trace_notes (const char *user, const char *notes,
- const char *stopnotes)
- TARGET_DEFAULT_RETURN (0);
+ virtual bool set_trace_notes (const char *user, const char *notes,
+ const char *stopnotes)
+ TARGET_DEFAULT_RETURN (false);
/* Return the processor core that thread PTID was last seen on.
This information is updated only when:
/* Return the address of the start of the Thread Information Block
a Windows OS specific feature. */
- virtual int get_tib_address (ptid_t ptid, CORE_ADDR *addr)
+ virtual bool get_tib_address (ptid_t ptid, CORE_ADDR *addr)
TARGET_DEFAULT_NORETURN (tcomplain ());
/* Send the new settings of write permission variables. */
virtual traceframe_info_up traceframe_info ()
TARGET_DEFAULT_NORETURN (tcomplain ());
- /* Ask the target to use or not to use agent according to USE. Return 1
- successful, 0 otherwise. */
- virtual int use_agent (int use)
+ /* Ask the target to use or not to use agent according to USE.
+ Return true if successful, false otherwise. */
+ virtual bool use_agent (bool use)
TARGET_DEFAULT_NORETURN (tcomplain ());
/* Is the target able to use agent in current state? */
- virtual int can_use_agent ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool can_use_agent ()
+ TARGET_DEFAULT_RETURN (false);
/* Enable branch tracing for PTID using CONF configuration.
Return a branch trace target information struct for reading and for
TARGET_DEFAULT_NORETURN (tcomplain ());
/* Query if the record target is currently replaying PTID. */
- virtual int record_is_replaying (ptid_t ptid)
- TARGET_DEFAULT_RETURN (0);
+ virtual bool record_is_replaying (ptid_t ptid)
+ TARGET_DEFAULT_RETURN (false);
/* Query if the record target will replay PTID if it were resumed in
execution direction DIR. */
- virtual int record_will_replay (ptid_t ptid, int dir)
- TARGET_DEFAULT_RETURN (0);
+ virtual bool record_will_replay (ptid_t ptid, int dir)
+ TARGET_DEFAULT_RETURN (false);
/* Stop replaying. */
virtual void record_stop_replaying ()
virtual void call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
TARGET_DEFAULT_NORETURN (tcomplain ());
- /* Nonzero if TARGET_OBJECT_LIBRARIES_SVR4 may be read with a
+ /* True if TARGET_OBJECT_LIBRARIES_SVR4 may be read with a
non-empty annex. */
- virtual int augmented_libraries_svr4_read ()
- TARGET_DEFAULT_RETURN (0);
+ virtual bool augmented_libraries_svr4_read ()
+ TARGET_DEFAULT_RETURN (false);
/* Those unwinders are tried before any other arch unwinders. If
SELF doesn't have unwinders, it should delegate to the
TARGET_DEFAULT_IGNORE ();
};
+/* Deleter for std::unique_ptr. See comments in
+ target_ops::~target_ops and target_ops::close about heap-allocated
+ targets. */
+struct target_ops_deleter
+{
+ void operator() (target_ops *target)
+ {
+ target->close ();
+ }
+};
+
+/* A unique pointer for target_ops. */
+typedef std::unique_ptr<target_ops, target_ops_deleter> target_ops_up;
+
+/* Native target backends call this once at initialization time to
+ inform the core about which is the target that can respond to "run"
+ or "attach". Note: native targets are always singletons. */
+extern void set_native_target (target_ops *target);
+
+/* Get the registered native target, if there's one. Otherwise return
+ NULL. */
+extern target_ops *get_native_target ();
+
+/* Type that manages a target stack. See description of target stacks
+ and strata at the top of the file. */
+
+class target_stack
+{
+public:
+ target_stack () = default;
+ DISABLE_COPY_AND_ASSIGN (target_stack);
+
+ /* Push a new target into the stack of the existing target
+ accessors, possibly superseding some existing accessor. */
+ void push (target_ops *t);
+
+ /* Remove a target from the stack, wherever it may be. Return true
+ if it was removed, false otherwise. */
+ bool unpush (target_ops *t);
+
+ /* Returns true if T is pushed on the target stack. */
+ bool is_pushed (target_ops *t) const
+ { return at (t->to_stratum) == t; }
+
+ /* Return the target at STRATUM. */
+ target_ops *at (strata stratum) const { return m_stack[stratum]; }
+
+ /* Return the target at the top of the stack. */
+ target_ops *top () const { return at (m_top); }
+
+ /* Find the next target down the stack from the specified target. */
+ target_ops *find_beneath (const target_ops *t) const;
+
+private:
+ /* The stratum of the top target. */
+ enum strata m_top {};
+
+ /* The stack, represented as an array, with one slot per stratum.
+ If no target is pushed at some stratum, the corresponding slot is
+ null. */
+ target_ops *m_stack[(int) debug_stratum + 1] {};
+};
+
/* The ops structure for our "current" target process. This should
never be NULL. If there is no target, it points to the dummy_target. */
-extern struct target_ops *target_stack;
+extern target_ops *current_top_target ();
/* Define easy words for doing these operations on our current target. */
-#define target_shortname (target_stack->shortname ())
-#define target_longname (target_stack->longname ())
+#define target_shortname (current_top_target ()->shortname ())
+#define target_longname (current_top_target ()->longname ())
/* Does whatever cleanup is required for a target that we are no
longer going to be calling. This routine is automatically always
These targets must set to_attach_no_wait. */
#define target_attach_no_wait() \
- (target_stack->attach_no_wait ())
+ (current_top_target ()->attach_no_wait ())
/* The target_attach operation places a process under debugger control,
and stops the process.
This operation provides a target-specific hook that allows the
necessary bookkeeping to be performed after an attach completes. */
#define target_post_attach(pid) \
- (target_stack->post_attach) (pid)
+ (current_top_target ()->post_attach) (pid)
/* Display a message indicating we're about to detach from the current
inferior process. */
debugged. */
#define target_prepare_to_store(regcache) \
- (target_stack->prepare_to_store) (regcache)
+ (current_top_target ()->prepare_to_store) (regcache)
/* Determine current address space of thread PTID. */
while a trace experiment is running. */
#define target_supports_enable_disable_tracepoint() \
- (target_stack->supports_enable_disable_tracepoint) ()
+ (current_top_target ()->supports_enable_disable_tracepoint) ()
#define target_supports_string_tracing() \
- (target_stack->supports_string_tracing) ()
+ (current_top_target ()->supports_string_tracing) ()
/* Returns true if this target can handle breakpoint conditions
on its end. */
#define target_supports_evaluation_of_breakpoint_conditions() \
- (target_stack->supports_evaluation_of_breakpoint_conditions) ()
+ (current_top_target ()->supports_evaluation_of_breakpoint_conditions) ()
/* Returns true if this target can handle breakpoint commands
on its end. */
#define target_can_run_breakpoint_commands() \
- (target_stack->can_run_breakpoint_commands) ()
+ (current_top_target ()->can_run_breakpoint_commands) ()
extern int target_read_string (CORE_ADDR, gdb::unique_xmalloc_ptr<char> *,
int, int *);
/* Print a line about the current target. */
#define target_files_info() \
- (target_stack->files_info) ()
+ (current_top_target ()->files_info) ()
/* Insert a breakpoint at address BP_TGT->placed_address in
the target machine. Returns 0 for success, and returns non-zero or
Such targets will supply an appropriate definition for this function. */
#define target_post_startup_inferior(ptid) \
- (target_stack->post_startup_inferior) (ptid)
+ (current_top_target ()->post_startup_inferior) (ptid)
/* On some targets, we can catch an inferior fork or vfork event when
it occurs. These functions insert/remove an already-created
catchpoint type is not supported and -1 for failure. */
#define target_insert_fork_catchpoint(pid) \
- (target_stack->insert_fork_catchpoint) (pid)
+ (current_top_target ()->insert_fork_catchpoint) (pid)
#define target_remove_fork_catchpoint(pid) \
- (target_stack->remove_fork_catchpoint) (pid)
+ (current_top_target ()->remove_fork_catchpoint) (pid)
#define target_insert_vfork_catchpoint(pid) \
- (target_stack->insert_vfork_catchpoint) (pid)
+ (current_top_target ()->insert_vfork_catchpoint) (pid)
#define target_remove_vfork_catchpoint(pid) \
- (target_stack->remove_vfork_catchpoint) (pid)
+ (current_top_target ()->remove_vfork_catchpoint) (pid)
/* If the inferior forks or vforks, this function will be called at
the next resume in order to perform any bookkeeping and fiddling
catchpoint type is not supported and -1 for failure. */
#define target_insert_exec_catchpoint(pid) \
- (target_stack->insert_exec_catchpoint) (pid)
+ (current_top_target ()->insert_exec_catchpoint) (pid)
#define target_remove_exec_catchpoint(pid) \
- (target_stack->remove_exec_catchpoint) (pid)
+ (current_top_target ()->remove_exec_catchpoint) (pid)
/* Syscall catch.
for failure. */
#define target_set_syscall_catchpoint(pid, needed, any_count, syscall_counts) \
- (target_stack->set_syscall_catchpoint) (pid, needed, any_count, \
+ (current_top_target ()->set_syscall_catchpoint) (pid, needed, any_count, \
syscall_counts)
/* The debugger has completed a blocking wait() call. There is now
placed in OUTBUF. */
#define target_rcmd(command, outbuf) \
- (target_stack->rcmd) (command, outbuf)
+ (current_top_target ()->rcmd) (command, outbuf)
/* Does the target include all of memory, or only part of it? This
Can it lock the thread scheduler? */
#define target_can_lock_scheduler \
- (target_stack->get_thread_control_capabilities () & tc_schedlock)
+ (current_top_target ()->get_thread_control_capabilities () & tc_schedlock)
/* Controls whether async mode is permitted. */
extern int target_async_permitted;
/* Can the target support asynchronous execution? */
-#define target_can_async_p() (target_stack->can_async_p ())
+#define target_can_async_p() (current_top_target ()->can_async_p ())
/* Is the target in asynchronous execution mode? */
-#define target_is_async_p() (target_stack->is_async_p ())
+#define target_is_async_p() (current_top_target ()->is_async_p ())
/* Enables/disabled async target events. */
extern void target_async (int enable);
extern int target_is_non_stop_p (void);
#define target_execution_direction() \
- (target_stack->execution_direction ())
+ (current_top_target ()->execution_direction ())
/* Converts a process id to a string. Usually, the string just contains
`process xyz', but on some systems it may contain
is okay. */
#define target_extra_thread_info(TP) \
- (target_stack->extra_thread_info (TP))
+ (current_top_target ()->extra_thread_info (TP))
/* Return the thread's name, or NULL if the target is unable to determine it.
The returned value must not be freed by the caller. */
it must persist. */
#define target_pid_to_exec_file(pid) \
- (target_stack->pid_to_exec_file) (pid)
+ (current_top_target ()->pid_to_exec_file) (pid)
/* See the to_thread_architecture description in struct target_ops. */
#define target_thread_architecture(ptid) \
- (target_stack->thread_architecture (ptid))
+ (current_top_target ()->thread_architecture (ptid))
/*
* Iterator function for target memory regions.
*/
#define target_find_memory_regions(FUNC, DATA) \
- (target_stack->find_memory_regions) (FUNC, DATA)
+ (current_top_target ()->find_memory_regions) (FUNC, DATA)
/*
* Compose corefile .note section.
*/
#define target_make_corefile_notes(BFD, SIZE_P) \
- (target_stack->make_corefile_notes) (BFD, SIZE_P)
+ (current_top_target ()->make_corefile_notes) (BFD, SIZE_P)
/* Bookmark interfaces. */
#define target_get_bookmark(ARGS, FROM_TTY) \
- (target_stack->get_bookmark) (ARGS, FROM_TTY)
+ (current_top_target ()->get_bookmark) (ARGS, FROM_TTY)
#define target_goto_bookmark(ARG, FROM_TTY) \
- (target_stack->goto_bookmark) (ARG, FROM_TTY)
+ (current_top_target ()->goto_bookmark) (ARG, FROM_TTY)
/* Hardware watchpoint interfaces. */
write). Only the INFERIOR_PTID task is being queried. */
#define target_stopped_by_watchpoint() \
- ((target_stack->stopped_by_watchpoint) ())
+ ((current_top_target ()->stopped_by_watchpoint) ())
/* Returns non-zero if the target stopped because it executed a
software breakpoint instruction. */
#define target_stopped_by_sw_breakpoint() \
- ((target_stack->stopped_by_sw_breakpoint) ())
+ ((current_top_target ()->stopped_by_sw_breakpoint) ())
#define target_supports_stopped_by_sw_breakpoint() \
- ((target_stack->supports_stopped_by_sw_breakpoint) ())
+ ((current_top_target ()->supports_stopped_by_sw_breakpoint) ())
#define target_stopped_by_hw_breakpoint() \
- ((target_stack->stopped_by_hw_breakpoint) ())
+ ((current_top_target ()->stopped_by_hw_breakpoint) ())
#define target_supports_stopped_by_hw_breakpoint() \
- ((target_stack->supports_stopped_by_hw_breakpoint) ())
+ ((current_top_target ()->supports_stopped_by_hw_breakpoint) ())
/* Non-zero if we have steppable watchpoints */
#define target_have_steppable_watchpoint \
- (target_stack->have_steppable_watchpoint ())
+ (current_top_target ()->have_steppable_watchpoint ())
/* Non-zero if we have continuable watchpoints */
#define target_have_continuable_watchpoint \
- (target_stack->have_continuable_watchpoint ())
+ (current_top_target ()->have_continuable_watchpoint ())
/* Provide defaults for hardware watchpoint functions. */
this one used so far. */
#define target_can_use_hardware_watchpoint(TYPE,CNT,OTHERTYPE) \
- (target_stack->can_use_hw_breakpoint) ( \
+ (current_top_target ()->can_use_hw_breakpoint) ( \
TYPE, CNT, OTHERTYPE)
/* Returns the number of debug registers needed to watch the given
memory region, or zero if not supported. */
#define target_region_ok_for_hw_watchpoint(addr, len) \
- (target_stack->region_ok_for_hw_watchpoint) (addr, len)
+ (current_top_target ()->region_ok_for_hw_watchpoint) (addr, len)
#define target_can_do_single_step() \
- (target_stack->can_do_single_step) ()
+ (current_top_target ()->can_do_single_step) ()
/* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes.
TYPE is 0 for write, 1 for read, and 2 for read/write accesses.
-1 for failure. */
#define target_insert_watchpoint(addr, len, type, cond) \
- (target_stack->insert_watchpoint) (addr, len, type, cond)
+ (current_top_target ()->insert_watchpoint) (addr, len, type, cond)
#define target_remove_watchpoint(addr, len, type, cond) \
- (target_stack->remove_watchpoint) (addr, len, type, cond)
+ (current_top_target ()->remove_watchpoint) (addr, len, type, cond)
/* Insert a new masked watchpoint at ADDR using the mask MASK.
RW may be hw_read for a read watchpoint, hw_write for a write watchpoint
message) otherwise. */
#define target_insert_hw_breakpoint(gdbarch, bp_tgt) \
- (target_stack->insert_hw_breakpoint) (gdbarch, bp_tgt)
+ (current_top_target ()->insert_hw_breakpoint) (gdbarch, bp_tgt)
#define target_remove_hw_breakpoint(gdbarch, bp_tgt) \
- (target_stack->remove_hw_breakpoint) (gdbarch, bp_tgt)
+ (current_top_target ()->remove_hw_breakpoint) (gdbarch, bp_tgt)
/* Return number of debug registers needed for a ranged breakpoint,
or -1 if ranged breakpoints are not supported. */
For this reason, GDB will still evaluate the condition expression when
the watchpoint triggers. */
#define target_can_accel_watchpoint_condition(addr, len, type, cond) \
- (target_stack->can_accel_watchpoint_condition) (addr, len, type, cond)
+ (current_top_target ()->can_accel_watchpoint_condition) (addr, len, type, cond)
/* Return number of debug registers needed for a masked watchpoint,
-1 if masked watchpoints are not supported or -2 if the given address
/* Target can execute in reverse? */
#define target_can_execute_reverse \
- target_stack->can_execute_reverse ()
+ current_top_target ()->can_execute_reverse ()
extern const struct target_desc *target_read_description (struct target_ops *);
#define target_get_ada_task_ptid(lwp, tid) \
- (target_stack->get_ada_task_ptid) (lwp,tid)
+ (current_top_target ()->get_ada_task_ptid) (lwp,tid)
/* Utility implementation of searching memory. */
extern int simple_search_memory (struct target_ops* ops,
/* Return nonzero if the filesystem seen by the current inferior
is the local filesystem, zero otherwise. */
#define target_filesystem_is_local() \
- target_stack->filesystem_is_local ()
+ current_top_target ()->filesystem_is_local ()
/* Open FILENAME on the target, in the filesystem as seen by INF,
using FLAGS and MODE. If INF is NULL, use the filesystem seen
/* Tracepoint-related operations. */
#define target_trace_init() \
- (target_stack->trace_init) ()
+ (current_top_target ()->trace_init) ()
#define target_download_tracepoint(t) \
- (target_stack->download_tracepoint) (t)
+ (current_top_target ()->download_tracepoint) (t)
#define target_can_download_tracepoint() \
- (target_stack->can_download_tracepoint) ()
+ (current_top_target ()->can_download_tracepoint) ()
#define target_download_trace_state_variable(tsv) \
- (target_stack->download_trace_state_variable) (tsv)
+ (current_top_target ()->download_trace_state_variable) (tsv)
#define target_enable_tracepoint(loc) \
- (target_stack->enable_tracepoint) (loc)
+ (current_top_target ()->enable_tracepoint) (loc)
#define target_disable_tracepoint(loc) \
- (target_stack->disable_tracepoint) (loc)
+ (current_top_target ()->disable_tracepoint) (loc)
#define target_trace_start() \
- (target_stack->trace_start) ()
+ (current_top_target ()->trace_start) ()
#define target_trace_set_readonly_regions() \
- (target_stack->trace_set_readonly_regions) ()
+ (current_top_target ()->trace_set_readonly_regions) ()
#define target_get_trace_status(ts) \
- (target_stack->get_trace_status) (ts)
+ (current_top_target ()->get_trace_status) (ts)
#define target_get_tracepoint_status(tp,utp) \
- (target_stack->get_tracepoint_status) (tp, utp)
+ (current_top_target ()->get_tracepoint_status) (tp, utp)
#define target_trace_stop() \
- (target_stack->trace_stop) ()
+ (current_top_target ()->trace_stop) ()
#define target_trace_find(type,num,addr1,addr2,tpp) \
- (target_stack->trace_find) (\
+ (current_top_target ()->trace_find) (\
(type), (num), (addr1), (addr2), (tpp))
#define target_get_trace_state_variable_value(tsv,val) \
- (target_stack->get_trace_state_variable_value) ((tsv), (val))
+ (current_top_target ()->get_trace_state_variable_value) ((tsv), (val))
#define target_save_trace_data(filename) \
- (target_stack->save_trace_data) (filename)
+ (current_top_target ()->save_trace_data) (filename)
#define target_upload_tracepoints(utpp) \
- (target_stack->upload_tracepoints) (utpp)
+ (current_top_target ()->upload_tracepoints) (utpp)
#define target_upload_trace_state_variables(utsvp) \
- (target_stack->upload_trace_state_variables) (utsvp)
+ (current_top_target ()->upload_trace_state_variables) (utsvp)
#define target_get_raw_trace_data(buf,offset,len) \
- (target_stack->get_raw_trace_data) ((buf), (offset), (len))
+ (current_top_target ()->get_raw_trace_data) ((buf), (offset), (len))
#define target_get_min_fast_tracepoint_insn_len() \
- (target_stack->get_min_fast_tracepoint_insn_len) ()
+ (current_top_target ()->get_min_fast_tracepoint_insn_len) ()
#define target_set_disconnected_tracing(val) \
- (target_stack->set_disconnected_tracing) (val)
+ (current_top_target ()->set_disconnected_tracing) (val)
#define target_set_circular_trace_buffer(val) \
- (target_stack->set_circular_trace_buffer) (val)
+ (current_top_target ()->set_circular_trace_buffer) (val)
#define target_set_trace_buffer_size(val) \
- (target_stack->set_trace_buffer_size) (val)
+ (current_top_target ()->set_trace_buffer_size) (val)
#define target_set_trace_notes(user,notes,stopnotes) \
- (target_stack->set_trace_notes) ((user), (notes), (stopnotes))
+ (current_top_target ()->set_trace_notes) ((user), (notes), (stopnotes))
#define target_get_tib_address(ptid, addr) \
- (target_stack->get_tib_address) ((ptid), (addr))
+ (current_top_target ()->get_tib_address) ((ptid), (addr))
#define target_set_permissions() \
- (target_stack->set_permissions) ()
+ (current_top_target ()->set_permissions) ()
#define target_static_tracepoint_marker_at(addr, marker) \
- (target_stack->static_tracepoint_marker_at) (addr, marker)
+ (current_top_target ()->static_tracepoint_marker_at) (addr, marker)
#define target_static_tracepoint_markers_by_strid(marker_id) \
- (target_stack->static_tracepoint_markers_by_strid) (marker_id)
+ (current_top_target ()->static_tracepoint_markers_by_strid) (marker_id)
#define target_traceframe_info() \
- (target_stack->traceframe_info) ()
+ (current_top_target ()->traceframe_info) ()
#define target_use_agent(use) \
- (target_stack->use_agent) (use)
+ (current_top_target ()->use_agent) (use)
#define target_can_use_agent() \
- (target_stack->can_use_agent) ()
+ (current_top_target ()->can_use_agent) ()
#define target_augmented_libraries_svr4_read() \
- (target_stack->augmented_libraries_svr4_read) ()
+ (current_top_target ()->augmented_libraries_svr4_read) ()
/* Command logging facility. */
#define target_log_command(p) \
- (target_stack->log_command) (p)
+ (current_top_target ()->log_command) (p)
extern int target_core_of_thread (ptid_t ptid);
no matter where it is on the list. Returns 0 if no
change, 1 if removed from stack. */
-extern void add_target (struct target_ops *);
+/* Type of callback called when the user activates a target with
+ "target TARGET_NAME". The callback routine takes the rest of the
+ parameters from the command, and (if successful) pushes a new
+ target onto the stack. */
+typedef void target_open_ftype (const char *args, int from_tty);
+
+/* Add the target described by INFO to the list of possible targets
+ and add a new command 'target $(INFO->shortname)'. Set COMPLETER
+ as the command's completer if not NULL. */
-extern void add_target_with_completer (struct target_ops *t,
- completer_ftype *completer);
+extern void add_target (const target_info &info,
+ target_open_ftype *func,
+ completer_ftype *completer = NULL);
-/* Adds a command ALIAS for target T and marks it deprecated. This is useful
- for maintaining backwards compatibility when renaming targets. */
+/* Adds a command ALIAS for the target described by INFO and marks it
+ deprecated. This is useful for maintaining backwards compatibility
+ when renaming targets. */
-extern void add_deprecated_target_alias (struct target_ops *t,
+extern void add_deprecated_target_alias (const target_info &info,
const char *alias);
extern void push_target (struct target_ops *);
extern void target_require_runnable (void);
-extern struct target_ops *find_target_beneath (struct target_ops *);
-
/* Find the target at STRATUM. If no target is at that stratum,
return NULL. */
to_stratum = process_stratum;
}
- const char *shortname () override
- {
- return NULL;
- }
-
- const char *longname () override
- {
- return NULL;
- }
-
- const char *doc () override
- {
- return NULL;
- }
+ const target_info &info () const override;
- int has_registers () override
+ bool has_registers () override
{
- return 1;
+ return true;
}
- int has_stack () override
+ bool has_stack () override
{
- return 1;
+ return true;
}
- int has_memory () override
+ bool has_memory () override
{
- return 1;
+ return true;
}
void prepare_to_store (regcache *regs) override