Saving and restoring cooked registers?

Andrew Cagney ac131313@ges.redhat.com
Sat Aug 17 15:59:00 GMT 2002


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




More information about the Gdb mailing list