/* Select target systems and architectures at runtime for GDB.
- Copyright (C) 1990-2015 Free Software Foundation, Inc.
+ Copyright (C) 1990-2016 Free Software Foundation, Inc.
Contributed by Cygnus Support.
static void
open_target (char *args, int from_tty, struct cmd_list_element *command)
{
- struct target_ops *ops = get_cmd_context (command);
+ struct target_ops *ops = (struct target_ops *) get_cmd_context (command);
if (targetdebug)
fprintf_unfiltered (gdb_stdlog, "-> %s->to_open (...)\n",
terminal_is_ours = 2
};
-static enum terminal_state terminal_state;
+static enum terminal_state terminal_state = terminal_is_ours;
/* See target.h. */
/* See target.h. */
+int
+target_terminal_is_ours (void)
+{
+ return (terminal_state == terminal_is_ours);
+}
+
+/* See target.h. */
+
void
target_terminal_inferior (void)
{
static void
cleanup_restore_target_terminal (void *arg)
{
- enum terminal_state *previous_state = arg;
+ enum terminal_state *previous_state = (enum terminal_state *) arg;
switch (*previous_state)
{
struct cleanup *
make_cleanup_restore_target_terminal (void)
{
- enum terminal_state *ts = xmalloc (sizeof (*ts));
+ enum terminal_state *ts = XNEW (enum terminal_state);
*ts = terminal_state;
return 1;
}
+/* Unpush TARGET and assert that it worked. */
+
+static void
+unpush_target_and_assert (struct target_ops *target)
+{
+ if (!unpush_target (target))
+ {
+ fprintf_unfiltered (gdb_stderr,
+ "pop_all_targets couldn't find target %s\n",
+ target->to_shortname);
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
+ }
+}
+
void
pop_all_targets_above (enum strata above_stratum)
{
while ((int) (current_target.to_stratum) > (int) above_stratum)
- {
- if (!unpush_target (target_stack))
- {
- fprintf_unfiltered (gdb_stderr,
- "pop_all_targets couldn't find target %s\n",
- target_stack->to_shortname);
- internal_error (__FILE__, __LINE__,
- _("failed internal consistency check"));
- break;
- }
- }
+ unpush_target_and_assert (target_stack);
+}
+
+/* See target.h. */
+
+void
+pop_all_targets_at_and_above (enum strata stratum)
+{
+ while ((int) (current_target.to_stratum) >= (int) stratum)
+ unpush_target_and_assert (target_stack);
}
void
/* Small for testing. */
buffer_allocated = 4;
- buffer = xmalloc (buffer_allocated);
+ buffer = (char *) xmalloc (buffer_allocated);
bufptr = buffer;
while (len > 0)
bytes = bufptr - buffer;
buffer_allocated *= 2;
- buffer = xrealloc (buffer, buffer_allocated);
+ buffer = (char *) xrealloc (buffer, buffer_allocated);
bufptr = buffer + bytes;
}
}
else
{
- void *buf;
+ gdb_byte *buf;
struct cleanup *old_chain;
/* A large write request is likely to be partially satisfied
subset of it. Cap writes to 4KB to mitigate this. */
len = min (4096, len);
- buf = xmalloc (len);
+ buf = (gdb_byte *) xmalloc (len);
old_chain = make_cleanup (xfree, buf);
memcpy (buf, writebuf, len);
/* Read LEN bytes of target memory at address MEMADDR, placing the
results in GDB's memory at MYADDR. Returns either 0 for success or
- TARGET_XFER_E_IO if any error occurs.
+ -1 if any error occurs.
If an error occurs, no guarantee is made about the contents of the data at
MYADDR. In particular, the caller should not depend upon partial reads
myaddr, memaddr, len) == len)
return 0;
else
- return TARGET_XFER_E_IO;
+ return -1;
}
/* See target/target.h. */
myaddr, memaddr, len) == len)
return 0;
else
- return TARGET_XFER_E_IO;
+ return -1;
}
/* Like target_read_memory, but specify explicitly that this is a read from
myaddr, memaddr, len) == len)
return 0;
else
- return TARGET_XFER_E_IO;
+ return -1;
}
/* Like target_read_memory, but specify explicitly that this is a read from
myaddr, memaddr, len) == len)
return 0;
else
- return TARGET_XFER_E_IO;
+ return -1;
}
/* Write LEN bytes from MYADDR to target memory at address MEMADDR.
- Returns either 0 for success or TARGET_XFER_E_IO 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. */
+ Returns either 0 for success or -1 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, ssize_t len)
myaddr, memaddr, len) == len)
return 0;
else
- return TARGET_XFER_E_IO;
+ return -1;
}
/* Write LEN bytes from MYADDR to target raw memory at address
- MEMADDR. Returns either 0 for success or TARGET_XFER_E_IO
- 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. */
+ MEMADDR. Returns either 0 for success or -1 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)
myaddr, memaddr, len) == len)
return 0;
else
- return TARGET_XFER_E_IO;
+ return -1;
}
/* Fetch the target's memory map. */
int unit_size,
VEC(memory_read_result_s) **result)
{
- gdb_byte *buf = xmalloc (end - begin);
+ gdb_byte *buf = (gdb_byte *) xmalloc (end - begin);
ULONGEST current_begin = begin;
ULONGEST current_end = end;
int forward;
/* The [current_end, end) range has been read. */
LONGEST region_len = end - current_end;
- r.data = xmalloc (region_len * unit_size);
+ r.data = (gdb_byte *) xmalloc (region_len * unit_size);
memcpy (r.data, buf + (current_end - begin) * unit_size,
region_len * unit_size);
r.begin = current_end;
void
free_memory_read_result_vector (void *x)
{
- VEC(memory_read_result_s) *v = x;
+ VEC(memory_read_result_s) *v = (VEC(memory_read_result_s) *) x;
memory_read_result_s *current;
int ix;
/* Got an error reading full chunk. See if maybe we can read
some subrange. */
xfree (buffer);
- read_whatever_is_readable (ops, offset + xfered_total, unit_size,
- offset + xfered_total + to_read, &result);
+ read_whatever_is_readable (ops, offset + xfered_total,
+ offset + xfered_total + to_read,
+ unit_size, &result);
xfered_total += to_read;
}
else
/* 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 = (gdb_byte *) xmalloc (buf_alloc);
buf_pos = 0;
while (1)
{
if (buf_alloc < buf_pos * 2)
{
buf_alloc *= 2;
- buf = xrealloc (buf, buf_alloc);
+ buf = (gdb_byte *) xrealloc (buf, buf_alloc);
}
QUIT;
target_clear_description ();
}
+ /* attach_flag may be set if the previous process associated with
+ the inferior was attached to. */
+ current_inferior ()->attach_flag = 0;
+
+ current_inferior ()->highest_thread_num = 0;
+
agent_capability_invalidate ();
}
return (current_target.to_wait) (¤t_target, ptid, status, options);
}
+/* See target.h. */
+
+ptid_t
+default_target_wait (struct target_ops *ops,
+ ptid_t ptid, struct target_waitstatus *status,
+ int options)
+{
+ status->kind = TARGET_WAITKIND_IGNORE;
+ return minus_one_ptid;
+}
+
char *
target_pid_to_str (ptid_t ptid)
{
return (*current_target.to_pid_to_str) (¤t_target, ptid);
}
-char *
+const char *
target_thread_name (struct thread_info *info)
{
return current_target.to_thread_name (¤t_target, info);
follow_child, detach_fork);
}
+/* Target wrapper for follow exec hook. */
+
+void
+target_follow_exec (struct inferior *inf, char *execd_pathname)
+{
+ current_target.to_follow_exec (¤t_target, inf, execd_pathname);
+}
+
static void
default_mourn_inferior (struct target_ops *self)
{
if (search_space_len < search_buf_size)
search_buf_size = search_space_len;
- search_buf = malloc (search_buf_size);
+ search_buf = (gdb_byte *) malloc (search_buf_size);
if (search_buf == NULL)
error (_("Unable to allocate memory to perform the search."));
old_cleanups = make_cleanup (free_current_contents, &search_buf);
gdb_byte *found_ptr;
unsigned nr_search_bytes = min (search_space_len, search_buf_size);
- found_ptr = memmem (search_buf, nr_search_bytes,
- pattern, pattern_len);
+ found_ptr = (gdb_byte *) memmem (search_buf, nr_search_bytes,
+ pattern, pattern_len);
if (found_ptr != NULL)
{
#define fileio_fd_to_fh(fd) \
VEC_index (fileio_fh_t, fileio_fhandles, (fd))
-/* See target.h. */
+/* Helper for target_fileio_open and
+ target_fileio_open_warn_if_slow. */
-int
-target_fileio_open (struct inferior *inf, const char *filename,
- int flags, int mode, int *target_errno)
+static int
+target_fileio_open_1 (struct inferior *inf, const char *filename,
+ int flags, int mode, int warn_if_slow,
+ int *target_errno)
{
struct target_ops *t;
if (t->to_fileio_open != NULL)
{
int fd = t->to_fileio_open (t, inf, filename, flags, mode,
- target_errno);
+ warn_if_slow, target_errno);
if (fd < 0)
fd = -1;
if (targetdebug)
fprintf_unfiltered (gdb_stdlog,
- "target_fileio_open (%d,%s,0x%x,0%o)"
+ "target_fileio_open (%d,%s,0x%x,0%o,%d)"
" = %d (%d)\n",
inf == NULL ? 0 : inf->num,
filename, flags, mode,
- fd, fd != -1 ? 0 : *target_errno);
+ warn_if_slow, fd,
+ fd != -1 ? 0 : *target_errno);
return fd;
}
}
/* See target.h. */
+int
+target_fileio_open (struct inferior *inf, const char *filename,
+ int flags, int mode, int *target_errno)
+{
+ return target_fileio_open_1 (inf, filename, flags, mode, 0,
+ target_errno);
+}
+
+/* See target.h. */
+
+int
+target_fileio_open_warn_if_slow (struct inferior *inf,
+ const char *filename,
+ int flags, int mode, int *target_errno)
+{
+ return target_fileio_open_1 (inf, filename, flags, mode, 1,
+ target_errno);
+}
+
+/* See target.h. */
+
int
target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
ULONGEST offset, int *target_errno)
/* 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 = (gdb_byte *) xmalloc (buf_alloc);
buf_pos = 0;
while (1)
{
if (buf_alloc < buf_pos * 2)
{
buf_alloc *= 2;
- buf = xrealloc (buf, buf_alloc);
+ buf = (gdb_byte *) xrealloc (buf, buf_alloc);
}
QUIT;
(*current_target.to_stop) (¤t_target, ptid);
}
+void
+target_interrupt (ptid_t ptid)
+{
+ if (!may_stop)
+ {
+ warning (_("May not interrupt or stop the target, ignoring attempt"));
+ return;
+ }
+
+ (*current_target.to_interrupt) (¤t_target, ptid);
+}
+
+/* See target.h. */
+
+void
+target_check_pending_interrupt (void)
+{
+ (*current_target.to_check_pending_interrupt) (¤t_target);
+}
+
/* See target/target.h. */
void
target.h. */
int
-target_insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, int rw)
+target_insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
+ enum target_hw_bp_type rw)
{
return current_target.to_insert_mask_watchpoint (¤t_target,
addr, mask, rw);
target.h. */
int
-target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask, int rw)
+target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
+ enum target_hw_bp_type rw)
{
return current_target.to_remove_mask_watchpoint (¤t_target,
addr, mask, rw);
/* See target.h. */
int
-target_record_is_replaying (void)
+target_record_is_replaying (ptid_t ptid)
+{
+ return current_target.to_record_is_replaying (¤t_target, ptid);
+}
+
+/* See target.h. */
+
+int
+target_record_will_replay (ptid_t ptid, int dir)
+{
+ return current_target.to_record_will_replay (¤t_target, ptid, dir);
+}
+
+/* See target.h. */
+
+void
+target_record_stop_replaying (void)
{
- return current_target.to_record_is_replaying (¤t_target);
+ current_target.to_record_stop_replaying (¤t_target);
}
/* See target.h. */
}
}
+/* See target.h. */
+
+void
+target_async (int enable)
+{
+ infrun_async (enable);
+ current_target.to_async (¤t_target, enable);
+}
+
+/* See target.h. */
+
+void
+target_thread_events (int enable)
+{
+ current_target.to_thread_events (¤t_target, enable);
+}
+
/* Controls if targets can report that they can/are async. This is
just for maintainers to use when debugging gdb. */
int target_async_permitted = 1;
"asynchronous mode is %s.\n"), value);
}
+/* Return true if the target operates in non-stop mode even with "set
+ non-stop off". */
+
+static int
+target_always_non_stop_p (void)
+{
+ return current_target.to_always_non_stop_p (¤t_target);
+}
+
+/* See target.h. */
+
+int
+target_is_non_stop_p (void)
+{
+ return (non_stop
+ || target_non_stop_enabled == AUTO_BOOLEAN_TRUE
+ || (target_non_stop_enabled == AUTO_BOOLEAN_AUTO
+ && target_always_non_stop_p ()));
+}
+
+/* Controls if targets can report that they always run in non-stop
+ mode. This is just for maintainers to use when debugging gdb. */
+enum auto_boolean target_non_stop_enabled = AUTO_BOOLEAN_AUTO;
+
+/* The set command writes to this variable. If the inferior is
+ executing, target_non_stop_enabled is *not* updated. */
+static enum auto_boolean target_non_stop_enabled_1 = AUTO_BOOLEAN_AUTO;
+
+/* Implementation of "maint set target-non-stop". */
+
+static void
+maint_set_target_non_stop_command (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ if (have_live_inferiors ())
+ {
+ target_non_stop_enabled_1 = target_non_stop_enabled;
+ error (_("Cannot change this setting while the inferior is running."));
+ }
+
+ target_non_stop_enabled = target_non_stop_enabled_1;
+}
+
+/* Implementation of "maint show target-non-stop". */
+
+static void
+maint_show_target_non_stop_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ if (target_non_stop_enabled == AUTO_BOOLEAN_AUTO)
+ fprintf_filtered (file,
+ _("Whether the target is always in non-stop mode "
+ "is %s (currently %s).\n"), value,
+ target_always_non_stop_p () ? "on" : "off");
+ else
+ fprintf_filtered (file,
+ _("Whether the target is always in non-stop mode "
+ "is %s.\n"), value);
+}
+
/* Temporary copies of permission settings. */
static int may_write_registers_1 = 1;
&maintenance_set_cmdlist,
&maintenance_show_cmdlist);
+ add_setshow_auto_boolean_cmd ("target-non-stop", no_class,
+ &target_non_stop_enabled_1, _("\
+Set whether gdb always controls the inferior in non-stop mode."), _("\
+Show whether gdb always controls the inferior in non-stop mode."), _("\
+Tells gdb whether to control the inferior in non-stop mode."),
+ maint_set_target_non_stop_command,
+ maint_show_target_non_stop_command,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
+
add_setshow_boolean_cmd ("may-write-registers", class_support,
&may_write_registers_1, _("\
Set permission to write into registers."), _("\