gdb: Fix build failure with GCC 7
[deliverable/binutils-gdb.git] / gdb / remote-sim.c
index fd2fd5872d243a6fbae2cc42b2a6e17bccf7bf0c..ca824d7985b76e08152b7fa35c262e31244ddc40 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic remote debugging interface for simulators.
 
-   Copyright (C) 1993-2015 Free Software Foundation, Inc.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
    Steve Chamberlain (sac@cygnus.com).
@@ -21,6 +21,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "gdb_bfd.h"
 #include "inferior.h"
 #include "infrun.h"
 #include "value.h"
@@ -39,6 +40,7 @@
 #include "arch-utils.h"
 #include "readline/readline.h"
 #include "gdbthread.h"
+#include "common/byte-vector.h"
 
 /* Prototypes */
 
@@ -87,7 +89,7 @@ static void gdbsim_files_info (struct target_ops *target);
 
 static void gdbsim_mourn_inferior (struct target_ops *target);
 
-static void gdbsim_stop (struct target_ops *self, ptid_t ptid);
+static void gdbsim_interrupt (struct target_ops *self, ptid_t ptid);
 
 void simulator_command (char *args, int from_tty);
 
@@ -151,9 +153,10 @@ static int
 check_for_duplicate_sim_descriptor (struct inferior *inf, void *arg)
 {
   struct sim_inferior_data *sim_data;
-  SIM_DESC new_sim_desc = arg;
+  SIM_DESC new_sim_desc = (SIM_DESC) arg;
 
-  sim_data = inferior_data (inf, sim_inferior_data_key);
+  sim_data = ((struct sim_inferior_data *)
+             inferior_data (inf, sim_inferior_data_key));
 
   return (sim_data != NULL && sim_data->gdbsim_desc == new_sim_desc);
 }
@@ -171,7 +174,7 @@ get_sim_inferior_data (struct inferior *inf, int sim_instance_needed)
 {
   SIM_DESC sim_desc = NULL;
   struct sim_inferior_data *sim_data
-    = inferior_data (inf, sim_inferior_data_key);
+    = (struct sim_inferior_data *) inferior_data (inf, sim_inferior_data_key);
 
   /* Try to allocate a new sim instance, if needed.  We do this ahead of
      a potential allocation of a sim_inferior_data struct in order to
@@ -256,7 +259,7 @@ get_sim_inferior_data_by_ptid (ptid_t ptid, int sim_instance_needed)
 static void
 sim_inferior_data_cleanup (struct inferior *inf, void *data)
 {
-  struct sim_inferior_data *sim_data = data;
+  struct sim_inferior_data *sim_data = (struct sim_inferior_data *) data;
 
   if (sim_data != NULL)
     {
@@ -427,8 +430,9 @@ gdbsim_fetch_register (struct target_ops *ops,
                       struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct inferior *inf = find_inferior_ptid (regcache_get_ptid (regcache));
   struct sim_inferior_data *sim_data
-    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+    = get_sim_inferior_data (inf, SIM_INSTANCE_NEEDED);
 
   if (regno == -1)
     {
@@ -445,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'
@@ -484,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;
       }
@@ -503,8 +500,9 @@ gdbsim_store_register (struct target_ops *ops,
                       struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct inferior *inf = find_inferior_ptid (regcache_get_ptid (regcache));
   struct sim_inferior_data *sim_data
-    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+    = get_sim_inferior_data (inf, SIM_INSTANCE_NEEDED);
 
   if (regno == -1)
     {
@@ -514,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)
@@ -536,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);
        }
     }
 }
@@ -552,7 +552,7 @@ gdbsim_kill (struct target_ops *ops)
 
   /* There is no need to `kill' running simulator - the simulator is
      not running.  Mourning it is enough.  */
-  target_mourn_inferior ();
+  target_mourn_inferior (inferior_ptid);
 }
 
 /* Load an executable file into the target process.  This is expected to
@@ -562,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);
@@ -570,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]);
 
@@ -603,13 +601,14 @@ gdbsim_load (struct target_ops *self, const char *args, int fromtty)
    user types "run" after having attached.  */
 
 static void
-gdbsim_create_inferior (struct target_ops *target, char *exec_file, char *args,
-                       char **env, int from_tty)
+gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
+                       const std::string &allargs, char **env, int from_tty)
 {
   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)
     warning (_("No executable file specified."));
@@ -627,24 +626,23 @@ gdbsim_create_inferior (struct target_ops *target, char *exec_file, char *args,
   remove_breakpoints ();
   init_wait_for_inferior ();
 
+  gdb_argv built_argv;
   if (exec_file != NULL)
     {
-      len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
+      len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10;
       arg_buf = (char *) alloca (len);
       arg_buf[0] = '\0';
       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."));
 
@@ -669,8 +667,13 @@ gdbsim_open (const char *args, int from_tty)
   int len;
   char *arg_buf;
   struct sim_inferior_data *sim_data;
+  const char *sysroot;
   SIM_DESC gdbsim_desc;
 
+  sysroot = gdb_sysroot;
+  if (is_target_filename (sysroot))
+    sysroot += strlen (TARGET_SYSROOT_PREFIX);
+
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog,
                        "gdbsim_open: args \"%s\"\n", args ? args : "(null)");
@@ -688,7 +691,7 @@ gdbsim_open (const char *args, int from_tty)
   len = (7 + 1                 /* gdbsim */
         + strlen (" -E little")
         + strlen (" --architecture=xxxxxxxxxx")
-        + strlen (" --sysroot=") + strlen (gdb_sysroot) +
+        + strlen (" --sysroot=") + strlen (sysroot) +
         + (args ? strlen (args) : 0)
         + 50) /* slack */ ;
   arg_buf = (char *) alloca (len);
@@ -715,25 +718,28 @@ gdbsim_open (const char *args, int from_tty)
     }
   /* Pass along gdb's concept of the sysroot.  */
   strcat (arg_buf, " --sysroot=");
-  strcat (arg_buf, gdb_sysroot);
+  strcat (arg_buf, sysroot);
   /* finally, any explicit args */
   if (args)
     {
       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;
 
@@ -760,8 +766,8 @@ gdbsim_open (const char *args, int from_tty)
 static int
 gdbsim_close_inferior (struct inferior *inf, void *arg)
 {
-  struct sim_inferior_data *sim_data = inferior_data (inf,
-                                                     sim_inferior_data_key);
+  struct sim_inferior_data *sim_data
+    = (struct sim_inferior_data *) inferior_data (inf, sim_inferior_data_key);
   if (sim_data != NULL)
     {
       ptid_t ptid = sim_data->remote_sim_ptid;
@@ -843,7 +849,7 @@ gdbsim_resume_inferior (struct inferior *inf, void *arg)
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (inf, SIM_INSTANCE_NOT_NEEDED);
-  struct resume_data *rd = arg;
+  struct resume_data *rd = (struct resume_data *) arg;
 
   if (sim_data)
     {
@@ -888,17 +894,17 @@ gdbsim_resume (struct target_ops *ops,
     error (_("The program is not being run."));
 }
 
-/* Notify the simulator of an asynchronous request to stop.
+/* Notify the simulator of an asynchronous request to interrupt.
 
-   The simulator shall ensure that the stop request is eventually
+   The simulator shall ensure that the interrupt request is eventually
    delivered to the simulator.  If the call is made while the
-   simulator is not running then the stop request is processed when
+   simulator is not running then the interrupt request is processed when
    the simulator is next resumed.
 
    For simulators that do not support this operation, just abort.  */
 
 static int
-gdbsim_stop_inferior (struct inferior *inf, void *arg)
+gdbsim_interrupt_inferior (struct inferior *inf, void *arg)
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (inf, SIM_INSTANCE_NEEDED);
@@ -918,13 +924,13 @@ gdbsim_stop_inferior (struct inferior *inf, void *arg)
 }
 
 static void
-gdbsim_stop (struct target_ops *self, ptid_t ptid)
+gdbsim_interrupt (struct target_ops *self, ptid_t ptid)
 {
   struct sim_inferior_data *sim_data;
 
   if (ptid_equal (ptid, minus_one_ptid))
     {
-      iterate_over_inferiors (gdbsim_stop_inferior, NULL);
+      iterate_over_inferiors (gdbsim_interrupt_inferior, NULL);
     }
   else
     {
@@ -934,7 +940,7 @@ gdbsim_stop (struct target_ops *self, ptid_t ptid)
        error (_("Can't stop pid %d.  No inferior found."),
               ptid_get_pid (ptid));
 
-      gdbsim_stop_inferior (inf, NULL);
+      gdbsim_interrupt_inferior (inf, NULL);
     }
 }
 
@@ -948,10 +954,7 @@ gdb_os_poll_quit (host_callback *p)
     deprecated_ui_loop_hook (0);
 
   if (check_quit_flag ())      /* gdb's idea of quit */
-    {
-      clear_quit_flag ();      /* we've stolen it */
-      return 1;
-    }
+    return 1;
   return 0;
 }
 
@@ -962,7 +965,7 @@ gdb_os_poll_quit (host_callback *p)
 static void
 gdbsim_cntrl_c (int signo)
 {
-  gdbsim_stop (NULL, minus_one_ptid);
+  gdbsim_interrupt (NULL, minus_one_ptid);
 }
 
 static ptid_t
@@ -970,7 +973,7 @@ gdbsim_wait (struct target_ops *ops,
             ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct sim_inferior_data *sim_data;
-  static RETSIGTYPE (*prev_sigint) ();
+  static sighandler_t prev_sigint;
   int sigrc = 0;
   enum sim_stop reason = sim_running;
 
@@ -1028,13 +1031,13 @@ gdbsim_wait (struct target_ops *ops,
        case GDB_SIGNAL_TRAP:
        default:
          status->kind = TARGET_WAITKIND_STOPPED;
-         status->value.sig = sigrc;
+         status->value.sig = (enum gdb_signal) sigrc;
          break;
        }
       break;
     case sim_signalled:
       status->kind = TARGET_WAITKIND_SIGNALLED;
-      status->value.sig = sigrc;
+      status->value.sig = (enum gdb_signal) sigrc;
       break;
     case sim_running:
     case sim_polling:
@@ -1192,7 +1195,8 @@ simulator_command (char *args, int from_tty)
      thus allocating memory that would not be garbage collected until
      the ultimate destruction of the associated inferior.  */
 
-  sim_data  = inferior_data (current_inferior (), sim_inferior_data_key);
+  sim_data  = ((struct sim_inferior_data *)
+              inferior_data (current_inferior (), sim_inferior_data_key));
   if (sim_data == NULL || sim_data->gdbsim_desc == NULL)
     {
 
@@ -1216,29 +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 = inferior_data (current_inferior (), sim_inferior_data_key);
+  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);
+    }
+  };
 
-  /* 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);
+  std::unique_ptr<char *[], sim_completions_deleter> sim_completions
+    (sim_complete_command (sim_data->gdbsim_desc, text, word));
+  if (sim_completions == NULL)
+    return;
 
-  return result;
+  /* 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++;
+
+  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.  */
@@ -1262,7 +1285,7 @@ gdbsim_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Convert a thread ID to a string.  Returns the string in a static
    buffer.  */
 
-static char *
+static const char *
 gdbsim_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   return normal_pid_to_str (ptid);
@@ -1320,7 +1343,7 @@ init_gdbsim_ops (void)
   gdbsim_ops.to_load = gdbsim_load;
   gdbsim_ops.to_create_inferior = gdbsim_create_inferior;
   gdbsim_ops.to_mourn_inferior = gdbsim_mourn_inferior;
-  gdbsim_ops.to_stop = gdbsim_stop;
+  gdbsim_ops.to_interrupt = gdbsim_interrupt;
   gdbsim_ops.to_thread_alive = gdbsim_thread_alive;
   gdbsim_ops.to_pid_to_str = gdbsim_pid_to_str;
   gdbsim_ops.to_stratum = process_stratum;
This page took 0.033338 seconds and 4 git commands to generate.