#include "gdbthread.h"
#include "solib.h"
#include "exec.h"
+#include "inline-frame.h"
static void target_info (char *, int);
void *readbuf, const void *writebuf,
ULONGEST offset, LONGEST len);
+static struct gdbarch *default_thread_architecture (struct target_ops *ops,
+ ptid_t ptid);
+
static void init_dummy_target (void);
static struct target_ops debug_target;
static void debug_to_files_info (struct target_ops *);
-static int debug_to_insert_breakpoint (struct bp_target_info *);
+static int debug_to_insert_breakpoint (struct gdbarch *,
+ struct bp_target_info *);
-static int debug_to_remove_breakpoint (struct bp_target_info *);
+static int debug_to_remove_breakpoint (struct gdbarch *,
+ struct bp_target_info *);
static int debug_to_can_use_hw_breakpoint (int, int, int);
-static int debug_to_insert_hw_breakpoint (struct bp_target_info *);
+static int debug_to_insert_hw_breakpoint (struct gdbarch *,
+ struct bp_target_info *);
-static int debug_to_remove_hw_breakpoint (struct bp_target_info *);
+static int debug_to_remove_hw_breakpoint (struct gdbarch *,
+ struct bp_target_info *);
static int debug_to_insert_watchpoint (CORE_ADDR, int, int);
static void setup_target_debug (void);
-DCACHE *target_dcache;
+/* The option sets this. */
+static int stack_cache_enabled_p_1 = 1;
+/* And set_stack_cache_enabled_p updates this.
+ The reason for the separation is so that we don't flush the cache for
+ on->on transitions. */
+static int stack_cache_enabled_p = 1;
+
+/* This is called *after* the stack-cache has been set.
+ Flush the cache for off->on and on->off transitions.
+ There's no real need to flush the cache for on->off transitions,
+ except cleanliness. */
+
+static void
+set_stack_cache_enabled_p (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (stack_cache_enabled_p != stack_cache_enabled_p_1)
+ target_dcache_invalidate ();
+
+ stack_cache_enabled_p = stack_cache_enabled_p_1;
+}
+
+static void
+show_stack_cache_enabled_p (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Cache use for stack accesses is %s.\n"), value);
+}
+
+/* Cache of memory operations, to speed up remote access. */
+static DCACHE *target_dcache;
+
+/* Invalidate the target dcache. */
+
+void
+target_dcache_invalidate (void)
+{
+ dcache_invalidate (target_dcache);
+}
/* The user just typed 'target' without the name of a target. */
gdb_stdout);
}
+/* Default target_has_* methods for process_stratum targets. */
+
+int
+default_child_has_all_memory (struct target_ops *ops)
+{
+ /* If no inferior selected, then we can't read memory here. */
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return 0;
+
+ return 1;
+}
+
+int
+default_child_has_memory (struct target_ops *ops)
+{
+ /* If no inferior selected, then we can't read memory here. */
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return 0;
+
+ return 1;
+}
+
+int
+default_child_has_stack (struct target_ops *ops)
+{
+ /* If no inferior selected, there's no stack. */
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return 0;
+
+ return 1;
+}
+
+int
+default_child_has_registers (struct target_ops *ops)
+{
+ /* Can't read registers from no inferior. */
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return 0;
+
+ return 1;
+}
+
+int
+default_child_has_execution (struct target_ops *ops)
+{
+ /* If there's no thread selected, then we can't make it run through
+ hoops. */
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return 0;
+
+ return 1;
+}
+
+
+int
+target_has_all_memory_1 (void)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ if (t->to_has_all_memory (t))
+ return 1;
+
+ return 0;
+}
+
+int
+target_has_memory_1 (void)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ if (t->to_has_memory (t))
+ return 1;
+
+ return 0;
+}
+
+int
+target_has_stack_1 (void)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ if (t->to_has_stack (t))
+ return 1;
+
+ return 0;
+}
+
+int
+target_has_registers_1 (void)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ if (t->to_has_registers (t))
+ return 1;
+
+ return 0;
+}
+
+int
+target_has_execution_1 (void)
+{
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ if (t->to_has_execution (t))
+ return 1;
+
+ return 0;
+}
+
/* Add a possible target architecture to the list. */
void
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;
+
+ if (t->to_has_memory == NULL)
+ t->to_has_memory = (int (*) (struct target_ops *)) return_zero;
+
+ if (t->to_has_stack == NULL)
+ t->to_has_stack = (int (*) (struct target_ops *)) return_zero;
+
+ if (t->to_has_registers == NULL)
+ t->to_has_registers = (int (*) (struct target_ops *)) return_zero;
+
+ if (t->to_has_execution == NULL)
+ t->to_has_execution = (int (*) (struct target_ops *)) return_zero;
+
if (!target_structs)
{
target_struct_allocsize = DEFAULT_ALLOCSIZE;
void
target_load (char *arg, int from_tty)
{
- dcache_invalidate (target_dcache);
+ target_dcache_invalidate ();
(*current_target.to_load) (arg, from_tty);
}
target_terminal_inferior (void)
{
/* A background resume (``run&'') should leave GDB in control of the
- terminal. */
- if (target_is_async_p () && !sync_execution)
+ terminal. Use target_can_async_p, not target_is_async_p, since at
+ this point the target is not async yet. However, if sync_execution
+ is not set, we know it will become async prior to resume. */
+ if (target_can_async_p () && !sync_execution)
return;
/* If GDB is resuming the inferior in the foreground, install
/* Do not inherit to_follow_fork. */
INHERIT (to_insert_exec_catchpoint, t);
INHERIT (to_remove_exec_catchpoint, t);
+ INHERIT (to_set_syscall_catchpoint, t);
INHERIT (to_has_exited, t);
/* Do not inherit to_mourn_inferiour. */
INHERIT (to_can_run, t);
INHERIT (to_pid_to_exec_file, t);
INHERIT (to_log_command, t);
INHERIT (to_stratum, t);
- INHERIT (to_has_all_memory, t);
- INHERIT (to_has_memory, t);
- INHERIT (to_has_stack, t);
- INHERIT (to_has_registers, t);
- INHERIT (to_has_execution, 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);
INHERIT (to_can_async_p, t);
INHERIT (to_is_async_p, 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_thread_architecture, t);
/* Do not inherit to_read_description. */
INHERIT (to_get_ada_task_ptid, t);
/* Do not inherit to_search_memory. */
(int (*) (int, int, int))
return_zero);
de_fault (to_insert_hw_breakpoint,
- (int (*) (struct bp_target_info *))
+ (int (*) (struct gdbarch *, struct bp_target_info *))
return_minus_one);
de_fault (to_remove_hw_breakpoint,
- (int (*) (struct bp_target_info *))
+ (int (*) (struct gdbarch *, struct bp_target_info *))
return_minus_one);
de_fault (to_insert_watchpoint,
(int (*) (CORE_ADDR, int, int))
de_fault (to_remove_exec_catchpoint,
(int (*) (int))
tcomplain);
+ de_fault (to_set_syscall_catchpoint,
+ (int (*) (int, int, int, int, int *))
+ tcomplain);
de_fault (to_has_exited,
(int (*) (int, int, int *))
return_zero);
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_get_ada_task_ptid,
(ptid_t (*) (long, long))
setup_target_debug ();
}
-/* Mark OPS as a running target. This reverses the effect
- of target_mark_exited. */
-
-void
-target_mark_running (struct target_ops *ops)
-{
- struct target_ops *t;
-
- for (t = target_stack; t != NULL; t = t->beneath)
- if (t == ops)
- break;
- if (t == NULL)
- internal_error (__FILE__, __LINE__,
- "Attempted to mark unpushed target \"%s\" as running",
- ops->to_shortname);
-
- ops->to_has_execution = 1;
- ops->to_has_all_memory = 1;
- ops->to_has_memory = 1;
- ops->to_has_stack = 1;
- ops->to_has_registers = 1;
-
- update_current_target ();
-}
-
-/* Mark OPS as a non-running target. This reverses the effect
- of target_mark_running. */
-
-void
-target_mark_exited (struct target_ops *ops)
-{
- struct target_ops *t;
-
- for (t = target_stack; t != NULL; t = t->beneath)
- if (t == ops)
- break;
- if (t == NULL)
- internal_error (__FILE__, __LINE__,
- "Attempted to mark unpushed target \"%s\" as running",
- ops->to_shortname);
-
- ops->to_has_execution = 0;
- ops->to_has_all_memory = 0;
- ops->to_has_memory = 0;
- ops->to_has_stack = 0;
- ops->to_has_registers = 0;
-
- update_current_target ();
-}
-
/* Push a new target type into the stack of the existing target accessors,
possibly superseding some of the existing accessors.
return NULL;
}
-/* Perform a partial memory transfer. The arguments and return
- value are just as for target_xfer_partial. */
+/* Perform a partial memory transfer.
+ For docs see target.h, to_xfer_partial. */
static LONGEST
-memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf,
- ULONGEST memaddr, LONGEST len)
+memory_xfer_partial (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 -1;
}
- if (region->attrib.cache)
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
+ else
+ inf = NULL;
+
+ if (inf != NULL
+ && (region->attrib.cache
+ || (stack_cache_enabled_p && object == TARGET_OBJECT_STACK_MEMORY)))
{
- /* FIXME drow/2006-08-09: This call discards OPS, so the raw
- memory request will start back at current_target. */
if (readbuf != NULL)
- res = dcache_xfer_memory (target_dcache, memaddr, readbuf,
+ res = dcache_xfer_memory (ops, target_dcache, memaddr, readbuf,
reg_len, 0);
else
/* FIXME drow/2006-08-09: If we're going to preserve const
correctness dcache_xfer_memory should take readbuf and
writebuf. */
- res = dcache_xfer_memory (target_dcache, memaddr,
+ res = dcache_xfer_memory (ops, target_dcache, memaddr,
(void *) writebuf,
reg_len, 1);
if (res <= 0)
/* We want to continue past core files to executables, but not
past a running target's memory. */
- if (ops->to_has_all_memory)
+ if (ops->to_has_all_memory (ops))
break;
ops = ops->beneath;
if (readbuf && !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. */
+
+ if (res > 0
+ && inf != NULL
+ && writebuf != NULL
+ && !region->attrib.cache
+ && stack_cache_enabled_p
+ && object != TARGET_OBJECT_STACK_MEMORY)
+ {
+ dcache_update (target_dcache, memaddr, (void *) writebuf, res);
+ }
+
/* If we still haven't got anything, return the last error. We
give up. */
return res;
(void *) (uintptr_t) current);
}
+/* For docs see target.h, to_xfer_partial. */
+
static LONGEST
target_xfer_partial (struct target_ops *ops,
enum target_object object, const char *annex,
/* If this is a memory transfer, let the memory-specific code
have a look at it instead. Memory transfers are more
complicated. */
- if (object == TARGET_OBJECT_MEMORY)
- retval = memory_xfer_partial (ops, readbuf, writebuf, offset, len);
+ if (object == TARGET_OBJECT_MEMORY || object == TARGET_OBJECT_STACK_MEMORY)
+ retval = memory_xfer_partial (ops, object, readbuf,
+ writebuf, offset, len);
else
{
enum target_object raw_object = object;
int
target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
{
- if (target_read (¤t_target, TARGET_OBJECT_MEMORY, NULL,
+ /* 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_read (current_target.beneath, TARGET_OBJECT_MEMORY, NULL,
myaddr, memaddr, len) == len)
return 0;
else
return EIO;
}
+/* Like target_read_memory, but specify explicitly that this is a read from
+ the target's stack. This may trigger different cache behavior. */
+
+int
+target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int 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_read (current_target.beneath, TARGET_OBJECT_STACK_MEMORY, NULL,
+ myaddr, memaddr, len) == len)
+ return 0;
+ else
+ return EIO;
+}
+
+/* Write LEN bytes from MYADDR to target 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_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
{
- if (target_write (¤t_target, TARGET_OBJECT_MEMORY, NULL,
+ /* 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_MEMORY, NULL,
myaddr, memaddr, len) == len)
return 0;
else
{
if (targetdebug)
fprintf_unfiltered (gdb_stdlog, "target_flash_erase (%s, %s)\n",
- paddr (address), phex (length, 0));
+ hex_string (address), phex (length, 0));
t->to_flash_erase (t, address, length);
return;
}
return -1;
}
-/* Target vector read/write partial wrapper functions.
-
- NOTE: cagney/2003-10-21: I wonder if having "to_xfer_partial
- (inbuf, outbuf)", instead of separate read/write methods, make life
- easier. */
+/* Target vector read/write partial wrapper functions. */
static LONGEST
target_read_partial (struct target_ops *ops,
}
/* Wrappers to perform the full transfer. */
+
+/* For docs on target_read see target.h. */
+
LONGEST
target_read (struct target_ops *ops,
enum target_object object,
return len;
}
-
/* An alternative to target_write with progress callbacks. */
LONGEST
return len;
}
+/* For docs on target_write see target.h. */
+
LONGEST
target_write (struct target_ops *ops,
enum target_object object,
ULONGEST
get_target_memory_unsigned (struct target_ops *ops,
- CORE_ADDR addr, int len)
+ CORE_ADDR addr, int len, enum bfd_endian byte_order)
{
gdb_byte buf[sizeof (ULONGEST)];
gdb_assert (len <= sizeof (buf));
get_target_memory (ops, addr, buf, len);
- return extract_unsigned_integer (buf, len);
+ return extract_unsigned_integer (buf, len, byte_order);
}
static void
for (t = target_stack; t != NULL; t = t->beneath)
{
- if (!t->to_has_memory)
+ if (!(*t->to_has_memory) (t))
continue;
if ((int) (t->to_stratum) <= (int) dummy_stratum)
printf_unfiltered (_("\tWhile running this, GDB does not access memory from...\n"));
printf_unfiltered ("%s:\n", t->to_longname);
(t->to_files_info) (t);
- has_all_mem = t->to_has_all_memory;
+ has_all_mem = (*t->to_has_all_memory) (t);
}
}
}
}
+/* Callback for iterate_over_inferiors. Gets rid of the given
+ inferior. */
+
+static int
+dispose_inferior (struct inferior *inf, void *args)
+{
+ struct thread_info *thread;
+
+ thread = any_thread_of_process (inf->pid);
+ if (thread)
+ {
+ switch_to_thread (thread->ptid);
+
+ /* Core inferiors actually should be detached, not killed. */
+ if (target_has_execution)
+ target_kill ();
+ else
+ target_detach (NULL, 0);
+ }
+
+ return 0;
+}
+
/* This is to be called by the open routine before it does
anything. */
{
dont_repeat ();
- if (target_has_execution)
+ if (have_inferiors ())
{
if (!from_tty
- || query (_("A program is being debugged already. Kill it? ")))
- target_kill ();
+ || !have_live_inferiors ()
+ || query (_("A program is being debugged already. Kill it? ")))
+ iterate_over_inferiors (dispose_inferior, NULL);
else
error (_("Program not killed."));
}
else
/* If we're in breakpoints-always-inserted mode, have to remove
them before detaching. */
- remove_breakpoints ();
+ remove_breakpoints_pid (PIDGET (inferior_ptid));
for (t = current_target.beneath; t != NULL; t = t->beneath)
{
{
struct target_ops *t;
- dcache_invalidate (target_dcache);
+ target_dcache_invalidate ();
for (t = current_target.beneath; t != NULL; t = t->beneath)
{
set_executing (ptid, 1);
set_running (ptid, 1);
+ clear_inline_frame_state (ptid);
return;
}
}
if (search_space_len >= pattern_len)
{
unsigned keep_len = search_buf_size - chunk_size;
- CORE_ADDR read_addr = start_addr + keep_len;
+ CORE_ADDR read_addr = start_addr + chunk_size + keep_len;
int nr_to_read;
/* Copy the trailing part of the previous iteration to the front
{
/* If a special version of to_search_memory isn't available, use the
simple version. */
- found = simple_search_memory (¤t_target,
+ found = simple_search_memory (current_target.beneath,
start_addr, search_space_len,
pattern, pattern_len, found_addrp);
}
/* Do not worry about thread_stratum targets that can not
create inferiors. Assume they will be pushed again if
necessary, and continue to the process_stratum. */
- if (t->to_stratum == thread_stratum)
+ if (t->to_stratum == thread_stratum
+ || t->to_stratum == arch_stratum)
continue;
error (_("\
return target_read_stralloc (t, TARGET_OBJECT_OSDATA, type);
}
+/* Determine the current address space of thread PTID. */
+
+struct address_space *
+target_thread_address_space (ptid_t ptid)
+{
+ struct address_space *aspace;
+ struct inferior *inf;
+ struct target_ops *t;
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_thread_address_space != NULL)
+ {
+ aspace = t->to_thread_address_space (t, ptid);
+ gdb_assert (aspace);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_thread_address_space (%s) = %d\n",
+ target_pid_to_str (ptid),
+ address_space_num (aspace));
+ return aspace;
+ }
+ }
+
+ /* Fall-back to the "main" address space of the inferior. */
+ inf = find_inferior_pid (ptid_get_pid (ptid));
+
+ if (inf == NULL || inf->aspace == NULL)
+ internal_error (__FILE__, __LINE__, "\
+Can't determine the current address space of thread %s\n",
+ target_pid_to_str (ptid));
+
+ return inf->aspace;
+}
+
static int
default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
{
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)
{
if (!ptid_equal (ptid, null_ptid))
{
int pid = ptid_get_pid (ptid);
- delete_inferior (pid);
+ exit_inferior (pid);
}
breakpoint_init_inferior (inf_exited);
return normal_pid_to_str (ptid);
}
-/* Error-catcher for target_find_memory_regions */
-static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2)
+/* Error-catcher for target_find_memory_regions. */
+static int
+dummy_find_memory_regions (int (*ignore1) (), void *ignore2)
{
- error (_("No target."));
+ error (_("Command not implemented for this target."));
return 0;
}
-/* Error-catcher for target_make_corefile_notes */
-static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2)
+/* Error-catcher for target_make_corefile_notes. */
+static char *
+dummy_make_corefile_notes (bfd *ignore1, int *ignore2)
{
- error (_("No target."));
+ error (_("Command not implemented for this target."));
return NULL;
}
+/* Error-catcher for target_get_bookmark. */
+static gdb_byte *
+dummy_get_bookmark (char *ignore1, int ignore2)
+{
+ tcomplain ();
+ return NULL;
+}
+
+/* Error-catcher for target_goto_bookmark. */
+static void
+dummy_goto_bookmark (gdb_byte *ignore, int from_tty)
+{
+ tcomplain ();
+}
+
/* Set up the handful of non-empty slots needed by the dummy target
vector. */
dummy_target.to_stratum = dummy_stratum;
dummy_target.to_find_memory_regions = dummy_find_memory_regions;
dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
+ dummy_target.to_get_bookmark = dummy_get_bookmark;
+ dummy_target.to_goto_bookmark = dummy_goto_bookmark;
dummy_target.to_xfer_partial = default_xfer_partial;
+ 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 *)) return_zero;
dummy_target.to_magic = OPS_MAGIC;
}
\f
case TARGET_WAITKIND_EXECD:
return xstrprintf ("%sexecd", kind_str);
case TARGET_WAITKIND_SYSCALL_ENTRY:
- return xstrprintf ("%ssyscall-entry", kind_str);
+ return xstrprintf ("%sentered syscall", kind_str);
case TARGET_WAITKIND_SYSCALL_RETURN:
- return xstrprintf ("%ssyscall-return", kind_str);
+ return xstrprintf ("%sexited syscall", kind_str);
case TARGET_WAITKIND_SPURIOUS:
return xstrprintf ("%sspurious", kind_str);
case TARGET_WAITKIND_IGNORE:
fprintf_unfiltered (gdb_stdlog, "(%d)", regno);
if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
{
+ 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);
}
if (size <= sizeof (LONGEST))
{
- ULONGEST val = extract_unsigned_integer (buf, size);
+ ULONGEST val = extract_unsigned_integer (buf, size, byte_order);
fprintf_unfiltered (gdb_stdlog, " %s %s",
core_addr_to_string_nz (val), plongest (val));
}
fprintf_unfiltered (gdb_stdlog,
"target_xfer_memory (%s, xxx, %d, %s, xxx) = %d",
- paddress (memaddr), len, write ? "write" : "read",
- retval);
+ paddress (target_gdbarch, memaddr), len,
+ write ? "write" : "read", retval);
if (retval > 0)
{
}
static int
-debug_to_insert_breakpoint (struct bp_target_info *bp_tgt)
+debug_to_insert_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
int retval;
- retval = debug_target.to_insert_breakpoint (bp_tgt);
+ retval = debug_target.to_insert_breakpoint (gdbarch, bp_tgt);
fprintf_unfiltered (gdb_stdlog,
"target_insert_breakpoint (0x%lx, xxx) = %ld\n",
}
static int
-debug_to_remove_breakpoint (struct bp_target_info *bp_tgt)
+debug_to_remove_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
int retval;
- retval = debug_target.to_remove_breakpoint (bp_tgt);
+ retval = debug_target.to_remove_breakpoint (gdbarch, bp_tgt);
fprintf_unfiltered (gdb_stdlog,
"target_remove_breakpoint (0x%lx, xxx) = %ld\n",
}
static int
-debug_to_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
+debug_to_insert_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
int retval;
- retval = debug_target.to_insert_hw_breakpoint (bp_tgt);
+ retval = debug_target.to_insert_hw_breakpoint (gdbarch, bp_tgt);
fprintf_unfiltered (gdb_stdlog,
"target_insert_hw_breakpoint (0x%lx, xxx) = %ld\n",
}
static int
-debug_to_remove_hw_breakpoint (struct bp_target_info *bp_tgt)
+debug_to_remove_hw_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
int retval;
- retval = debug_target.to_remove_hw_breakpoint (bp_tgt);
+ retval = debug_target.to_remove_hw_breakpoint (gdbarch, bp_tgt);
fprintf_unfiltered (gdb_stdlog,
"target_remove_hw_breakpoint (0x%lx, xxx) = %ld\n",
PIDGET (ptid));
}
+static struct gdbarch *
+debug_to_thread_architecture (struct target_ops *ops, ptid_t ptid)
+{
+ struct gdbarch *retval;
+
+ retval = debug_target.to_thread_architecture (ops, ptid);
+
+ fprintf_unfiltered (gdb_stdlog, "target_thread_architecture (%s) = %s [%s]\n",
+ target_pid_to_str (ptid), host_address_to_string (retval),
+ gdbarch_bfd_arch_info (retval)->printable_name);
+ return retval;
+}
+
static void
debug_to_stop (ptid_t ptid)
{
current_target.to_stop = debug_to_stop;
current_target.to_rcmd = debug_to_rcmd;
current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
+ current_target.to_thread_architecture = debug_to_thread_architecture;
}
\f
set_maintenance_target_async_permitted (char *args, int from_tty,
struct cmd_list_element *c)
{
- if (target_has_execution)
+ if (have_live_inferiors ())
{
target_async_permitted_1 = target_async_permitted;
error (_("Cannot change this setting while the inferior is running."));
&setlist,
&showlist);
+ add_setshow_boolean_cmd ("stack-cache", class_support,
+ &stack_cache_enabled_p_1, _("\
+Set cache use for stack access."), _("\
+Show cache use for stack access."), _("\
+When on, use the data cache for all stack access, regardless of any\n\
+configured memory regions. This improves remote performance significantly.\n\
+By default, caching for stack access is on."),
+ set_stack_cache_enabled_p,
+ show_stack_cache_enabled_p,
+ &setlist, &showlist);
+
target_dcache = dcache_init ();
}