Marcin Kościelnicki wrote:
I don't think generalizing that function to arbitrary pseudo registers
is a good idea - there's already a pseudo_register_write, which covers
writing them. The only reason I'm not using it in tracepoint.c is
that there's no "current register state" to write over, I'm making
a new one from scratch.
Well, strictly speaking there is already a "current register state"
since tracefile_fetch_registers just initialized all registers to
the "unavailable" state. At this point they could be fetched (and
would read all zeros).
So in principle you could just use regcache_write_pc at this point.
The reason this doesn't work is a different one: that routine would
attempt to *update target state*, i.e. it would call to the target's
to_store_registers method. However, the tracefile target only
provides a to_fetch_registers method, and no to_store_registers,
and the default target to_store_registers method just errors out.
You *could* add a to_store_registers tracefile target method that
would simply ignore writes (in effect, making the tracefile regcache
modifyable without any underlying "real" target); then you could
just use regcache_write_pc.
However, this would not address the fact that there are potentially
target-specific settings beyond a pure PC value that must be
present in order to make a "synthetic" regcache at least minimally
consistent. This includes e.g. the address mode bit on 31-bit.
Note that a default value of 0 isn't really valid for the PSWM
register either, even though probably nobody checks. But there
are a number of bits that have to be set to make it a valid
user-space PSW (e.g. interrupts and address translation must be
enabled etc.). If you'd ever try to load the PSW back to the
hardware via ptrace, a 0 PSWM would get rejected.
Perhaps a better generalization would be to instead make a hook that's
supposed to provide a whole regcache based on the tracepoint location,
not just PC? I can imagine a few uses for that:
- on machines like ARM where you have several instruction encodings,
you could also supply whatever registers determine the encoding
(arm vs thumb) based on the location.
- if you can determine from the debug information that the function
keeps GOT pointer / literal pool pointer / whatever in some register
at the tracepoint location, you can also guess the contents of these
(although that's probably not all that useful, and can be a lie
if something is horribly buggy).
Given the above, I therefore agree that this is really probably
the preferable level of abstraction here. You want a gdbarch hook
to synthesize a minimally-valid regcache given only information
statically known about the tracepoint. Whether this hook gets
just the PC or a full tracepoint structure is probably not so
important right now; this could still be modified if necessary.
I'd also suggest that this hook doesn't get a predicate, but a
default implementation, which does the current handling of just
setting a real PC register. If overridden by a gdbarch, the
platform can do anything that's necessary there instead.
Bye,
Ulrich