This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]