#include "tracepoint.h"
#include "gdb/fileio.h"
#include "agent.h"
+#include "auxv.h"
static void target_info (char *, int);
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 int nomemory (CORE_ADDR, char *, int, int, struct target_ops *);
+static void default_mourn_inferior (struct target_ops *self);
-static int return_zero (void);
+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 return_minus_one (void);
+static void tcomplain (void) ATTRIBUTE_NORETURN;
-static void *return_null (void);
+static int return_zero (struct target_ops *);
-void target_ignore (void);
+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 char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
+
static int find_default_can_async_p (struct target_ops *ignore);
static int find_default_is_async_p (struct target_ops *ignore);
static enum exec_direction_kind default_execution_direction
(struct target_ops *self);
+static CORE_ADDR default_target_decr_pc_after_break (struct target_ops *ops,
+ struct gdbarch *gdbarch);
+
#include "target-delegates.c"
static void init_dummy_target (void);
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;
install_delegators (t);
}
/* 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;
- }
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_kill ()\n");
- noprocess ();
+ current_target.to_kill (¤t_target);
}
void
(*current_target.to_terminal_inferior) (¤t_target);
}
-static int
-nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write,
- struct target_ops *t)
-{
- errno = EIO; /* Can't read/write this location. */
- return 0; /* No bytes handled. */
-}
-
static void
tcomplain (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. */
- INHERIT (to_stop, t);
- /* 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. */
- INHERIT (to_download_trace_state_variable, t);
- INHERIT (to_enable_tracepoint, t);
- INHERIT (to_disable_tracepoint, t);
- INHERIT (to_trace_set_readonly_regions, t);
- INHERIT (to_trace_start, t);
- INHERIT (to_get_trace_status, t);
- INHERIT (to_get_tracepoint_status, t);
- INHERIT (to_trace_stop, t);
- INHERIT (to_trace_find, t);
- INHERIT (to_get_trace_state_variable_value, t);
- INHERIT (to_save_trace_data, t);
- INHERIT (to_upload_tracepoints, t);
- INHERIT (to_upload_trace_state_variables, t);
- INHERIT (to_get_raw_trace_data, t);
- INHERIT (to_get_min_fast_tracepoint_insn_len, t);
- INHERIT (to_set_disconnected_tracing, t);
- INHERIT (to_set_circular_trace_buffer, t);
- INHERIT (to_set_trace_buffer_size, t);
- INHERIT (to_set_trace_notes, t);
- INHERIT (to_get_tib_address, t);
- INHERIT (to_set_permissions, t);
- INHERIT (to_static_tracepoint_marker_at, t);
- INHERIT (to_static_tracepoint_markers_by_strid, t);
- INHERIT (to_traceframe_info, t);
- INHERIT (to_use_agent, t);
- INHERIT (to_can_use_agent, t);
- INHERIT (to_augmented_libraries_svr4_read, t);
- INHERIT (to_magic, t);
- INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
- INHERIT (to_can_run_breakpoint_commands, t);
- /* 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);
- de_fault (to_stop,
- (void (*) (struct target_ops *, ptid_t))
- target_ignore);
- current_target.to_read_description = NULL;
- de_fault (to_download_trace_state_variable,
- (void (*) (struct target_ops *, struct trace_state_variable *))
- tcomplain);
- de_fault (to_enable_tracepoint,
- (void (*) (struct target_ops *, struct bp_location *))
- tcomplain);
- de_fault (to_disable_tracepoint,
- (void (*) (struct target_ops *, struct bp_location *))
- tcomplain);
- de_fault (to_trace_set_readonly_regions,
- (void (*) (struct target_ops *))
- tcomplain);
- de_fault (to_trace_start,
- (void (*) (struct target_ops *))
- tcomplain);
- de_fault (to_get_trace_status,
- (int (*) (struct target_ops *, struct trace_status *))
- return_minus_one);
- de_fault (to_get_tracepoint_status,
- (void (*) (struct target_ops *, struct breakpoint *,
- struct uploaded_tp *))
- tcomplain);
- de_fault (to_trace_stop,
- (void (*) (struct target_ops *))
- tcomplain);
- de_fault (to_trace_find,
- (int (*) (struct target_ops *,
- enum trace_find_type, int, CORE_ADDR, CORE_ADDR, int *))
- return_minus_one);
- de_fault (to_get_trace_state_variable_value,
- (int (*) (struct target_ops *, int, LONGEST *))
- return_zero);
- de_fault (to_save_trace_data,
- (int (*) (struct target_ops *, const char *))
- tcomplain);
- de_fault (to_upload_tracepoints,
- (int (*) (struct target_ops *, struct uploaded_tp **))
- return_zero);
- de_fault (to_upload_trace_state_variables,
- (int (*) (struct target_ops *, struct uploaded_tsv **))
- return_zero);
- de_fault (to_get_raw_trace_data,
- (LONGEST (*) (struct target_ops *, gdb_byte *, ULONGEST, LONGEST))
- tcomplain);
- de_fault (to_get_min_fast_tracepoint_insn_len,
- (int (*) (struct target_ops *))
- return_minus_one);
- de_fault (to_set_disconnected_tracing,
- (void (*) (struct target_ops *, int))
- target_ignore);
- de_fault (to_set_circular_trace_buffer,
- (void (*) (struct target_ops *, int))
- target_ignore);
- de_fault (to_set_trace_buffer_size,
- (void (*) (struct target_ops *, LONGEST))
- target_ignore);
- de_fault (to_set_trace_notes,
- (int (*) (struct target_ops *,
- const char *, const char *, const char *))
- return_zero);
- de_fault (to_get_tib_address,
- (int (*) (struct target_ops *, ptid_t, CORE_ADDR *))
- tcomplain);
- de_fault (to_set_permissions,
- (void (*) (struct target_ops *))
- target_ignore);
- de_fault (to_static_tracepoint_marker_at,
- (int (*) (struct target_ops *,
- CORE_ADDR, struct static_tracepoint_marker *))
- return_zero);
- de_fault (to_static_tracepoint_markers_by_strid,
- (VEC(static_tracepoint_marker_p) * (*) (struct target_ops *,
- const char *))
- tcomplain);
- de_fault (to_traceframe_info,
- (struct traceframe_info * (*) (struct target_ops *))
- return_null);
- de_fault (to_supports_evaluation_of_breakpoint_conditions,
- (int (*) (struct target_ops *))
- return_zero);
- de_fault (to_can_run_breakpoint_commands,
- (int (*) (struct target_ops *))
- return_zero);
- de_fault (to_use_agent,
- (int (*) (struct target_ops *, int))
- tcomplain);
- de_fault (to_can_use_agent,
- (int (*) (struct target_ops *))
- return_zero);
- de_fault (to_augmented_libraries_svr4_read,
- (int (*) (struct target_ops *))
- return_zero);
-
-#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. */
}
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. */
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
/* No use trying further, we know some memory starting
at MEMADDR isn't available. */
*xfered_len = len;
- return TARGET_XFER_E_UNAVAILABLE;
+ return TARGET_XFER_UNAVAILABLE;
}
}
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
{
/* 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;
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 ();
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
+ hex_string (address), phex (length, 0));
+ 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 ();
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
+ 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. */
static enum target_xfer_status
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);
void
target_disconnect (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 ();
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n",
+ args, from_tty);
+ current_target.to_disconnect (¤t_target, args, from_tty);
}
ptid_t
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 *
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 (targetdebug)
{
- if (t->to_pass_signals != NULL)
- {
- if (targetdebug)
- {
- int i;
+ int i;
- fprintf_unfiltered (gdb_stdlog, "target_pass_signals (%d, {",
- numsigs);
+ 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));
+ 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;
- }
+ fprintf_unfiltered (gdb_stdlog, " })\n");
}
+
+ (*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 (targetdebug)
{
- if (t->to_program_signals != NULL)
- {
- if (targetdebug)
- {
- int i;
+ int i;
- fprintf_unfiltered (gdb_stdlog, "target_program_signals (%d, {",
- numsigs);
+ 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));
+ 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");
- }
-
- (*t->to_program_signals) (t, numsigs, program_signals);
- return;
- }
+ fprintf_unfiltered (gdb_stdlog, " })\n");
}
+
+ (*current_target.to_program_signals) (¤t_target,
+ numsigs, program_signals);
+}
+
+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;
+ int retval = current_target.to_follow_fork (¤t_target,
+ follow_child, detach_fork);
- 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;
- }
- }
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_follow_fork (%d, %d) = %d\n",
+ follow_child, detach_fork, retval);
+ return retval;
+}
- /* 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);
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_mourn_inferior ()\n");
- 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);
- }
+ found = current_target.to_search_memory (¤t_target, start_addr,
+ search_space_len,
+ pattern, pattern_len, found_addrp);
if (targetdebug)
fprintf_unfiltered (gdb_stdlog, " = %d\n", found);
for (t = target_structs; t < target_structs + target_struct_size;
++t)
{
- if ((*t)->to_can_run && target_can_run (*t))
+ if ((*t)->to_can_run != delegate_can_run && target_can_run (*t))
{
runable = *t;
++count;
}
static int
-return_zero (void)
+return_zero (struct target_ops *ignore)
{
return 0;
}
static int
-return_minus_one (void)
-{
- return -1;
-}
-
-static void *
-return_null (void)
+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_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);
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);
+ int retval;
- return retval;
- }
- }
+ retval = current_target.to_thread_alive (¤t_target, ptid);
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
+ ptid_get_pid (ptid), retval);
- return 0;
+ return retval;
}
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);
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_find_new_threads ()\n");
}
void
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;
+ int retval = current_target.to_core_of_thread (¤t_target, ptid);
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_core_of_thread != NULL)
- {
- int retval = t->to_core_of_thread (t, ptid);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_core_of_thread (%d) = %d\n",
- ptid_get_pid (ptid), retval);
- return retval;
- }
- }
-
- return -1;
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_core_of_thread (%d) = %d\n",
+ ptid_get_pid (ptid), retval);
+ return retval;
}
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);
+ int retval = current_target.to_verify_memory (¤t_target,
+ 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 ();
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_verify_memory (%s, %s) = %d\n",
+ paddress (target_gdbarch (), memaddr),
+ pulongest (size),
+ retval);
+ return retval;
}
/* 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;
+ int ret;
- 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);
+ ret = current_target.to_insert_mask_watchpoint (¤t_target,
+ addr, mask, rw);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "\
+ 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;
+ core_addr_to_string (addr),
+ core_addr_to_string (mask), rw, ret);
+
+ return ret;
}
/* 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;
+ int ret;
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_remove_mask_watchpoint != NULL)
- {
- int ret;
+ ret = current_target.to_remove_mask_watchpoint (¤t_target,
+ addr, mask, rw);
- ret = t->to_remove_mask_watchpoint (t, addr, mask, rw);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "\
+ 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);
+ core_addr_to_string (addr),
+ core_addr_to_string (mask), rw, ret);
- return ret;
- }
-
- return 1;
+ return ret;
}
/* 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. */
+ 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. */
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 ();
+ current_target.to_call_history_range (¤t_target, begin, end, flags);
}
static void
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);
-}
-
-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;
+ return current_target.to_decr_pc_after_break (¤t_target, gdbarch);
}
static void
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;