From: Daniel Jacobowitz <drow@mvista.com>
To: Mark Kettenis <kettenis@chello.nl>
Cc: gdb@sources.redhat.com
Subject: Re: [RFC] Register sets
Date: Sun, 24 Aug 2003 16:43:00 -0000 [thread overview]
Message-ID: <20030824164347.GA17520@nevyn.them.org> (raw)
In-Reply-To: <200308232249.h7NMnvhh090154@elgar.kettenis.dyndns.org>
On Sun, Aug 24, 2003 at 12:49:57AM +0200, Mark Kettenis wrote:
> 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.
Hi Mark,
I've been thinking about the same problem for a while now. I have a
slightly different mental picture; let's see if we can put them
together.
> 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.
I don't think this is a good assumption. There are two problems with
it:
- It assumes that everything relating to a particular target uses the
same register set format. In general (there are exceptions where
libthread_db will zero the regset instead of calling ps_*getregs) we
can pass regsets through libthread_db as opaque objects; we might wish
to include registers that are not available in a core dump. Then we've
got two different "general" regsets. There are some other examples.
- It assumes that there is one possible xregset for a target.
Suppose that you have two ARM targets with different vector extensions;
I'll pick Cirrus/Maverick and iWMMXt, since there happen to be two ARM
targets with different vector extensions. We may not know right away
which regset is available. I'm not sure this is a problem; we could
just define the architecture appropriately; but another example is the
embedded x86 architecture registers, which a remote stub might want to
transfer.
(Choice of iWMMXt isn't just an example. I need to add gdbserver
support for iWMMXt, and I want to do it without changing the g/G
packet. See below...)
> 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.
Can we define the REGNUM != -1 case a little more clearly? Is the
regnum a hint, what registers must be valid in the regcache when
collecting, what registers must be valid in the regset when supplying,
et cetera. Right now we're a bit inconsistent between targets.
> 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?
I was thinking of something like this, very roughly:
struct regset
{
size_t size;
mapping_of_registers_and_sizes_and_offsets mapping;
};
struct native_regsets
{
struct regset *gregset, *fpregset, *xregset;
};
struct regset *
gdbarch_core_section_to_regset (int which, int sizeof);
This would replace lots of identical copies of fetch_core_registers all
over GDB.
And then:
struct regset *
gdbarch_remote_name_to_regset (int which, int sizeof);
The companion to this would be some remote protocol work:
-> qRegsets::
<- qRegsets:General,FP,iWMMXt
[Local GDB calls gdbarch_remote_name_to_regset on each of these]
-> g
<- 0000102109210831973987etc
[This would be the General set.]
-> qFetchRegset:FP
<- 000000831092831098201923etc
-> qSetRegset:FP:100000831092831098201923etc
<- OK
[This would be the FP set.]
Also available might be:
-> qDescribeRegset:General
<- a0:8;a1:8;a2:8;a3:8;v0:8;sp:8;pc:8
which could be used before trying the gdbarch_remote_name_to_regset as
a fallback. And this logically extends to a CLI command to specify the
format of the G packet, which I think there's a PR requesting?
How does that sound? I'll implement it if folks like it. Open to
any/all suggestions.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
next prev parent reply other threads:[~2003-08-24 16:43 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-08-23 22:50 Mark Kettenis
2003-08-24 16:43 ` Daniel Jacobowitz [this message]
2003-08-25 22:35 ` Mark Kettenis
2003-08-26 15:49 ` Andrew Cagney
2003-08-26 16:55 ` Daniel Jacobowitz
2003-08-27 3:50 ` Andrew Cagney
2003-08-31 14:04 ` Mark Kettenis
2003-09-02 18:40 ` Andrew Cagney
2003-09-04 21:31 ` Mark Kettenis
2003-09-04 12:55 ` Daniel Jacobowitz
2003-09-04 14:00 ` Andrew Cagney
2003-09-04 14:08 ` Daniel Jacobowitz
2003-09-04 15:04 ` Andrew Cagney
2003-09-04 15:13 ` Daniel Jacobowitz
2003-09-04 22:07 ` Mark Kettenis
2003-09-04 22:05 ` Mark Kettenis
2003-09-04 22:16 ` Andrew Cagney
2003-09-04 22:59 ` Andrew Cagney
2003-09-05 23:15 ` Daniel Jacobowitz
2003-09-09 4:21 ` Andrew Cagney
2003-09-04 21:58 ` Mark Kettenis
2003-09-06 0:02 ` Jim Blandy
2003-09-06 14:18 ` Mark Kettenis
2003-09-09 4:51 ` Andrew Cagney
2003-09-09 17:15 ` Jim Blandy
2003-09-09 19:16 ` Andrew Cagney
2003-08-29 20:20 ` Mark Kettenis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030824164347.GA17520@nevyn.them.org \
--to=drow@mvista.com \
--cc=gdb@sources.redhat.com \
--cc=kettenis@chello.nl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox