diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-02-18 09:21:38 +0100 |
---|---|---|
committer | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-02-18 17:21:22 +0100 |
commit | 5f034a78b986d30a90030b2409c61a8660b9b48c (patch) | |
tree | 312e005927c2673b81ad675d0e46e8b6ac5a5cd2 /gdb/tracefile.c | |
parent | c304e18e5ca825f57963bd0c5f022fa8f5797b29 (diff) | |
download | gdb-5f034a78b986d30a90030b2409c61a8660b9b48c.zip gdb-5f034a78b986d30a90030b2409c61a8660b9b48c.tar.gz gdb-5f034a78b986d30a90030b2409c61a8660b9b48c.tar.bz2 |
gdb: Add guess_tracepoint_registers hook to gdbarch.
When we're looking at a tracefile trace frame where registers are not
available, and the tracepoint has only one location, we supply
the location's address as the PC register. However, this only works
if PC is not a pseudo register, and individual architectures may want
to guess more registers. Add a gdbarch hook that will handle that.
gdb/ChangeLog:
* arch-utils.c (default_guess_tracepoint_registers): New function.
* arch-utils.h (default_guess_tracepoint_registers): New prototype.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
* gdbarch.sh: Add guess_tracepoint_registers hook.
* tracefile.c (tracefile_fetch_registers): Use the new gdbarch hook.
Diffstat (limited to 'gdb/tracefile.c')
-rw-r--r-- | gdb/tracefile.c | 60 |
1 files changed, 21 insertions, 39 deletions
diff --git a/gdb/tracefile.c b/gdb/tracefile.c index de42165..609b7e5 100644 --- a/gdb/tracefile.c +++ b/gdb/tracefile.c @@ -388,7 +388,8 @@ void tracefile_fetch_registers (struct regcache *regcache, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); - int regn, pc_regno; + struct tracepoint *tp = get_tracepoint (get_tracepoint_number ()); + int regn; /* We get here if no register data has been found. Mark registers as unavailable. */ @@ -397,48 +398,29 @@ tracefile_fetch_registers (struct regcache *regcache, int regno) /* 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)) + if (tp == NULL || tp->base.loc == NULL) return; - if (regno == -1 || regno == pc_regno) + /* But don't try to guess if tracepoint is multi-location... */ + if (tp->base.loc->next) { - 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 = (gdb_byte *) 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); - } + 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. */ |