diff options
Diffstat (limited to 'gdb/remote-sim.c')
-rw-r--r-- | gdb/remote-sim.c | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c index fd1bc66..ca824d7 100644 --- a/gdb/remote-sim.c +++ b/gdb/remote-sim.c @@ -40,6 +40,7 @@ #include "arch-utils.h" #include "readline/readline.h" #include "gdbthread.h" +#include "common/byte-vector.h" /* Prototypes */ @@ -448,38 +449,31 @@ gdbsim_fetch_register (struct target_ops *ops, { /* For moment treat a `does not exist' register the same way as an ``unavailable'' register. */ - gdb_byte buf[MAX_REGISTER_SIZE]; - int nr_bytes; - - memset (buf, 0, MAX_REGISTER_SIZE); - regcache_raw_supply (regcache, regno, buf); + regcache->raw_supply_zeroed (regno); break; } default: { static int warn_user = 1; - gdb_byte buf[MAX_REGISTER_SIZE]; + int regsize = register_size (gdbarch, regno); + gdb::byte_vector buf (regsize, 0); int nr_bytes; gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch)); - memset (buf, 0, MAX_REGISTER_SIZE); nr_bytes = sim_fetch_register (sim_data->gdbsim_desc, gdbarch_register_sim_regno (gdbarch, regno), - buf, - register_size (gdbarch, regno)); - if (nr_bytes > 0 - && nr_bytes != register_size (gdbarch, regno) && warn_user) + buf.data (), regsize); + if (nr_bytes > 0 && nr_bytes != regsize && warn_user) { fprintf_unfiltered (gdb_stderr, "Size of register %s (%d/%d) " "incorrect (%d instead of %d))", gdbarch_register_name (gdbarch, regno), regno, - gdbarch_register_sim_regno - (gdbarch, regno), - nr_bytes, register_size (gdbarch, regno)); + gdbarch_register_sim_regno (gdbarch, regno), + nr_bytes, regsize); warn_user = 0; } /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0' @@ -487,13 +481,13 @@ gdbsim_fetch_register (struct target_ops *ops, which registers are fetchable. */ /* Else if (nr_bytes < 0): an old simulator, that doesn't think to return the register size. Just assume all is ok. */ - regcache_raw_supply (regcache, regno, buf); + regcache->raw_supply (regno, buf.data ()); if (remote_debug) { fprintf_unfiltered (gdb_stdlog, "gdbsim_fetch_register: %d", regno); /* FIXME: We could print something more intelligible. */ - dump_mem (buf, register_size (gdbarch, regno)); + dump_mem (buf.data (), regsize); } break; } @@ -518,15 +512,17 @@ gdbsim_store_register (struct target_ops *ops, } else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0) { - gdb_byte tmp[MAX_REGISTER_SIZE]; + int regsize = register_size (gdbarch, regno); + gdb::byte_vector tmp (regsize); int nr_bytes; - regcache_cooked_read (regcache, regno, tmp); + regcache->cooked_read (regno, tmp.data ()); nr_bytes = sim_store_register (sim_data->gdbsim_desc, gdbarch_register_sim_regno (gdbarch, regno), - tmp, register_size (gdbarch, regno)); - if (nr_bytes > 0 && nr_bytes != register_size (gdbarch, regno)) + tmp.data (), regsize); + + if (nr_bytes > 0 && nr_bytes != regsize) internal_error (__FILE__, __LINE__, _("Register size different to expected")); if (nr_bytes < 0) @@ -540,7 +536,7 @@ gdbsim_store_register (struct target_ops *ops, { fprintf_unfiltered (gdb_stdlog, "gdbsim_store_register: %d", regno); /* FIXME: We could print something more intelligible. */ - dump_mem (tmp, register_size (gdbarch, regno)); + dump_mem (tmp.data (), regsize); } } } @@ -566,7 +562,6 @@ gdbsim_kill (struct target_ops *ops) static void gdbsim_load (struct target_ops *self, const char *args, int fromtty) { - char **argv; const char *prog; struct sim_inferior_data *sim_data = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); @@ -574,8 +569,7 @@ gdbsim_load (struct target_ops *self, const char *args, int fromtty) if (args == NULL) error_no_arg (_("program to load")); - argv = gdb_buildargv (args); - make_cleanup_freeargv (argv); + gdb_argv argv (args); prog = tilde_expand (argv[0]); @@ -613,7 +607,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, struct sim_inferior_data *sim_data = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED); int len; - char *arg_buf, **argv; + char *arg_buf; const char *args = allargs.c_str (); if (exec_file == 0 || exec_bfd == 0) @@ -632,6 +626,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, remove_breakpoints (); init_wait_for_inferior (); + gdb_argv built_argv; if (exec_file != NULL) { len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10; @@ -640,16 +635,14 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file, strcat (arg_buf, exec_file); strcat (arg_buf, " "); strcat (arg_buf, args); - argv = gdb_buildargv (arg_buf); - make_cleanup_freeargv (argv); + built_argv.reset (arg_buf); } - else - argv = NULL; if (!have_inferiors ()) init_thread_list (); - if (sim_create_inferior (sim_data->gdbsim_desc, exec_bfd, argv, env) + if (sim_create_inferior (sim_data->gdbsim_desc, exec_bfd, + built_argv.get (), env) != SIM_RC_OK) error (_("Unable to create sim inferior.")); @@ -732,18 +725,21 @@ gdbsim_open (const char *args, int from_tty) strcat (arg_buf, " "); /* 1 */ strcat (arg_buf, args); } - sim_argv = gdb_buildargv (arg_buf); + + gdb_argv argv (arg_buf); + sim_argv = argv.get (); init_callbacks (); gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv); if (gdbsim_desc == 0) { - freeargv (sim_argv); sim_argv = NULL; error (_("unable to create simulator instance")); } + argv.release (); + /* Reset the pid numberings for this batch of sim instances. */ next_pid = INITIAL_PID; @@ -1224,30 +1220,48 @@ simulator_command (char *args, int from_tty) registers_changed (); } -static VEC (char_ptr) * -sim_command_completer (struct cmd_list_element *ignore, const char *text, - const char *word) +static void +sim_command_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, + const char *text, const char *word) { struct sim_inferior_data *sim_data; - char **tmp; - int i; - VEC (char_ptr) *result = NULL; sim_data = ((struct sim_inferior_data *) inferior_data (current_inferior (), sim_inferior_data_key)); if (sim_data == NULL || sim_data->gdbsim_desc == NULL) - return NULL; + return; - tmp = sim_complete_command (sim_data->gdbsim_desc, text, word); - if (tmp == NULL) - return NULL; + /* sim_complete_command returns a NULL-terminated malloc'ed array of + malloc'ed strings. */ + struct sim_completions_deleter + { + void operator() (char **ptr) const + { + for (size_t i = 0; ptr[i] != NULL; i++) + xfree (ptr[i]); + xfree (ptr); + } + }; + + std::unique_ptr<char *[], sim_completions_deleter> sim_completions + (sim_complete_command (sim_data->gdbsim_desc, text, word)); + if (sim_completions == NULL) + return; - /* Transform the array into a VEC, and then free the array. */ - for (i = 0; tmp[i] != NULL; i++) - VEC_safe_push (char_ptr, result, tmp[i]); - xfree (tmp); + /* Count the elements and add completions from tail to head because + below we'll swap elements out of the array in case add_completion + throws and the deleter deletes until it finds a NULL element. */ + size_t count = 0; + while (sim_completions[count] != NULL) + count++; - return result; + for (size_t i = count; i > 0; i--) + { + gdb::unique_xmalloc_ptr<char> match (sim_completions[i - 1]); + sim_completions[i - 1] = NULL; + tracker.add_completion (std::move (match)); + } } /* Check to see if a thread is still alive. */ |