summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/ctf.c48
-rw-r--r--gdb/tracefile-tfile.c58
-rw-r--r--gdb/tracefile.c61
-rw-r--r--gdb/tracefile.h2
5 files changed, 82 insertions, 97 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 23ca6c09f4d..6a61a53c100 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/ctf.c b/gdb/ctf.c
index 25d63c6655c..bac7c28425c 100644
--- 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.
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index a36596f0084..efa69b260d1 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -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
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index a7c3cf7fe31..0b89cfa4981 100644
--- a/gdb/tracefile.c
+++ b/gdb/tracefile.c
@@ -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
diff --git a/gdb/tracefile.h b/gdb/tracefile.h
index db454e31077..54853708291 100644
--- a/gdb/tracefile.h
+++ b/gdb/tracefile.h
@@ -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 */