This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Saving and restoring cooked registers?
- From: Andrew Cagney <ac131313 at ges dot redhat dot com>
- To: gdb at sources dot redhat dot com
- Date: Sat, 17 Aug 2002 18:58:49 -0400
- Subject: Saving and restoring cooked registers?
Hello,
The background:
Several sections of GDB contain code to save/restore registers:
- the inferior function call code saves the registers, before making the
call, so that they can be restored after the call has finished
- the inferior function call code captures the registers, after the call
has finished (but before restoring) so that the return value of the
function can be displayed
- the finish command saves the state of the registers, before each
stepi, so that the functions return value is available
They use the recently introduced methods, regcache_dup...() and
regcache_cpy..(). For new targets, these functions save [0..NUM_REGS)
but for old targets they save all [0..NUM_REGS+NUM_PSEUDO_REGS).
The problems (or the ones I'm aware of):
- The code saves all registers. Not just the ABI registers but also
system registers that are not relevant to the ABI. Instead, only a
subset of the registers (those involved in the call) should to be
saved/restored.
Ex: I'm looking at an old patch, by Fernando Nasser, that adds a
(large) number of system registers to the i386. None of those system
registers should be saved/restored.
- The target might need to save/restore registers that reside in memory.
These fall in the range [NUM_REGS .. NUM_REGS+NUM_PSEUDO_REGS) and
hence, for new targets, these are not saved/restored.
I suspect that this is why the old code was trying to save the full
NUM_REGS+NUM_PSEUDO_REGS. I'm not sure mind :-)
The proposed changes:
I'd like to propose the following changes to the register cache:
- save/restore cooked, rather than raw, registers
This would make it possible to save memory based registers across an
inferior call or return. By default, only [0..NUM_REGS) cooked
registers would be saved and since they are 1:1 with the raw registers,
existing new code wouldn't notice the change.
I suspect this is why the old code was saving the full register range.
- disallow writes to a saved copy of the register cache
If this isn't done, there is a problem with keeping the cooked registers
coherent.
The only thing I think this would affect is dummy frames and there, the
registers are already treated read-only!
- add architecture based iterators:
next_cooked_register_to_save (gdbarch, last_regnum)
next_cooked_register_to_restore (gdbarch, last_regnum)
that could be used vis:
for (regnum = next_cooked_register_to_save (gdbarch, -1);
regnum >= 0;
regnum = next_cooked_register_to_save (gdbarch, regnum))
save the register ...
(alternative interfaces welcome)
This would make it possible for an architecture to select a subset of
registers to save/restore across a function call, or to save duringe a
function return.
By default, these methods would just iterate over [0 .. NUM_REGS) for
new code; or [0 .. NUM_REGS+NUM_PSEUDO_REGS) for legacy code.
- (for want of a better idea) when code tries to read an unsaved cooked
register, fall back to the normal regcache_pseudo_read() and possibly
the global register cache, for the value.
Not 100% sure about this bit :-)
Comments? Suggestions?
Andrew