/* Select target systems and architectures at runtime for GDB.
- Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1990-2013 Free Software Foundation, Inc.
Contributed by Cygnus Support.
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
-#include "gdb_wait.h"
#include "dcache.h"
#include <signal.h>
#include "regcache.h"
#include "exec.h"
#include "inline-frame.h"
#include "tracepoint.h"
+#include "gdb/fileio.h"
+#include "agent.h"
static void target_info (char *, int);
-static void default_terminal_info (char *, int);
+static void default_terminal_info (const char *, int);
static int default_watchpoint_addr_within_range (struct target_ops *,
CORE_ADDR, CORE_ADDR, int);
static void debug_to_terminal_ours (void);
-static void debug_to_terminal_info (char *, int);
-
static void debug_to_load (char *, int);
static int debug_to_can_run (void);
-static void debug_to_notice_signals (ptid_t);
-
static void debug_to_stop (ptid_t);
/* Pointer to array of target architecture structures; the size of the
array. */
struct target_ops **target_structs;
unsigned target_struct_size;
-unsigned target_struct_index;
unsigned target_struct_allocsize;
#define DEFAULT_ALLOCSIZE 10
/* Non-zero if we want to see trace of target level stuff. */
-static int targetdebug = 0;
+static unsigned int targetdebug = 0;
static void
show_targetdebug (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
return target_has_execution_1 (inferior_ptid);
}
-/* Add a possible target architecture to the list. */
+/* Complete initialization of T. This ensures that various fields in
+ T are set, if needed by the target implementation. */
void
-add_target (struct target_ops *t)
+complete_target_initialization (struct target_ops *t)
{
/* Provide default values for all "must have" methods. */
if (t->to_xfer_partial == NULL)
if (t->to_has_execution == NULL)
t->to_has_execution = (int (*) (struct target_ops *, ptid_t)) return_zero;
+}
+
+/* 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. */
+
+void
+add_target_with_completer (struct target_ops *t,
+ completer_ftype *completer)
+{
+ struct cmd_list_element *c;
+
+ complete_target_initialization (t);
if (!target_structs)
{
information on the arguments for a particular protocol, type\n\
`help target ' followed by the protocol name."),
&targetlist, "target ", 0, &cmdlist);
- add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc, &targetlist);
+ c = add_cmd (t->to_shortname, no_class, t->to_open, t->to_doc,
+ &targetlist);
+ if (completer != NULL)
+ set_cmd_completer (c, completer);
+}
+
+/* Add a possible target architecture to the list. */
+
+void
+add_target (struct target_ops *t)
+{
+ add_target_with_completer (t, NULL);
+}
+
+/* See target.h. */
+
+void
+add_deprecated_target_alias (struct target_ops *t, char *alias)
+{
+ struct cmd_list_element *c;
+ char *alt;
+
+ /* 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);
+ alt = xstrprintf ("target %s", t->to_shortname);
+ deprecate_cmd (c, alt);
}
/* Stub functions */
}
static void
-default_terminal_info (char *args, int from_tty)
+default_terminal_info (const char *args, int from_tty)
{
printf_unfiltered (_("No saved terminal information.\n"));
}
return ptid_build (ptid_get_pid (inferior_ptid), lwp, tid);
}
+static enum exec_direction_kind
+default_execution_direction (void)
+{
+ if (!target_can_execute_reverse)
+ return EXEC_FORWARD;
+ else if (!target_can_async_p ())
+ return EXEC_FORWARD;
+ else
+ gdb_assert_not_reached ("\
+to_execution_direction must be implemented for reverse async");
+}
+
/* Go through the target stack from top to bottom, copying over zero
entries in current_target, then filling in still empty entries. In
effect, we are doing class inheritance through the pushed target
INHERIT (to_can_use_hw_breakpoint, t);
INHERIT (to_insert_hw_breakpoint, t);
INHERIT (to_remove_hw_breakpoint, t);
+ /* Do not inherit to_ranged_break_num_registers. */
INHERIT (to_insert_watchpoint, t);
INHERIT (to_remove_watchpoint, t);
+ /* Do not inherit to_insert_mask_watchpoint. */
+ /* Do not inherit to_remove_mask_watchpoint. */
INHERIT (to_stopped_data_address, t);
INHERIT (to_have_steppable_watchpoint, t);
INHERIT (to_have_continuable_watchpoint, t);
INHERIT (to_watchpoint_addr_within_range, t);
INHERIT (to_region_ok_for_hw_watchpoint, t);
INHERIT (to_can_accel_watchpoint_condition, t);
+ /* Do not inherit to_masked_watch_num_registers. */
INHERIT (to_terminal_init, t);
INHERIT (to_terminal_inferior, t);
INHERIT (to_terminal_ours_for_output, t);
INHERIT (to_has_exited, t);
/* Do not inherit to_mourn_inferior. */
INHERIT (to_can_run, t);
- INHERIT (to_notice_signals, 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. */
INHERIT (to_can_async_p, t);
INHERIT (to_is_async_p, t);
INHERIT (to_async, t);
- INHERIT (to_async_mask, t);
INHERIT (to_find_memory_regions, t);
INHERIT (to_make_corefile_notes, t);
INHERIT (to_get_bookmark, t);
INHERIT (to_goto_bookmark, t);
/* Do not inherit to_get_thread_local_address. */
INHERIT (to_can_execute_reverse, t);
+ INHERIT (to_execution_direction, t);
INHERIT (to_thread_architecture, t);
/* Do not inherit to_read_description. */
INHERIT (to_get_ada_task_ptid, t);
/* Do not inherit to_search_memory. */
INHERIT (to_supports_multi_process, t);
+ INHERIT (to_supports_enable_disable_tracepoint, t);
+ INHERIT (to_supports_string_tracing, t);
INHERIT (to_trace_init, t);
INHERIT (to_download_tracepoint, t);
+ INHERIT (to_can_download_tracepoint, t);
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_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. */
(void (*) (char *, int))
tcomplain);
de_fault (to_close,
- (void (*) (int))
+ (void (*) (void))
target_ignore);
de_fault (to_post_attach,
(void (*) (int))
return_zero);
de_fault (to_can_run,
return_zero);
- de_fault (to_notice_signals,
- (void (*) (ptid_t))
- target_ignore);
de_fault (to_extra_thread_info,
(char *(*) (struct thread_info *))
return_zero);
de_fault (to_async,
(void (*) (void (*) (enum inferior_event_type, void*), void*))
tcomplain);
- de_fault (to_async_mask,
- (int (*) (int))
- return_one);
de_fault (to_thread_architecture,
default_thread_architecture);
current_target.to_read_description = NULL;
de_fault (to_supports_multi_process,
(int (*) (void))
return_zero);
+ de_fault (to_supports_enable_disable_tracepoint,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_supports_string_tracing,
+ (int (*) (void))
+ return_zero);
de_fault (to_trace_init,
(void (*) (void))
tcomplain);
de_fault (to_download_tracepoint,
- (void (*) (struct breakpoint *))
+ (void (*) (struct bp_location *))
tcomplain);
+ de_fault (to_can_download_tracepoint,
+ (int (*) (void))
+ return_zero);
de_fault (to_download_trace_state_variable,
(void (*) (struct trace_state_variable *))
tcomplain);
+ de_fault (to_enable_tracepoint,
+ (void (*) (struct bp_location *))
+ tcomplain);
+ de_fault (to_disable_tracepoint,
+ (void (*) (struct bp_location *))
+ tcomplain);
de_fault (to_trace_set_readonly_regions,
(void (*) (void))
tcomplain);
de_fault (to_get_trace_status,
(int (*) (struct trace_status *))
return_minus_one);
+ de_fault (to_get_tracepoint_status,
+ (void (*) (struct breakpoint *, struct uploaded_tp *))
+ tcomplain);
de_fault (to_trace_stop,
(void (*) (void))
tcomplain);
de_fault (to_trace_find,
- (int (*) (enum trace_find_type, int, ULONGEST, ULONGEST, int *))
+ (int (*) (enum trace_find_type, int, CORE_ADDR, CORE_ADDR, int *))
return_minus_one);
de_fault (to_get_trace_state_variable_value,
(int (*) (int, LONGEST *))
de_fault (to_get_raw_trace_data,
(LONGEST (*) (gdb_byte *, ULONGEST, LONGEST))
tcomplain);
+ de_fault (to_get_min_fast_tracepoint_insn_len,
+ (int (*) (void))
+ return_minus_one);
de_fault (to_set_disconnected_tracing,
(void (*) (int))
target_ignore);
de_fault (to_set_circular_trace_buffer,
(void (*) (int))
target_ignore);
+ de_fault (to_set_trace_buffer_size,
+ (void (*) (LONGEST))
+ target_ignore);
+ de_fault (to_set_trace_notes,
+ (int (*) (const char *, const char *, const char *))
+ return_zero);
de_fault (to_get_tib_address,
(int (*) (ptid_t, CORE_ADDR *))
tcomplain);
tcomplain);
de_fault (to_traceframe_info,
(struct traceframe_info * (*) (void))
+ return_zero);
+ de_fault (to_supports_evaluation_of_breakpoint_conditions,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_can_run_breakpoint_commands,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_use_agent,
+ (int (*) (int))
tcomplain);
+ de_fault (to_can_use_agent,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_augmented_libraries_svr4_read,
+ (int (*) (void))
+ return_zero);
+ de_fault (to_execution_direction, default_execution_direction);
+
#undef de_fault
/* Finally, position the target-stack beneath the squashed
(*cur) = (*cur)->beneath;
tmp->beneath = NULL;
- target_close (tmp, 0);
+ target_close (tmp);
}
/* We have removed all targets in our stratum, now add the new one. */
break;
}
+ /* If we don't find target_ops, quit. Only open targets should be
+ closed. */
if ((*cur) == NULL)
- return 0; /* Didn't find target_ops, quit now. */
-
- /* NOTE: cagney/2003-12-06: In '94 the close call was made
- unconditional by moving it to before the above check that the
- target was in the target stack (something about "Change the way
- pushing and popping of targets work to support target overlays
- and inheritance"). This doesn't make much sense - only open
- targets should be closed. */
- target_close (t, 0);
+ return 0;
/* Unchain the target. */
tmp = (*cur);
update_current_target ();
- return 1;
-}
-
-void
-pop_target (void)
-{
- target_close (target_stack, 0); /* Let it clean up. */
- if (unpush_target (target_stack) == 1)
- return;
+ /* Finally close the target. Note we do this after unchaining, so
+ any target method calls from within the target_close
+ implementation don't end up in T anymore. */
+ target_close (t);
- fprintf_unfiltered (gdb_stderr,
- "pop_target couldn't find target %s\n",
- current_target.to_shortname);
- internal_error (__FILE__, __LINE__,
- _("failed internal consistency check"));
+ return 1;
}
void
-pop_all_targets_above (enum strata above_stratum, int quitting)
+pop_all_targets_above (enum strata above_stratum)
{
while ((int) (current_target.to_stratum) > (int) above_stratum)
{
- target_close (target_stack, quitting);
if (!unpush_target (target_stack))
{
fprintf_unfiltered (gdb_stderr,
}
void
-pop_all_targets (int quitting)
+pop_all_targets (void)
{
- pop_all_targets_above (dummy_stratum, quitting);
+ pop_all_targets_above (dummy_stratum);
}
/* Return 1 if T is now pushed in the target stack. Return 0 otherwise. */
}
if (target != NULL
- && gdbarch_fetch_tls_load_module_address_p (target_gdbarch))
+ && gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
{
ptid_t ptid = inferior_ptid;
volatile struct gdb_exception ex;
CORE_ADDR lm_addr;
/* Fetch the load module address for this objfile. */
- lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch,
+ lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (),
objfile);
/* If it's 0, throw the appropriate exception. */
if (lm_addr == 0)
int
target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
{
- int tlen, origlen, offset, i;
+ int tlen, offset, i;
gdb_byte buf[4];
int errcode = 0;
char *buffer;
buffer = xmalloc (buffer_allocated);
bufptr = buffer;
- origlen = len;
-
while (len > 0)
{
tlen = MIN (len, 4 - (memaddr & 3));
secp = target_section_by_addr (ops, memaddr);
if (secp != NULL
- && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+ && (bfd_get_section_flags (secp->the_bfd_section->owner,
+ secp->the_bfd_section)
& SEC_READONLY))
{
struct target_section *p;
For docs see target.h, to_xfer_partial. */
static LONGEST
-memory_xfer_partial (struct target_ops *ops, enum target_object object,
- void *readbuf, const void *writebuf, ULONGEST memaddr,
- LONGEST len)
+memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
+ void *readbuf, const void *writebuf, ULONGEST memaddr,
+ LONGEST len)
{
LONGEST res;
int reg_len;
struct mem_region *region;
struct inferior *inf;
- /* Zero length requests are ok and require no work. */
- if (len == 0)
- return 0;
-
/* For accesses to unmapped overlay sections, read directly from
files. Must do this first, as MEMADDR may need adjustment. */
if (readbuf != NULL && overlay_debugging)
secp = target_section_by_addr (ops, memaddr);
if (secp != NULL
- && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
+ && (bfd_get_section_flags (secp->the_bfd_section->owner,
+ secp->the_bfd_section)
& SEC_READONLY))
{
table = target_get_section_table (ops);
if (res <= 0)
return -1;
else
- {
- if (readbuf && !show_memory_breakpoints)
- breakpoint_restore_shadows (readbuf, memaddr, reg_len);
- return res;
- }
+ return res;
}
/* If none of those methods found the memory we wanted, fall back
}
while (ops != NULL);
- if (res > 0 && readbuf != NULL && !show_memory_breakpoints)
- breakpoint_restore_shadows (readbuf, memaddr, reg_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. */
return res;
}
+/* Perform a partial memory transfer. For docs see target.h,
+ to_xfer_partial. */
+
+static LONGEST
+memory_xfer_partial (struct target_ops *ops, enum target_object object,
+ void *readbuf, const void *writebuf, ULONGEST memaddr,
+ LONGEST len)
+{
+ int res;
+
+ /* Zero length requests are ok and require no work. */
+ if (len == 0)
+ return 0;
+
+ /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
+ breakpoint insns, thus hiding out from higher layers whether
+ there are software breakpoints inserted in the code stream. */
+ if (readbuf != NULL)
+ {
+ res = memory_xfer_partial_1 (ops, object, readbuf, NULL, memaddr, len);
+
+ if (res > 0 && !show_memory_breakpoints)
+ breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, res);
+ }
+ else
+ {
+ void *buf;
+ struct cleanup *old_chain;
+
+ buf = xmalloc (len);
+ old_chain = make_cleanup (xfree, buf);
+ memcpy (buf, writebuf, len);
+
+ breakpoint_xfer_memory (NULL, buf, writebuf, memaddr, len);
+ res = memory_xfer_partial_1 (ops, object, NULL, buf, memaddr, len);
+
+ do_cleanups (old_chain);
+ }
+
+ return res;
+}
+
static void
restore_show_memory_breakpoints (void *arg)
{
it makes no progress, and then return how much was transferred). */
int
-target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
{
/* Dispatch to the topmost target, not the flattened current_target.
Memory accesses check target->to_has_(all_)memory, and the
the target's stack. This may trigger different cache behavior. */
int
-target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
{
/* Dispatch to the topmost target, not the flattened current_target.
Memory accesses check target->to_has_(all_)memory, and the
Callers that can deal with partial writes should call target_write. */
int
-target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
+target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
{
/* Dispatch to the topmost target, not the flattened current_target.
Memory accesses check target->to_has_(all_)memory, and the
return EIO;
}
+/* Write LEN bytes from MYADDR to target raw memory at address
+ MEMADDR. Returns either 0 for success or an errno value if any
+ error occurs. If an error occurs, no guarantee is made about how
+ much data got written. Callers that can deal with partial writes
+ should call target_write. */
+
+int
+target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
+{
+ /* Dispatch to the topmost target, not the flattened current_target.
+ Memory accesses check target->to_has_(all_)memory, and the
+ flattened target doesn't inherit those. */
+ if (target_write (current_target.beneath, TARGET_OBJECT_RAW_MEMORY, NULL,
+ myaddr, memaddr, len) == len)
+ return 0;
+ else
+ return EIO;
+}
+
/* Fetch the target's memory map. */
VEC(mem_region_s) *
const char *annex)
{
gdb_byte *buffer;
- LONGEST transferred;
+ char *bufstr;
+ LONGEST i, transferred;
transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
+ bufstr = (char *) buffer;
if (transferred < 0)
return NULL;
if (transferred == 0)
return xstrdup ("");
- buffer[transferred] = 0;
- if (strlen (buffer) < transferred)
- warning (_("target object %d, annex %s, "
- "contained unexpected null characters"),
- (int) object, annex ? annex : "(none)");
+ bufstr[transferred] = 0;
+
+ /* Check for embedded NUL bytes; but allow trailing NULs. */
+ for (i = strlen (bufstr); i < transferred; i++)
+ if (bufstr[i] != 0)
+ {
+ warning (_("target object %d, annex %s, "
+ "contained unexpected null characters"),
+ (int) object, annex ? annex : "(none)");
+ break;
+ }
- return (char *) buffer;
+ return bufstr;
}
/* Memory transfer methods. */
/* In some OSs, the shared library list is the same/global/shared
across inferiors. If code is shared between processes, so are
memory regions and features. */
- if (!gdbarch_has_global_solist (target_gdbarch))
+ if (!gdbarch_has_global_solist (target_gdbarch ()))
{
no_shared_libraries (NULL, from_tty);
target_clear_description ();
}
+
+ agent_capability_invalidate ();
}
/* Callback for iterate_over_inferiors. Gets rid of the given
it doesn't (which seems like a win for UDI), remove it now. */
/* Leave the exec target, though. The user may be switching from a
live process to a core of the same program. */
- pop_all_targets_above (file_stratum, 0);
+ pop_all_targets_above (file_stratum);
target_pre_inferior (from_tty);
}
{
struct target_ops* t;
- if (gdbarch_has_global_breakpoints (target_gdbarch))
+ if (gdbarch_has_global_breakpoints (target_gdbarch ()))
/* Don't remove global breakpoints here. They're removed on
disconnection from the target. */
;
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) = %d, %s\n",
- PIDGET (ptid), PIDGET (retval),
- status_string);
+ "target_wait (%d, status, options={%s})"
+ " = %d, %s\n",
+ PIDGET (ptid), options_string,
+ PIDGET (retval), status_string);
xfree (status_string);
+ xfree (options_string);
}
return retval;
}
void
-target_resume (ptid_t ptid, int step, enum target_signal signal)
+target_resume (ptid_t ptid, int step, enum gdb_signal signal)
{
struct target_ops *t;
fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n",
PIDGET (ptid),
step ? "step" : "continue",
- target_signal_to_name (signal));
+ gdb_signal_to_name (signal));
registers_changed_ptid (ptid);
set_executing (ptid, 1);
noprocess ();
}
+
+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) (numsigs, pass_signals);
+ return;
+ }
+ }
+}
+
+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");
+ }
+
+ (*t->to_program_signals) (numsigs, program_signals);
+ return;
+ }
+ }
+}
+
/* Look through the list of possible targets for a target that can
follow forks. */
if (target_read (ops, TARGET_OBJECT_MEMORY, NULL,
search_buf, start_addr, search_buf_size) != search_buf_size)
{
- warning (_("Unable to access target memory at %s, halting search."),
- hex_string (start_addr));
+ warning (_("Unable to access %s bytes of target "
+ "memory at %s, halting search."),
+ pulongest (search_buf_size), hex_string (start_addr));
do_cleanups (old_cleanups);
return -1;
}
search_buf + keep_len, read_addr,
nr_to_read) != nr_to_read)
{
- warning (_("Unable to access target "
+ warning (_("Unable to access %s bytes of target "
"memory at %s, halting search."),
+ plongest (nr_to_read),
hex_string (read_addr));
do_cleanups (old_cleanups);
return -1;
return 0;
}
+/* Implement the "info proc" command. */
+
+int
+target_info_proc (char *args, enum info_proc_what what)
+{
+ struct target_ops *t;
+
+ /* If we're already connected to something that can get us OS
+ related data, use it. Otherwise, try using the native
+ target. */
+ if (current_target.to_stratum >= process_stratum)
+ t = current_target.beneath;
+ else
+ t = find_default_run_target (NULL);
+
+ for (; t != NULL; t = t->beneath)
+ {
+ if (t->to_info_proc != NULL)
+ {
+ t->to_info_proc (t, args, what);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_info_proc (\"%s\", %d)\n", args, what);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+find_default_supports_disable_randomization (void)
+{
+ struct target_ops *t;
+
+ t = find_default_run_target (NULL);
+ if (t && t->to_supports_disable_randomization)
+ return (t->to_supports_disable_randomization) ();
+ return 0;
+}
+
+int
+target_supports_disable_randomization (void)
+{
+ struct target_ops *t;
+
+ for (t = ¤t_target; t != NULL; t = t->beneath)
+ if (t->to_supports_disable_randomization)
+ return t->to_supports_disable_randomization ();
+
+ return 0;
+}
char *
target_get_osdata (const char *type)
return inf->aspace;
}
-static int
-default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
-{
- return (len <= gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT);
-}
-static int
-default_watchpoint_addr_within_range (struct target_ops *target,
- CORE_ADDR addr,
- CORE_ADDR start, int length)
-{
- return addr >= start && addr < start + length;
-}
+/* Target file operations. */
-static struct gdbarch *
-default_thread_architecture (struct target_ops *ops, ptid_t ptid)
+static struct target_ops *
+default_fileio_target (void)
{
- return target_gdbarch;
+ /* If we're already connected to something that can perform
+ file I/O, use it. Otherwise, try using the native target. */
+ if (current_target.to_stratum >= process_stratum)
+ return current_target.beneath;
+ else
+ return find_default_run_target ("file I/O");
}
-static int
-return_zero (void)
+/* Open FILENAME on the target, using FLAGS and MODE. Return a
+ target file descriptor, or -1 if an error occurs (and set
+ *TARGET_ERRNO). */
+int
+target_fileio_open (const char *filename, int flags, int mode,
+ int *target_errno)
{
- return 0;
-}
+ struct target_ops *t;
-static int
-return_one (void)
-{
- return 1;
-}
+ for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ {
+ if (t->to_fileio_open != NULL)
+ {
+ int fd = t->to_fileio_open (filename, flags, mode, target_errno);
-static int
-return_minus_one (void)
-{
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_fileio_open (%s,0x%x,0%o) = %d (%d)\n",
+ filename, flags, mode,
+ fd, fd != -1 ? 0 : *target_errno);
+ return fd;
+ }
+ }
+
+ *target_errno = FILEIO_ENOSYS;
return -1;
}
-/* Find a single runnable target in the stack and return it. If for
- some reason there is more than one, return NULL. */
-
-struct target_ops *
-find_run_target (void)
+/* Write up to LEN bytes from WRITE_BUF to FD on the target.
+ Return the number of bytes written, or -1 if an error occurs
+ (and set *TARGET_ERRNO). */
+int
+target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+ ULONGEST offset, int *target_errno)
{
- struct target_ops **t;
- struct target_ops *runable = NULL;
- int count;
-
- count = 0;
+ struct target_ops *t;
- for (t = target_structs; t < target_structs + target_struct_size; ++t)
+ for (t = default_fileio_target (); t != NULL; t = t->beneath)
{
- if ((*t)->to_can_run && target_can_run (*t))
+ if (t->to_fileio_pwrite != NULL)
{
- runable = *t;
- ++count;
+ int ret = t->to_fileio_pwrite (fd, write_buf, len, offset,
+ target_errno);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_fileio_pwrite (%d,...,%d,%s) "
+ "= %d (%d)\n",
+ fd, len, pulongest (offset),
+ ret, ret != -1 ? 0 : *target_errno);
+ return ret;
}
}
- return (count == 1 ? runable : NULL);
+ *target_errno = FILEIO_ENOSYS;
+ return -1;
}
-/*
- * Find the next target down the stack from the specified target.
- */
-
+/* Read up to LEN bytes FD on the target into READ_BUF.
+ Return the number of bytes read, or -1 if an error occurs
+ (and set *TARGET_ERRNO). */
+int
+target_fileio_pread (int fd, gdb_byte *read_buf, int len,
+ ULONGEST offset, int *target_errno)
+{
+ struct target_ops *t;
+
+ for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ {
+ if (t->to_fileio_pread != NULL)
+ {
+ int ret = t->to_fileio_pread (fd, read_buf, len, offset,
+ target_errno);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_fileio_pread (%d,...,%d,%s) "
+ "= %d (%d)\n",
+ fd, len, pulongest (offset),
+ ret, ret != -1 ? 0 : *target_errno);
+ return ret;
+ }
+ }
+
+ *target_errno = FILEIO_ENOSYS;
+ return -1;
+}
+
+/* Close FD on the target. Return 0, or -1 if an error occurs
+ (and set *TARGET_ERRNO). */
+int
+target_fileio_close (int fd, int *target_errno)
+{
+ struct target_ops *t;
+
+ for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ {
+ if (t->to_fileio_close != NULL)
+ {
+ int ret = t->to_fileio_close (fd, target_errno);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_fileio_close (%d) = %d (%d)\n",
+ fd, ret, ret != -1 ? 0 : *target_errno);
+ return ret;
+ }
+ }
+
+ *target_errno = FILEIO_ENOSYS;
+ return -1;
+}
+
+/* Unlink FILENAME on the target. Return 0, or -1 if an error
+ occurs (and set *TARGET_ERRNO). */
+int
+target_fileio_unlink (const char *filename, int *target_errno)
+{
+ struct target_ops *t;
+
+ for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ {
+ if (t->to_fileio_unlink != NULL)
+ {
+ int ret = t->to_fileio_unlink (filename, target_errno);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_fileio_unlink (%s) = %d (%d)\n",
+ filename, ret, ret != -1 ? 0 : *target_errno);
+ return ret;
+ }
+ }
+
+ *target_errno = FILEIO_ENOSYS;
+ return -1;
+}
+
+/* Read value of symbolic link FILENAME on the target. Return a
+ null-terminated string allocated via xmalloc, or NULL if an error
+ occurs (and set *TARGET_ERRNO). */
+char *
+target_fileio_readlink (const char *filename, int *target_errno)
+{
+ struct target_ops *t;
+
+ for (t = default_fileio_target (); t != NULL; t = t->beneath)
+ {
+ if (t->to_fileio_readlink != NULL)
+ {
+ char *ret = t->to_fileio_readlink (filename, target_errno);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_fileio_readlink (%s) = %s (%d)\n",
+ filename, ret? ret : "(nil)",
+ ret? 0 : *target_errno);
+ return ret;
+ }
+ }
+
+ *target_errno = FILEIO_ENOSYS;
+ return NULL;
+}
+
+static void
+target_fileio_close_cleanup (void *opaque)
+{
+ int fd = *(int *) opaque;
+ int target_errno;
+
+ target_fileio_close (fd, &target_errno);
+}
+
+/* Read target file FILENAME. Store the result in *BUF_P and
+ return the size of the transferred data. PADDING additional bytes are
+ available in *BUF_P. This is a helper function for
+ target_fileio_read_alloc; see the declaration of that function for more
+ information. */
+
+static LONGEST
+target_fileio_read_alloc_1 (const char *filename,
+ gdb_byte **buf_p, int padding)
+{
+ struct cleanup *close_cleanup;
+ size_t buf_alloc, buf_pos;
+ gdb_byte *buf;
+ LONGEST n;
+ int fd;
+ int target_errno;
+
+ fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno);
+ if (fd == -1)
+ return -1;
+
+ close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd);
+
+ /* Start by reading up to 4K at a time. The target will throttle
+ this number down if necessary. */
+ buf_alloc = 4096;
+ buf = xmalloc (buf_alloc);
+ buf_pos = 0;
+ while (1)
+ {
+ n = target_fileio_pread (fd, &buf[buf_pos],
+ buf_alloc - buf_pos - padding, buf_pos,
+ &target_errno);
+ if (n < 0)
+ {
+ /* An error occurred. */
+ do_cleanups (close_cleanup);
+ xfree (buf);
+ return -1;
+ }
+ else if (n == 0)
+ {
+ /* Read all there was. */
+ do_cleanups (close_cleanup);
+ if (buf_pos == 0)
+ xfree (buf);
+ else
+ *buf_p = buf;
+ return buf_pos;
+ }
+
+ buf_pos += n;
+
+ /* If the buffer is filling up, expand it. */
+ if (buf_alloc < buf_pos * 2)
+ {
+ buf_alloc *= 2;
+ buf = xrealloc (buf, buf_alloc);
+ }
+
+ QUIT;
+ }
+}
+
+/* Read target file FILENAME. Store the result in *BUF_P and return
+ the size of the transferred data. See the declaration in "target.h"
+ function for more information about the return value. */
+
+LONGEST
+target_fileio_read_alloc (const char *filename, gdb_byte **buf_p)
+{
+ return target_fileio_read_alloc_1 (filename, buf_p, 0);
+}
+
+/* Read target file FILENAME. The result is NUL-terminated and
+ returned as a string, allocated using xmalloc. If an error occurs
+ or the transfer is unsupported, NULL is returned. Empty objects
+ are returned as allocated but empty strings. A warning is issued
+ if the result contains any embedded NUL bytes. */
+
+char *
+target_fileio_read_stralloc (const char *filename)
+{
+ gdb_byte *buffer;
+ char *bufstr;
+ LONGEST i, transferred;
+
+ transferred = target_fileio_read_alloc_1 (filename, &buffer, 1);
+ bufstr = (char *) buffer;
+
+ if (transferred < 0)
+ return NULL;
+
+ if (transferred == 0)
+ return xstrdup ("");
+
+ bufstr[transferred] = 0;
+
+ /* Check for embedded NUL bytes; but allow trailing NULs. */
+ for (i = strlen (bufstr); i < transferred; i++)
+ if (bufstr[i] != 0)
+ {
+ warning (_("target file %s "
+ "contained unexpected null characters"),
+ filename);
+ break;
+ }
+
+ return bufstr;
+}
+
+
+static int
+default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
+{
+ return (len <= gdbarch_ptr_bit (target_gdbarch ()) / TARGET_CHAR_BIT);
+}
+
+static int
+default_watchpoint_addr_within_range (struct target_ops *target,
+ CORE_ADDR addr,
+ CORE_ADDR start, int length)
+{
+ return addr >= start && addr < start + length;
+}
+
+static struct gdbarch *
+default_thread_architecture (struct target_ops *ops, ptid_t ptid)
+{
+ return target_gdbarch ();
+}
+
+static int
+return_zero (void)
+{
+ return 0;
+}
+
+static int
+return_one (void)
+{
+ return 1;
+}
+
+static int
+return_minus_one (void)
+{
+ return -1;
+}
+
+/*
+ * Find the next target down the stack from the specified target.
+ */
+
struct target_ops *
find_target_beneath (struct target_ops *t)
{
ptid = inferior_ptid;
inferior_ptid = null_ptid;
+ /* Mark breakpoints uninserted in case something tries to delete a
+ breakpoint while we delete the inferior's threads (which would
+ fail, since the inferior is long gone). */
+ mark_breakpoints_out ();
+
if (!ptid_equal (ptid, null_ptid))
{
int pid = ptid_get_pid (ptid);
exit_inferior (pid);
}
+ /* Note this wipes step-resume breakpoints, so needs to be done
+ after exit_inferior, which ends up referencing the step-resume
+ breakpoints through clear_thread_inferior_resources. */
breakpoint_init_inferior (inf_exited);
+
registers_changed ();
reopen_exec_file ();
deprecated_detach_hook ();
}
\f
-/* Helper function for child_wait and the derivatives of child_wait.
- HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
- translation of that in OURSTATUS. */
-void
-store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
-{
- if (WIFEXITED (hoststatus))
- {
- ourstatus->kind = TARGET_WAITKIND_EXITED;
- ourstatus->value.integer = WEXITSTATUS (hoststatus);
- }
- else if (!WIFSTOPPED (hoststatus))
- {
- ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
- ourstatus->value.sig = target_signal_from_host (WTERMSIG (hoststatus));
- }
- else
- {
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
- ourstatus->value.sig = target_signal_from_host (WSTOPSIG (hoststatus));
- }
-}
-\f
/* Convert a normal process ID to a string. Returns the string in a
static buffer. */
dummy_target.to_can_async_p = find_default_can_async_p;
dummy_target.to_is_async_p = find_default_is_async_p;
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_find_memory_regions = dummy_find_memory_regions;
}
void
-target_close (struct target_ops *targ, int quitting)
+target_close (struct target_ops *targ)
{
+ gdb_assert (!target_is_pushed (targ));
+
if (targ->to_xclose != NULL)
- targ->to_xclose (targ, quitting);
+ targ->to_xclose (targ);
else if (targ->to_close != NULL)
- targ->to_close (quitting);
+ targ->to_close ();
if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_close (%d)\n", quitting);
+ fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
}
void
fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
}
-/* Return a pretty printed form of target_waitstatus.
- Space for the result is malloc'd, caller must free. */
+/* Concatenate ELEM to LIST, a comma separate list, and return the
+ result. The LIST incoming argument is released. */
-char *
-target_waitstatus_to_string (const struct target_waitstatus *ws)
+static char *
+str_comma_list_concat_elem (char *list, const char *elem)
{
- const char *kind_str = "status->kind = ";
+ if (list == NULL)
+ return xstrdup (elem);
+ else
+ return reconcat (list, list, ", ", elem, (char *) NULL);
+}
- switch (ws->kind)
+/* Helper for target_options_to_string. If OPT is present in
+ TARGET_OPTIONS, append the OPT_STR (string version of OPT) in RET.
+ Returns the new resulting string. OPT is removed from
+ TARGET_OPTIONS. */
+
+static char *
+do_option (int *target_options, char *ret,
+ int opt, char *opt_str)
+{
+ if ((*target_options & opt) != 0)
{
- case TARGET_WAITKIND_EXITED:
- return xstrprintf ("%sexited, status = %d",
- kind_str, ws->value.integer);
- case TARGET_WAITKIND_STOPPED:
- return xstrprintf ("%sstopped, signal = %s",
- kind_str, target_signal_to_name (ws->value.sig));
- case TARGET_WAITKIND_SIGNALLED:
- return xstrprintf ("%ssignalled, signal = %s",
- kind_str, target_signal_to_name (ws->value.sig));
- case TARGET_WAITKIND_LOADED:
- return xstrprintf ("%sloaded", kind_str);
- case TARGET_WAITKIND_FORKED:
- return xstrprintf ("%sforked", kind_str);
- case TARGET_WAITKIND_VFORKED:
- return xstrprintf ("%svforked", kind_str);
- case TARGET_WAITKIND_EXECD:
- return xstrprintf ("%sexecd", kind_str);
- case TARGET_WAITKIND_SYSCALL_ENTRY:
- return xstrprintf ("%sentered syscall", kind_str);
- case TARGET_WAITKIND_SYSCALL_RETURN:
- return xstrprintf ("%sexited syscall", kind_str);
- case TARGET_WAITKIND_SPURIOUS:
- return xstrprintf ("%sspurious", kind_str);
- case TARGET_WAITKIND_IGNORE:
- return xstrprintf ("%signore", kind_str);
- case TARGET_WAITKIND_NO_HISTORY:
- return xstrprintf ("%sno-history", kind_str);
- default:
- return xstrprintf ("%sunknown???", kind_str);
+ ret = str_comma_list_concat_elem (ret, opt_str);
+ *target_options &= ~opt;
}
+
+ return ret;
+}
+
+char *
+target_options_to_string (int target_options)
+{
+ char *ret = NULL;
+
+#define DO_TARG_OPTION(OPT) \
+ ret = do_option (&target_options, ret, OPT, #OPT)
+
+ DO_TARG_OPTION (TARGET_WNOHANG);
+
+ if (target_options != 0)
+ ret = str_comma_list_concat_elem (ret, "unknown???");
+
+ if (ret == NULL)
+ ret = xstrdup ("");
+ return ret;
}
static void
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i, size = register_size (gdbarch, regno);
- unsigned char buf[MAX_REGISTER_SIZE];
+ gdb_byte buf[MAX_REGISTER_SIZE];
regcache_raw_collect (regcache, regno, buf);
fprintf_unfiltered (gdb_stdlog, " = ");
if (targetdebug)
fprintf_unfiltered (gdb_stdlog,
"target_verify_memory (%s, %s) = %d\n",
- paddress (target_gdbarch, memaddr),
+ paddress (target_gdbarch (), memaddr),
pulongest (size),
retval);
return retval;
tcomplain ();
}
+/* The documentation for this function is in its prototype declaration in
+ target.h. */
+
+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;
+}
+
+/* The documentation for this function is in its prototype declaration in
+ target.h. */
+
+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;
+}
+
+/* The documentation for this function is in its prototype declaration
+ in target.h. */
+
+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;
+}
+
+/* The documentation for this function is in its prototype declaration
+ in target.h. */
+
+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;
+}
+
+/* See target.h. */
+
+int
+target_supports_btrace (void)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ if (t->to_supports_btrace != NULL)
+ return t->to_supports_btrace ();
+
+ return 0;
+}
+
+/* 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 (ptid);
+
+ tcomplain ();
+ return NULL;
+}
+
+/* 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)
+ return t->to_disable_btrace (btinfo);
+
+ tcomplain ();
+}
+
+/* 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)
+ return t->to_teardown_btrace (btinfo);
+
+ tcomplain ();
+}
+
+/* See target.h. */
+
+VEC (btrace_block_s) *
+target_read_btrace (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 (btinfo, type);
+
+ tcomplain ();
+ return NULL;
+}
+
+/* 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 ();
+ 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 ();
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (filename);
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* See target.h. */
+
+int
+target_supports_delete_record (void)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ if (t->to_delete_record != NULL)
+ return 1;
+
+ return 0;
+}
+
+/* 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 ();
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 ();
+
+ return 0;
+}
+
+/* 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 ();
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 ();
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (insn);
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (size, flags);
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (from, size, flags);
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (begin, end, flags);
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (size, flags);
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (begin, size, flags);
+ return;
+ }
+
+ tcomplain ();
+}
+
+/* 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 (begin, end, flags);
+ return;
+ }
+
+ tcomplain ();
+}
+
static void
debug_to_prepare_to_store (struct regcache *regcache)
{
fprintf_unfiltered (gdb_stdlog,
"target_xfer_memory (%s, xxx, %d, %s, xxx) = %d",
- paddress (target_gdbarch, memaddr), len,
+ paddress (target_gdbarch (), memaddr), len,
write ? "write" : "read", retval);
if (retval > 0)
}
static void
-debug_to_terminal_info (char *arg, int from_tty)
+debug_to_terminal_info (const char *arg, int from_tty)
{
debug_target.to_terminal_info (arg, from_tty);
return retval;
}
-static void
-debug_to_notice_signals (ptid_t ptid)
-{
- debug_target.to_notice_signals (ptid);
-
- fprintf_unfiltered (gdb_stdlog, "target_notice_signals (%d)\n",
- PIDGET (ptid));
-}
-
static struct gdbarch *
debug_to_thread_architecture (struct target_ops *ops, ptid_t ptid)
{
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_notice_signals = debug_to_notice_signals;
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;
int target_async_permitted = 0;
/* The set command writes to this variable. If the inferior is
- executing, linux_nat_async_permitted is *not* updated. */
+ executing, target_async_permitted is *not* updated. */
static int target_async_permitted_1 = 0;
static void
-set_maintenance_target_async_permitted (char *args, int from_tty,
- struct cmd_list_element *c)
+set_target_async_command (char *args, int from_tty,
+ struct cmd_list_element *c)
{
if (have_live_inferiors ())
{
}
static void
-show_maintenance_target_async_permitted (struct ui_file *file, int from_tty,
- struct cmd_list_element *c,
- const char *value)
+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 "
add_info ("target", target_info, targ_desc);
add_info ("files", target_info, targ_desc);
- add_setshow_zinteger_cmd ("target", class_maintenance, &targetdebug, _("\
+ add_setshow_zuinteger_cmd ("target", class_maintenance, &targetdebug, _("\
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,
- show_targetdebug,
- &setdebuglist, &showdebuglist);
+ NULL,
+ show_targetdebug,
+ &setdebuglist, &showdebuglist);
add_setshow_boolean_cmd ("trust-readonly-sections", class_support,
&trust_readonly, _("\
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_maintenance_target_async_permitted,
- show_maintenance_target_async_permitted,
+ set_target_async_command,
+ show_target_async_command,
&setlist,
&showlist);