gdb: Add guess_tracepoint_registers hook to gdbarch.
[deliverable/binutils-gdb.git] / gdb / tracefile.c
index 79722901ec585778e84a283fe57be913a27db762..609b7e5a42a2522c7f52b8b62e026174b98bfc3d 100644 (file)
@@ -1,6 +1,6 @@
 /* Trace file support in GDB.
 
-   Copyright (C) 1997-2014 Free Software Foundation, Inc.
+   Copyright (C) 1997-2016 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);
@@ -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);
 
@@ -376,6 +381,64 @@ 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 = get_regcache_arch (regcache);
+  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->base.loc == NULL)
+    return;
+
+  /* But don't try to guess if tracepoint is multi-location...  */
+  if (tp->base.loc->next)
+    {
+      warning (_("Tracepoint %d has multiple "
+                "locations, cannot infer $pc"),
+              tp->base.number);
+      return;
+    }
+  /* ... or does while-stepping.  */
+  else if (tp->step_count > 0)
+    {
+      warning (_("Tracepoint %d does while-stepping, "
+                "cannot infer $pc"),
+              tp->base.number);
+      return;
+    }
+
+  /* Guess what we can from the tracepoint location.  */
+  gdbarch_guess_tracepoint_registers (gdbarch, regcache,
+                                     tp->base.loc->address);
+}
+
+/* This is the implementation of target_ops method to_has_all_memory.  */
+
+static int
+tracefile_has_all_memory (struct target_ops *ops)
+{
+  return 1;
+}
+
+/* This is the implementation of target_ops method to_has_memory.  */
+
+static int
+tracefile_has_memory (struct target_ops *ops)
+{
+  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.  */
@@ -424,6 +487,8 @@ init_tracefile_ops (struct target_ops *ops)
 {
   ops->to_stratum = process_stratum;
   ops->to_get_trace_status = tracefile_get_trace_status;
+  ops->to_has_all_memory = tracefile_has_all_memory;
+  ops->to_has_memory = tracefile_has_memory;
   ops->to_has_stack = tracefile_has_stack;
   ops->to_has_registers = tracefile_has_registers;
   ops->to_thread_alive = tracefile_thread_alive;
This page took 0.026408 seconds and 4 git commands to generate.