#include "solib.h"
#include "exec.h"
#include "inline-frame.h"
+#include "tracepoint.h"
static void target_info (char *, int);
-static void kill_or_be_killed (int);
-
static void default_terminal_info (char *, int);
static int default_watchpoint_addr_within_range (struct target_ops *,
static int nosymbol (char *, CORE_ADDR *);
-static void tcomplain (void) ATTR_NORETURN;
+static void tcomplain (void) ATTRIBUTE_NORETURN;
static int nomemory (CORE_ADDR, char *, int, int, struct target_ops *);
static struct target_ops *find_default_run_target (char *);
-static void nosupport_runtime (void);
-
static LONGEST default_xfer_partial (struct target_ops *ops,
enum target_object object,
const char *annex, gdb_byte *readbuf,
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)
return 1; /* Symbol does not exist in target env */
}
-static void
-nosupport_runtime (void)
-{
- if (ptid_equal (inferior_ptid, null_ptid))
- noprocess ();
- else
- error (_("No run-time support for this"));
-}
-
-
static void
default_terminal_info (char *args, int from_tty)
{
printf_unfiltered (_("No saved terminal information.\n"));
}
-/* This is the default target_create_inferior and target_attach function.
- If the current target is executing, it asks whether to kill it off.
- If this function returns without calling error(), it has killed off
- the target, and the operation should be attempted. */
-
-static void
-kill_or_be_killed (int from_tty)
-{
- if (target_has_execution)
- {
- printf_unfiltered (_("You are already running a program:\n"));
- target_files_info ();
- if (query (_("Kill it? ")))
- {
- target_kill ();
- if (target_has_execution)
- error (_("Killing the program did not help."));
- return;
- }
- else
- {
- error (_("Program not killed."));
- }
- }
- tcomplain ();
-}
-
/* A default implementation for the to_get_ada_task_ptid target method.
This function builds the PTID by using both LWP and TID as part of
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_set_disconnected_tracing, t);
+ INHERIT (to_set_circular_trace_buffer, t);
+ INHERIT (to_get_tib_address, t);
INHERIT (to_magic, t);
/* Do not inherit to_memory_map. */
/* Do not inherit to_flash_erase. */
(void (*) (void))
tcomplain);
de_fault (to_get_trace_status,
- (int (*) (int *))
+ (int (*) (struct trace_status *))
return_minus_one);
de_fault (to_trace_stop,
(void (*) (void))
tcomplain);
de_fault (to_trace_find,
(int (*) (enum trace_find_type, int, ULONGEST, ULONGEST, int *))
- return_zero);
+ return_minus_one);
de_fault (to_get_trace_state_variable_value,
(int (*) (int, LONGEST *))
return_zero);
+ de_fault (to_save_trace_data,
+ (int (*) (const char *))
+ tcomplain);
+ de_fault (to_upload_tracepoints,
+ (int (*) (struct uploaded_tp **))
+ return_zero);
+ de_fault (to_upload_trace_state_variables,
+ (int (*) (struct uploaded_tsv **))
+ return_zero);
+ de_fault (to_get_raw_trace_data,
+ (LONGEST (*) (gdb_byte *, ULONGEST, LONGEST))
+ tcomplain);
de_fault (to_set_disconnected_tracing,
(void (*) (int))
+ target_ignore);
+ de_fault (to_set_circular_trace_buffer,
+ (void (*) (int))
+ target_ignore);
+ de_fault (to_get_tib_address,
+ (int (*) (ptid_t, CORE_ADDR *))
tcomplain);
#undef de_fault
/* Push a new target type into the stack of the existing target accessors,
possibly superseding some of the existing accessors.
- Result is zero if the pushed target ended up on top of the stack,
- nonzero if at least one target is on top of it.
-
Rather than allow an empty stack, we always have the dummy target at
the bottom stratum, so we can call the function vectors without
checking them. */
-int
+void
push_target (struct target_ops *t)
{
struct target_ops **cur;
/* There's already something at this stratum level. Close it,
and un-hook it from the stack. */
struct target_ops *tmp = (*cur);
+
(*cur) = (*cur)->beneath;
tmp->beneath = NULL;
target_close (tmp, 0);
(*cur) = t;
update_current_target ();
-
- /* Not on top? */
- return (t != target_stack);
}
/* Remove a target_ops vector from the stack, wherever it may be.
fprintf_unfiltered (gdb_stderr,
"pop_target couldn't find target %s\n",
current_target.to_shortname);
- internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
}
void
if (bufptr - buffer + tlen > buffer_allocated)
{
unsigned int bytes;
+
bytes = bufptr - buffer;
buffer_allocated *= 2;
buffer = xrealloc (buffer, buffer_allocated);
if (readbuf != NULL && overlay_debugging)
{
struct obj_section *section = find_pc_overlay (memaddr);
+
if (pc_in_unmapped_range (memaddr, section))
{
struct target_section_table *table
= target_get_section_table (ops);
const char *section_name = section->the_bfd_section->name;
+
memaddr = overlay_mapped_address (memaddr, section);
return section_table_xfer_memory_partial (readbuf, writebuf,
memaddr, len,
inf = NULL;
if (inf != 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. */
+ && get_traceframe_number () == -1
&& (region->attrib.cache
|| (stack_cache_enabled_p && object == TARGET_OBJECT_STACK_MEMORY)))
{
make_show_memory_breakpoints_cleanup (int show)
{
int current = show_memory_breakpoints;
- show_memory_breakpoints = show;
+ show_memory_breakpoints = show;
return make_cleanup (restore_show_memory_breakpoints,
(void *) (uintptr_t) current);
}
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;
- }
+ {
+ 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 ();
}
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;
- }
+ {
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_flash_done\n");
+ t->to_flash_done (t);
+ return;
+ }
tcomplain ();
}
"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);
ULONGEST offset, LONGEST len)
{
LONGEST xfered = 0;
+
while (xfered < len)
{
LONGEST xfer = target_read_partial (ops, object, annex,
(gdb_byte *) buf + xfered,
offset + xfered, len - xfered);
+
/* Call an observer, notifying them of the xfer progress? */
if (xfer == 0)
return xfered;
ULONGEST offset, LONGEST len)
{
LONGEST xfered = 0;
+
while (xfered < len)
{
LONGEST xfer = target_read_partial (ops, object, annex,
(gdb_byte *) buf + xfered,
offset + xfered, len - xfered);
+
/* Call an observer, notifying them of the xfer progress? */
if (xfer == 0)
return xfered;
}
ULONGEST
-get_target_memory_unsigned (struct target_ops *ops,
- CORE_ADDR addr, int len, enum bfd_endian byte_order)
+get_target_memory_unsigned (struct target_ops *ops, CORE_ADDR addr,
+ int len, enum bfd_endian byte_order)
{
gdb_byte buf[sizeof (ULONGEST)];
them before detaching. */
remove_breakpoints_pid (PIDGET (inferior_ptid));
+ prepare_for_detach ();
+
for (t = current_target.beneath; t != NULL; t = t->beneath)
{
if (t->to_detach != NULL)
step ? "step" : "continue",
target_signal_to_name (signal));
+ registers_changed_ptid (ptid);
set_executing (ptid, 1);
set_running (ptid, 1);
clear_inline_frame_state (ptid);
if (t->to_follow_fork != NULL)
{
int retval = t->to_follow_fork (t, follow_child);
+
if (targetdebug)
fprintf_unfiltered (gdb_stdlog, "target_follow_fork (%d) = %d\n",
follow_child, retval);
target_mourn_inferior (void)
{
struct target_ops *t;
+
for (t = current_target.beneath; t != NULL; t = t->beneath)
{
if (t->to_mourn_inferior != NULL)
if (found_ptr != NULL)
{
CORE_ADDR found_addr = start_addr + (found_ptr - search_buf);
+
*found_addrp = found_addr;
do_cleanups (old_cleanups);
return 1;
target_supports_non_stop (void)
{
struct target_ops *t;
+
for (t = ¤t_target; t != NULL; t = t->beneath)
if (t->to_supports_non_stop)
return t->to_supports_non_stop ();
char *
target_get_osdata (const char *type)
{
- char *document;
struct target_ops *t;
/* If we're already connected to something that can get us OS
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 *)) return_zero;
+ dummy_target.to_stopped_by_watchpoint = return_zero;
+ dummy_target.to_stopped_data_address =
+ (int (*) (struct target_ops *, CORE_ADDR *)) return_zero;
dummy_target.to_magic = OPS_MAGIC;
}
\f
target_attach (char *args, int from_tty)
{
struct target_ops *t;
+
for (t = current_target.beneath; t != NULL; t = t->beneath)
{
if (t->to_attach != NULL)
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)
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)
struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
fprintf_unfiltered (gdb_stdlog, "%s ", func);
if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)
&& gdbarch_register_name (gdbarch, regno) != NULL
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i, size = register_size (gdbarch, regno);
unsigned char buf[MAX_REGISTER_SIZE];
+
regcache_raw_collect (regcache, regno, buf);
fprintf_unfiltered (gdb_stdlog, " = ");
for (i = 0; i < size; i++)
if (size <= sizeof (LONGEST))
{
ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
+
fprintf_unfiltered (gdb_stdlog, " %s %s",
core_addr_to_string_nz (val), plongest (val));
}
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)
void
target_store_registers (struct regcache *regcache, int regno)
{
-
struct target_ops *t;
+
for (t = current_target.beneath; t != NULL; t = t->beneath)
{
if (t->to_store_registers != NULL)
noprocess ();
}
+int
+target_core_of_thread (ptid_t ptid)
+{
+ struct target_ops *t;
+
+ 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",
+ PIDGET (ptid), retval);
+ return retval;
+ }
+ }
+
+ return -1;
+}
+
+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 ();
+}
+
static void
debug_to_prepare_to_store (struct regcache *regcache)
{