target_ops: Use bool throughout
[deliverable/binutils-gdb.git] / gdb / tracefile.c
index 79722901ec585778e84a283fe57be913a27db762..f7e69f2df6c082fe6b8c909315df4ca57a2cc3a4 100644 (file)
@@ -1,6 +1,6 @@
 /* Trace file support in GDB.
 
-   Copyright (C) 1997-2014 Free Software Foundation, Inc.
+   Copyright (C) 1997-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,6 +20,8 @@
 #include "defs.h"
 #include "tracefile.h"
 #include "ctf.h"
+#include "exec.h"
+#include "regcache.h"
 
 /* Helper macros.  */
 
@@ -39,7 +41,7 @@
 static void
 trace_file_writer_xfree (void *arg)
 {
-  struct trace_file_writer *writer = arg;
+  struct trace_file_writer *writer = (struct trace_file_writer *) arg;
 
   writer->ops->dtor (writer);
   xfree (writer);
@@ -55,14 +57,12 @@ trace_save (const char *filename, struct trace_file_writer *writer,
            int target_does_save)
 {
   struct trace_status *ts = current_trace_status ();
-  int status;
   struct uploaded_tp *uploaded_tps = NULL, *utp;
   struct uploaded_tsv *uploaded_tsvs = NULL, *utsv;
 
   ULONGEST offset = 0;
 #define MAX_TRACE_UPLOAD 2000
   gdb_byte buf[MAX_TRACE_UPLOAD];
-  int written;
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
 
   /* If the target is to save the data to a file on its own, then just
@@ -76,8 +76,10 @@ trace_save (const char *filename, struct trace_file_writer *writer,
     }
 
   /* Get the trace status first before opening the file, so if the
-     target is losing, we can get out without touching files.  */
-  status = target_get_trace_status (ts);
+     target is losing, we can get out without touching files.  Since
+     we're just calling this for side effects, we ignore the
+     result.  */
+  target_get_trace_status (ts);
 
   writer->ops->start (writer, filename);
 
@@ -88,6 +90,9 @@ trace_save (const char *filename, struct trace_file_writer *writer,
   /* Write out the size of a register block.  */
   writer->ops->write_regblock_type (writer, trace_regblock_size);
 
+  /* Write out the target description info.  */
+  writer->ops->write_tdesc (writer);
+
   /* Write out status of the tracing run (aka "tstatus" info).  */
   writer->ops->write_status (writer, ts);
 
@@ -301,7 +306,7 @@ trace_save (const char *filename, struct trace_file_writer *writer,
 }
 
 static void
-trace_save_command (char *args, int from_tty)
+tsave_command (const char *args, int from_tty)
 {
   int target_does_save = 0;
   char **argv;
@@ -313,14 +318,14 @@ trace_save_command (char *args, int from_tty)
   if (args == NULL)
     error_no_arg (_("file in which to save trace data"));
 
-  argv = gdb_buildargv (args);
-  back_to = make_cleanup_freeargv (argv);
+  gdb_argv built_argv (args);
+  argv = built_argv.get ();
 
   for (; *argv; ++argv)
     {
       if (strcmp (*argv, "-r") == 0)
        target_does_save = 1;
-      if (strcmp (*argv, "-ctf") == 0)
+      else if (strcmp (*argv, "-ctf") == 0)
        generate_ctf = 1;
       else if (**argv == '-')
        error (_("unknown option `%s'"), *argv);
@@ -336,7 +341,7 @@ trace_save_command (char *args, int from_tty)
   else
     writer = tfile_trace_file_writer_new ();
 
-  make_cleanup (trace_file_writer_xfree, writer);
+  back_to = make_cleanup (trace_file_writer_xfree, writer);
 
   trace_save (filename, writer, target_does_save);
 
@@ -376,12 +381,70 @@ trace_save_ctf (const char *dirname, int target_does_save)
   do_cleanups (back_to);
 }
 
+/* Fetch register data from tracefile, shared for both tfile and
+   ctf.  */
+
+void
+tracefile_fetch_registers (struct regcache *regcache, int regno)
+{
+  struct gdbarch *gdbarch = regcache->arch ();
+  struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
+  int regn;
+
+  /* We get here if no register data has been found.  Mark registers
+     as unavailable.  */
+  for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
+    regcache_raw_supply (regcache, regn, NULL);
+
+  /* We can often usefully guess that the PC is going to be the same
+     as the address of the tracepoint.  */
+  if (tp == NULL || tp->loc == NULL)
+    return;
+
+  /* But don't try to guess if tracepoint is multi-location...  */
+  if (tp->loc->next)
+    {
+      warning (_("Tracepoint %d has multiple "
+                "locations, cannot infer $pc"),
+              tp->number);
+      return;
+    }
+  /* ... or does while-stepping.  */
+  else if (tp->step_count > 0)
+    {
+      warning (_("Tracepoint %d does while-stepping, "
+                "cannot infer $pc"),
+              tp->number);
+      return;
+    }
+
+  /* Guess what we can from the tracepoint location.  */
+  gdbarch_guess_tracepoint_registers (gdbarch, regcache,
+                                     tp->loc->address);
+}
+
+/* This is the implementation of target_ops method to_has_all_memory.  */
+
+bool
+tracefile_target::has_all_memory ()
+{
+  return 1;
+}
+
+/* This is the implementation of target_ops method to_has_memory.  */
+
+bool
+tracefile_target::has_memory ()
+{
+  return 1;
+}
+
 /* This is the implementation of target_ops method to_has_stack.
    The target has a stack when GDB has already selected one trace
    frame.  */
 
-static int
-tracefile_has_stack (struct target_ops *ops)
+bool
+tracefile_target::has_stack ()
 {
   return get_traceframe_number () != -1;
 }
@@ -390,8 +453,8 @@ tracefile_has_stack (struct target_ops *ops)
    The target has registers when GDB has already selected one trace
    frame.  */
 
-static int
-tracefile_has_registers (struct target_ops *ops)
+bool
+tracefile_target::has_registers ()
 {
   return get_traceframe_number () != -1;
 }
@@ -399,8 +462,8 @@ tracefile_has_registers (struct target_ops *ops)
 /* This is the implementation of target_ops method to_thread_alive.
    tracefile has one thread faked by GDB.  */
 
-static int
-tracefile_thread_alive (struct target_ops *ops, ptid_t ptid)
+bool
+tracefile_target::thread_alive (ptid_t ptid)
 {
   return 1;
 }
@@ -408,8 +471,8 @@ tracefile_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* This is the implementation of target_ops method to_get_trace_status.
    The trace status for a file is that tracing can never be run.  */
 
-static int
-tracefile_get_trace_status (struct target_ops *self, struct trace_status *ts)
+int
+tracefile_target::get_trace_status (struct trace_status *ts)
 {
   /* Other bits of trace status were collected as part of opening the
      trace files, so nothing to do here.  */
@@ -417,25 +480,15 @@ tracefile_get_trace_status (struct target_ops *self, struct trace_status *ts)
   return -1;
 }
 
-/* Initialize OPS for tracefile related targets.  */
-
-void
-init_tracefile_ops (struct target_ops *ops)
+tracefile_target::tracefile_target ()
 {
-  ops->to_stratum = process_stratum;
-  ops->to_get_trace_status = tracefile_get_trace_status;
-  ops->to_has_stack = tracefile_has_stack;
-  ops->to_has_registers = tracefile_has_registers;
-  ops->to_thread_alive = tracefile_thread_alive;
-  ops->to_magic = OPS_MAGIC;
+  this->to_stratum = process_stratum;
 }
 
-extern initialize_file_ftype _initialize_tracefile;
-
 void
 _initialize_tracefile (void)
 {
-  add_com ("tsave", class_trace, trace_save_command, _("\
+  add_com ("tsave", class_trace, tsave_command, _("\
 Save the trace data to a file.\n\
 Use the '-ctf' option to save the data to CTF format.\n\
 Use the '-r' option to direct the target to save directly to the file,\n\
This page took 0.030172 seconds and 4 git commands to generate.