Unify ctf_fetch_registers and tfile_fetch_registers
authorYao Qi <yao@codesourcery.com>
Fri, 18 Apr 2014 11:32:01 +0000 (19:32 +0800)
committerYao Qi <yao@codesourcery.com>
Tue, 22 Apr 2014 01:21:55 +0000 (09:21 +0800)
Functions ctf_fetch_registers and tfile_fetch_registers have some
duplicated code about guessing the PC in regcache.  Sometimes, we
may change one function and forget to update the other one, like this
https://www.sourceware.org/ml/gdb-patches/2014-01/msg00292.html

This patch is to move the duplicated code into a new function
tracefile_fetch_registers, and let both ctf_fetch_registers and
tfile_fetch_registers call it.

gdb:

2014-04-22  Yao Qi  <yao@codesourcery.com>

* tracefile-tfile.c (tfile_fetch_registers): Move the bottom to ...
* tracefile.c (tracefile_fetch_registers): ... it.  New function.
* tracefile.h (tracefile_fetch_registers): Declare.
* ctf.c (ctf_fetch_registers): Remove the bottom.  Call
tracefile_fetch_registers.

gdb/ChangeLog
gdb/ctf.c
gdb/tracefile-tfile.c
gdb/tracefile.c
gdb/tracefile.h

index 23ca6c09f4d8576d108a9813f6e4f5d093b1d92d..6a61a53c100f7ef1e08843dc9c920143ee33ed0c 100644 (file)
@@ -1,3 +1,13 @@
+2014-04-22  Yao Qi  <yao@codesourcery.com>
+
+       * tracefile-tfile.c (tfile_fetch_registers): Move the bottom
+       to ...
+       * tracefile.c (tracefile_fetch_registers): ... it.  New
+       function.
+       * tracefile.h (tracefile_fetch_registers): Declare.
+       * ctf.c (ctf_fetch_registers): Remove the bottom.  Call
+       tracefile_fetch_registers.
+
 2014-04-19  Eli Zaretskii  <eliz@gnu.org>
 
        PR gdb/14018
index 25d63c6655c29641f855a9ea1658e4412c854940..bac7c28425cdd848828220dd8dfb1c862099d098 100644 (file)
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -1229,8 +1229,6 @@ ctf_fetch_registers (struct target_ops *ops,
                     struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int offset, regn, regsize, pc_regno;
-  gdb_byte *regs = NULL;
   struct bt_ctf_event *event = NULL;
   struct bt_iter_pos *pos;
 
@@ -1270,13 +1268,14 @@ ctf_fetch_registers (struct target_ops *ops,
 
   if (event != NULL)
     {
+      int offset, regsize, regn;
       const struct bt_definition *scope
        = bt_ctf_get_top_level_scope (event,
                                      BT_EVENT_FIELDS);
       const struct bt_definition *array
        = bt_ctf_get_field (event, scope, "contents");
+      gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);
 
-      regs = (gdb_byte *) bt_ctf_get_char_array (array);
       /* Assume the block is laid out in GDB register number order,
         each register with the size that it has in GDB.  */
       offset = 0;
@@ -1300,48 +1299,9 @@ ctf_fetch_registers (struct target_ops *ops,
            }
          offset += regsize;
        }
-      return;
-    }
-
-  regs = alloca (trace_regblock_size);
-
-  /* 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.  */
-  pc_regno = gdbarch_pc_regnum (gdbarch);
-  if (pc_regno >= 0 && (regno == -1 || regno == pc_regno))
-    {
-      struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
-
-      if (tp != NULL && tp->base.loc)
-       {
-         /* But don't try to guess if tracepoint is multi-location...  */
-         if (tp->base.loc->next != NULL)
-           {
-             warning (_("Tracepoint %d has multiple "
-                        "locations, cannot infer $pc"),
-                      tp->base.number);
-             return;
-           }
-         /* ... or does while-stepping.  */
-         if (tp->step_count > 0)
-           {
-             warning (_("Tracepoint %d does while-stepping, "
-                        "cannot infer $pc"),
-                      tp->base.number);
-             return;
-           }
-
-         store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
-                                 gdbarch_byte_order (gdbarch),
-                                 tp->base.loc->address);
-         regcache_raw_supply (regcache, pc_regno, regs);
-       }
     }
+  else
+    tracefile_fetch_registers (regcache, regno);
 }
 
 /* This is the implementation of target_ops method to_xfer_partial.
index a36596f00842c4d854facaa75c32348cc6bd013d..efa69b260d1fe3f4cdd69d4477aa3356c4ad9593 100644 (file)
@@ -795,18 +795,17 @@ tfile_fetch_registers (struct target_ops *ops,
                       struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int offset, regn, regsize, pc_regno;
-  gdb_byte *regs;
+  int offset, regn, regsize;
 
   /* An uninitialized reg size says we're not going to be
      successful at getting register blocks.  */
   if (!trace_regblock_size)
     return;
 
-  regs = alloca (trace_regblock_size);
-
   if (traceframe_find_block_type ('R', 0) >= 0)
     {
+      gdb_byte *regs = alloca (trace_regblock_size);
+
       tfile_read (regs, trace_regblock_size);
 
       /* Assume the block is laid out in GDB register number order,
@@ -832,56 +831,9 @@ tfile_fetch_registers (struct target_ops *ops,
            }
          offset += regsize;
        }
-      return;
-    }
-
-  /* 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.  */
-  pc_regno = gdbarch_pc_regnum (gdbarch);
-
-  /* XXX This guessing code below only works if the PC register isn't
-     a pseudo-register.  The value of a pseudo-register isn't stored
-     in the (non-readonly) regcache -- instead it's recomputed
-     (probably from some other cached raw register) whenever the
-     register is read.  This guesswork should probably move to some
-     higher layer.  */
-  if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch))
-    return;
-
-  if (regno == -1 || regno == pc_regno)
-    {
-      struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
-
-      if (tp && tp->base.loc)
-       {
-         /* 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.  */
-         if (tp->step_count > 0)
-           {
-             warning (_("Tracepoint %d does while-stepping, "
-                        "cannot infer $pc"),
-                      tp->base.number);
-             return;
-           }
-
-         store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
-                                 gdbarch_byte_order (gdbarch),
-                                 tp->base.loc->address);
-         regcache_raw_supply (regcache, pc_regno, regs);
-       }
     }
+  else
+    tracefile_fetch_registers (regcache, regno);
 }
 
 static enum target_xfer_status
index a7c3cf7fe31a44132e3ba3bf211acd4bf4882913..0b89cfa4981ff74677a6af4167916bca9baf5f3b 100644 (file)
@@ -21,6 +21,7 @@
 #include "tracefile.h"
 #include "ctf.h"
 #include "exec.h"
+#include "regcache.h"
 
 /* Helper macros.  */
 
@@ -377,6 +378,66 @@ 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);
+  int regn, pc_regno;
+
+  /* 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.  */
+  pc_regno = gdbarch_pc_regnum (gdbarch);
+
+  /* XXX This guessing code below only works if the PC register isn't
+     a pseudo-register.  The value of a pseudo-register isn't stored
+     in the (non-readonly) regcache -- instead it's recomputed
+     (probably from some other cached raw register) whenever the
+     register is read.  This guesswork should probably move to some
+     higher layer.  */
+  if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch))
+    return;
+
+  if (regno == -1 || regno == pc_regno)
+    {
+      struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
+      gdb_byte *regs;
+
+      if (tp && tp->base.loc)
+       {
+         /* 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.  */
+         if (tp->step_count > 0)
+           {
+             warning (_("Tracepoint %d does while-stepping, "
+                        "cannot infer $pc"),
+                      tp->base.number);
+             return;
+           }
+
+         regs = alloca (register_size (gdbarch, pc_regno));
+         store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
+                                 gdbarch_byte_order (gdbarch),
+                                 tp->base.loc->address);
+         regcache_raw_supply (regcache, pc_regno, regs);
+       }
+    }
+}
+
 /* This is the implementation of target_ops method to_has_all_memory.  */
 
 static int
index db454e310774c48e930fbc9cd4b8bd17f3667121..54853708291640b6b61fce45b308ee21efc6fd37 100644 (file)
@@ -113,4 +113,6 @@ extern struct trace_file_writer *tfile_trace_file_writer_new (void);
 
 extern void init_tracefile_ops (struct target_ops *ops);
 
+extern void tracefile_fetch_registers (struct regcache *regcache, int regno);
+
 #endif /* TRACEFILE_H */