along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include <errno.h>
-#include <string.h>
#include "target.h"
#include "target-dcache.h"
#include "gdbcmd.h"
#include "symtab.h"
#include "inferior.h"
+#include "infrun.h"
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
#include "dcache.h"
#include <signal.h>
#include "regcache.h"
-#include "gdb_assert.h"
#include "gdbcore.h"
-#include "exceptions.h"
#include "target-descriptions.h"
#include "gdbthread.h"
#include "solib.h"
#include "tracepoint.h"
#include "gdb/fileio.h"
#include "agent.h"
+#include "auxv.h"
+#include "target-debug.h"
static void target_info (char *, int);
+static void generic_tls_error (void) ATTRIBUTE_NORETURN;
+
static void default_terminal_info (struct target_ops *, const char *, int);
static int default_watchpoint_addr_within_range (struct target_ops *,
static int default_region_ok_for_hw_watchpoint (struct target_ops *,
CORE_ADDR, int);
-static void default_rcmd (struct target_ops *, char *, struct ui_file *);
+static void default_rcmd (struct target_ops *, const char *, struct ui_file *);
static ptid_t default_get_ada_task_ptid (struct target_ops *self,
long lwp, long tid);
-static void tcomplain (void) ATTRIBUTE_NORETURN;
+static int default_follow_fork (struct target_ops *self, int follow_child,
+ int detach_fork);
+
+static void default_mourn_inferior (struct target_ops *self);
+
+static int default_search_memory (struct target_ops *ops,
+ CORE_ADDR start_addr,
+ ULONGEST search_space_len,
+ const gdb_byte *pattern,
+ ULONGEST pattern_len,
+ CORE_ADDR *found_addrp);
-static int nomemory (CORE_ADDR, char *, int, int, struct target_ops *);
+static int default_verify_memory (struct target_ops *self,
+ const gdb_byte *data,
+ CORE_ADDR memaddr, ULONGEST size);
-static int return_zero (void);
+static struct address_space *default_thread_address_space
+ (struct target_ops *self, ptid_t ptid);
-void target_ignore (void);
+static void tcomplain (void) ATTRIBUTE_NORETURN;
+
+static int return_zero (struct target_ops *);
+
+static int return_zero_has_execution (struct target_ops *, ptid_t);
static void target_command (char *, int);
static struct target_ops *find_default_run_target (char *);
-static target_xfer_partial_ftype default_xfer_partial;
-
static struct gdbarch *default_thread_architecture (struct target_ops *ops,
ptid_t ptid);
static char *dummy_make_corefile_notes (struct target_ops *self,
bfd *ignore1, int *ignore2);
-static int find_default_can_async_p (struct target_ops *ignore);
-
-static int find_default_is_async_p (struct target_ops *ignore);
+static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
static enum exec_direction_kind default_execution_direction
(struct target_ops *self);
-#include "target-delegates.c"
-
-static void init_dummy_target (void);
+static CORE_ADDR default_target_decr_pc_after_break (struct target_ops *ops,
+ struct gdbarch *gdbarch);
static struct target_ops debug_target;
-static void debug_to_open (char *, int);
-
-static void debug_to_prepare_to_store (struct target_ops *self,
- struct regcache *);
-
-static void debug_to_files_info (struct target_ops *);
-
-static int debug_to_insert_breakpoint (struct target_ops *, struct gdbarch *,
- struct bp_target_info *);
-
-static int debug_to_remove_breakpoint (struct target_ops *, struct gdbarch *,
- struct bp_target_info *);
-
-static int debug_to_can_use_hw_breakpoint (struct target_ops *self,
- int, int, int);
-
-static int debug_to_insert_hw_breakpoint (struct target_ops *self,
- struct gdbarch *,
- struct bp_target_info *);
-
-static int debug_to_remove_hw_breakpoint (struct target_ops *self,
- struct gdbarch *,
- struct bp_target_info *);
-
-static int debug_to_insert_watchpoint (struct target_ops *self,
- CORE_ADDR, int, int,
- struct expression *);
-
-static int debug_to_remove_watchpoint (struct target_ops *self,
- CORE_ADDR, int, int,
- struct expression *);
-
-static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *);
-
-static int debug_to_watchpoint_addr_within_range (struct target_ops *,
- CORE_ADDR, CORE_ADDR, int);
-
-static int debug_to_region_ok_for_hw_watchpoint (struct target_ops *self,
- CORE_ADDR, int);
-
-static int debug_to_can_accel_watchpoint_condition (struct target_ops *self,
- CORE_ADDR, int, int,
- struct expression *);
-
-static void debug_to_terminal_init (struct target_ops *self);
-
-static void debug_to_terminal_inferior (struct target_ops *self);
-
-static void debug_to_terminal_ours_for_output (struct target_ops *self);
-
-static void debug_to_terminal_save_ours (struct target_ops *self);
-
-static void debug_to_terminal_ours (struct target_ops *self);
-
-static void debug_to_load (struct target_ops *self, char *, int);
+#include "target-delegates.c"
-static int debug_to_can_run (struct target_ops *self);
+static void init_dummy_target (void);
-static void debug_to_stop (struct target_ops *self, ptid_t);
+static void update_current_target (void);
-/* Pointer to array of target architecture structures; the size of the
- array; the current index into the array; the allocated size of the
- array. */
-struct target_ops **target_structs;
-unsigned target_struct_size;
-unsigned target_struct_allocsize;
-#define DEFAULT_ALLOCSIZE 10
+/* Vector of existing target structures. */
+typedef struct target_ops *target_ops_p;
+DEF_VEC_P (target_ops_p);
+static VEC (target_ops_p) *target_structs;
/* The initial current target, so that there is always a semi-valid
current target. */
/* Non-zero if we want to see trace of target level stuff. */
static unsigned int targetdebug = 0;
+
+static void
+set_targetdebug (char *args, int from_tty, struct cmd_list_element *c)
+{
+ update_current_target ();
+}
+
static void
show_targetdebug (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
complete_target_initialization (struct target_ops *t)
{
/* Provide default values for all "must have" methods. */
- if (t->to_xfer_partial == NULL)
- t->to_xfer_partial = default_xfer_partial;
if (t->to_has_all_memory == NULL)
- t->to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
+ t->to_has_all_memory = return_zero;
if (t->to_has_memory == NULL)
- t->to_has_memory = (int (*) (struct target_ops *)) return_zero;
+ t->to_has_memory = return_zero;
if (t->to_has_stack == NULL)
- t->to_has_stack = (int (*) (struct target_ops *)) return_zero;
+ t->to_has_stack = return_zero;
if (t->to_has_registers == NULL)
- t->to_has_registers = (int (*) (struct target_ops *)) return_zero;
+ t->to_has_registers = return_zero;
if (t->to_has_execution == NULL)
- t->to_has_execution = (int (*) (struct target_ops *, ptid_t)) return_zero;
+ t->to_has_execution = return_zero_has_execution;
+
+ /* These methods can be called on an unpushed target and so require
+ a default implementation if the target might plausibly be the
+ default run target. */
+ gdb_assert (t->to_can_run == NULL || (t->to_can_async_p != NULL
+ && t->to_supports_non_stop != NULL));
install_delegators (t);
}
+/* This is used to implement the various target commands. */
+
+static void
+open_target (char *args, int from_tty, struct cmd_list_element *command)
+{
+ struct target_ops *ops = get_cmd_context (command);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "-> %s->to_open (...)\n",
+ ops->to_shortname);
+
+ ops->to_open (args, from_tty);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "<- %s->to_open (%s, %d)\n",
+ ops->to_shortname, args, from_tty);
+}
+
/* Add possible target architecture T to the list and add a new
command 'target T->to_shortname'. Set COMPLETER as the command's
completer if not NULL. */
complete_target_initialization (t);
- if (!target_structs)
- {
- target_struct_allocsize = DEFAULT_ALLOCSIZE;
- target_structs = (struct target_ops **) xmalloc
- (target_struct_allocsize * sizeof (*target_structs));
- }
- if (target_struct_size >= target_struct_allocsize)
- {
- target_struct_allocsize *= 2;
- target_structs = (struct target_ops **)
- xrealloc ((char *) target_structs,
- target_struct_allocsize * sizeof (*target_structs));
- }
- target_structs[target_struct_size++] = t;
+ VEC_safe_push (target_ops_p, target_structs, t);
if (targetlist == NULL)
add_prefix_cmd ("target", class_run, target_command, _("\
information on the arguments for a particular protocol, type\n\
`help target ' followed by the protocol name."),
&targetlist, "target ", 0, &cmdlist);
- c = add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc,
- &targetlist);
+ c = add_cmd (t->to_shortname, no_class, NULL, t->to_doc, &targetlist);
+ set_cmd_sfunc (c, open_target);
+ set_cmd_context (c, t);
if (completer != NULL)
set_cmd_completer (c, completer);
}
/* If we use add_alias_cmd, here, we do not get the deprecated warning,
see PR cli/15104. */
- c = add_cmd (alias, no_class, t->to_open, t->to_doc, &targetlist);
+ c = add_cmd (alias, no_class, NULL, t->to_doc, &targetlist);
+ set_cmd_sfunc (c, open_target);
+ set_cmd_context (c, t);
alt = xstrprintf ("target %s", t->to_shortname);
deprecate_cmd (c, alt);
}
/* Stub functions */
void
-target_ignore (void)
-{
-}
-
-void
target_kill (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_kill != NULL)
- {
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_kill ()\n");
-
- t->to_kill (t);
- return;
- }
-
- noprocess ();
+ current_target.to_kill (¤t_target);
}
void
-target_load (char *arg, int from_tty)
+target_load (const char *arg, int from_tty)
{
target_dcache_invalidate ();
(*current_target.to_load) (¤t_target, arg, from_tty);
}
void
-target_create_inferior (char *exec_file, char *args,
- char **env, int from_tty)
-{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_create_inferior != NULL)
- {
- t->to_create_inferior (t, exec_file, args, env, from_tty);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_create_inferior (%s, %s, xxx, %d)\n",
- exec_file, args, from_tty);
- return;
- }
- }
-
- internal_error (__FILE__, __LINE__,
- _("could not find a target to create inferior"));
-}
-
-void
target_terminal_inferior (void)
{
/* A background resume (``run&'') should leave GDB in control of the
(*current_target.to_terminal_inferior) (¤t_target);
}
-static int
-nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write,
- struct target_ops *t)
+/* See target.h. */
+
+int
+target_supports_terminal_ours (void)
{
- errno = EIO; /* Can't read/write this location. */
- return 0; /* No bytes handled. */
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_terminal_ours != delegate_terminal_ours
+ && t->to_terminal_ours != tdefault_terminal_ours)
+ return 1;
+ }
+
+ return 0;
}
static void
/* Install the delegators. */
install_delegators (¤t_target);
+ current_target.to_stratum = target_stack->to_stratum;
+
#define INHERIT(FIELD, TARGET) \
if (!current_target.FIELD) \
current_target.FIELD = (TARGET)->FIELD
+ /* Do not add any new INHERITs here. Instead, use the delegation
+ mechanism provided by make-target-delegates. */
for (t = target_stack; t; t = t->beneath)
{
INHERIT (to_shortname, t);
INHERIT (to_longname, t);
- INHERIT (to_doc, t);
- /* Do not inherit to_open. */
- /* Do not inherit to_close. */
- /* Do not inherit to_attach. */
- /* Do not inherit to_post_attach. */
INHERIT (to_attach_no_wait, t);
- /* Do not inherit to_detach. */
- /* Do not inherit to_disconnect. */
- /* Do not inherit to_resume. */
- /* Do not inherit to_wait. */
- /* Do not inherit to_fetch_registers. */
- /* Do not inherit to_store_registers. */
- /* Do not inherit to_prepare_to_store. */
- INHERIT (deprecated_xfer_memory, t);
- /* Do not inherit to_files_info. */
- /* Do not inherit to_insert_breakpoint. */
- /* Do not inherit to_remove_breakpoint. */
- /* Do not inherit to_can_use_hw_breakpoint. */
- /* Do not inherit to_insert_hw_breakpoint. */
- /* Do not inherit to_remove_hw_breakpoint. */
- /* Do not inherit to_ranged_break_num_registers. */
- /* Do not inherit to_insert_watchpoint. */
- /* Do not inherit to_remove_watchpoint. */
- /* Do not inherit to_insert_mask_watchpoint. */
- /* Do not inherit to_remove_mask_watchpoint. */
- /* Do not inherit to_stopped_data_address. */
INHERIT (to_have_steppable_watchpoint, t);
INHERIT (to_have_continuable_watchpoint, t);
- /* Do not inherit to_stopped_by_watchpoint. */
- /* Do not inherit to_watchpoint_addr_within_range. */
- /* Do not inherit to_region_ok_for_hw_watchpoint. */
- /* Do not inherit to_can_accel_watchpoint_condition. */
- /* Do not inherit to_masked_watch_num_registers. */
- /* Do not inherit to_terminal_init. */
- /* Do not inherit to_terminal_inferior. */
- /* Do not inherit to_terminal_ours_for_output. */
- /* Do not inherit to_terminal_ours. */
- /* Do not inherit to_terminal_save_ours. */
- /* Do not inherit to_terminal_info. */
- /* Do not inherit to_kill. */
- /* Do not inherit to_load. */
- /* Do no inherit to_create_inferior. */
- /* Do not inherit to_post_startup_inferior. */
- /* Do not inherit to_insert_fork_catchpoint. */
- /* Do not inherit to_remove_fork_catchpoint. */
- /* Do not inherit to_insert_vfork_catchpoint. */
- /* Do not inherit to_remove_vfork_catchpoint. */
- /* Do not inherit to_follow_fork. */
- /* Do not inherit to_insert_exec_catchpoint. */
- /* Do not inherit to_remove_exec_catchpoint. */
- /* Do not inherit to_set_syscall_catchpoint. */
- /* Do not inherit to_has_exited. */
- /* Do not inherit to_mourn_inferior. */
- INHERIT (to_can_run, t);
- /* Do not inherit to_pass_signals. */
- /* Do not inherit to_program_signals. */
- /* Do not inherit to_thread_alive. */
- /* Do not inherit to_find_new_threads. */
- /* Do not inherit to_pid_to_str. */
- /* Do not inherit to_extra_thread_info. */
- /* Do not inherit to_thread_name. */
- /* Do not inherit to_stop. */
- /* Do not inherit to_xfer_partial. */
- /* Do not inherit to_rcmd. */
- /* Do not inherit to_pid_to_exec_file. */
- /* Do not inherit to_log_command. */
- INHERIT (to_stratum, t);
- /* Do not inherit to_has_all_memory. */
- /* Do not inherit to_has_memory. */
- /* Do not inherit to_has_stack. */
- /* Do not inherit to_has_registers. */
- /* Do not inherit to_has_execution. */
INHERIT (to_has_thread_control, t);
- /* Do not inherit to_can_async_p. */
- /* Do not inherit to_is_async_p. */
- /* Do not inherit to_async. */
- /* Do not inherit to_find_memory_regions. */
- /* Do not inherit to_make_corefile_notes. */
- /* Do not inherit to_get_bookmark. */
- /* Do not inherit to_goto_bookmark. */
- /* Do not inherit to_get_thread_local_address. */
- /* Do not inherit to_can_execute_reverse. */
- /* Do not inherit to_execution_direction. */
- /* Do not inherit to_thread_architecture. */
- /* Do not inherit to_read_description. */
- /* Do not inherit to_get_ada_task_ptid. */
- /* Do not inherit to_search_memory. */
- /* Do not inherit to_supports_multi_process. */
- /* Do not inherit to_supports_enable_disable_tracepoint. */
- /* Do not inherit to_supports_string_tracing. */
- /* Do not inherit to_trace_init. */
- /* Do not inherit to_download_tracepoint. */
- /* Do not inherit to_can_download_tracepoint. */
- /* Do not inherit to_download_trace_state_variable. */
- /* Do not inherit to_enable_tracepoint. */
- /* Do not inherit to_disable_tracepoint. */
- /* Do not inherit to_trace_set_readonly_regions. */
- /* Do not inherit to_trace_start. */
- /* Do not inherit to_get_trace_status. */
- /* Do not inherit to_get_tracepoint_status. */
- /* Do not inherit to_trace_stop. */
- /* Do not inherit to_trace_find. */
- /* Do not inherit to_get_trace_state_variable_value. */
- /* Do not inherit to_save_trace_data. */
- /* Do not inherit to_upload_tracepoints. */
- /* Do not inherit to_upload_trace_state_variables. */
- /* Do not inherit to_get_raw_trace_data. */
- /* Do not inherit to_get_min_fast_tracepoint_insn_len. */
- /* Do not inherit to_set_disconnected_tracing. */
- /* Do not inherit to_set_circular_trace_buffer. */
- /* Do not inherit to_set_trace_buffer_size. */
- /* Do not inherit to_set_trace_notes. */
- /* Do not inherit to_get_tib_address. */
- /* Do not inherit to_set_permissions. */
- /* Do not inherit to_static_tracepoint_marker_at. */
- /* Do not inherit to_static_tracepoint_markers_by_strid. */
- /* Do not inherit to_traceframe_info. */
- /* Do not inherit to_use_agent. */
- /* Do not inherit to_can_use_agent. */
- /* Do not inherit to_augmented_libraries_svr4_read. */
- INHERIT (to_magic, t);
- /* Do not inherit
- to_supports_evaluation_of_breakpoint_conditions. */
- /* Do not inherit to_can_run_breakpoint_commands. */
- /* Do not inherit to_memory_map. */
- /* Do not inherit to_flash_erase. */
- /* Do not inherit to_flash_done. */
}
#undef INHERIT
- /* Clean up a target struct so it no longer has any zero pointers in
- it. Some entries are defaulted to a method that print an error,
- others are hard-wired to a standard recursive default. */
-
-#define de_fault(field, value) \
- if (!current_target.field) \
- current_target.field = value
-
- de_fault (to_open,
- (void (*) (char *, int))
- tcomplain);
- de_fault (to_close,
- (void (*) (struct target_ops *))
- target_ignore);
- de_fault (deprecated_xfer_memory,
- (int (*) (CORE_ADDR, gdb_byte *, int, int,
- struct mem_attrib *, struct target_ops *))
- nomemory);
- de_fault (to_can_run,
- (int (*) (struct target_ops *))
- return_zero);
- current_target.to_read_description = NULL;
-
-#undef de_fault
-
/* Finally, position the target-stack beneath the squashed
"current_target". That way code looking for a non-inherited
target method can quickly and simply find it. */
int
target_is_pushed (struct target_ops *t)
{
- struct target_ops **cur;
+ struct target_ops *cur;
/* Check magic number. If wrong, it probably means someone changed
the struct definition, but not all the places that initialize one. */
_("failed internal consistency check"));
}
- for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
- if (*cur == t)
+ for (cur = target_stack; cur != NULL; cur = cur->beneath)
+ if (cur == t)
return 1;
return 0;
}
+/* Default implementation of to_get_thread_local_address. */
+
+static void
+generic_tls_error (void)
+{
+ throw_error (TLS_GENERIC_ERROR,
+ _("Cannot find thread-local variables on this target"));
+}
+
/* Using the objfile specified in OBJFILE, find the address for the
current thread's thread-local storage with offset OFFSET. */
CORE_ADDR
target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
{
volatile CORE_ADDR addr = 0;
- struct target_ops *target;
-
- for (target = current_target.beneath;
- target != NULL;
- target = target->beneath)
- {
- if (target->to_get_thread_local_address != NULL)
- break;
- }
+ struct target_ops *target = ¤t_target;
- if (target != NULL
- && gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
+ if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
{
ptid_t ptid = inferior_ptid;
volatile struct gdb_exception ex;
/* Fetch the load module address for this objfile. */
lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (),
objfile);
- /* If it's 0, throw the appropriate exception. */
- if (lm_addr == 0)
- throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
- _("TLS load module not found"));
addr = target->to_get_thread_local_address (target, ptid,
lm_addr, offset);
}
const char *
-target_xfer_status_to_string (enum target_xfer_status err)
+target_xfer_status_to_string (enum target_xfer_status status)
{
#define CASE(X) case X: return #X
- switch (err)
+ switch (status)
{
CASE(TARGET_XFER_E_IO);
- CASE(TARGET_XFER_E_UNAVAILABLE);
+ CASE(TARGET_XFER_UNAVAILABLE);
default:
return "<unknown>";
}
struct target_section_table *
target_get_section_table (struct target_ops *target)
{
- struct target_ops *t;
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_get_section_table ()\n");
-
- for (t = target; t != NULL; t = t->beneath)
- if (t->to_get_section_table != NULL)
- return (*t->to_get_section_table) (t);
-
- return NULL;
+ return (*target->to_get_section_table) (target);
}
/* Find a section containing ADDR. */
return NULL;
}
-/* Read memory from the live target, even if currently inspecting a
- traceframe. The return is the same as that of target_read. */
-
-static enum target_xfer_status
-target_read_live_memory (enum target_object object,
- ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len,
- ULONGEST *xfered_len)
-{
- enum target_xfer_status ret;
- struct cleanup *cleanup;
-
- /* Switch momentarily out of tfind mode so to access live memory.
- Note that this must not clear global state, such as the frame
- cache, which must still remain valid for the previous traceframe.
- We may be _building_ the frame cache at this point. */
- cleanup = make_cleanup_restore_traceframe_number ();
- set_traceframe_number (-1);
- ret = target_xfer_partial (current_target.beneath, object, NULL,
- myaddr, NULL, memaddr, len, xfered_len);
+/* Helper for the memory xfer routines. Checks the attributes of the
+ memory region of MEMADDR against the read or write being attempted.
+ If the access is permitted returns true, otherwise returns false.
+ REGION_P is an optional output parameter. If not-NULL, it is
+ filled with a pointer to the memory region of MEMADDR. REG_LEN
+ returns LEN trimmed to the end of the region. This is how much the
+ caller can continue requesting, if the access is permitted. A
+ single xfer request must not straddle memory region boundaries. */
- do_cleanups (cleanup);
- return ret;
-}
-
-/* Using the set of read-only target sections of OPS, read live
- read-only memory. Note that the actual reads start from the
- top-most target again.
+static int
+memory_xfer_check_region (gdb_byte *readbuf, const gdb_byte *writebuf,
+ ULONGEST memaddr, ULONGEST len, ULONGEST *reg_len,
+ struct mem_region **region_p)
+{
+ struct mem_region *region;
- For interface/parameters/return description see target.h,
- to_xfer_partial. */
+ region = lookup_mem_region (memaddr);
-static enum target_xfer_status
-memory_xfer_live_readonly_partial (struct target_ops *ops,
- enum target_object object,
- gdb_byte *readbuf, ULONGEST memaddr,
- ULONGEST len, ULONGEST *xfered_len)
-{
- struct target_section *secp;
- struct target_section_table *table;
+ if (region_p != NULL)
+ *region_p = region;
- secp = target_section_by_addr (ops, memaddr);
- if (secp != NULL
- && (bfd_get_section_flags (secp->the_bfd_section->owner,
- secp->the_bfd_section)
- & SEC_READONLY))
+ switch (region->attrib.mode)
{
- struct target_section *p;
- ULONGEST memend = memaddr + len;
+ case MEM_RO:
+ if (writebuf != NULL)
+ return 0;
+ break;
- table = target_get_section_table (ops);
+ case MEM_WO:
+ if (readbuf != NULL)
+ return 0;
+ break;
- for (p = table->sections; p < table->sections_end; p++)
- {
- if (memaddr >= p->addr)
- {
- if (memend <= p->endaddr)
- {
- /* Entire transfer is within this section. */
- return target_read_live_memory (object, memaddr,
- readbuf, len, xfered_len);
- }
- else if (memaddr >= p->endaddr)
- {
- /* This section ends before the transfer starts. */
- continue;
- }
- else
- {
- /* This section overlaps the transfer. Just do half. */
- len = p->endaddr - memaddr;
- return target_read_live_memory (object, memaddr,
- readbuf, len, xfered_len);
- }
- }
- }
+ case MEM_FLASH:
+ /* We only support writing to flash during "load" for now. */
+ if (writebuf != NULL)
+ error (_("Writing to flash memory forbidden in this context"));
+ break;
+
+ case MEM_NONE:
+ return 0;
}
- return TARGET_XFER_EOF;
+ /* region->hi == 0 means there's no upper bound. */
+ if (memaddr + len < region->hi || region->hi == 0)
+ *reg_len = len;
+ else
+ *reg_len = region->hi - memaddr;
+
+ return 1;
}
/* Read memory from more than one valid target. A core file, for
break;
/* Stop if the target reports that the memory is not available. */
- if (res == TARGET_XFER_E_UNAVAILABLE)
+ if (res == TARGET_XFER_UNAVAILABLE)
break;
/* We want to continue past core files to executables, but not
}
while (ops != NULL);
+ /* The cache works at the raw memory level. Make sure the cache
+ gets updated with raw contents no matter what kind of memory
+ object was originally being written. Note we do write-through
+ first, so that if it fails, we don't write to the cache contents
+ that never made it to the target. */
+ if (writebuf != NULL
+ && !ptid_equal (inferior_ptid, null_ptid)
+ && target_dcache_init_p ()
+ && (stack_cache_enabled_p () || code_cache_enabled_p ()))
+ {
+ DCACHE *dcache = target_dcache_get ();
+
+ /* Note that writing to an area of memory which wasn't present
+ in the cache doesn't cause it to be loaded in. */
+ dcache_update (dcache, res, memaddr, writebuf, *xfered_len);
+ }
+
return res;
}
ULONGEST len, ULONGEST *xfered_len)
{
enum target_xfer_status res;
- int reg_len;
+ ULONGEST reg_len;
struct mem_region *region;
struct inferior *inf;
}
}
- /* If reading unavailable memory in the context of traceframes, and
- this address falls within a read-only section, fallback to
- reading from live memory. */
- if (readbuf != NULL && get_traceframe_number () != -1)
- {
- VEC(mem_range_s) *available;
-
- /* If we fail to get the set of available memory, then the
- target does not support querying traceframe info, and so we
- attempt reading from the traceframe anyway (assuming the
- target implements the old QTro packet then). */
- if (traceframe_available_memory (&available, memaddr, len))
- {
- struct cleanup *old_chain;
-
- old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available);
-
- if (VEC_empty (mem_range_s, available)
- || VEC_index (mem_range_s, available, 0)->start != memaddr)
- {
- /* Don't read into the traceframe's available
- memory. */
- if (!VEC_empty (mem_range_s, available))
- {
- LONGEST oldlen = len;
-
- len = VEC_index (mem_range_s, available, 0)->start - memaddr;
- gdb_assert (len <= oldlen);
- }
-
- do_cleanups (old_chain);
-
- /* This goes through the topmost target again. */
- res = memory_xfer_live_readonly_partial (ops, object,
- readbuf, memaddr,
- len, xfered_len);
- if (res == TARGET_XFER_OK)
- return TARGET_XFER_OK;
- else
- {
- /* No use trying further, we know some memory starting
- at MEMADDR isn't available. */
- *xfered_len = len;
- return TARGET_XFER_E_UNAVAILABLE;
- }
- }
-
- /* Don't try to read more than how much is available, in
- case the target implements the deprecated QTro packet to
- cater for older GDBs (the target's knowledge of read-only
- sections may be outdated by now). */
- len = VEC_index (mem_range_s, available, 0)->length;
-
- do_cleanups (old_chain);
- }
- }
-
/* Try GDB's internal data cache. */
- region = lookup_mem_region (memaddr);
- /* region->hi == 0 means there's no upper bound. */
- if (memaddr + len < region->hi || region->hi == 0)
- reg_len = len;
- else
- reg_len = region->hi - memaddr;
-
- switch (region->attrib.mode)
- {
- case MEM_RO:
- if (writebuf != NULL)
- return TARGET_XFER_E_IO;
- break;
-
- case MEM_WO:
- if (readbuf != NULL)
- return TARGET_XFER_E_IO;
- break;
-
- case MEM_FLASH:
- /* We only support writing to flash during "load" for now. */
- if (writebuf != NULL)
- error (_("Writing to flash memory forbidden in this context"));
- break;
- case MEM_NONE:
- return TARGET_XFER_E_IO;
- }
+ if (!memory_xfer_check_region (readbuf, writebuf, memaddr, len, ®_len,
+ ®ion))
+ return TARGET_XFER_E_IO;
if (!ptid_equal (inferior_ptid, null_ptid))
inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
inf = NULL;
if (inf != NULL
+ && readbuf != NULL
/* The dcache reads whole cache lines; that doesn't play well
with reading from a trace buffer, because reading outside of
the collected memory range fails. */
|| (code_cache_enabled_p () && object == TARGET_OBJECT_CODE_MEMORY)))
{
DCACHE *dcache = target_dcache_get_or_init ();
- int l;
- if (readbuf != NULL)
- l = dcache_xfer_memory (ops, dcache, memaddr, readbuf, reg_len, 0);
- else
- /* FIXME drow/2006-08-09: If we're going to preserve const
- correctness dcache_xfer_memory should take readbuf and
- writebuf. */
- l = dcache_xfer_memory (ops, dcache, memaddr, (void *) writebuf,
- reg_len, 1);
- if (l <= 0)
- return TARGET_XFER_E_IO;
- else
- {
- *xfered_len = (ULONGEST) l;
- return TARGET_XFER_OK;
- }
+ return dcache_read_memory_partial (ops, dcache, memaddr, readbuf,
+ reg_len, xfered_len);
}
/* If none of those methods found the memory we wanted, fall back
res = raw_memory_xfer_partial (ops, readbuf, writebuf, memaddr, reg_len,
xfered_len);
- /* Make sure the cache gets updated no matter what - if we are writing
- to the stack. Even if this write is not tagged as such, we still need
- to update the cache. */
-
- if (res == TARGET_XFER_OK
- && inf != NULL
- && writebuf != NULL
- && target_dcache_init_p ()
- && !region->attrib.cache
- && ((stack_cache_enabled_p () && object != TARGET_OBJECT_STACK_MEMORY)
- || (code_cache_enabled_p () && object != TARGET_OBJECT_CODE_MEMORY)))
- {
- DCACHE *dcache = target_dcache_get ();
-
- dcache_update (dcache, memaddr, (void *) writebuf, reg_len);
- }
-
/* If we still haven't got anything, return the last error. We
give up. */
return res;
xfered_len);
if (res == TARGET_XFER_OK && !show_memory_breakpoints)
- breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, res);
+ breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, *xfered_len);
}
else
{
writebuf, offset, len, xfered_len);
else if (object == TARGET_OBJECT_RAW_MEMORY)
{
+ /* Skip/avoid accessing the target if the memory region
+ attributes block the access. Check this here instead of in
+ raw_memory_xfer_partial as otherwise we'd end up checking
+ this twice in the case of the memory_xfer_partial path is
+ taken; once before checking the dcache, and another in the
+ tail call to raw_memory_xfer_partial. */
+ if (!memory_xfer_check_region (readbuf, writebuf, offset, len, &len,
+ NULL))
+ return TARGET_XFER_E_IO;
+
/* Request the normal memory object from other layers. */
retval = raw_memory_xfer_partial (ops, readbuf, writebuf, offset, len,
xfered_len);
/* Check implementations of to_xfer_partial update *XFERED_LEN
properly. Do assertion after printing debug messages, so that we
can find more clues on assertion failure from debugging messages. */
- if (retval == TARGET_XFER_OK || retval == TARGET_XFER_E_UNAVAILABLE)
+ if (retval == TARGET_XFER_OK || retval == TARGET_XFER_UNAVAILABLE)
gdb_assert (*xfered_len > 0);
return retval;
return TARGET_XFER_E_IO;
}
+/* See target/target.h. */
+
+int
+target_read_uint32 (CORE_ADDR memaddr, uint32_t *result)
+{
+ gdb_byte buf[4];
+ int r;
+
+ r = target_read_memory (memaddr, buf, sizeof buf);
+ if (r != 0)
+ return r;
+ *result = extract_unsigned_integer (buf, sizeof buf,
+ gdbarch_byte_order (target_gdbarch ()));
+ return 0;
+}
+
/* Like target_read_memory, but specify explicitly that this is a read
from the target's raw memory. That is, this read bypasses the
dcache, breakpoint shadowing, etc. */
int ix;
struct target_ops *t;
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_memory_map ()\n");
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_memory_map != NULL)
- break;
-
- if (t == NULL)
- return NULL;
-
- result = t->to_memory_map (t);
+ result = current_target.to_memory_map (¤t_target);
if (result == NULL)
return NULL;
void
target_flash_erase (ULONGEST address, LONGEST length)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_flash_erase != NULL)
- {
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
- hex_string (address), phex (length, 0));
- t->to_flash_erase (t, address, length);
- return;
- }
-
- tcomplain ();
+ current_target.to_flash_erase (¤t_target, address, length);
}
void
target_flash_done (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_flash_done != NULL)
- {
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
- t->to_flash_done (t);
- return;
- }
-
- tcomplain ();
+ current_target.to_flash_done (¤t_target);
}
static void
value);
}
-/* More generic transfers. */
-
-static enum target_xfer_status
-default_xfer_partial (struct target_ops *ops, enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
- ULONGEST *xfered_len)
-{
- if (object == TARGET_OBJECT_MEMORY
- && ops->deprecated_xfer_memory != NULL)
- /* If available, fall back to the target's
- "deprecated_xfer_memory" method. */
- {
- int xfered = -1;
-
- errno = 0;
- if (writebuf != NULL)
- {
- void *buffer = xmalloc (len);
- struct cleanup *cleanup = make_cleanup (xfree, buffer);
-
- memcpy (buffer, writebuf, len);
- xfered = ops->deprecated_xfer_memory (offset, buffer, len,
- 1/*write*/, NULL, ops);
- do_cleanups (cleanup);
- }
- if (readbuf != NULL)
- xfered = ops->deprecated_xfer_memory (offset, readbuf, len,
- 0/*read*/, NULL, ops);
- if (xfered > 0)
- {
- *xfered_len = (ULONGEST) xfered;
- return TARGET_XFER_E_IO;
- }
- else if (xfered == 0 && errno == 0)
- /* "deprecated_xfer_memory" uses 0, cross checked against
- ERRNO as one indication of an error. */
- return TARGET_XFER_EOF;
- else
- return TARGET_XFER_E_IO;
- }
- else
- {
- gdb_assert (ops->beneath != NULL);
- return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
- readbuf, writebuf, offset, len,
- xfered_len);
- }
-}
-
-/* Target vector read/write partial wrapper functions. */
+/* Target vector read/write partial wrapper functions. */
static enum target_xfer_status
target_read_partial (struct target_ops *ops,
offset + xfered, len - xfered,
&xfered_len);
- if (status == TARGET_XFER_EOF)
- return xfered;
- if (TARGET_XFER_STATUS_ERROR_P (status))
- return -1;
+ if (status != TARGET_XFER_OK)
+ return status == TARGET_XFER_EOF ? xfered : -1;
- gdb_assert (status == TARGET_XFER_OK);
if (progress)
(*progress) (xfered_len, baton);
prepare_for_detach ();
current_target.to_detach (¤t_target, args, from_tty);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_detach (%s, %d)\n",
- args, from_tty);
}
void
-target_disconnect (char *args, int from_tty)
+target_disconnect (const char *args, int from_tty)
{
- struct target_ops *t;
-
/* If we're in breakpoints-always-inserted mode or if breakpoints
are global across processes, we have to remove them before
disconnecting. */
remove_breakpoints ();
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_disconnect != NULL)
- {
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
- args, from_tty);
- t->to_disconnect (t, args, from_tty);
- return;
- }
-
- tcomplain ();
+ current_target.to_disconnect (¤t_target, args, from_tty);
}
ptid_t
target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
{
- struct target_ops *t;
- ptid_t retval = (current_target.to_wait) (¤t_target, ptid,
- status, options);
-
- if (targetdebug)
- {
- char *status_string;
- char *options_string;
-
- status_string = target_waitstatus_to_string (status);
- options_string = target_options_to_string (options);
- fprintf_unfiltered (gdb_stdlog,
- "target_wait (%d, status, options={%s})"
- " = %d, %s\n",
- ptid_get_pid (ptid), options_string,
- ptid_get_pid (retval), status_string);
- xfree (status_string);
- xfree (options_string);
- }
-
- return retval;
+ return (current_target.to_wait) (¤t_target, ptid, status, options);
}
char *
target_pid_to_str (ptid_t ptid)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_pid_to_str != NULL)
- return (*t->to_pid_to_str) (t, ptid);
- }
-
- return normal_pid_to_str (ptid);
+ return (*current_target.to_pid_to_str) (¤t_target, ptid);
}
char *
target_dcache_invalidate ();
current_target.to_resume (¤t_target, ptid, step, signal);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n",
- ptid_get_pid (ptid),
- step ? "step" : "continue",
- gdb_signal_to_name (signal));
registers_changed_ptid (ptid);
+ /* We only set the internal executing state here. The user/frontend
+ running state is set at a higher level. */
set_executing (ptid, 1);
- set_running (ptid, 1);
clear_inline_frame_state (ptid);
}
void
target_pass_signals (int numsigs, unsigned char *pass_signals)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_pass_signals != NULL)
- {
- if (targetdebug)
- {
- int i;
-
- fprintf_unfiltered (gdb_stdlog, "target_pass_signals (%d, {",
- numsigs);
-
- for (i = 0; i < numsigs; i++)
- if (pass_signals[i])
- fprintf_unfiltered (gdb_stdlog, " %s",
- gdb_signal_to_name (i));
-
- fprintf_unfiltered (gdb_stdlog, " })\n");
- }
-
- (*t->to_pass_signals) (t, numsigs, pass_signals);
- return;
- }
- }
+ (*current_target.to_pass_signals) (¤t_target, numsigs, pass_signals);
}
void
target_program_signals (int numsigs, unsigned char *program_signals)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_program_signals != NULL)
- {
- if (targetdebug)
- {
- int i;
-
- fprintf_unfiltered (gdb_stdlog, "target_program_signals (%d, {",
- numsigs);
-
- for (i = 0; i < numsigs; i++)
- if (program_signals[i])
- fprintf_unfiltered (gdb_stdlog, " %s",
- gdb_signal_to_name (i));
-
- fprintf_unfiltered (gdb_stdlog, " })\n");
- }
+ (*current_target.to_program_signals) (¤t_target,
+ numsigs, program_signals);
+}
- (*t->to_program_signals) (t, numsigs, program_signals);
- return;
- }
- }
+static int
+default_follow_fork (struct target_ops *self, int follow_child,
+ int detach_fork)
+{
+ /* Some target returned a fork event, but did not know how to follow it. */
+ internal_error (__FILE__, __LINE__,
+ _("could not find a target to follow fork"));
}
/* Look through the list of possible targets for a target that can
int
target_follow_fork (int follow_child, int detach_fork)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_follow_fork != NULL)
- {
- int retval = t->to_follow_fork (t, follow_child, detach_fork);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_follow_fork (%d, %d) = %d\n",
- follow_child, detach_fork, retval);
- return retval;
- }
- }
+ return current_target.to_follow_fork (¤t_target,
+ follow_child, detach_fork);
+}
- /* Some target returned a fork event, but did not know how to follow it. */
+static void
+default_mourn_inferior (struct target_ops *self)
+{
internal_error (__FILE__, __LINE__,
- _("could not find a target to follow fork"));
+ _("could not find a target to follow mourn inferior"));
}
void
target_mourn_inferior (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_mourn_inferior != NULL)
- {
- t->to_mourn_inferior (t);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_mourn_inferior ()\n");
-
- /* We no longer need to keep handles on any of the object files.
- Make sure to release them to avoid unnecessarily locking any
- of them while we're not actually debugging. */
- bfd_cache_close_all ();
-
- return;
- }
- }
+ current_target.to_mourn_inferior (¤t_target);
- internal_error (__FILE__, __LINE__,
- _("could not find a target to follow mourn inferior"));
+ /* We no longer need to keep handles on any of the object files.
+ Make sure to release them to avoid unnecessarily locking any
+ of them while we're not actually debugging. */
+ bfd_cache_close_all ();
}
/* Look for a target which can describe architectural features, starting
const struct target_desc *
target_read_description (struct target_ops *target)
{
- struct target_ops *t;
-
- for (t = target; t != NULL; t = t->beneath)
- if (t->to_read_description != NULL)
- {
- const struct target_desc *tdesc;
-
- tdesc = t->to_read_description (t);
- if (tdesc)
- return tdesc;
- }
-
- return NULL;
+ return target->to_read_description (target);
}
-/* The default implementation of to_search_memory.
- This implements a basic search of memory, reading target memory and
+/* This implements a basic search of memory, reading target memory and
performing the search here (as opposed to performing the search in on the
target side with, for example, gdbserver). */
return 0;
}
+/* Default implementation of memory-searching. */
+
+static int
+default_search_memory (struct target_ops *self,
+ CORE_ADDR start_addr, ULONGEST search_space_len,
+ const gdb_byte *pattern, ULONGEST pattern_len,
+ CORE_ADDR *found_addrp)
+{
+ /* Start over from the top of the target stack. */
+ return simple_search_memory (current_target.beneath,
+ start_addr, search_space_len,
+ pattern, pattern_len, found_addrp);
+}
+
/* Search SEARCH_SPACE_LEN bytes beginning at START_ADDR for the
sequence of bytes in PATTERN with length PATTERN_LEN.
const gdb_byte *pattern, ULONGEST pattern_len,
CORE_ADDR *found_addrp)
{
- struct target_ops *t;
- int found;
-
- /* We don't use INHERIT to set current_target.to_search_memory,
- so we have to scan the target stack and handle targetdebug
- ourselves. */
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_search_memory (%s, ...)\n",
- hex_string (start_addr));
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_search_memory != NULL)
- break;
-
- if (t != NULL)
- {
- found = t->to_search_memory (t, start_addr, search_space_len,
- pattern, pattern_len, found_addrp);
- }
- else
- {
- /* If a special version of to_search_memory isn't available, use the
- simple version. */
- found = simple_search_memory (current_target.beneath,
- start_addr, search_space_len,
- pattern, pattern_len, found_addrp);
- }
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, " = %d\n", found);
-
- return found;
+ return current_target.to_search_memory (¤t_target, start_addr,
+ search_space_len,
+ pattern, pattern_len, found_addrp);
}
/* Look through the currently pushed targets. If none of them will
if (t->to_create_inferior != NULL)
return;
- /* Do not worry about thread_stratum targets that can not
+ /* Do not worry about targets at certain strata that can not
create inferiors. Assume they will be pushed again if
necessary, and continue to the process_stratum. */
if (t->to_stratum == thread_stratum
+ || t->to_stratum == record_stratum
|| t->to_stratum == arch_stratum)
continue;
internal_error (__FILE__, __LINE__, _("No targets found"));
}
+/* Whether GDB is allowed to fall back to the default run target for
+ "run", "attach", etc. when no target is connected yet. */
+static int auto_connect_native_target = 1;
+
+static void
+show_auto_connect_native_target (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file,
+ _("Whether GDB may automatically connect to the "
+ "native target is %s.\n"),
+ value);
+}
+
/* Look through the list of possible targets for a target that can
execute a run or attach command without any other data. This is
used to locate the default process stratum.
static struct target_ops *
find_default_run_target (char *do_mesg)
{
- struct target_ops **t;
struct target_ops *runable = NULL;
- int count;
-
- count = 0;
- for (t = target_structs; t < target_structs + target_struct_size;
- ++t)
+ if (auto_connect_native_target)
{
- if ((*t)->to_can_run && target_can_run (*t))
+ struct target_ops *t;
+ int count = 0;
+ int i;
+
+ for (i = 0; VEC_iterate (target_ops_p, target_structs, i, t); ++i)
{
- runable = *t;
- ++count;
+ if (t->to_can_run != delegate_can_run && target_can_run (t))
+ {
+ runable = t;
+ ++count;
+ }
}
+
+ if (count != 1)
+ runable = NULL;
}
- if (count != 1)
+ if (runable == NULL)
{
if (do_mesg)
error (_("Don't know how to %s. Try \"help target\"."), do_mesg);
return runable;
}
-void
-find_default_attach (struct target_ops *ops, char *args, int from_tty)
-{
- struct target_ops *t;
-
- t = find_default_run_target ("attach");
- (t->to_attach) (t, args, from_tty);
- return;
-}
+/* See target.h. */
-void
-find_default_create_inferior (struct target_ops *ops,
- char *exec_file, char *allargs, char **env,
- int from_tty)
+struct target_ops *
+find_attach_target (void)
{
struct target_ops *t;
- t = find_default_run_target ("run");
- (t->to_create_inferior) (t, exec_file, allargs, env, from_tty);
- return;
-}
+ /* If a target on the current stack can attach, use it. */
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_attach != NULL)
+ break;
+ }
-static int
-find_default_can_async_p (struct target_ops *ignore)
-{
- struct target_ops *t;
+ /* Otherwise, use the default run target for attaching. */
+ if (t == NULL)
+ t = find_default_run_target ("attach");
- /* This may be called before the target is pushed on the stack;
- look for the default process stratum. If there's none, gdb isn't
- configured with a native debugger, and target remote isn't
- connected yet. */
- t = find_default_run_target (NULL);
- if (t && t->to_can_async_p != delegate_can_async_p)
- return (t->to_can_async_p) (t);
- return 0;
+ return t;
}
-static int
-find_default_is_async_p (struct target_ops *ignore)
-{
- struct target_ops *t;
-
- /* This may be called before the target is pushed on the stack;
- look for the default process stratum. If there's none, gdb isn't
- configured with a native debugger, and target remote isn't
- connected yet. */
- t = find_default_run_target (NULL);
- if (t && t->to_is_async_p != delegate_is_async_p)
- return (t->to_is_async_p) (t);
- return 0;
-}
+/* See target.h. */
-static int
-find_default_supports_non_stop (struct target_ops *self)
+struct target_ops *
+find_run_target (void)
{
struct target_ops *t;
- t = find_default_run_target (NULL);
- if (t && t->to_supports_non_stop)
- return (t->to_supports_non_stop) (t);
- return 0;
-}
-
-int
-target_supports_non_stop (void)
-{
- struct target_ops *t;
+ /* If a target on the current stack can attach, use it. */
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_create_inferior != NULL)
+ break;
+ }
- for (t = ¤t_target; t != NULL; t = t->beneath)
- if (t->to_supports_non_stop)
- return t->to_supports_non_stop (t);
+ /* Otherwise, use the default run target. */
+ if (t == NULL)
+ t = find_default_run_target ("run");
- return 0;
+ return t;
}
/* Implement the "info proc" command. */
int
-target_info_proc (char *args, enum info_proc_what what)
+target_info_proc (const char *args, enum info_proc_what what)
{
struct target_ops *t;
return target_read_stralloc (t, TARGET_OBJECT_OSDATA, type);
}
-/* Determine the current address space of thread PTID. */
-
-struct address_space *
-target_thread_address_space (ptid_t ptid)
+static struct address_space *
+default_thread_address_space (struct target_ops *self, ptid_t ptid)
{
- struct address_space *aspace;
struct inferior *inf;
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_thread_address_space != NULL)
- {
- aspace = t->to_thread_address_space (t, ptid);
- gdb_assert (aspace);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_thread_address_space (%s) = %d\n",
- target_pid_to_str (ptid),
- address_space_num (aspace));
- return aspace;
- }
- }
/* Fall-back to the "main" address space of the inferior. */
inf = find_inferior_pid (ptid_get_pid (ptid));
return inf->aspace;
}
+/* Determine the current address space of thread PTID. */
+
+struct address_space *
+target_thread_address_space (ptid_t ptid)
+{
+ struct address_space *aspace;
+
+ aspace = current_target.to_thread_address_space (¤t_target, ptid);
+ gdb_assert (aspace != NULL);
+
+ return aspace;
+}
+
/* Target file operations. */
}
static int
-return_zero (void)
+return_zero (struct target_ops *ignore)
+{
+ return 0;
+}
+
+static int
+return_zero_has_execution (struct target_ops *ignore, ptid_t ignore2)
{
return 0;
}
}
static char *
-dummy_pid_to_str (struct target_ops *ops, ptid_t ptid)
+default_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
return normal_pid_to_str (ptid);
}
dummy_target.to_shortname = "None";
dummy_target.to_longname = "None";
dummy_target.to_doc = "";
- dummy_target.to_create_inferior = find_default_create_inferior;
- dummy_target.to_supports_non_stop = find_default_supports_non_stop;
dummy_target.to_supports_disable_randomization
= find_default_supports_disable_randomization;
- dummy_target.to_pid_to_str = dummy_pid_to_str;
dummy_target.to_stratum = dummy_stratum;
- dummy_target.to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
- dummy_target.to_has_memory = (int (*) (struct target_ops *)) return_zero;
- dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_zero;
- dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_zero;
- dummy_target.to_has_execution
- = (int (*) (struct target_ops *, ptid_t)) return_zero;
+ dummy_target.to_has_all_memory = return_zero;
+ dummy_target.to_has_memory = return_zero;
+ dummy_target.to_has_stack = return_zero;
+ dummy_target.to_has_registers = return_zero;
+ dummy_target.to_has_execution = return_zero_has_execution;
dummy_target.to_magic = OPS_MAGIC;
install_dummy_methods (&dummy_target);
}
\f
-static void
-debug_to_open (char *args, int from_tty)
-{
- debug_target.to_open (args, from_tty);
-
- fprintf_unfiltered (gdb_stdlog, "target_open (%s, %d)\n", args, from_tty);
-}
void
target_close (struct target_ops *targ)
fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
}
-void
-target_attach (char *args, int from_tty)
-{
- current_target.to_attach (¤t_target, args, from_tty);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_attach (%s, %d)\n",
- args, from_tty);
-}
-
int
target_thread_alive (ptid_t ptid)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_thread_alive != NULL)
- {
- int retval;
-
- retval = t->to_thread_alive (t, ptid);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
- ptid_get_pid (ptid), retval);
-
- return retval;
- }
- }
-
- return 0;
+ return current_target.to_thread_alive (¤t_target, ptid);
}
void
target_find_new_threads (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_find_new_threads != NULL)
- {
- t->to_find_new_threads (t);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_find_new_threads ()\n");
-
- return;
- }
- }
+ current_target.to_find_new_threads (¤t_target);
}
void
(*current_target.to_stop) (¤t_target, ptid);
}
-static void
-debug_to_post_attach (struct target_ops *self, int pid)
+/* See target/target.h. */
+
+void
+target_stop_and_wait (ptid_t ptid)
{
- debug_target.to_post_attach (&debug_target, pid);
+ struct target_waitstatus status;
+ int was_non_stop = non_stop;
- fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
+ non_stop = 1;
+ target_stop (ptid);
+
+ memset (&status, 0, sizeof (status));
+ target_wait (ptid, &status, 0);
+
+ non_stop = was_non_stop;
+}
+
+/* See target/target.h. */
+
+void
+target_continue_no_signal (ptid_t ptid)
+{
+ target_resume (ptid, 0, GDB_SIGNAL_0);
}
/* Concatenate ELEM to LIST, a comma separate list, and return the
void
target_fetch_registers (struct regcache *regcache, int regno)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_fetch_registers != NULL)
- {
- t->to_fetch_registers (t, regcache, regno);
- if (targetdebug)
- debug_print_register ("target_fetch_registers", regcache, regno);
- return;
- }
- }
+ current_target.to_fetch_registers (¤t_target, regcache, regno);
+ if (targetdebug)
+ debug_print_register ("target_fetch_registers", regcache, regno);
}
void
int
target_core_of_thread (ptid_t ptid)
{
- struct target_ops *t;
+ return current_target.to_core_of_thread (¤t_target, ptid);
+}
- for (t = current_target.beneath; t != NULL; t = t->beneath)
+int
+simple_verify_memory (struct target_ops *ops,
+ const gdb_byte *data, CORE_ADDR lma, ULONGEST size)
+{
+ LONGEST total_xfered = 0;
+
+ while (total_xfered < size)
{
- if (t->to_core_of_thread != NULL)
- {
- int retval = t->to_core_of_thread (t, ptid);
+ ULONGEST xfered_len;
+ enum target_xfer_status status;
+ gdb_byte buf[1024];
+ ULONGEST howmuch = min (sizeof (buf), size - total_xfered);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_core_of_thread (%d) = %d\n",
- ptid_get_pid (ptid), retval);
- return retval;
+ status = target_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
+ buf, NULL, lma + total_xfered, howmuch,
+ &xfered_len);
+ if (status == TARGET_XFER_OK
+ && memcmp (data + total_xfered, buf, xfered_len) == 0)
+ {
+ total_xfered += xfered_len;
+ QUIT;
}
+ else
+ return 0;
}
+ return 1;
+}
- return -1;
+/* Default implementation of memory verification. */
+
+static int
+default_verify_memory (struct target_ops *self,
+ const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
+{
+ /* Start over from the top of the target stack. */
+ return simple_verify_memory (current_target.beneath,
+ data, memaddr, size);
}
int
target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_verify_memory != NULL)
- {
- int retval = t->to_verify_memory (t, data, memaddr, size);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_verify_memory (%s, %s) = %d\n",
- paddress (target_gdbarch (), memaddr),
- pulongest (size),
- retval);
- return retval;
- }
- }
-
- tcomplain ();
+ return current_target.to_verify_memory (¤t_target,
+ data, memaddr, size);
}
/* The documentation for this function is in its prototype declaration in
int
target_insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, int rw)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_insert_mask_watchpoint != NULL)
- {
- int ret;
-
- ret = t->to_insert_mask_watchpoint (t, addr, mask, rw);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "\
-target_insert_mask_watchpoint (%s, %s, %d) = %d\n",
- core_addr_to_string (addr),
- core_addr_to_string (mask), rw, ret);
-
- return ret;
- }
-
- return 1;
+ return current_target.to_insert_mask_watchpoint (¤t_target,
+ addr, mask, rw);
}
/* The documentation for this function is in its prototype declaration in
int
target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, int rw)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_remove_mask_watchpoint != NULL)
- {
- int ret;
-
- ret = t->to_remove_mask_watchpoint (t, addr, mask, rw);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "\
-target_remove_mask_watchpoint (%s, %s, %d) = %d\n",
- core_addr_to_string (addr),
- core_addr_to_string (mask), rw, ret);
-
- return ret;
- }
-
- return 1;
+ return current_target.to_remove_mask_watchpoint (¤t_target,
+ addr, mask, rw);
}
/* The documentation for this function is in its prototype declaration
int
target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_masked_watch_num_registers != NULL)
- return t->to_masked_watch_num_registers (t, addr, mask);
-
- return -1;
+ return current_target.to_masked_watch_num_registers (¤t_target,
+ addr, mask);
}
/* The documentation for this function is in its prototype declaration
int
target_ranged_break_num_registers (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_ranged_break_num_registers != NULL)
- return t->to_ranged_break_num_registers (t);
-
- return -1;
+ return current_target.to_ranged_break_num_registers (¤t_target);
}
/* See target.h. */
struct btrace_target_info *
target_enable_btrace (ptid_t ptid)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_enable_btrace != NULL)
- return t->to_enable_btrace (t, ptid);
-
- tcomplain ();
- return NULL;
+ return current_target.to_enable_btrace (¤t_target, ptid);
}
/* See target.h. */
void
target_disable_btrace (struct btrace_target_info *btinfo)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_disable_btrace != NULL)
- {
- t->to_disable_btrace (t, btinfo);
- return;
- }
-
- tcomplain ();
+ current_target.to_disable_btrace (¤t_target, btinfo);
}
/* See target.h. */
void
target_teardown_btrace (struct btrace_target_info *btinfo)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_teardown_btrace != NULL)
- {
- t->to_teardown_btrace (t, btinfo);
- return;
- }
-
- tcomplain ();
+ current_target.to_teardown_btrace (¤t_target, btinfo);
}
/* See target.h. */
struct btrace_target_info *btinfo,
enum btrace_read_type type)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_read_btrace != NULL)
- return t->to_read_btrace (t, btrace, btinfo, type);
-
- tcomplain ();
- return BTRACE_ERR_NOT_SUPPORTED;
+ return current_target.to_read_btrace (¤t_target, btrace, btinfo, type);
}
/* See target.h. */
void
target_stop_recording (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_stop_recording != NULL)
- {
- t->to_stop_recording (t);
- return;
- }
-
- /* This is optional. */
-}
-
-/* See target.h. */
-
-void
-target_info_record (void)
-{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_info_record != NULL)
- {
- t->to_info_record (t);
- return;
- }
-
- tcomplain ();
+ current_target.to_stop_recording (¤t_target);
}
/* See target.h. */
void
target_save_record (const char *filename)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_save_record != NULL)
- {
- t->to_save_record (t, filename);
- return;
- }
-
- tcomplain ();
+ current_target.to_save_record (¤t_target, filename);
}
/* See target.h. */
struct target_ops *t;
for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_delete_record != NULL)
+ if (t->to_delete_record != delegate_delete_record
+ && t->to_delete_record != tdefault_delete_record)
return 1;
return 0;
void
target_delete_record (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_delete_record != NULL)
- {
- t->to_delete_record (t);
- return;
- }
-
- tcomplain ();
+ current_target.to_delete_record (¤t_target);
}
/* See target.h. */
int
target_record_is_replaying (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_record_is_replaying != NULL)
- return t->to_record_is_replaying (t);
-
- return 0;
+ return current_target.to_record_is_replaying (¤t_target);
}
/* See target.h. */
void
target_goto_record_begin (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_goto_record_begin != NULL)
- {
- t->to_goto_record_begin (t);
- return;
- }
-
- tcomplain ();
+ current_target.to_goto_record_begin (¤t_target);
}
/* See target.h. */
void
target_goto_record_end (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_goto_record_end != NULL)
- {
- t->to_goto_record_end (t);
- return;
- }
-
- tcomplain ();
+ current_target.to_goto_record_end (¤t_target);
}
/* See target.h. */
void
target_goto_record (ULONGEST insn)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_goto_record != NULL)
- {
- t->to_goto_record (t, insn);
- return;
- }
-
- tcomplain ();
+ current_target.to_goto_record (¤t_target, insn);
}
/* See target.h. */
void
target_insn_history (int size, int flags)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_insn_history != NULL)
- {
- t->to_insn_history (t, size, flags);
- return;
- }
-
- tcomplain ();
+ current_target.to_insn_history (¤t_target, size, flags);
}
/* See target.h. */
void
target_insn_history_from (ULONGEST from, int size, int flags)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_insn_history_from != NULL)
- {
- t->to_insn_history_from (t, from, size, flags);
- return;
- }
-
- tcomplain ();
+ current_target.to_insn_history_from (¤t_target, from, size, flags);
}
/* See target.h. */
void
target_insn_history_range (ULONGEST begin, ULONGEST end, int flags)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_insn_history_range != NULL)
- {
- t->to_insn_history_range (t, begin, end, flags);
- return;
- }
-
- tcomplain ();
+ current_target.to_insn_history_range (¤t_target, begin, end, flags);
}
/* See target.h. */
void
target_call_history (int size, int flags)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_call_history != NULL)
- {
- t->to_call_history (t, size, flags);
- return;
- }
-
- tcomplain ();
+ current_target.to_call_history (¤t_target, size, flags);
}
/* See target.h. */
void
target_call_history_from (ULONGEST begin, int size, int flags)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_call_history_from != NULL)
- {
- t->to_call_history_from (t, begin, size, flags);
- return;
- }
-
- tcomplain ();
+ current_target.to_call_history_from (¤t_target, begin, size, flags);
}
/* See target.h. */
void
target_call_history_range (ULONGEST begin, ULONGEST end, int flags)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_call_history_range != NULL)
- {
- t->to_call_history_range (t, begin, end, flags);
- return;
- }
-
- tcomplain ();
-}
-
-static void
-debug_to_prepare_to_store (struct target_ops *self, struct regcache *regcache)
-{
- debug_target.to_prepare_to_store (&debug_target, regcache);
-
- fprintf_unfiltered (gdb_stdlog, "target_prepare_to_store ()\n");
+ current_target.to_call_history_range (¤t_target, begin, end, flags);
}
/* See target.h. */
const struct frame_unwind *
target_get_unwinder (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_get_unwinder != NULL)
- return t->to_get_unwinder;
-
- return NULL;
+ return current_target.to_get_unwinder (¤t_target);
}
/* See target.h. */
const struct frame_unwind *
target_get_tailcall_unwinder (void)
{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_get_tailcall_unwinder != NULL)
- return t->to_get_tailcall_unwinder;
-
- return NULL;
+ return current_target.to_get_tailcall_unwinder (¤t_target);
}
-/* See target.h. */
+/* Default implementation of to_decr_pc_after_break. */
-CORE_ADDR
-forward_target_decr_pc_after_break (struct target_ops *ops,
+static CORE_ADDR
+default_target_decr_pc_after_break (struct target_ops *ops,
struct gdbarch *gdbarch)
{
- for (; ops != NULL; ops = ops->beneath)
- if (ops->to_decr_pc_after_break != NULL)
- return ops->to_decr_pc_after_break (ops, gdbarch);
-
return gdbarch_decr_pc_after_break (gdbarch);
}
CORE_ADDR
target_decr_pc_after_break (struct gdbarch *gdbarch)
{
- return forward_target_decr_pc_after_break (current_target.beneath, gdbarch);
+ return current_target.to_decr_pc_after_break (¤t_target, gdbarch);
}
-static int
-deprecated_debug_xfer_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len,
- int write, struct mem_attrib *attrib,
- struct target_ops *target)
-{
- int retval;
-
- retval = debug_target.deprecated_xfer_memory (memaddr, myaddr, len, write,
- attrib, target);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_xfer_memory (%s, xxx, %d, %s, xxx) = %d",
- paddress (target_gdbarch (), memaddr), len,
- write ? "write" : "read", retval);
-
- if (retval > 0)
- {
- int i;
-
- fputs_unfiltered (", bytes =", gdb_stdlog);
- for (i = 0; i < retval; i++)
- {
- if ((((intptr_t) &(myaddr[i])) & 0xf) == 0)
- {
- if (targetdebug < 2 && i > 0)
- {
- fprintf_unfiltered (gdb_stdlog, " ...");
- break;
- }
- fprintf_unfiltered (gdb_stdlog, "\n");
- }
-
- fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff);
- }
- }
-
- fputc_unfiltered ('\n', gdb_stdlog);
-
- return retval;
-}
-
-static void
-debug_to_files_info (struct target_ops *target)
-{
- debug_target.to_files_info (target);
-
- fprintf_unfiltered (gdb_stdlog, "target_files_info (xxx)\n");
-}
-
-static int
-debug_to_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- int retval;
-
- retval = debug_target.to_insert_breakpoint (&debug_target, gdbarch, bp_tgt);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_insert_breakpoint (%s, xxx) = %ld\n",
- core_addr_to_string (bp_tgt->placed_address),
- (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- int retval;
-
- retval = debug_target.to_remove_breakpoint (&debug_target, gdbarch, bp_tgt);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_remove_breakpoint (%s, xxx) = %ld\n",
- core_addr_to_string (bp_tgt->placed_address),
- (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_can_use_hw_breakpoint (struct target_ops *self,
- int type, int cnt, int from_tty)
-{
- int retval;
-
- retval = debug_target.to_can_use_hw_breakpoint (&debug_target,
- type, cnt, from_tty);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_can_use_hw_breakpoint (%ld, %ld, %ld) = %ld\n",
- (unsigned long) type,
- (unsigned long) cnt,
- (unsigned long) from_tty,
- (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_region_ok_for_hw_watchpoint (struct target_ops *self,
- CORE_ADDR addr, int len)
-{
- CORE_ADDR retval;
-
- retval = debug_target.to_region_ok_for_hw_watchpoint (&debug_target,
- addr, len);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_region_ok_for_hw_watchpoint (%s, %ld) = %s\n",
- core_addr_to_string (addr), (unsigned long) len,
- core_addr_to_string (retval));
- return retval;
-}
-
-static int
-debug_to_can_accel_watchpoint_condition (struct target_ops *self,
- CORE_ADDR addr, int len, int rw,
- struct expression *cond)
-{
- int retval;
-
- retval = debug_target.to_can_accel_watchpoint_condition (&debug_target,
- addr, len,
- rw, cond);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_can_accel_watchpoint_condition "
- "(%s, %d, %d, %s) = %ld\n",
- core_addr_to_string (addr), len, rw,
- host_address_to_string (cond), (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_stopped_by_watchpoint (struct target_ops *ops)
-{
- int retval;
-
- retval = debug_target.to_stopped_by_watchpoint (&debug_target);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_stopped_by_watchpoint () = %ld\n",
- (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_stopped_data_address (struct target_ops *target, CORE_ADDR *addr)
-{
- int retval;
-
- retval = debug_target.to_stopped_data_address (target, addr);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_stopped_data_address ([%s]) = %ld\n",
- core_addr_to_string (*addr),
- (unsigned long)retval);
- return retval;
-}
-
-static int
-debug_to_watchpoint_addr_within_range (struct target_ops *target,
- CORE_ADDR addr,
- CORE_ADDR start, int length)
-{
- int retval;
-
- retval = debug_target.to_watchpoint_addr_within_range (target, addr,
- start, length);
-
- fprintf_filtered (gdb_stdlog,
- "target_watchpoint_addr_within_range (%s, %s, %d) = %d\n",
- core_addr_to_string (addr), core_addr_to_string (start),
- length, retval);
- return retval;
-}
-
-static int
-debug_to_insert_hw_breakpoint (struct target_ops *self,
- struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- int retval;
-
- retval = debug_target.to_insert_hw_breakpoint (&debug_target,
- gdbarch, bp_tgt);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_insert_hw_breakpoint (%s, xxx) = %ld\n",
- core_addr_to_string (bp_tgt->placed_address),
- (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_remove_hw_breakpoint (struct target_ops *self,
- struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
-{
- int retval;
-
- retval = debug_target.to_remove_hw_breakpoint (&debug_target,
- gdbarch, bp_tgt);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_remove_hw_breakpoint (%s, xxx) = %ld\n",
- core_addr_to_string (bp_tgt->placed_address),
- (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_insert_watchpoint (struct target_ops *self,
- CORE_ADDR addr, int len, int type,
- struct expression *cond)
-{
- int retval;
-
- retval = debug_target.to_insert_watchpoint (&debug_target,
- addr, len, type, cond);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_insert_watchpoint (%s, %d, %d, %s) = %ld\n",
- core_addr_to_string (addr), len, type,
- host_address_to_string (cond), (unsigned long) retval);
- return retval;
-}
-
-static int
-debug_to_remove_watchpoint (struct target_ops *self,
- CORE_ADDR addr, int len, int type,
- struct expression *cond)
-{
- int retval;
-
- retval = debug_target.to_remove_watchpoint (&debug_target,
- addr, len, type, cond);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_remove_watchpoint (%s, %d, %d, %s) = %ld\n",
- core_addr_to_string (addr), len, type,
- host_address_to_string (cond), (unsigned long) retval);
- return retval;
-}
-
-static void
-debug_to_terminal_init (struct target_ops *self)
-{
- debug_target.to_terminal_init (&debug_target);
-
- fprintf_unfiltered (gdb_stdlog, "target_terminal_init ()\n");
-}
-
-static void
-debug_to_terminal_inferior (struct target_ops *self)
-{
- debug_target.to_terminal_inferior (&debug_target);
-
- fprintf_unfiltered (gdb_stdlog, "target_terminal_inferior ()\n");
-}
-
-static void
-debug_to_terminal_ours_for_output (struct target_ops *self)
-{
- debug_target.to_terminal_ours_for_output (&debug_target);
-
- fprintf_unfiltered (gdb_stdlog, "target_terminal_ours_for_output ()\n");
-}
-
-static void
-debug_to_terminal_ours (struct target_ops *self)
-{
- debug_target.to_terminal_ours (&debug_target);
-
- fprintf_unfiltered (gdb_stdlog, "target_terminal_ours ()\n");
-}
-
-static void
-debug_to_terminal_save_ours (struct target_ops *self)
-{
- debug_target.to_terminal_save_ours (&debug_target);
-
- fprintf_unfiltered (gdb_stdlog, "target_terminal_save_ours ()\n");
-}
-
-static void
-debug_to_terminal_info (struct target_ops *self,
- const char *arg, int from_tty)
-{
- debug_target.to_terminal_info (&debug_target, arg, from_tty);
-
- fprintf_unfiltered (gdb_stdlog, "target_terminal_info (%s, %d)\n", arg,
- from_tty);
-}
-
-static void
-debug_to_load (struct target_ops *self, char *args, int from_tty)
-{
- debug_target.to_load (&debug_target, args, from_tty);
-
- fprintf_unfiltered (gdb_stdlog, "target_load (%s, %d)\n", args, from_tty);
-}
-
-static void
-debug_to_post_startup_inferior (struct target_ops *self, ptid_t ptid)
-{
- debug_target.to_post_startup_inferior (&debug_target, ptid);
-
- fprintf_unfiltered (gdb_stdlog, "target_post_startup_inferior (%d)\n",
- ptid_get_pid (ptid));
-}
-
-static int
-debug_to_insert_fork_catchpoint (struct target_ops *self, int pid)
-{
- int retval;
-
- retval = debug_target.to_insert_fork_catchpoint (&debug_target, pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_insert_fork_catchpoint (%d) = %d\n",
- pid, retval);
-
- return retval;
-}
-
-static int
-debug_to_remove_fork_catchpoint (struct target_ops *self, int pid)
-{
- int retval;
-
- retval = debug_target.to_remove_fork_catchpoint (&debug_target, pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_remove_fork_catchpoint (%d) = %d\n",
- pid, retval);
-
- return retval;
-}
-
-static int
-debug_to_insert_vfork_catchpoint (struct target_ops *self, int pid)
-{
- int retval;
-
- retval = debug_target.to_insert_vfork_catchpoint (&debug_target, pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_insert_vfork_catchpoint (%d) = %d\n",
- pid, retval);
-
- return retval;
-}
-
-static int
-debug_to_remove_vfork_catchpoint (struct target_ops *self, int pid)
-{
- int retval;
-
- retval = debug_target.to_remove_vfork_catchpoint (&debug_target, pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_remove_vfork_catchpoint (%d) = %d\n",
- pid, retval);
-
- return retval;
-}
-
-static int
-debug_to_insert_exec_catchpoint (struct target_ops *self, int pid)
-{
- int retval;
-
- retval = debug_target.to_insert_exec_catchpoint (&debug_target, pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_insert_exec_catchpoint (%d) = %d\n",
- pid, retval);
-
- return retval;
-}
-
-static int
-debug_to_remove_exec_catchpoint (struct target_ops *self, int pid)
-{
- int retval;
-
- retval = debug_target.to_remove_exec_catchpoint (&debug_target, pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_remove_exec_catchpoint (%d) = %d\n",
- pid, retval);
-
- return retval;
-}
-
-static int
-debug_to_has_exited (struct target_ops *self,
- int pid, int wait_status, int *exit_status)
-{
- int has_exited;
-
- has_exited = debug_target.to_has_exited (&debug_target,
- pid, wait_status, exit_status);
-
- fprintf_unfiltered (gdb_stdlog, "target_has_exited (%d, %d, %d) = %d\n",
- pid, wait_status, *exit_status, has_exited);
-
- return has_exited;
-}
-
-static int
-debug_to_can_run (struct target_ops *self)
-{
- int retval;
-
- retval = debug_target.to_can_run (&debug_target);
-
- fprintf_unfiltered (gdb_stdlog, "target_can_run () = %d\n", retval);
-
- return retval;
-}
-
-static struct gdbarch *
-debug_to_thread_architecture (struct target_ops *ops, ptid_t ptid)
-{
- struct gdbarch *retval;
-
- retval = debug_target.to_thread_architecture (ops, ptid);
-
- fprintf_unfiltered (gdb_stdlog,
- "target_thread_architecture (%s) = %s [%s]\n",
- target_pid_to_str (ptid),
- host_address_to_string (retval),
- gdbarch_bfd_arch_info (retval)->printable_name);
- return retval;
-}
+/* See target.h. */
-static void
-debug_to_stop (struct target_ops *self, ptid_t ptid)
+void
+target_prepare_to_generate_core (void)
{
- debug_target.to_stop (&debug_target, ptid);
-
- fprintf_unfiltered (gdb_stdlog, "target_stop (%s)\n",
- target_pid_to_str (ptid));
+ current_target.to_prepare_to_generate_core (¤t_target);
}
-static void
-debug_to_rcmd (struct target_ops *self, char *command,
- struct ui_file *outbuf)
-{
- debug_target.to_rcmd (&debug_target, command, outbuf);
- fprintf_unfiltered (gdb_stdlog, "target_rcmd (%s, ...)\n", command);
-}
+/* See target.h. */
-static char *
-debug_to_pid_to_exec_file (struct target_ops *self, int pid)
+void
+target_done_generating_core (void)
{
- char *exec_file;
-
- exec_file = debug_target.to_pid_to_exec_file (&debug_target, pid);
-
- fprintf_unfiltered (gdb_stdlog, "target_pid_to_exec_file (%d) = %s\n",
- pid, exec_file);
-
- return exec_file;
+ current_target.to_done_generating_core (¤t_target);
}
static void
{
memcpy (&debug_target, ¤t_target, sizeof debug_target);
- current_target.to_open = debug_to_open;
- current_target.to_post_attach = debug_to_post_attach;
- current_target.to_prepare_to_store = debug_to_prepare_to_store;
- current_target.deprecated_xfer_memory = deprecated_debug_xfer_memory;
- current_target.to_files_info = debug_to_files_info;
- current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
- current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
- current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint;
- current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint;
- current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint;
- current_target.to_insert_watchpoint = debug_to_insert_watchpoint;
- current_target.to_remove_watchpoint = debug_to_remove_watchpoint;
- current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint;
- current_target.to_stopped_data_address = debug_to_stopped_data_address;
- current_target.to_watchpoint_addr_within_range
- = debug_to_watchpoint_addr_within_range;
- current_target.to_region_ok_for_hw_watchpoint
- = debug_to_region_ok_for_hw_watchpoint;
- current_target.to_can_accel_watchpoint_condition
- = debug_to_can_accel_watchpoint_condition;
- current_target.to_terminal_init = debug_to_terminal_init;
- current_target.to_terminal_inferior = debug_to_terminal_inferior;
- current_target.to_terminal_ours_for_output
- = debug_to_terminal_ours_for_output;
- current_target.to_terminal_ours = debug_to_terminal_ours;
- current_target.to_terminal_save_ours = debug_to_terminal_save_ours;
- current_target.to_terminal_info = debug_to_terminal_info;
- current_target.to_load = debug_to_load;
- current_target.to_post_startup_inferior = debug_to_post_startup_inferior;
- current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint;
- current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
- current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
- current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
- current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
- current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
- current_target.to_has_exited = debug_to_has_exited;
- current_target.to_can_run = debug_to_can_run;
- current_target.to_stop = debug_to_stop;
- current_target.to_rcmd = debug_to_rcmd;
- current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
- current_target.to_thread_architecture = debug_to_thread_architecture;
+ init_debug_target (¤t_target);
}
\f
core-file, and process, if any), as well as the symbol file name.";
static void
-default_rcmd (struct target_ops *self, char *command, struct ui_file *output)
+default_rcmd (struct target_ops *self, const char *command,
+ struct ui_file *output)
{
error (_("\"monitor\" command not supported by this target."));
}
}
}
-/* Controls if async mode is permitted. */
-int target_async_permitted = 0;
+/* Controls if targets can report that they can/are async. This is
+ just for maintainers to use when debugging gdb. */
+int target_async_permitted = 1;
/* The set command writes to this variable. If the inferior is
executing, target_async_permitted is *not* updated. */
-static int target_async_permitted_1 = 0;
+static int target_async_permitted_1 = 1;
static void
-set_target_async_command (char *args, int from_tty,
- struct cmd_list_element *c)
+maint_set_target_async_command (char *args, int from_tty,
+ struct cmd_list_element *c)
{
if (have_live_inferiors ())
{
}
static void
-show_target_async_command (struct ui_file *file, int from_tty,
- struct cmd_list_element *c,
- const char *value)
+maint_show_target_async_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
{
fprintf_filtered (file,
_("Controlling the inferior in "
Set target debugging."), _("\
Show target debugging."), _("\
When non-zero, target debugging is enabled. Higher numbers are more\n\
-verbose. Changes do not take effect until the next \"run\" or \"target\"\n\
-command."),
- NULL,
+verbose."),
+ set_targetdebug,
show_targetdebug,
&setdebuglist, &showdebuglist);
Set whether gdb controls the inferior in asynchronous mode."), _("\
Show whether gdb controls the inferior in asynchronous mode."), _("\
Tells gdb whether to control the inferior in asynchronous mode."),
- set_target_async_command,
- show_target_async_command,
- &setlist,
- &showlist);
+ maint_set_target_async_command,
+ maint_show_target_async_command,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
add_setshow_boolean_cmd ("may-write-registers", class_support,
&may_write_registers_1, _("\
Otherwise, any attempt to interrupt or stop will be ignored."),
set_target_permissions, NULL,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("auto-connect-native-target", class_support,
+ &auto_connect_native_target, _("\
+Set whether GDB may automatically connect to the native target."), _("\
+Show whether GDB may automatically connect to the native target."), _("\
+When on, and GDB is not connected to a target yet, GDB\n\
+attempts \"run\" and other commands with the native target."),
+ NULL, show_auto_connect_native_target,
+ &setlist, &showlist);
}