aboutsummaryrefslogtreecommitdiff
path: root/gdb/tracefile.c
diff options
context:
space:
mode:
authorYao Qi <yao@codesourcery.com>2014-04-18 19:32:01 +0800
committerYao Qi <yao@codesourcery.com>2014-04-22 09:21:55 +0800
commit48b6e87ef297136a6409c2c993c4626f28bbb4d1 (patch)
treea54fda3ab474325c513a7981d0a8f8ec4063990a /gdb/tracefile.c
parentf159927f4d15d820a6eb615e33d68780db035c8d (diff)
downloadfsf-binutils-gdb-48b6e87ef297136a6409c2c993c4626f28bbb4d1.zip
fsf-binutils-gdb-48b6e87ef297136a6409c2c993c4626f28bbb4d1.tar.gz
fsf-binutils-gdb-48b6e87ef297136a6409c2c993c4626f28bbb4d1.tar.bz2
Unify ctf_fetch_registers and tfile_fetch_registers
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.
Diffstat (limited to 'gdb/tracefile.c')
-rw-r--r--gdb/tracefile.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index a7c3cf7..0b89cfa 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