/* Interface between GDB and target environments, including files and processes
- Copyright (C) 1990-2018 Free Software Foundation, Inc.
+ Copyright (C) 1990-2020 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by John Gilmore.
#include "infrun.h" /* For enum exec_direction_kind. */
#include "breakpoint.h" /* For enum bptype. */
-#include "common/scoped_restore.h"
+#include "gdbsupport/scoped_restore.h"
+#include "gdbsupport/refcounted-object.h"
/* This include file defines the interface between the main part
of the debugger, and the part which is target-specific, or
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"
#include "bfd.h"
#include "symtab.h"
#include "memattr.h"
-#include "vec.h"
-#include "gdb_signals.h"
+#include "gdbsupport/gdb_signals.h"
#include "btrace.h"
#include "record.h"
#include "command.h"
#include "disasm.h"
#include "tracepoint.h"
-#include "break-common.h" /* For enum target_hw_bp_type. */
+#include "gdbsupport/break-common.h" /* For enum target_hw_bp_type. */
enum strata
{
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. */
{
/* AVR target specific transfer. See "avr-tdep.c" and "remote.c". */
TARGET_OBJECT_AVR,
- /* SPU target specific transfer. See "spu-tdep.c". */
- TARGET_OBJECT_SPU,
/* Transfer up-to LEN bytes of memory starting at OFFSET. */
TARGET_OBJECT_MEMORY,
/* Memory, avoiding GDB's data cache and trusting the executable.
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, ... */
};
};
struct target_ops
+ : public refcounted_object
{
- struct target_ops *beneath; /* To the target under this one. */
+ /* Return this target's stratum. */
+ virtual strata stratum () const = 0;
+
+ /* 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
virtual const target_info &info () const = 0;
/* Name this target type. */
- const char *shortname ()
+ const char *shortname () const
{ return info ().shortname; }
- const char *longname ()
+ const char *longname () const
{ return info ().longname; }
/* Close the target. This is where the target can handle
TARGET_DEFAULT_NORETURN (noprocess ());
virtual void commit_resume ()
TARGET_DEFAULT_IGNORE ();
+ /* See target_wait's description. Note that implementations of
+ this method must not assume that inferior_ptid on entry is
+ pointing at the thread or inferior that ends up reporting an
+ event. The reported event could be for some other thread in
+ the current inferior or even for a different process of the
+ current target. inferior_ptid may also be null_ptid on
+ entry. */
virtual ptid_t wait (ptid_t, struct target_waitstatus *,
int TARGET_DEBUG_PRINTER (target_debug_print_options))
TARGET_DEFAULT_FUNC (default_target_wait);
TARGET_DEFAULT_RETURN (1);
virtual bool stopped_by_watchpoint ()
TARGET_DEFAULT_RETURN (false);
- virtual int have_steppable_watchpoint ()
- TARGET_DEFAULT_RETURN (false);
- virtual bool have_continuable_watchpoint ()
+ virtual bool have_steppable_watchpoint ()
TARGET_DEFAULT_RETURN (false);
virtual bool stopped_data_address (CORE_ADDR *)
TARGET_DEFAULT_RETURN (false);
TARGET_DEFAULT_RETURN (1);
virtual int remove_vfork_catchpoint (int)
TARGET_DEFAULT_RETURN (1);
- virtual int follow_fork (int, int)
+ virtual bool follow_fork (bool, bool)
TARGET_DEFAULT_FUNC (default_follow_fork);
virtual int insert_exec_catchpoint (int)
TARGET_DEFAULT_RETURN (1);
virtual int remove_exec_catchpoint (int)
TARGET_DEFAULT_RETURN (1);
- virtual void follow_exec (struct inferior *, char *)
+ virtual void follow_exec (struct inferior *, const char *)
TARGET_DEFAULT_IGNORE ();
virtual int set_syscall_catchpoint (int, bool, int,
gdb::array_view<const int>)
/* Documentation of this routine is provided with the corresponding
target_* macro. */
- virtual void pass_signals (int,
- unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
+ virtual void pass_signals (gdb::array_view<const unsigned char> TARGET_DEBUG_PRINTER (target_debug_print_signals))
TARGET_DEFAULT_IGNORE ();
/* Documentation of this routine is provided with the
corresponding target_* function. */
- virtual void program_signals (int,
- unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
+ virtual void program_signals (gdb::array_view<const unsigned char> TARGET_DEBUG_PRINTER (target_debug_print_signals))
TARGET_DEFAULT_IGNORE ();
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)
+ virtual std::string pid_to_str (ptid_t)
TARGET_DEFAULT_FUNC (default_pid_to_str);
virtual const char *extra_thread_info (thread_info *)
TARGET_DEFAULT_RETURN (NULL);
int,
inferior *inf)
TARGET_DEFAULT_RETURN (NULL);
+ /* See target_thread_info_to_thread_handle. */
+ virtual gdb::byte_vector thread_info_to_thread_handle (struct thread_info *)
+ TARGET_DEFAULT_RETURN (gdb::byte_vector ());
virtual void stop (ptid_t)
TARGET_DEFAULT_IGNORE ();
virtual void interrupt ()
TARGET_DEFAULT_IGNORE ();
virtual struct target_section_table *get_section_table ()
TARGET_DEFAULT_RETURN (NULL);
- enum strata to_stratum;
/* Provide default values for all "must have" methods. */
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; }
+ virtual bool has_execution (inferior *inf) { return false; }
/* Control thread execution. */
virtual thread_control_capabilities get_thread_control_capabilities ()
TARGET_DEFAULT_RETURN (false);
virtual void async (int)
TARGET_DEFAULT_NORETURN (tcomplain ());
+ virtual int async_wait_fd ()
+ TARGET_DEFAULT_NORETURN (noprocess ());
virtual void thread_events (int)
TARGET_DEFAULT_IGNORE ();
/* This method must be implemented in some situations. See the
TARGET_DEFAULT_NORETURN (tcomplain ());
/* Return the thread-local address at OFFSET in the
thread-local storage for the thread PTID and the shared library
- or executable file given by OBJFILE. If that block of
+ or executable file given by LOAD_MODULE_ADDR. If that block of
thread-local storage hasn't been allocated yet, this function
- may return an error. LOAD_MODULE_ADDR may be zero for statically
+ may throw an error. LOAD_MODULE_ADDR may be zero for statically
linked multithreaded inferiors. */
virtual CORE_ADDR get_thread_local_address (ptid_t ptid,
CORE_ADDR load_module_addr,
/* Determine current architecture of thread PTID.
The target is supposed to determine the architecture of the code where
- the target is currently stopped at (on Cell, if a target is in spu_run,
- to_thread_architecture would return SPU, otherwise PPC32 or PPC64).
- This is architecture used to perform decr_pc_after_break adjustment,
- and also determines the frame architecture of the innermost frame.
- ptrace operations need to operate according to target_gdbarch ().
-
- The default implementation always returns target_gdbarch (). */
+ the target is currently stopped at. The architecture information is
+ used to perform decr_pc_after_break adjustment, and also to determine
+ the frame architecture of the innermost frame. ptrace operations need to
+ operate according to target_gdbarch (). */
virtual struct gdbarch *thread_architecture (ptid_t)
- TARGET_DEFAULT_FUNC (default_thread_architecture);
-
- /* Determine current address space of thread PTID.
+ TARGET_DEFAULT_RETURN (NULL);
- The default implementation always returns the inferior's
- address space. */
+ /* Determine current address space of thread PTID. */
virtual struct address_space *thread_address_space (ptid_t)
- TARGET_DEFAULT_FUNC (default_thread_address_space);
+ TARGET_DEFAULT_RETURN (NULL);
/* Target file operations. */
/* A unique pointer for target_ops. */
typedef std::unique_ptr<target_ops, target_ops_deleter> target_ops_up;
+/* Decref a target and close if, if there are no references left. */
+extern void decref_target (target_ops *t);
+
+/* A policy class to interface gdb::ref_ptr with target_ops. */
+
+struct target_ops_ref_policy
+{
+ static void incref (target_ops *t)
+ {
+ t->incref ();
+ }
+
+ static void decref (target_ops *t)
+ {
+ decref_target (t);
+ }
+};
+
+/* A gdb::ref_ptr pointer to a target_ops. */
+typedef gdb::ref_ptr<target_ops, target_ops_ref_policy> target_ops_ref;
+
/* 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. */
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->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 target_ops *current_top_target ();
+/* Return the dummy target. */
+extern target_ops *get_dummy_target ();
+
/* Define easy words for doing these operations on our current target. */
#define target_shortname (current_top_target ()->shortname ())
#define target_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 *);
+/* Read a string from target memory at address MEMADDR. The string
+ will be at most LEN bytes long (note that excess bytes may be read
+ in some cases -- but these will not be returned). Returns nullptr
+ on error. */
+
+extern gdb::unique_xmalloc_ptr<char> target_read_string
+ (CORE_ADDR memaddr, int len, int *bytes_read = nullptr);
/* For target_read_memory see target/target.h. */
that supports writing to flash memory, and it should be used for
all cases where access to flash memory is desirable.
- REQUESTS is the vector (see vec.h) of memory_write_request.
+ REQUESTS is the vector of memory_write_request.
PRESERVE_FLASH_P indicates what to do with blocks which must be
erased, but not completely rewritten.
PROGRESS_CB is a function that will be periodically called to provide
/* Return true if the target stack has a non-default
"terminal_ours" method. */
-extern int target_supports_terminal_ours (void);
+extern bool target_supports_terminal_ours (void);
/* Kill the inferior process. Make it go away. */
necessary to continue debugging either the parent or child, as
requested, and releasing the other. Information about the fork
or vfork event is available via get_last_target_status ().
- This function returns 1 if the inferior should not be resumed
+ This function returns true if the inferior should not be resumed
(i.e. there is another event pending). */
-int target_follow_fork (int follow_child, int detach_fork);
+bool target_follow_fork (bool follow_child, bool detach_fork);
/* Handle the target-specific bookkeeping required when the inferior
makes an exec call. INF is the exec'd inferior. */
-void target_follow_exec (struct inferior *inf, char *execd_pathname);
+void target_follow_exec (struct inferior *inf, const char *execd_pathname);
/* On some targets, we can catch an inferior exec event when it
occurs. These functions insert/remove an already-created
/* Set list of signals to be handled in the target.
- PASS_SIGNALS is an array of size NSIG, indexed by target signal number
+ PASS_SIGNALS is an array indexed by target signal number
(enum gdb_signal). For every signal whose entry in this array is
non-zero, the target is allowed -but not required- to skip reporting
arrival of the signal to the GDB core by returning from target_wait,
about to receive a signal, it needs to be reported in any case, even
if mentioned in a previous target_pass_signals call. */
-extern void target_pass_signals (int nsig, unsigned char *pass_signals);
+extern void target_pass_signals
+ (gdb::array_view<const unsigned char> pass_signals);
/* Set list of signals the target may pass to the inferior. This
directly maps to the "handle SIGNAL pass/nopass" setting.
- PROGRAM_SIGNALS is an array of size NSIG, indexed by target signal
+ PROGRAM_SIGNALS is an array indexed by target signal
number (enum gdb_signal). For every signal whose entry in this
array is non-zero, the target is allowed to pass the signal to the
inferior. Signals not present in the array shall be silently
example, when detaching (as threads may have been suspended with
pending signals not reported to GDB). */
-extern void target_program_signals (int nsig, unsigned char *program_signals);
+extern void target_program_signals
+ (gdb::array_view<const unsigned char> program_signals);
/* Check to see if a thread is still alive. */
case this will become true after to_create_inferior or
to_attach. */
-extern int target_has_execution_1 (ptid_t);
+extern bool target_has_execution_1 (inferior *inf);
-/* Like target_has_execution_1, but always passes inferior_ptid. */
+/* Like target_has_execution_1, but always passes
+ current_inferior(). */
extern int target_has_execution_current (void);
#define target_has_execution target_has_execution_current ()
-/* Default implementations for process_stratum targets. Return true
- if there's a selected inferior, false otherwise. */
-
-extern int default_child_has_all_memory ();
-extern int default_child_has_memory ();
-extern int default_child_has_stack ();
-extern int default_child_has_registers ();
-extern int default_child_has_execution (ptid_t the_ptid);
-
/* Can the target support the debugger control of thread execution?
Can it lock the thread scheduler? */
(current_top_target ()->get_thread_control_capabilities () & tc_schedlock)
/* Controls whether async mode is permitted. */
-extern int target_async_permitted;
+extern bool target_async_permitted;
/* Can the target support asynchronous execution? */
#define target_can_async_p() (current_top_target ()->can_async_p ())
non-stop" is on. */
extern int target_is_non_stop_p (void);
+/* Return true if at least one inferior has a non-stop target. */
+extern bool exists_non_stop_target ();
+
#define target_execution_direction() \
(current_top_target ()->execution_direction ())
`process xyz', but on some systems it may contain
`process xyz thread abc'. */
-extern const char *target_pid_to_str (ptid_t ptid);
+extern std::string target_pid_to_str (ptid_t ptid);
-extern const char *normal_pid_to_str (ptid_t ptid);
+extern std::string normal_pid_to_str (ptid_t ptid);
/* Return a short string describing extra information about PID,
e.g. "sleeping", "runnable", "running on LWP 3". Null return value
extern struct thread_info *target_thread_handle_to_thread_info
(const gdb_byte *thread_handle, int handle_len, struct inferior *inf);
+/* Given a thread, return the thread handle, a target-specific sequence of
+ bytes which serves as a thread identifier within the program being
+ debugged. */
+extern gdb::byte_vector target_thread_info_to_thread_handle
+ (struct thread_info *);
+
/* Attempts to find the pathname of the executable file
that was run to create a specified process.
/* 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_have_steppable_watchpoint \
(current_top_target ()->have_steppable_watchpoint ())
-/* Non-zero if we have continuable watchpoints */
-
-#define target_have_continuable_watchpoint \
- (current_top_target ()->have_continuable_watchpoint ())
-
/* Provide defaults for hardware watchpoint functions. */
/* If the *_hw_beakpoint functions have not been defined
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
- by the debugger (GDB or, for remote targets, the remote stub).
- Return a target file descriptor, or -1 if an error occurs (and
- set *TARGET_ERRNO). */
+ using FLAGS and MODE. If INF is NULL, use the filesystem seen by
+ the debugger (GDB or, for remote targets, the remote stub). Return
+ a target file descriptor, or -1 if an error occurs (and set
+ *TARGET_ERRNO). If WARN_IF_SLOW is true, print a warning message
+ if the file is being accessed over a link that may be slow. */
extern int target_fileio_open (struct inferior *inf,
const char *filename, int flags,
- int mode, int *target_errno);
-
-/* Like target_fileio_open, but print a warning message if the
- file is being accessed over a link that may be slow. */
-extern int target_fileio_open_warn_if_slow (struct inferior *inf,
- const char *filename,
- int flags,
- int mode,
- int *target_errno);
+ int mode, bool warn_if_slow,
+ int *target_errno);
/* Write up to LEN bytes from WRITE_BUF to FD on the target.
Return the number of bytes written, or -1 if an error occurs
extern void push_target (struct target_ops *);
+/* An overload that deletes the target on failure. */
+extern void push_target (target_ops_up &&);
+
extern int unpush_target (struct target_ops *);
extern void target_pre_inferior (int);
strictly above ABOVE_STRATUM. */
extern void pop_all_targets_above (enum strata above_stratum);
-extern int target_is_pushed (struct target_ops *t);
+extern bool target_is_pushed (target_ops *t);
extern CORE_ADDR target_translate_tls_address (struct objfile *objfile,
CORE_ADDR offset);
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. */
extern scoped_restore_tmpl<int>
make_scoped_restore_show_memory_breakpoints (int show);
-extern int may_write_registers;
-extern int may_write_memory;
-extern int may_insert_breakpoints;
-extern int may_insert_tracepoints;
-extern int may_insert_fast_tracepoints;
-extern int may_stop;
+extern bool may_write_registers;
+extern bool may_write_memory;
+extern bool may_insert_breakpoints;
+extern bool may_insert_tracepoints;
+extern bool may_insert_fast_tracepoints;
+extern bool may_stop;
extern void update_target_permissions (void);
/* See to_done_generating_core. */
extern void target_done_generating_core (void);
-#if GDB_SELF_TEST
-namespace selftests {
-
-/* A mock process_stratum target_ops that doesn't read/write registers
- anywhere. */
-
-class test_target_ops : public target_ops
-{
-public:
- test_target_ops ()
- : target_ops {}
- {
- to_stratum = process_stratum;
- }
-
- const target_info &info () const override;
-
- bool has_registers () override
- {
- return true;
- }
-
- bool has_stack () override
- {
- return true;
- }
-
- bool has_memory () override
- {
- return true;
- }
-
- void prepare_to_store (regcache *regs) override
- {
- }
-
- void store_registers (regcache *regs, int regno) override
- {
- }
-};
-
-
-} // namespace selftests
-#endif /* GDB_SELF_TEST */
-
#endif /* !defined (TARGET_H) */