[RFC] Register sets
Mark Kettenis
kettenis@chello.nl
Sat Aug 23 22:50:00 GMT 2003
Folks (and especially Andrew),
A while back, Andrew submitted a patch that made it possible to read
Linux/i386 corefiles on Linux/x86-64. He tricked me into fixing the
"gcore" command for this case, which forced me to think a bit more
about how we can solve this cleanly. Here's what I think is the
solution.
Registers sets
--------------
In most hosted environments, the underlying OS devides the ISA's
registers in groups. Typically there is a set of general-purpose
(which usually includes all integer register)s and a set of
floating-point registers. That's one of the reasons why we have
reggroups in GDB.
Most OS'es define data structures for dealing with these groups of
registers:
* Modern BSD's have `struct reg' and `struct fpreg'.
* System V has `gregset_t' and `fpregset_t'. Solaris (as an
SVR4-derivative) has `prgregset_t' and `fpregset_t' and the
provision for an `xregset'.
* QNX has `procfs_greg', `procfs_fpreg' and `procfs_altreg'.
* Linux is a bit messy, but tries to mimic SVR4/Solaris.
These data structures are used in several interfaces:
* ptrace(2) (for systems that have PT_GETREGS/PTRACE_GETREGS and
friends, e.g. modern BSD's and most Linuxen).
* proc(4) filesystem (a.k.a. procfs on e.g. SVR4/Solaris and QNX).
* libthread_db(3)/proc_service(3) debugging interface (on Solaris and
Linux).
* core(5) memory dumps (on ELF systems, but also in some cases,
traditional a.out systems).
As a result, we use these data structures all over the place in GDB,
usually in ways that make it difficult to re-use code and/or
multi-arch things. I'd like to introduce a more unified approach to
handling these data structures, which I propose to call register sets,
or regsets for short. Basically a register set is just a block of
memory of a certain size. We may want to put these register sets (or
a single register from them) into GDB's register cache. We also need
to be able to grab these register sets (or a single register in them)
from the register cache.
It seems that we need a maximum of three of these sets. I propose to
name these register sets as follows:
* `gregset' for the general-purpose registers.
* `fpregset' for the floating-point registers.
* `xregset' for any "extra" registers.
For each register set we have to provide a function that takes apart
the register set and stores it in GDB's register cache, and a
functions that puts together a register set from GDB's register set.
For these functions I propose the functions:
void <prefix>_supply_<regset> (struct regcache *regcache,
const void *regs, int regnum);
for supplying register REGNUM from register set REGS into the cache
REGCACHE, and
void <prefix>_collect_<regset> (const struct regcache *regcache,
void *regs, int regnum)
for collecting register REGNUM from the cache REGCACHE into register
set REGS.
If REGNUM is -1, these function operate on all registers within the set.
For each architecture we will have a structure that contains all
information about the register sets:
struct regset_info
{
size_t sizeof_gregset;
void (*supply_gregset)(struct regcache *, const void *, int);
void (*collect_gregset)(const struct regcache *, void *, int);
size_t sizeof_fpregset;
void (*supply_fpregset)(struct regcache *, const void *, int);
void (*collect_fpregset)(const struct regcache *, void *, int);
size_t sizeof_xregset;
void (*supply_xregset)(const struct regcache *, void *, int);
void (*collect_xregset)(const struct regcache *, void *, int);
};
A pointer to this structure will be stored in the architecture vector,
such that we can use this from various places in GDB.
Thoughts?
Mark
More information about the Gdb
mailing list