Simple -Wshadow=local fixes
[deliverable/binutils-gdb.git] / gdb / target.h
index cd49fce92bcab0cb72faacade106b98d2689ca8d..a3000c80c6412f212abf77ca29a07278317bffcd 100644 (file)
@@ -61,7 +61,11 @@ struct inferior;
    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"
@@ -112,9 +116,8 @@ struct syscall
     const char *name;
   };
 
-/* Return a pretty printed form of TARGET_OPTIONS.
-   Space for the result is malloc'd, caller must free.  */
-extern char *target_options_to_string (int target_options);
+/* Return a pretty printed form of TARGET_OPTIONS.  */
+extern std::string target_options_to_string (int target_options);
 
 /* Possible types of events that the inferior handler will have to
    deal with.  */
@@ -199,6 +202,10 @@ enum target_object
      of the process ID of the process in question, in hexadecimal
      format.  */
   TARGET_OBJECT_EXEC_FILE,
+  /* FreeBSD virtual memory mappings.  */
+  TARGET_OBJECT_FREEBSD_VMMAP,
+  /* FreeBSD process strings.  */
+  TARGET_OBJECT_FREEBSD_PS_STRINGS,
   /* Possible future objects: TARGET_OBJECT_FILE, ...  */
 };
 
@@ -404,27 +411,45 @@ typedef void async_callback_ftype (enum inferior_event_type event_type,
 #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
@@ -531,8 +556,6 @@ struct target_ops
       TARGET_DEFAULT_RETURN (false);
     virtual int have_steppable_watchpoint ()
       TARGET_DEFAULT_RETURN (false);
-    virtual bool have_continuable_watchpoint ()
-      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)
@@ -1226,15 +1249,78 @@ struct target_ops
       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
@@ -1262,7 +1348,7 @@ extern struct target_ops *find_run_target (void);
    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.
@@ -1270,7 +1356,7 @@ extern struct target_ops *find_run_target (void);
    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.  */
@@ -1352,7 +1438,7 @@ extern void target_store_registers (struct regcache *regcache, int regs);
    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.  */
 
@@ -1373,22 +1459,22 @@ int target_supports_disable_randomization (void);
    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 *);
@@ -1471,7 +1557,7 @@ int target_write_memory_blocks
 /* 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
@@ -1521,7 +1607,7 @@ extern void target_load (const char *arg, int from_tty);
    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
@@ -1529,16 +1615,16 @@ extern void target_load (const char *arg, int from_tty);
    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
@@ -1561,10 +1647,10 @@ void target_follow_exec (struct inferior *inf, char *execd_pathname);
    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.
 
@@ -1583,7 +1669,7 @@ void target_follow_exec (struct inferior *inf, char *execd_pathname);
    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
@@ -1667,7 +1753,7 @@ extern void default_target_pass_ctrlc (struct target_ops *ops);
    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
@@ -1722,16 +1808,16 @@ extern int default_child_has_execution (ptid_t the_ptid);
    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);
@@ -1749,7 +1835,7 @@ extern enum auto_boolean target_non_stop_enabled;
 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
@@ -1764,7 +1850,7 @@ extern const char *normal_pid_to_str (ptid_t ptid);
    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.  */
@@ -1790,12 +1876,12 @@ extern struct thread_info *target_thread_handle_to_thread_info
    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.
@@ -1805,54 +1891,83 @@ extern struct thread_info *target_thread_handle_to_thread_info
  */
 
 #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.  */
 
+/* GDB's current model is that there are three "kinds" of watchpoints,
+   with respect to when they trigger and how you can move past them.
+
+   Those are: continuable, steppable, and non-steppable.
+
+   Continuable watchpoints are like x86's -- those trigger after the
+   memory access's side effects are fully committed to memory.  I.e.,
+   they trap with the PC pointing at the next instruction already.
+   Continuing past such a watchpoint is doable by just normally
+   continuing, hence the name.
+
+   Both steppable and non-steppable watchpoints trap before the memory
+   access.  I.e, the PC points at the instruction that is accessing
+   the memory.  So GDB needs to single-step once past the current
+   instruction in order to make the access effective and check whether
+   the instruction's side effects change the watched expression.
+
+   Now, in order to step past that instruction, depending on
+   architecture and target, you can have two situations:
+
+   - steppable watchpoints: you can single-step with the watchpoint
+     still armed, and the watchpoint won't trigger again.
+
+   - non-steppable watchpoints: if you try to single-step with the
+     watchpoint still armed, you'd trap the watchpoint again and the
+     thread wouldn't make any progress.  So GDB needs to temporarily
+     remove the watchpoint in order to step past it.
+
+   If your target/architecture does not signal that it has either
+   steppable or non-steppable watchpoints via either
+   target_have_steppable_watchpoint or
+   gdbarch_have_nonsteppable_watchpoint, GDB assumes continuable
+   watchpoints.  */
+
 /* Returns non-zero if we were stopped by a hardware watchpoint (memory read or
    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 ())
-
-/* Non-zero if we have continuable watchpoints  */
-
-#define target_have_continuable_watchpoint \
-  (target_stack->have_continuable_watchpoint ())
+  (current_top_target ()->have_steppable_watchpoint ())
 
 /* Provide defaults for hardware watchpoint functions.  */
 
@@ -1869,18 +1984,18 @@ extern struct thread_info *target_thread_handle_to_thread_info
    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.
@@ -1889,10 +2004,10 @@ extern struct thread_info *target_thread_handle_to_thread_info
    -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
@@ -1916,10 +2031,10 @@ extern int target_remove_mask_watchpoint (CORE_ADDR, CORE_ADDR,
    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.  */
@@ -1948,7 +2063,7 @@ extern int target_ranged_break_num_registers (void);
    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
@@ -1958,12 +2073,12 @@ extern int target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask);
 
 /* 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,
@@ -1985,7 +2100,7 @@ extern int target_search_memory (CORE_ADDR start_addr,
 /* 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
@@ -2072,100 +2187,100 @@ extern gdb::unique_xmalloc_ptr<char> target_fileio_read_stralloc
 /* 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);
@@ -2207,15 +2322,25 @@ int target_verify_memory (const gdb_byte *data,
    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 *);
@@ -2325,8 +2450,6 @@ extern void noprocess (void) ATTRIBUTE_NORETURN;
 
 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.  */
 
@@ -2466,20 +2589,7 @@ public:
     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;
 
   bool has_registers () override
   {
This page took 0.035681 seconds and 4 git commands to generate.