#include "top.h"
#include "event-top.h"
#include <algorithm>
+#include "byte-vector.h"
-static void target_info (char *, int);
+static void info_target_command (char *, int);
static void generic_tls_error (void) ATTRIBUTE_NORETURN;
static int return_zero_has_execution (struct target_ops *, ptid_t);
-static void target_command (char *, int);
-
-static struct target_ops *find_default_run_target (char *);
+static struct target_ops *find_default_run_target (const char *);
static struct gdbarch *default_thread_architecture (struct target_ops *ops,
ptid_t ptid);
static char *dummy_make_corefile_notes (struct target_ops *self,
bfd *ignore1, int *ignore2);
-static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
+static const char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
static enum exec_direction_kind default_execution_direction
(struct target_ops *self);
/* The user just typed 'target' without the name of a target. */
static void
-target_command (char *arg, int from_tty)
+target_command (const char *arg, int from_tty)
{
fputs_filtered ("Argument required (target name). Try `help target'\n",
gdb_stdout);
information on the arguments for a particular protocol, type\n\
`help target ' followed by the protocol name."),
&targetlist, "target ", 0, &cmdlist);
- c = add_cmd (t->to_shortname, no_class, NULL, t->to_doc, &targetlist);
+ c = add_cmd (t->to_shortname, no_class, t->to_doc, &targetlist);
set_cmd_sfunc (c, open_target);
set_cmd_context (c, t);
if (completer != NULL)
/* See target.h. */
void
-add_deprecated_target_alias (struct target_ops *t, char *alias)
+add_deprecated_target_alias (struct target_ops *t, const 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, NULL, t->to_doc, &targetlist);
+ c = add_cmd (alias, no_class, t->to_doc, &targetlist);
set_cmd_sfunc (c, open_target);
set_cmd_context (c, t);
alt = xstrprintf ("target %s", t->to_shortname);
(*current_target.to_load) (¤t_target, arg, from_tty);
}
-/* Possible terminal states. */
-
-enum terminal_state
- {
- /* The inferior's terminal settings are in effect. */
- terminal_is_inferior = 0,
-
- /* Some of our terminal settings are in effect, enough to get
- proper output. */
- terminal_is_ours_for_output = 1,
+/* Define it. */
- /* Our terminal settings are in effect, for output and input. */
- terminal_is_ours = 2
- };
+enum target_terminal::terminal_state target_terminal::terminal_state
+ = target_terminal::terminal_is_ours;
-static enum terminal_state terminal_state = terminal_is_ours;
-
-/* See target.h. */
+/* See target/target.h. */
void
-target_terminal_init (void)
+target_terminal::init (void)
{
(*current_target.to_terminal_init) (¤t_target);
terminal_state = terminal_is_ours;
}
-/* See target.h. */
-
-int
-target_terminal_is_inferior (void)
-{
- return (terminal_state == terminal_is_inferior);
-}
-
-/* See target.h. */
-
-int
-target_terminal_is_ours (void)
-{
- return (terminal_state == terminal_is_ours);
-}
-
-/* See target.h. */
+/* See target/target.h. */
void
-target_terminal_inferior (void)
+target_terminal::inferior (void)
{
struct ui *ui = current_ui;
/* Since we always run the inferior in the main console (unless "set
inferior-tty" is in effect), when some UI other than the main one
- calls target_terminal_inferior/target_terminal_inferior, then we
- leave the main UI's terminal settings as is. */
+ calls target_terminal::inferior, then we leave the main UI's
+ terminal settings as is. */
if (ui != main_ui)
return;
target_pass_ctrlc ();
}
-/* See target.h. */
+/* See target/target.h. */
void
-target_terminal_ours (void)
+target_terminal::ours ()
{
struct ui *ui = current_ui;
- /* See target_terminal_inferior. */
+ /* See target_terminal::inferior. */
if (ui != main_ui)
return;
terminal_state = terminal_is_ours;
}
-/* See target.h. */
+/* See target/target.h. */
void
-target_terminal_ours_for_output (void)
+target_terminal::ours_for_output ()
{
struct ui *ui = current_ui;
- /* See target_terminal_inferior. */
+ /* See target_terminal::inferior. */
if (ui != main_ui)
return;
terminal_state = terminal_is_ours_for_output;
}
+/* See target/target.h. */
+
+void
+target_terminal::info (const char *arg, int from_tty)
+{
+ (*current_target.to_terminal_info) (¤t_target, arg, from_tty);
+}
+
/* See target.h. */
int
return 0;
}
-/* Restore the terminal to its previous state (helper for
- make_cleanup_restore_target_terminal). */
-
-static void
-cleanup_restore_target_terminal (void *arg)
-{
- enum terminal_state *previous_state = (enum terminal_state *) arg;
-
- switch (*previous_state)
- {
- case terminal_is_ours:
- target_terminal_ours ();
- break;
- case terminal_is_ours_for_output:
- target_terminal_ours_for_output ();
- break;
- case terminal_is_inferior:
- target_terminal_inferior ();
- break;
- }
-}
-
-/* See target.h. */
-
-struct cleanup *
-make_cleanup_restore_target_terminal (void)
-{
- enum terminal_state *ts = XNEW (enum terminal_state);
-
- *ts = terminal_state;
-
- return make_cleanup_dtor (cleanup_restore_target_terminal, ts, xfree);
-}
-
static void
tcomplain (void)
{
}
else
{
- gdb_byte *buf;
- struct cleanup *old_chain;
-
/* A large write request is likely to be partially satisfied
by memory_xfer_partial_1. We will continually malloc
and free a copy of the entire write request for breakpoint
to mitigate this. */
len = std::min (ops->to_get_memory_xfer_limit (ops), len);
- buf = (gdb_byte *) 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,
+ gdb::byte_vector buf (writebuf, writebuf + len);
+ breakpoint_xfer_memory (NULL, buf.data (), writebuf, memaddr, len);
+ res = memory_xfer_partial_1 (ops, object, NULL, buf.data (), memaddr, len,
xfered_len);
-
- do_cleanups (old_chain);
}
return res;
}
-static void
-restore_show_memory_breakpoints (void *arg)
-{
- show_memory_breakpoints = (uintptr_t) arg;
-}
-
-struct cleanup *
-make_show_memory_breakpoints_cleanup (int show)
+scoped_restore_tmpl<int>
+make_scoped_restore_show_memory_breakpoints (int show)
{
- int current = show_memory_breakpoints;
-
- show_memory_breakpoints = show;
- return make_cleanup (restore_show_memory_breakpoints,
- (void *) (uintptr_t) current);
+ return make_scoped_restore (&show_memory_breakpoints, show);
}
/* For docs see target.h, to_xfer_partial. */
read_whatever_is_readable (struct target_ops *ops,
const ULONGEST begin, const ULONGEST end,
int unit_size,
- VEC(memory_read_result_s) **result)
+ std::vector<memory_read_result> *result)
{
- gdb_byte *buf = (gdb_byte *) xmalloc (end - begin);
ULONGEST current_begin = begin;
ULONGEST current_end = end;
int forward;
- memory_read_result_s r;
ULONGEST xfered_len;
/* If we previously failed to read 1 byte, nothing can be done here. */
if (end - begin <= 1)
- {
- xfree (buf);
- return;
- }
+ return;
+
+ gdb::unique_xmalloc_ptr<gdb_byte> buf ((gdb_byte *) xmalloc (end - begin));
/* Check that either first or the last byte is readable, and give up
if not. This heuristic is meant to permit reading accessible memory
at the boundary of accessible region. */
if (target_read_partial (ops, TARGET_OBJECT_MEMORY, NULL,
- buf, begin, 1, &xfered_len) == TARGET_XFER_OK)
+ buf.get (), begin, 1, &xfered_len) == TARGET_XFER_OK)
{
forward = 1;
++current_begin;
}
else if (target_read_partial (ops, TARGET_OBJECT_MEMORY, NULL,
- buf + (end - begin) - 1, end - 1, 1,
+ buf.get () + (end - begin) - 1, end - 1, 1,
&xfered_len) == TARGET_XFER_OK)
{
forward = 0;
--current_end;
}
else
- {
- xfree (buf);
- return;
- }
+ return;
/* Loop invariant is that the [current_begin, current_end) was previously
found to be not readable as a whole.
}
xfer = target_read (ops, TARGET_OBJECT_MEMORY, NULL,
- buf + (first_half_begin - begin) * unit_size,
+ buf.get () + (first_half_begin - begin) * unit_size,
first_half_begin,
first_half_end - first_half_begin);
if (forward)
{
/* The [begin, current_begin) range has been read. */
- r.begin = begin;
- r.end = current_begin;
- r.data = buf;
+ result->emplace_back (begin, current_end, std::move (buf));
}
else
{
/* The [current_end, end) range has been read. */
LONGEST region_len = end - current_end;
- r.data = (gdb_byte *) xmalloc (region_len * unit_size);
- memcpy (r.data, buf + (current_end - begin) * unit_size,
+ gdb::unique_xmalloc_ptr<gdb_byte> data
+ ((gdb_byte *) xmalloc (region_len * unit_size));
+ memcpy (data.get (), buf.get () + (current_end - begin) * unit_size,
region_len * unit_size);
- r.begin = current_end;
- r.end = end;
- xfree (buf);
- }
- VEC_safe_push(memory_read_result_s, (*result), &r);
-}
-
-void
-free_memory_read_result_vector (void *x)
-{
- VEC(memory_read_result_s) **v = (VEC(memory_read_result_s) **) x;
- memory_read_result_s *current;
- int ix;
-
- for (ix = 0; VEC_iterate (memory_read_result_s, *v, ix, current); ++ix)
- {
- xfree (current->data);
+ result->emplace_back (current_end, end, std::move (data));
}
- VEC_free (memory_read_result_s, *v);
}
-VEC(memory_read_result_s) *
+std::vector<memory_read_result>
read_memory_robust (struct target_ops *ops,
const ULONGEST offset, const LONGEST len)
{
- VEC(memory_read_result_s) *result = 0;
+ std::vector<memory_read_result> result;
int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
- struct cleanup *cleanup = make_cleanup (free_memory_read_result_vector,
- &result);
LONGEST xfered_total = 0;
while (xfered_total < len)
else
{
LONGEST to_read = std::min (len - xfered_total, region_len);
- gdb_byte *buffer = (gdb_byte *) xmalloc (to_read * unit_size);
- struct cleanup *inner_cleanup = make_cleanup (xfree, buffer);
+ gdb::unique_xmalloc_ptr<gdb_byte> buffer
+ ((gdb_byte *) xmalloc (to_read * unit_size));
LONGEST xfered_partial =
- target_read (ops, TARGET_OBJECT_MEMORY, NULL,
- (gdb_byte *) buffer,
+ target_read (ops, TARGET_OBJECT_MEMORY, NULL, buffer.get (),
offset + xfered_total, to_read);
/* Call an observer, notifying them of the xfer progress? */
if (xfered_partial <= 0)
{
/* Got an error reading full chunk. See if maybe we can read
some subrange. */
- do_cleanups (inner_cleanup);
read_whatever_is_readable (ops, offset + xfered_total,
offset + xfered_total + to_read,
unit_size, &result);
}
else
{
- struct memory_read_result r;
-
- discard_cleanups (inner_cleanup);
- r.data = buffer;
- r.begin = offset + xfered_total;
- r.end = r.begin + xfered_partial;
- VEC_safe_push (memory_read_result_s, result, &r);
+ result.emplace_back (offset + xfered_total,
+ offset + xfered_total + xfered_partial,
+ std::move (buffer));
xfered_total += xfered_partial;
}
QUIT;
}
}
- discard_cleanups (cleanup);
return result;
}
}
static void
-target_info (char *args, int from_tty)
+info_target_command (char *args, int from_tty)
{
struct target_ops *t;
int has_all_mem = 0;
return minus_one_ptid;
}
-char *
+const char *
target_pid_to_str (ptid_t ptid)
{
return (*current_target.to_pid_to_str) (¤t_target, ptid);
return current_target.to_thread_name (¤t_target, info);
}
+struct thread_info *
+target_thread_handle_to_thread_info (const gdb_byte *thread_handle,
+ int handle_len,
+ struct inferior *inf)
+{
+ return current_target.to_thread_handle_to_thread_info
+ (¤t_target, thread_handle, handle_len, inf);
+}
+
void
target_resume (ptid_t ptid, int step, enum gdb_signal signal)
{
/* See target.h. */
-struct cleanup *
-make_cleanup_defer_target_commit_resume (void)
+scoped_restore_tmpl<int>
+make_scoped_defer_target_commit_resume ()
{
- struct cleanup *old_chain;
-
- old_chain = make_cleanup_restore_integer (&defer_target_commit_resume);
- defer_target_commit_resume = 1;
- return old_chain;
+ return make_scoped_restore (&defer_target_commit_resume, 1);
}
void
#define SEARCH_CHUNK_SIZE 16000
const unsigned chunk_size = SEARCH_CHUNK_SIZE;
/* Buffer to hold memory contents for searching. */
- gdb_byte *search_buf;
unsigned search_buf_size;
- struct cleanup *old_cleanups;
search_buf_size = chunk_size + pattern_len - 1;
if (search_space_len < search_buf_size)
search_buf_size = search_space_len;
- 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_vector search_buf (search_buf_size);
/* Prime the search buffer. */
if (target_read (ops, TARGET_OBJECT_MEMORY, NULL,
- search_buf, start_addr, search_buf_size) != search_buf_size)
+ search_buf.data (), start_addr, search_buf_size)
+ != search_buf_size)
{
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;
}
unsigned nr_search_bytes
= std::min (search_space_len, (ULONGEST) search_buf_size);
- found_ptr = (gdb_byte *) memmem (search_buf, nr_search_bytes,
+ found_ptr = (gdb_byte *) memmem (search_buf.data (), nr_search_bytes,
pattern, pattern_len);
if (found_ptr != NULL)
{
- CORE_ADDR found_addr = start_addr + (found_ptr - search_buf);
+ CORE_ADDR found_addr = start_addr + (found_ptr - search_buf.data ());
*found_addrp = found_addr;
- do_cleanups (old_cleanups);
return 1;
}
/* Copy the trailing part of the previous iteration to the front
of the buffer for the next iteration. */
gdb_assert (keep_len == pattern_len - 1);
- memcpy (search_buf, search_buf + chunk_size, keep_len);
+ memcpy (&search_buf[0], &search_buf[chunk_size], keep_len);
nr_to_read = std::min (search_space_len - keep_len,
(ULONGEST) chunk_size);
if (target_read (ops, TARGET_OBJECT_MEMORY, NULL,
- search_buf + keep_len, read_addr,
+ &search_buf[keep_len], read_addr,
nr_to_read) != nr_to_read)
{
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;
}
/* Not found. */
- do_cleanups (old_cleanups);
return 0;
}
called for errors); else, return NULL on error. */
static struct target_ops *
-find_default_run_target (char *do_mesg)
+find_default_run_target (const char *do_mesg)
{
struct target_ops *runable = NULL;
static struct gdbarch *
default_thread_architecture (struct target_ops *ops, ptid_t ptid)
{
- return target_gdbarch ();
+ inferior *inf = find_inferior_ptid (ptid);
+ gdb_assert (inf != NULL);
+ return inf->gdbarch;
}
static int
target_announce_detach (int from_tty)
{
pid_t pid;
- char *exec_file;
+ const char *exec_file;
if (!from_tty)
return;
/* Convert a normal process ID to a string. Returns the string in a
static buffer. */
-char *
+const char *
normal_pid_to_str (ptid_t ptid)
{
static char buf[32];
return buf;
}
-static char *
+static const char *
default_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
return normal_pid_to_str (ptid);
static char *
do_option (int *target_options, char *ret,
- int opt, char *opt_str)
+ int opt, const char *opt_str)
{
if ((*target_options & opt) != 0)
{
return ret;
}
-static void
-debug_print_register (const char * func,
- 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
- && gdbarch_register_name (gdbarch, regno)[0] != '\0')
- fprintf_unfiltered (gdb_stdlog, "(%s)",
- gdbarch_register_name (gdbarch, regno));
- else
- 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);
- gdb_byte buf[MAX_REGISTER_SIZE];
-
- regcache_raw_collect (regcache, regno, buf);
- fprintf_unfiltered (gdb_stdlog, " = ");
- for (i = 0; i < size; i++)
- {
- fprintf_unfiltered (gdb_stdlog, "%02x", buf[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));
- }
- }
- fprintf_unfiltered (gdb_stdlog, "\n");
-}
-
void
target_fetch_registers (struct regcache *regcache, int regno)
{
current_target.to_fetch_registers (¤t_target, regcache, regno);
if (targetdebug)
- debug_print_register ("target_fetch_registers", regcache, regno);
+ regcache->debug_print_register ("target_fetch_registers", regno);
}
void
current_target.to_store_registers (¤t_target, regcache, regno);
if (targetdebug)
{
- debug_print_register ("target_store_registers", regcache, regno);
+ regcache->debug_print_register ("target_store_registers", regno);
}
}
/* See target.h. */
void
-target_insn_history (int size, int flags)
+target_insn_history (int size, gdb_disassembly_flags flags)
{
current_target.to_insn_history (¤t_target, size, flags);
}
/* See target.h. */
void
-target_insn_history_from (ULONGEST from, int size, int flags)
+target_insn_history_from (ULONGEST from, int size,
+ gdb_disassembly_flags flags)
{
current_target.to_insn_history_from (¤t_target, from, size, flags);
}
/* See target.h. */
void
-target_insn_history_range (ULONGEST begin, ULONGEST end, int flags)
+target_insn_history_range (ULONGEST begin, ULONGEST end,
+ gdb_disassembly_flags flags)
{
current_target.to_insn_history_range (¤t_target, begin, end, flags);
}
found_flash_region = true;
target_flash_erase (m->lo, m->hi - m->lo);
- struct cleanup *cleanup_tuple
- = make_cleanup_ui_out_tuple_begin_end (current_uiout,
- "erased-regions");
+ ui_out_emit_tuple tuple_emitter (current_uiout, "erased-regions");
current_uiout->message (_("Erasing flash memory region at address "));
current_uiout->field_fmt ("address", "%s", paddress (gdbarch,
current_uiout->message (", size = ");
current_uiout->field_fmt ("size", "%s", hex_string (m->hi - m->lo));
current_uiout->message ("\n");
- do_cleanups (cleanup_tuple);
}
}
/* Print the name of each layers of our target stack. */
static void
-maintenance_print_target_stack (char *cmd, int from_tty)
+maintenance_print_target_stack (const char *cmd, int from_tty)
{
struct target_ops *t;
init_dummy_target ();
push_target (&dummy_target);
- add_info ("target", target_info, targ_desc);
- add_info ("files", target_info, targ_desc);
+ add_info ("target", info_target_command, targ_desc);
+ add_info ("files", info_target_command, targ_desc);
add_setshow_zuinteger_cmd ("target", class_maintenance, &targetdebug, _("\
Set target debugging."), _("\