* [RFC] Register sets
@ 2003-08-23 22:50 Mark Kettenis
2003-08-24 16:43 ` Daniel Jacobowitz
0 siblings, 1 reply; 27+ messages in thread
From: Mark Kettenis @ 2003-08-23 22:50 UTC (permalink / raw)
To: gdb
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-08-23 22:50 [RFC] Register sets Mark Kettenis
@ 2003-08-24 16:43 ` Daniel Jacobowitz
2003-08-25 22:35 ` Mark Kettenis
0 siblings, 1 reply; 27+ messages in thread
From: Daniel Jacobowitz @ 2003-08-24 16:43 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb
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
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-08-24 16:43 ` Daniel Jacobowitz
@ 2003-08-25 22:35 ` Mark Kettenis
2003-08-26 15:49 ` Andrew Cagney
0 siblings, 1 reply; 27+ messages in thread
From: Mark Kettenis @ 2003-08-25 22:35 UTC (permalink / raw)
To: drow; +Cc: gdb
Date: Sun, 24 Aug 2003 12:43:47 -0400
From: Daniel Jacobowitz <drow@mvista.com>
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.
That's quite true. It's probably a better idea to have the
possibility of defining register sets for these particular purpose,
falling back on a generic definition if those register sets aren't
defined. That keeps things simple for "sane" targets.
Anyway, it's not a good idea to use the register set definition from
the acrhitecture vector for ptrace(2) anyway. On FreeBSD I can run
Linux binaries. But ptrace(2) still returns the registers in the
FreeBSD fromat for them (unless GDB itself is a Linux binary). So
using the Linux register set definitions would make things fail,
whereas using FreeBSD's register set format make it possible to debug
a Linux binary on FreeBSD :-). Similar things play a role when
debugging 32-bit code on a 64-bit platform such as amd64, but probably
also sparc64.
- 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.
Hmm. You certainly should define the architecture appropriately.
(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...)
While I have been hacking on gdbserver a bit to add FreeBSD support,
I'm not too familiar with the remote protocol :-(.
> 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.
It's pretty clear. If REGNUM is not -1, only that particular register
is transferred between the register cache and the buffer. If REGNUM
is -1, all registers (within the set) are transferred. When
collecting, this doesn't pay attention to the validity of the data.
> 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.
That's exactly what I'm aiming at :-). The "mapping" needs to be a
function though, since in some cases it might need to do some
arithmetic on the buffer contents in order to convert them to the
format used by GDB's register cache.
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?
Might be.
How does that sound? I'll implement it if folks like it. Open to
any/all suggestions.
I have to think about this a bit more...
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-08-25 22:35 ` Mark Kettenis
@ 2003-08-26 15:49 ` Andrew Cagney
2003-08-26 16:55 ` Daniel Jacobowitz
2003-08-29 20:20 ` Mark Kettenis
0 siblings, 2 replies; 27+ messages in thread
From: Andrew Cagney @ 2003-08-26 15:49 UTC (permalink / raw)
To: Mark Kettenis, drow; +Cc: gdb
> > * `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.
FYI, the table will definitly need to be generalized.
The i386 GNU/Linux (glibc and the kernel collued on this one :-)
PTRACE_GET_THREAD_AREA is really an additional register set and should
be implemented as such.
(oh, must remember to expand "unsigned long int desc[3]" to 4 words).
> That's quite true. It's probably a better idea to have the
> possibility of defining register sets for these particular purpose,
> falling back on a generic definition if those register sets aren't
> defined. That keeps things simple for "sane" targets.
I did this for reggroups. If the architecture does nothing a ""sane""
register grouping is defined.
Otherwize, the architecture can override everthing.
> Anyway, it's not a good idea to use the register set definition from
> the acrhitecture vector for ptrace(2) anyway. On FreeBSD I can run
> Linux binaries. But ptrace(2) still returns the registers in the
> FreeBSD fromat for them (unless GDB itself is a Linux binary). So
> using the Linux register set definitions would make things fail,
> whereas using FreeBSD's register set format make it possible to debug
> a Linux binary on FreeBSD :-). Similar things play a role when
> debugging 32-bit code on a 64-bit platform such as amd64, but probably
> also sparc64.
Yes. Assume nothing.
> > 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.
>
> It's pretty clear. If REGNUM is not -1, only that particular register
> is transferred between the register cache and the buffer. If REGNUM
> is -1, all registers (within the set) are transferred. When
> collecting, this doesn't pay attention to the validity of the data.
FYI, given a request for REGNUM (>= 0) the code must supply at least
that register (but is free to supply others).
The fun starts when trying to interpret target_fetch_registers(-1). I
guess it really does fetch all register sets.
There's a more general problem here (JeffJ pointed it out to me). At
present "gcore" obtains the registers being saved using regcache
collect. Unfortunatly, there's a missing target_fetch_registers(-1)
call, and, as a consequence, the registers written out can be invalid
:-( There are several issues here: should "gcore" use regcache collect
directly (bypassing the register fetch mechanism); if not, should this
regset methods be parameterized with the function that should be used
when collecting the registers (see regcache_cooked_read_ftype)?
> > 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);
> > };
I think they should take a the size of the buffer as a parameter - trust
me here - my i386 x86-64 code kept overflowing buffers :-(
> > 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.
>
> That's exactly what I'm aiming at :-). The "mapping" needs to be a
> function though, since in some cases it might need to do some
> arithmetic on the buffer contents in order to convert them to the
> format used by GDB's register cache.
Yes. Functions will work better.
--
What's the relationship between the regset and the regcache? That is,
are the supply/collect methods going to be expected to work with fairly
arbitrary register caches or with just a single "unified" register cache?
This gets into a dangling question of how to best handle combinations of
ABI, ISA and OS. For instance, o32 run on IRIX 64 and where to best put
indirection:
- on the supply side as I did for x86-64 i386
- on the cooked->raw regcache side as MIPS currently kind of does
- on the frame side (where a dummy frame does the mapping)
However, the dangling question shouldn't get in the way of these changes.
--
Just a heads up, I intend making things more thread/frame friendly this
time round. This means that, at some point, you might find that what
was supply_register(regnum, buf) gets converted into
cache_supply_register (cache, regnum, buf). However, that's orthogonal,
just don't be suprized if it happens at some point.
> How does that sound? I'll implement it if folks like it. Open to
> any/all suggestions.
>
> I have to think about this a bit more...
Yes.
Need to figure out how to relate these regsets back to ptrace/proc
requests in some sort of generic way. Doing the same for remote would
hopefully then fall out.
enjoy,
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
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-08-29 20:20 ` Mark Kettenis
1 sibling, 2 replies; 27+ messages in thread
From: Daniel Jacobowitz @ 2003-08-26 16:55 UTC (permalink / raw)
To: gdb
On Tue, Aug 26, 2003 at 11:49:07AM -0400, Andrew Cagney wrote:
>
> > > * `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.
>
> FYI, the table will definitly need to be generalized.
>
> The i386 GNU/Linux (glibc and the kernel collued on this one :-)
> PTRACE_GET_THREAD_AREA is really an additional register set and should
> be implemented as such.
Oh, good point. We could also use a regset for the debug registers,
if we switch to managing them through the regcache - would make
thread-specific use of them a little simpler I expect.
> > > 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.
> >
> >It's pretty clear. If REGNUM is not -1, only that particular register
> >is transferred between the register cache and the buffer. If REGNUM
> >is -1, all registers (within the set) are transferred. When
> >collecting, this doesn't pay attention to the validity of the data.
>
> FYI, given a request for REGNUM (>= 0) the code must supply at least
> that register (but is free to supply others).
That's where I'd like things more clearly specified. The difference
between Mark's statement and Andrew's is whether the other register
data in the regset is considered precious, or is clobbered from the
copy in the regcache. I believe not all our architectures agree on
that now.
> The fun starts when trying to interpret target_fetch_registers(-1). I
> guess it really does fetch all register sets.
>
> There's a more general problem here (JeffJ pointed it out to me). At
> present "gcore" obtains the registers being saved using regcache
> collect. Unfortunatly, there's a missing target_fetch_registers(-1)
> call, and, as a consequence, the registers written out can be invalid
> :-( There are several issues here: should "gcore" use regcache collect
> directly (bypassing the register fetch mechanism); if not, should this
> regset methods be parameterized with the function that should be used
> when collecting the registers (see regcache_cooked_read_ftype)?
I've run into this problem also. There's a target_fetch_registers in
linux-proc.c with a FIXME; that's in the threaded case. In the
non-threaded case the call is missing. Personally, I believe that the
call shouldn't be necessary, and that fill_gregset should use the
collect mechanism (which implicitly calls fetch). But I'm not sure if
that will work.
In the meantime, shall I submit the additional target_fetch_registers
with the matching FIXME?
> > > 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.
> >
> >That's exactly what I'm aiming at :-). The "mapping" needs to be a
> >function though, since in some cases it might need to do some
> >arithmetic on the buffer contents in order to convert them to the
> >format used by GDB's register cache.
>
> Yes. Functions will work better.
OK. I'd like to add a function in common code which does the mapping
based on a table though, since for many cases that's enough - cuts down
on duplication. What do you think?
> > How does that sound? I'll implement it if folks like it. Open to
> > any/all suggestions.
> >
> >I have to think about this a bit more...
>
> Yes.
>
> Need to figure out how to relate these regsets back to ptrace/proc
> requests in some sort of generic way. Doing the same for remote would
> hopefully then fall out.
I'm not sure that it's possible to relate them back in any generic way;
ptrace is just too quirky. The closest I can picture is the way I did
it in gdbserver, which is really more of a common-code thing than a
generic-interface thing:
struct regset_info target_regsets[] = {
{ PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
GENERAL_REGS,
i386_fill_gregset, i386_store_gregset },
{ PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
FP_REGS,
i386_fill_fpregset, i386_store_fpregset },
{ 0, 0, -1, -1, NULL, NULL }
};
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-08-26 16:55 ` Daniel Jacobowitz
@ 2003-08-27 3:50 ` Andrew Cagney
2003-08-31 14:04 ` Mark Kettenis
1 sibling, 0 replies; 27+ messages in thread
From: Andrew Cagney @ 2003-08-27 3:50 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb
> FYI, given a request for REGNUM (>= 0) the code must supply at least
>> that register (but is free to supply others).
>
>
> That's where I'd like things more clearly specified. The difference
> between Mark's statement and Andrew's is whether the other register
> data in the regset is considered precious, or is clobbered from the
> copy in the regcache. I believe not all our architectures agree on
> that now.
Here data is moving moving from the regset buffer to the regcache. The
problems you mention don't occure.
> There's a more general problem here (JeffJ pointed it out to me). At
>> present "gcore" obtains the registers being saved using regcache
>> collect. Unfortunatly, there's a missing target_fetch_registers(-1)
>> call, and, as a consequence, the registers written out can be invalid
>> :-( There are several issues here: should "gcore" use regcache collect
>> directly (bypassing the register fetch mechanism); if not, should this
>> regset methods be parameterized with the function that should be used
>> when collecting the registers (see regcache_cooked_read_ftype)?
>
>
> I've run into this problem also. There's a target_fetch_registers in
> linux-proc.c with a FIXME; that's in the threaded case. In the
> non-threaded case the call is missing. Personally, I believe that the
> call shouldn't be necessary, and that fill_gregset should use the
> collect mechanism (which implicitly calls fetch). But I'm not sure if
> that will work.
I agree that the target_fetch_registers call shouldn't be needed. I
think the correct way to avoid it though is to have the "gcore" code
pull register values from the high (regcache_raw_read) and not the low
(collect_register) side of the regcache. That way the target gets a
chance to on-demand pull in the registers it needs.
> That's exactly what I'm aiming at :-). The "mapping" needs to be a
>> >function though, since in some cases it might need to do some
>> >arithmetic on the buffer contents in order to convert them to the
>> >format used by GDB's register cache.
>
>>
>> Yes. Functions will work better.
>
>
> OK. I'd like to add a function in common code which does the mapping
> based on a table though, since for many cases that's enough - cuts down
> on duplication. What do you think?
I think transforming something like:
> void
> mipsnbsd_supply_reg (char *regs, int regno)
> {
> int i;
>
> for (i = 0; i <= PC_REGNUM; i++)
> {
> if (regno == i || regno == -1)
> {
> if (CANNOT_FETCH_REGISTER (i))
> supply_register (i, NULL);
> else
> supply_register (i, regs + (i * MIPS_REGSIZE));
> }
> }
> }
into an equivalent function like:
> void
> mipsnbsd_xfer_reg (void *cache, int regno, void (xfer*) (void *cache,
int regnum, int offset))
> {
> int i;
>
> for (i = 0; i <= PC_REGNUM; i++)
> {
> if (regno == i || regno == -1)
> {
> if (CANNOT_FETCH_REGISTER (i))
> xfer (cache, i, -1);
> else
> xfer (cache, i, (i * MIPS_REGSIZE));
> }
> }
> }
is far lower risk and less complex then trying to replace this with a table.
The key thing to remember is that the code is write once, fix, forget.
Any duplication isn't an issue as, once working, it won't be touched.
> Yes.
>>
>> Need to figure out how to relate these regsets back to ptrace/proc
>> requests in some sort of generic way. Doing the same for remote would
>> hopefully then fall out.
>
>
> I'm not sure that it's possible to relate them back in any generic way;
> ptrace is just too quirky. The closest I can picture is the way I did
> it in gdbserver, which is really more of a common-code thing than a
> generic-interface thing:
>
> struct regset_info target_regsets[] = {
> { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
> GENERAL_REGS,
> i386_fill_gregset, i386_store_gregset },
> { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
> FP_REGS,
> i386_fill_fpregset, i386_store_fpregset },
> { 0, 0, -1, -1, NULL, NULL }
> };
Right. It needs a method to perform an arbitrary map from a REGNUM to a
regset descriptor vis:
REGNUM -> regset descriptor
But what does a regset descriptor consist of?
- the buffer <-> cache method[s]
- the ptrace number (is this constant for an OS?)
- the /proc field (is this constant for an OS?)
- the size of the buffer
Recall an earlier suggestion that GDB be given access to /proc in the
remote target? This would let GDB initiate remote ptrace and remote
/proc requests.
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-08-26 15:49 ` Andrew Cagney
2003-08-26 16:55 ` Daniel Jacobowitz
@ 2003-08-29 20:20 ` Mark Kettenis
1 sibling, 0 replies; 27+ messages in thread
From: Mark Kettenis @ 2003-08-29 20:20 UTC (permalink / raw)
To: ac131313; +Cc: drow, gdb
Date: Tue, 26 Aug 2003 11:49:07 -0400
From: Andrew Cagney <ac131313@redhat.com>
Just a heads up, I intend making things more thread/frame friendly this
time round. This means that, at some point, you might find that what
was supply_register(regnum, buf) gets converted into
cache_supply_register (cache, regnum, buf). However, that's orthogonal,
just don't be suprized if it happens at some point.
Somehow I skipped this bit of your mail, since this is exactly what I
did eralier today.
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
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 12:55 ` Daniel Jacobowitz
1 sibling, 2 replies; 27+ messages in thread
From: Mark Kettenis @ 2003-08-31 14:04 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb
Daniel Jacobowitz <drow@mvista.com> writes:
> On Tue, Aug 26, 2003 at 11:49:07AM -0400, Andrew Cagney wrote:
> > Need to figure out how to relate these regsets back to ptrace/proc
> > requests in some sort of generic way. Doing the same for remote would
> > hopefully then fall out.
>
> I'm not sure that it's possible to relate them back in any generic way;
> ptrace is just too quirky. The closest I can picture is the way I did
> it in gdbserver, which is really more of a common-code thing than a
> generic-interface thing:
>
> struct regset_info target_regsets[] = {
> { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
> GENERAL_REGS,
> i386_fill_gregset, i386_store_gregset },
> { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
> FP_REGS,
> i386_fill_fpregset, i386_store_fpregset },
> { 0, 0, -1, -1, NULL, NULL }
> };
I agree with Daniel here. Trying to have some sort of generic
interface for ptrace(2)/proc(4) isn't worth the trouble, since there
are too many quirks. We should still try to use common code where
appropriate though (I'm usually able to share the ptrace(2) code
between the various BSD's).
Daniel's post put me on the right track on what to do about core files
though. If we look at how BFD munges core files, we see that it puts
registers in sections. Generally speaking it puts the general-purpose
registers in a section named ".reg" and the floating-point registers
(if any, and if they're not included in ".reg") in ".reg2". On the
i386, the SSE registers end up in ".reg-xfp". Currently we have these
strings hard-coded into GDB and convert them to a number, which we
then use in the various fetch_core_registers functions to identify the
register. However, why do we need this extra conversion step? If we
just include the BFD sectionname in the definition of the register set
GDB will be able to match things up. That way, it's easy to add new
register sets if they arise.
I'm not going to make the necessary changes to GDB to recognize
section names instead of numbers right now. However, I'll propose an
interface that will make this possible in the future. For now, I'd
like to propose the following definition of a `struct regset':
struct regset
{
/* Section name for core files as used by BFD. */
const char *name;
void (*supply_regset)(struct gdbarch *, struct regcache *,
const void *, size_t, int);
void (*read_regset)(struct gdbarch *, struct regcache *,
void *, size_t, int);
};
The supply_regset function will be used to supply registers from a
core file to GDB's register cache. It's signature is as follows:
void supply_regset (struct gdbarch *gdbarch, struct regcache *regcache,
const void *regs, size_t len, int regnum);
Here, GDBARCH is the architecture of the core file, REGCACHE the
register cache to store the information, REGS the (raw) buffer
containing the registers in the OS/ABI-dependent format, LEN the size
of this buffer, and REGNUM the register to supply. The latter can be
-1 to indicate that all registers in REGS are to be supplied to the
register cache.
I think with those arguments, the function has all information
available that it will need. I hope it is clear why we need the
REGCACHE, REGS and REGNUM arguments. Let me explain why we need the
GDBARCH and LEN arguments.
Andrew already suggested we need the latter to avoid buffer overruns.
The supply_regset function should check whether the buffer has the
appropriate size. Having LEN as argument also makes it easier to
support different releases of an OS since sometimes extra registers
get included in a register set with a new OS release. We can't detect
simple layout changes that don't change the size though.
Including GDBARCH has its purpose too. There are several cases where
the architecture of the core file and the executable don't match, even
though the core file in question was generated by that particular
executable:
* When a Linux binary running on FreeBSD dumps core, it will produce
a FreeBSD core dump.
* When a 32-bit binary running on FreeBSD/amd64 or Linux x86-64 dumps
core, it will produce a 64-bit coredump.
Now, if we supply the GDBARCH associated with the core file
architecture to supply_regset, it can do something intelligent with
it. And yes, it is possible to detect this case since we can get the
architecture associated with the register cache from its `struct
regcache_descr'.
The read_regset function is necessary to support the `gcore' command.
It should use regcache_raw_read to fetch all relevant registers from
the running target, such that we don't need target_fetch_registers(-1)
first.
How does this sound?
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
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
1 sibling, 1 reply; 27+ messages in thread
From: Andrew Cagney @ 2003-09-02 18:40 UTC (permalink / raw)
To: Mark Kettenis; +Cc: Daniel Jacobowitz, gdb
> The read_regset function is necessary to support the `gcore' command.
> It should use regcache_raw_read to fetch all relevant registers from
> the running target, such that we don't need target_fetch_registers(-1)
> first.
GDB currently has a conflict here. GCORE should definitly use
regcache_raw_read, but that still leaves the ptrace code writing back
register values - it uses regcache_collect. Hmm, perhaphs it two should
be using a regcache_raw_read anyway - might even make it possible to
eliminate "target_prepare_to_store"?
I like the use of BFD's names.
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-08-31 14:04 ` Mark Kettenis
2003-09-02 18:40 ` Andrew Cagney
@ 2003-09-04 12:55 ` Daniel Jacobowitz
2003-09-04 14:00 ` Andrew Cagney
` (2 more replies)
1 sibling, 3 replies; 27+ messages in thread
From: Daniel Jacobowitz @ 2003-09-04 12:55 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb
Hi Mark,
[Sorry about the delay in responding - busy week.]
On Sun, Aug 31, 2003 at 04:03:52PM +0200, Mark Kettenis wrote:
> Daniel's post put me on the right track on what to do about core files
> though. If we look at how BFD munges core files, we see that it puts
> registers in sections. Generally speaking it puts the general-purpose
> registers in a section named ".reg" and the floating-point registers
> (if any, and if they're not included in ".reg") in ".reg2". On the
> i386, the SSE registers end up in ".reg-xfp". Currently we have these
> strings hard-coded into GDB and convert them to a number, which we
> then use in the various fetch_core_registers functions to identify the
> register. However, why do we need this extra conversion step? If we
> just include the BFD sectionname in the definition of the register set
> GDB will be able to match things up. That way, it's easy to add new
> register sets if they arise.
>
> I'm not going to make the necessary changes to GDB to recognize
> section names instead of numbers right now. However, I'll propose an
> interface that will make this possible in the future. For now, I'd
> like to propose the following definition of a `struct regset':
>
> struct regset
> {
> /* Section name for core files as used by BFD. */
> const char *name;
>
> void (*supply_regset)(struct gdbarch *, struct regcache *,
> const void *, size_t, int);
> void (*read_regset)(struct gdbarch *, struct regcache *,
> void *, size_t, int);
> };
Hmm, yes and no. That definition of regset is only useful for core
files; I would like something more generally useful, for remote and
native use. I also don't really like passing the core gdbarch around,
for the same reason. How about this instead?
struct regset
{
void (*supply_regset)(struct regcache *, const void *, size_t, int);
void (*read_regset)(struct regcache *, void *, size_t, int);
};
const struct regset *
core_section_to_regset (struct gdbarch *core_gdbarch,
const char *sec_name, size_t sec_size);
which would then allow:
const struct regset *
remote_name_to_regset (const char *name);
And perhaps some method to fetch the regset descriptor for each of the
named regsets used by libthread_db.
Otherwise, I like all the below very much.
> The supply_regset function will be used to supply registers from a
> core file to GDB's register cache. It's signature is as follows:
>
> void supply_regset (struct gdbarch *gdbarch, struct regcache *regcache,
> const void *regs, size_t len, int regnum);
>
> Here, GDBARCH is the architecture of the core file, REGCACHE the
> register cache to store the information, REGS the (raw) buffer
> containing the registers in the OS/ABI-dependent format, LEN the size
> of this buffer, and REGNUM the register to supply. The latter can be
> -1 to indicate that all registers in REGS are to be supplied to the
> register cache.
>
> I think with those arguments, the function has all information
> available that it will need. I hope it is clear why we need the
> REGCACHE, REGS and REGNUM arguments. Let me explain why we need the
> GDBARCH and LEN arguments.
>
> Andrew already suggested we need the latter to avoid buffer overruns.
> The supply_regset function should check whether the buffer has the
> appropriate size. Having LEN as argument also makes it easier to
> support different releases of an OS since sometimes extra registers
> get included in a register set with a new OS release. We can't detect
> simple layout changes that don't change the size though.
>
> Including GDBARCH has its purpose too. There are several cases where
> the architecture of the core file and the executable don't match, even
> though the core file in question was generated by that particular
> executable:
>
> * When a Linux binary running on FreeBSD dumps core, it will produce
> a FreeBSD core dump.
>
> * When a 32-bit binary running on FreeBSD/amd64 or Linux x86-64 dumps
> core, it will produce a 64-bit coredump.
>
> Now, if we supply the GDBARCH associated with the core file
> architecture to supply_regset, it can do something intelligent with
> it. And yes, it is possible to detect this case since we can get the
> architecture associated with the register cache from its `struct
> regcache_descr'.
>
> The read_regset function is necessary to support the `gcore' command.
> It should use regcache_raw_read to fetch all relevant registers from
> the running target, such that we don't need target_fetch_registers(-1)
> first.
>
> How does this sound?
>
> Mark
>
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 12:55 ` Daniel Jacobowitz
@ 2003-09-04 14:00 ` Andrew Cagney
2003-09-04 14:08 ` Daniel Jacobowitz
2003-09-04 21:58 ` Mark Kettenis
2003-09-06 0:02 ` Jim Blandy
2 siblings, 1 reply; 27+ messages in thread
From: Andrew Cagney @ 2003-09-04 14:00 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb
> Hmm, yes and no. That definition of regset is only useful for core
> files; I would like something more generally useful, for remote and
> native use. I also don't really like passing the core gdbarch around,
> for the same reason. How about this instead?
>
> struct regset
> {
> void (*supply_regset)(struct regcache *, const void *, size_t, int);
> void (*read_regset)(struct regcache *, void *, size_t, int);
> };
>
> const struct regset *
> core_section_to_regset (struct gdbarch *core_gdbarch,
> const char *sec_name, size_t sec_size);
>
> which would then allow:
>
> const struct regset *
> remote_name_to_regset (const char *name);
As far as I know, the required lookups are:
REGNUM -> REGSET
foreach REGSET
and not SETNAME -> REGSET. This is so that a request for a single
register, or all registers, can be directed to the correct regset. I
also think having remote and corefile adopt an identical naming schema
should make life easier.
As for the architecture, supply_regset needs this. It might, for
instance, be an x86-64 method supplying registers to an i386 register cache.
--
I should note that I do know of a second way of handling cross
architectures (x86-64 on i386 et.al.). Add a table of cross
architecture unwinders and then allow different frames to have different
architectures vis:
x86-64 frame
<x86-64 X i386>
i386 frame
i386 frame
<ia64 X i386>
ia64 frame
but that's getting way ahead of many other changes.
enjoy,
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 14:00 ` Andrew Cagney
@ 2003-09-04 14:08 ` Daniel Jacobowitz
2003-09-04 15:04 ` Andrew Cagney
2003-09-04 22:05 ` Mark Kettenis
0 siblings, 2 replies; 27+ messages in thread
From: Daniel Jacobowitz @ 2003-09-04 14:08 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Mark Kettenis, gdb
On Thu, Sep 04, 2003 at 10:00:39AM -0400, Andrew Cagney wrote:
>
> >Hmm, yes and no. That definition of regset is only useful for core
> >files; I would like something more generally useful, for remote and
> >native use. I also don't really like passing the core gdbarch around,
> >for the same reason. How about this instead?
> >
> >struct regset
> >{
> > void (*supply_regset)(struct regcache *, const void *, size_t, int);
> > void (*read_regset)(struct regcache *, void *, size_t, int);
> >};
> >
> >const struct regset *
> >core_section_to_regset (struct gdbarch *core_gdbarch,
> > const char *sec_name, size_t sec_size);
> >
> >which would then allow:
> >
> >const struct regset *
> >remote_name_to_regset (const char *name);
>
> As far as I know, the required lookups are:
> REGNUM -> REGSET
> foreach REGSET
> and not SETNAME -> REGSET. This is so that a request for a single
> register, or all registers, can be directed to the correct regset. I
> also think having remote and corefile adopt an identical naming schema
> should make life easier.
I'd really rather not enforce that - remote can provide regsets that
BFD doesn't know about, and the ".reg" names would look silly being
defined as part of the remote protocol. My instinct says that the
flexibility is worthwhile so that the two implementation details don't
become coupled.
I believe REGSET->SETNAME is necessary for the remote protocol approach
I described. Don't necessarily want to fetch all register sets, so we
need to figure out the name of the one we do want. You could implement
the core side with REGSET->SETNAME and foreach REGSET, but I think it's
more straightforward with SETNAME->REGSET.
Also, core_section_to_regset is more than just SETNAME->REGSET. It
considers the regset's size and core file's architecture, for reasons
Mark described.
> As for the architecture, supply_regset needs this. It might, for
> instance, be an x86-64 method supplying registers to an i386 register cache.
It needs the regcache's architecture, but I don't believe it needs any
other. The method will be defined for a particular regcache layout,
which incorporates all of the information it needs about the other
involved architecture. We could get the regcache's architecture from
the regcache, or pass it explicitly.
> I should note that I do know of a second way of handling cross
> architectures (x86-64 on i386 et.al.). Add a table of cross
> architecture unwinders and then allow different frames to have different
> architectures vis:
>
> x86-64 frame
> <x86-64 X i386>
> i386 frame
> i386 frame
> <ia64 X i386>
> ia64 frame
>
> but that's getting way ahead of many other changes.
Hmmm...
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
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:05 ` Mark Kettenis
1 sibling, 1 reply; 27+ messages in thread
From: Andrew Cagney @ 2003-09-04 15:04 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb
> On Thu, Sep 04, 2003 at 10:00:39AM -0400, Andrew Cagney wrote:
>
>>
>
>> >Hmm, yes and no. That definition of regset is only useful for core
>> >files; I would like something more generally useful, for remote and
>> >native use. I also don't really like passing the core gdbarch around,
>> >for the same reason. How about this instead?
>> >
>> >struct regset
>> >{
>> > void (*supply_regset)(struct regcache *, const void *, size_t, int);
>> > void (*read_regset)(struct regcache *, void *, size_t, int);
>> >};
>> >
>> >const struct regset *
>> >core_section_to_regset (struct gdbarch *core_gdbarch,
>> > const char *sec_name, size_t sec_size);
>> >
>> >which would then allow:
>> >
>> >const struct regset *
>> >remote_name_to_regset (const char *name);
>
>>
>> As far as I know, the required lookups are:
>> REGNUM -> REGSET
>> foreach REGSET
>> and not SETNAME -> REGSET. This is so that a request for a single
>> register, or all registers, can be directed to the correct regset. I
>> also think having remote and corefile adopt an identical naming schema
>> should make life easier.
>
>
> I'd really rather not enforce that - remote can provide regsets that
> BFD doesn't know about, and the ".reg" names would look silly being
> defined as part of the remote protocol. My instinct says that the
> flexibility is worthwhile so that the two implementation details don't
> become coupled.
It's best to delay adding generality until there is hard evidence
supporting its need.
The core file's "reg" layout is pretty much wired down - it lets GDB
adopt an existing standard. Also, passing the BFD regset name down to
the remote end makes for a very simple remote core file reader.
Finally, if the remote end has a regset missing from the core file, then
the core file spec needs to be extended to include it - cf
GET_THREAD_INFO on i386, or the system registers from a core.
The original remote code had this right (intentional or not I don't
know) - "G" transfered the general registers or the gregset.
Unfortunatly, at some point in the mid '90's GDB lost the plot. Instead
of adding other packets to fetch other regset's the G packet started
growing :-( Getting regset's back into the protocol would be a good idea.
> I believe REGSET->SETNAME is necessary for the remote protocol approach
> I described. Don't necessarily want to fetch all register sets, so we
> need to figure out the name of the one we do want. You could implement
> the core side with REGSET->SETNAME and foreach REGSET, but I think it's
> more straightforward with SETNAME->REGSET.
Um, did you mean REGNUM -> {SETNAME, REGSET}? It's the REGNUM that
determines what happens next. Otherwize I don't understand your point :-(
> Also, core_section_to_regset is more than just SETNAME->REGSET. It
> considers the regset's size and core file's architecture, for reasons
> Mark described.
Ah! So you're suggesting a table of regcache-arch X regset-arch? That
requirement isn't unique to core files. /proc ptrace and other
interfaces can also need such transformations.
>> As for the architecture, supply_regset needs this. It might, for
>> instance, be an x86-64 method supplying registers to an i386 register cache.
>
>
> It needs the regcache's architecture, but I don't believe it needs any
> other. The method will be defined for a particular regcache layout,
> which incorporates all of the information it needs about the other
> involved architecture. We could get the regcache's architecture from
> the regcache, or pass it explicitly.
That's the architecture mark was passing in. The alternative is a
larger table of regcache X regset maps.
>> I should note that I do know of a second way of handling cross
>> architectures (x86-64 on i386 et.al.). Add a table of cross
>> architecture unwinders and then allow different frames to have different
>> architectures vis:
>>
>> x86-64 frame
>> <x86-64 X i386>
>> i386 frame
>> i386 frame
>> <ia64 X i386>
>> ia64 frame
>>
>> but that's getting way ahead of many other changes.
Here the regcache and regset architecture would always match. Cross
architectures would be handled elsewhere.
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 15:04 ` Andrew Cagney
@ 2003-09-04 15:13 ` Daniel Jacobowitz
2003-09-04 22:07 ` Mark Kettenis
0 siblings, 1 reply; 27+ messages in thread
From: Daniel Jacobowitz @ 2003-09-04 15:13 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Mark Kettenis, gdb
On Thu, Sep 04, 2003 at 11:04:18AM -0400, Andrew Cagney wrote:
> >On Thu, Sep 04, 2003 at 10:00:39AM -0400, Andrew Cagney wrote:
> >
> >>
> >
> >>>Hmm, yes and no. That definition of regset is only useful for core
> >>>files; I would like something more generally useful, for remote and
> >>>native use. I also don't really like passing the core gdbarch around,
> >>>for the same reason. How about this instead?
> >>>
> >>>struct regset
> >>>{
> >>> void (*supply_regset)(struct regcache *, const void *, size_t, int);
> >>> void (*read_regset)(struct regcache *, void *, size_t, int);
> >>>};
> >>>
> >>>const struct regset *
> >>>core_section_to_regset (struct gdbarch *core_gdbarch,
> >>> const char *sec_name, size_t sec_size);
> >>>
> >>>which would then allow:
> >>>
> >>>const struct regset *
> >>>remote_name_to_regset (const char *name);
> >
> >>
> >>As far as I know, the required lookups are:
> >> REGNUM -> REGSET
> >> foreach REGSET
> >>and not SETNAME -> REGSET. This is so that a request for a single
> >>register, or all registers, can be directed to the correct regset. I
> >>also think having remote and corefile adopt an identical naming schema
> >>should make life easier.
> >
> >
> >I'd really rather not enforce that - remote can provide regsets that
> >BFD doesn't know about, and the ".reg" names would look silly being
> >defined as part of the remote protocol. My instinct says that the
> >flexibility is worthwhile so that the two implementation details don't
> >become coupled.
>
> It's best to delay adding generality until there is hard evidence
> supporting its need.
>
> The core file's "reg" layout is pretty much wired down - it lets GDB
> adopt an existing standard. Also, passing the BFD regset name down to
> the remote end makes for a very simple remote core file reader.
> Finally, if the remote end has a regset missing from the core file, then
> the core file spec needs to be extended to include it - cf
> GET_THREAD_INFO on i386, or the system registers from a core.
I don't know.
For core files, we have a BFD architecture to use to determine what the
name ".reg-xfp" means. For remote targets we don't have an equivalent.
It seems to me that the simplest way to handle this is to give them
distinct names. I'd rather not require synchronizing this with BFD,
which isn't really designed to do this.
> The original remote code had this right (intentional or not I don't
> know) - "G" transfered the general registers or the gregset.
> Unfortunatly, at some point in the mid '90's GDB lost the plot. Instead
> of adding other packets to fetch other regset's the G packet started
> growing :-( Getting regset's back into the protocol would be a good idea.
Yes, 100% agree.
> >I believe REGSET->SETNAME is necessary for the remote protocol approach
> >I described. Don't necessarily want to fetch all register sets, so we
> >need to figure out the name of the one we do want. You could implement
> >the core side with REGSET->SETNAME and foreach REGSET, but I think it's
> >more straightforward with SETNAME->REGSET.
>
> Um, did you mean REGNUM -> {SETNAME, REGSET}? It's the REGNUM that
> determines what happens next. Otherwize I don't understand your point :-(
REGNUM -> {SETNAME, REGSET} would work, I suppose. This would have to
be a per-consumer mapping? We have defined G packets that are
different from defined core .reg sections.
> >Also, core_section_to_regset is more than just SETNAME->REGSET. It
> >considers the regset's size and core file's architecture, for reasons
> >Mark described.
>
> Ah! So you're suggesting a table of regcache-arch X regset-arch? That
> requirement isn't unique to core files. /proc ptrace and other
> interfaces can also need such transformations.
More or less, I suppose. The supply function would not be explicitly
parametrized with regset-arch, unless that turns out to be necessary
and possible, but it would be implicitly parametrized and the mapping
function would consider regset-arch in selecting the function. The
function would then supply registers in a way appropriate to the
regcache-arch.
> >>As for the architecture, supply_regset needs this. It might, for
> >>instance, be an x86-64 method supplying registers to an i386 register
> >>cache.
> >
> >
> >It needs the regcache's architecture, but I don't believe it needs any
> >other. The method will be defined for a particular regcache layout,
> >which incorporates all of the information it needs about the other
> >involved architecture. We could get the regcache's architecture from
> >the regcache, or pass it explicitly.
>
> That's the architecture mark was passing in. The alternative is a
> larger table of regcache X regset maps.
No, Mark was passing in the core's architecture != the regcache's
architecture.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-02 18:40 ` Andrew Cagney
@ 2003-09-04 21:31 ` Mark Kettenis
0 siblings, 0 replies; 27+ messages in thread
From: Mark Kettenis @ 2003-09-04 21:31 UTC (permalink / raw)
To: ac131313; +Cc: drow, gdb
Date: Tue, 02 Sep 2003 14:40:28 -0400
From: Andrew Cagney <ac131313@redhat.com>
> The read_regset function is necessary to support the `gcore' command.
> It should use regcache_raw_read to fetch all relevant registers from
> the running target, such that we don't need target_fetch_registers(-1)
> first.
GDB currently has a conflict here. GCORE should definitly use
regcache_raw_read, but that still leaves the ptrace code writing back
register values - it uses regcache_collect. Hmm, perhaphs it two should
be using a regcache_raw_read anyway - might even make it possible to
eliminate "target_prepare_to_store"?
We've said in the past that we the register cache is a write-through
cache. Not all of our targets treat it exactly like that, however,
for the ones that do (and all of them really should), it shouldn't
make a difference whether we use regcache_raw_collect or
regcache_raw_read. If we're storing a single register, that register
must be valid, and therefore won't trigger fetching any registers. If
we're storing all registers, we must have fetched them all before, and
they should all be valid too. That said, we should be able to
eliminate regcache_raw_collect in the future.
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 12:55 ` Daniel Jacobowitz
2003-09-04 14:00 ` Andrew Cagney
@ 2003-09-04 21:58 ` Mark Kettenis
2003-09-06 0:02 ` Jim Blandy
2 siblings, 0 replies; 27+ messages in thread
From: Mark Kettenis @ 2003-09-04 21:58 UTC (permalink / raw)
To: drow; +Cc: gdb
Date: Thu, 4 Sep 2003 08:55:15 -0400
From: Daniel Jacobowitz <drow@mvista.com>
Hi Mark,
[Sorry about the delay in responding - busy week.]
[Doesn't really matter. I've been away from home for most of the week.]
On Sun, Aug 31, 2003 at 04:03:52PM +0200, Mark Kettenis wrote:
> Daniel's post put me on the right track on what to do about core files
> though. If we look at how BFD munges core files, we see that it puts
> registers in sections. Generally speaking it puts the general-purpose
> registers in a section named ".reg" and the floating-point registers
> (if any, and if they're not included in ".reg") in ".reg2". On the
> i386, the SSE registers end up in ".reg-xfp". Currently we have these
> strings hard-coded into GDB and convert them to a number, which we
> then use in the various fetch_core_registers functions to identify the
> register. However, why do we need this extra conversion step? If we
> just include the BFD sectionname in the definition of the register set
> GDB will be able to match things up. That way, it's easy to add new
> register sets if they arise.
>
> I'm not going to make the necessary changes to GDB to recognize
> section names instead of numbers right now. However, I'll propose an
> interface that will make this possible in the future. For now, I'd
> like to propose the following definition of a `struct regset':
>
> struct regset
> {
> /* Section name for core files as used by BFD. */
> const char *name;
>
> void (*supply_regset)(struct gdbarch *, struct regcache *,
> const void *, size_t, int);
> void (*read_regset)(struct gdbarch *, struct regcache *,
> void *, size_t, int);
> };
Hmm, yes and no. That definition of regset is only useful for core
files; I would like something more generally useful, for remote and
native use. I also don't really like passing the core gdbarch around,
for the same reason. How about this instead?
struct regset
{
void (*supply_regset)(struct regcache *, const void *, size_t, int);
void (*read_regset)(struct regcache *, void *, size_t, int);
};
const struct regset *
core_section_to_regset (struct gdbarch *core_gdbarch,
const char *sec_name, size_t sec_size);
which would then allow:
const struct regset *
remote_name_to_regset (const char *name);
And perhaps some method to fetch the regset descriptor for each of the
named regsets used by libthread_db.
Otherwise, I like all the below very much.
Hmm, so you're proposing to drop the GDBARCH argument. You might be
right in that we don't need it. It's clear that its only useful in
the case where we're having what I'd call a cross-core situation,
i.e. when we're reading a corefile whose architecture doesn't match
the architecture of the executable, but that was nevertheless produced
by running that executable. Let's take as an example a FreeBSD/amd64
corefile produced by a FreeBSD/i386 executable.
My idea was to invoke the supply_regset method from the FreeBSD/i386
architecture. This method can only make sense out of the data if we
somehow tell it that it was really generated by FreeBSD/amd64, since
that can't be inferred from the REGCACHE. Hence the GDBARCH argument.
The alternative is to invoke the supply_regset method from the
FreeBSD/amd64 architecture. This method can infer that it is
supplying data to a FreeBSD/i386 target since it can get the proper
architecture from the REGCACHE. Therefore it doesn't need the GDBARCH
argument.
I think that the alternative is actually more correct. Let's consider
the case where we have a FreeBSD/i386 corefile produced by a
Linux/i386 executable running (crashing) on FreeBSD. In the first
case we'd have to teach the Linux architecture about reading FreeBSD
core files, which doesn't make sense, since you can't run FreeBSD
stuff on Linux AFAIK. The alternative implies we'd have to teach the
FreeBSD architecture about Linux's register cache, which makes a lot
more sense since we know that we can run Linux executables on FreeBSD.
I like your core_section_to_regset function too. That's the function
we should add to the architecture function.
I'm a bit agnostic about the remote_name_to_regset, since I can't see
the context in which it would be used. A method for fetching regsets
for the libthread_db case makes sense though. The great thing about
your function-interface is that it makes it very easy to re-use the
register set definitions if the definitions (core-file, remote,
libthread_db) are similar enough.
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 14:08 ` Daniel Jacobowitz
2003-09-04 15:04 ` Andrew Cagney
@ 2003-09-04 22:05 ` Mark Kettenis
2003-09-04 22:16 ` Andrew Cagney
2003-09-04 22:59 ` Andrew Cagney
1 sibling, 2 replies; 27+ messages in thread
From: Mark Kettenis @ 2003-09-04 22:05 UTC (permalink / raw)
To: drow; +Cc: ac131313, gdb
Date: Thu, 4 Sep 2003 10:08:23 -0400
From: Daniel Jacobowitz <drow@mvista.com>
On Thu, Sep 04, 2003 at 10:00:39AM -0400, Andrew Cagney wrote:
>
> >Hmm, yes and no. That definition of regset is only useful for core
> >files; I would like something more generally useful, for remote and
> >native use. I also don't really like passing the core gdbarch around,
> >for the same reason. How about this instead?
> >
> >struct regset
> >{
> > void (*supply_regset)(struct regcache *, const void *, size_t, int);
> > void (*read_regset)(struct regcache *, void *, size_t, int);
> >};
> >
> >const struct regset *
> >core_section_to_regset (struct gdbarch *core_gdbarch,
> > const char *sec_name, size_t sec_size);
> >
> >which would then allow:
> >
> >const struct regset *
> >remote_name_to_regset (const char *name);
>
> As far as I know, the required lookups are:
> REGNUM -> REGSET
> foreach REGSET
> and not SETNAME -> REGSET. This is so that a request for a single
> register, or all registers, can be directed to the correct regset. I
> also think having remote and corefile adopt an identical naming schema
> should make life easier.
I'd really rather not enforce that - remote can provide regsets that
BFD doesn't know about, and the ".reg" names would look silly being
defined as part of the remote protocol. My instinct says that the
flexibility is worthwhile so that the two implementation details don't
become coupled.
I'm with Daniel here. For most OS'es the corefile format isn't under
our control, and some of these formats simply don't make too much
sense. We shouldn't be forced to use those in the remote protocol.
And I don't think BFD should do a transformation on the corefile data
when it turns the register data into a section.
> As for the architecture, supply_regset needs this. It might, for
> instance, be an x86-64 method supplying registers to an i386 register cache.
It needs the regcache's architecture, but I don't believe it needs any
other. The method will be defined for a particular regcache layout,
which incorporates all of the information it needs about the other
involved architecture. We could get the regcache's architecture from
the regcache, or pass it explicitly.
See my reply to Daniels message earlier in this thread. Oh, and I do
think we should get the GDBARCH from the REGCACHE. We already can do
this for a frame so it makes sense to do it for a register cache too.
It's straightforward and I'll implement it this weekend.
> I should note that I do know of a second way of handling cross
> architectures (x86-64 on i386 et.al.). Add a table of cross
> architecture unwinders and then allow different frames to have different
> architectures vis:
>
> x86-64 frame
> <x86-64 X i386>
> i386 frame
> i386 frame
> <ia64 X i386>
> ia64 frame
>
> but that's getting way ahead of many other changes.
A cross unwinder here would be a method that converts say an amd64
register cache into an i386 register cache (among other things)?
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 15:13 ` Daniel Jacobowitz
@ 2003-09-04 22:07 ` Mark Kettenis
0 siblings, 0 replies; 27+ messages in thread
From: Mark Kettenis @ 2003-09-04 22:07 UTC (permalink / raw)
To: drow; +Cc: ac131313, gdb
Date: Thu, 4 Sep 2003 11:13:39 -0400
From: Daniel Jacobowitz <drow@mvista.com>
> >>As for the architecture, supply_regset needs this. It might, for
> >>instance, be an x86-64 method supplying registers to an i386 register
> >>cache.
> >
> >
> >It needs the regcache's architecture, but I don't believe it needs any
> >other. The method will be defined for a particular regcache layout,
> >which incorporates all of the information it needs about the other
> >involved architecture. We could get the regcache's architecture from
> >the regcache, or pass it explicitly.
>
> That's the architecture mark was passing in. The alternative is a
> larger table of regcache X regset maps.
No, Mark was passing in the core's architecture != the regcache's
architecture.
Indeed I was, and it's the wrong thing to do.
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 22:05 ` Mark Kettenis
@ 2003-09-04 22:16 ` Andrew Cagney
2003-09-04 22:59 ` Andrew Cagney
1 sibling, 0 replies; 27+ messages in thread
From: Andrew Cagney @ 2003-09-04 22:16 UTC (permalink / raw)
To: Mark Kettenis; +Cc: drow, gdb
> > I should note that I do know of a second way of handling cross
> > architectures (x86-64 on i386 et.al.). Add a table of cross
> > architecture unwinders and then allow different frames to have different
> > architectures vis:
> >
> > x86-64 frame
> > <x86-64 X i386>
> > i386 frame
> > i386 frame
> > <ia64 X i386>
> > ia64 frame
> >
> > but that's getting way ahead of many other changes.
>
> A cross unwinder here would be a method that converts say an amd64
> register cache into an i386 register cache (among other things)?
Yes, but it would do the conversion at the frame level.
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
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
1 sibling, 1 reply; 27+ messages in thread
From: Andrew Cagney @ 2003-09-04 22:59 UTC (permalink / raw)
To: Mark Kettenis; +Cc: drow, gdb
> I'd really rather not enforce that - remote can provide regsets that
> BFD doesn't know about, and the ".reg" names would look silly being
> defined as part of the remote protocol. My instinct says that the
> flexibility is worthwhile so that the two implementation details don't
> become coupled.
>
> I'm with Daniel here. For most OS'es the corefile format isn't under
> our control, and some of these formats simply don't make too much
> sense. We shouldn't be forced to use those in the remote protocol.
> And I don't think BFD should do a transformation on the corefile data
> when it turns the register data into a section.
... but here there is no suggestion that BFD should transform the
corefile data when it is turned into register data, in fact the oposite
is true. The intent is for just GDB to know how to pack/unpack these
regsets and then have BFD, proc, ptrace and the remote target all xfer
uninterpreted bytes. The natural format for those uninterpreted bytes
is what ever is specified by the system being debugged.
This would let gdbserver thin down to the point where it only needed to
know how to xfer those raw bytes - no need to repack them into a
standard G packet.
Of course a heavy weight gdbserver could also use this regset code to
repack bits into G and other packets before shipping them back to GDB.
> > As for the architecture, supply_regset needs this. It might, for
> > instance, be an x86-64 method supplying registers to an i386 register cache.
>
> It needs the regcache's architecture, but I don't believe it needs any
> other. The method will be defined for a particular regcache layout,
> which incorporates all of the information it needs about the other
> involved architecture. We could get the regcache's architecture from
> the regcache, or pass it explicitly.
>
> See my reply to Daniels message earlier in this thread. Oh, and I do
> think we should get the GDBARCH from the REGCACHE. We already can do
> this for a frame so it makes sense to do it for a register cache too.
> It's straightforward and I'll implement it this weekend.
right (so my miss reading was correct :-)
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 22:59 ` Andrew Cagney
@ 2003-09-05 23:15 ` Daniel Jacobowitz
2003-09-09 4:21 ` Andrew Cagney
0 siblings, 1 reply; 27+ messages in thread
From: Daniel Jacobowitz @ 2003-09-05 23:15 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Mark Kettenis, gdb
On Thu, Sep 04, 2003 at 06:59:06PM -0400, Andrew Cagney wrote:
>
> > I'd really rather not enforce that - remote can provide regsets that
> > BFD doesn't know about, and the ".reg" names would look silly being
> > defined as part of the remote protocol. My instinct says that the
> > flexibility is worthwhile so that the two implementation details don't
> > become coupled.
> >
> >I'm with Daniel here. For most OS'es the corefile format isn't under
> >our control, and some of these formats simply don't make too much
> >sense. We shouldn't be forced to use those in the remote protocol.
> >And I don't think BFD should do a transformation on the corefile data
> >when it turns the register data into a section.
>
> ... but here there is no suggestion that BFD should transform the
> corefile data when it is turned into register data, in fact the oposite
> is true. The intent is for just GDB to know how to pack/unpack these
> regsets and then have BFD, proc, ptrace and the remote target all xfer
> uninterpreted bytes. The natural format for those uninterpreted bytes
> is what ever is specified by the system being debugged.
Eh?
The remote protocol is fixed. The core file format is fixed. The
/proc output format is fixed. They aren't all the same, so I don't
see what this unity would accomplish - they have to be translated
around anyway.
> This would let gdbserver thin down to the point where it only needed to
> know how to xfer those raw bytes - no need to repack them into a
> standard G packet.
>
> Of course a heavy weight gdbserver could also use this regset code to
> repack bits into G and other packets before shipping them back to GDB.
The lighter-weight version isn't of much interest now - a number of
other issues have convinced me that lightening the stub further isn't
the way to go.
Things like kernel stubs have to convert anyway, since it's a whole
different format.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-04 12:55 ` Daniel Jacobowitz
2003-09-04 14:00 ` 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
2 siblings, 2 replies; 27+ messages in thread
From: Jim Blandy @ 2003-09-06 0:02 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb
Daniel Jacobowitz <drow@mvista.com> writes:
> struct regset
> {
> void (*supply_regset)(struct regcache *, const void *, size_t, int);
> void (*read_regset)(struct regcache *, void *, size_t, int);
> };
If you want to allow people to define regset formats via the CLI, it
seems to me you probably want some kind of closure argument in there,
like this:
struct regset
{
/* Always pass this to the supply_regset and read_regset
functions below as their first argument. */
void *closure;
void (*supply_regset)(void *closure,
struct regcache *, const void *, size_t, int);
void (*read_regset)(void *closure,
struct regcache *, void *, size_t, int);
};
This gives you the hook you need to have a single function for all
CLI-defined regsets, interpreting the layout the user supplies to the
CLI command.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-06 0:02 ` Jim Blandy
@ 2003-09-06 14:18 ` Mark Kettenis
2003-09-09 4:51 ` Andrew Cagney
1 sibling, 0 replies; 27+ messages in thread
From: Mark Kettenis @ 2003-09-06 14:18 UTC (permalink / raw)
To: jimb; +Cc: drow, gdb
From: Jim Blandy <jimb@redhat.com>
Date: 05 Sep 2003 19:01:34 -0500
Daniel Jacobowitz <drow@mvista.com> writes:
> struct regset
> {
> void (*supply_regset)(struct regcache *, const void *, size_t, int);
> void (*read_regset)(struct regcache *, void *, size_t, int);
> };
If you want to allow people to define regset formats via the CLI, it
seems to me you probably want some kind of closure argument in there,
like this:
struct regset
{
/* Always pass this to the supply_regset and read_regset
functions below as their first argument. */
void *closure;
void (*supply_regset)(void *closure,
struct regcache *, const void *, size_t, int);
void (*read_regset)(void *closure,
struct regcache *, void *, size_t, int);
};
This gives you the hook you need to have a single function for all
CLI-defined regsets, interpreting the layout the user supplies to the
CLI command.
Actually I need this closure argument for the corefile regset stuff
too. For the i386 I have a single supply_regset function for all the
different "gregsets", and I define a table with offsets that defines
rhe proper mapping in `struct gdbarch_tdep'. I could get at that
mapping since I was passing the architecture in, but that's just a
special case of the closure argument you propose.
Mark
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-05 23:15 ` Daniel Jacobowitz
@ 2003-09-09 4:21 ` Andrew Cagney
0 siblings, 0 replies; 27+ messages in thread
From: Andrew Cagney @ 2003-09-09 4:21 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb
> On Thu, Sep 04, 2003 at 06:59:06PM -0400, Andrew Cagney wrote:
>
>>
>
>> > I'd really rather not enforce that - remote can provide regsets that
>> > BFD doesn't know about, and the ".reg" names would look silly being
>> > defined as part of the remote protocol. My instinct says that the
>> > flexibility is worthwhile so that the two implementation details don't
>> > become coupled.
>> >
>> >I'm with Daniel here. For most OS'es the corefile format isn't under
>> >our control, and some of these formats simply don't make too much
>> >sense. We shouldn't be forced to use those in the remote protocol.
>> >And I don't think BFD should do a transformation on the corefile data
>> >when it turns the register data into a section.
>
>>
>> ... but here there is no suggestion that BFD should transform the
>> corefile data when it is turned into register data, in fact the oposite
>> is true. The intent is for just GDB to know how to pack/unpack these
>> regsets and then have BFD, proc, ptrace and the remote target all xfer
>> uninterpreted bytes. The natural format for those uninterpreted bytes
>> is what ever is specified by the system being debugged.
>
>
> Eh?
>
> The remote protocol is fixed. The core file format is fixed. The
> /proc output format is fixed. They aren't all the same, so I don't
> see what this unity would accomplish - they have to be translated
> around anyway.
I wrote:
> ... but here there is no suggestion that BFD should transform the
>> corefile data when it is turned into register data, in fact the oposite
>> is true. The intent is for just GDB to know how to pack/unpack these
>> regsets and then have BFD, proc, ptrace and the remote target all xfer
>> uninterpreted bytes. The natural format for those uninterpreted bytes
>> is what ever is specified by the system being debugged.
The translation would only need to be done once. As they say, keep it
simple.
>> This would let gdbserver thin down to the point where it only needed to
>> know how to xfer those raw bytes - no need to repack them into a
>> standard G packet.
>>
>> Of course a heavy weight gdbserver could also use this regset code to
>> repack bits into G and other packets before shipping them back to GDB.
>
>
> The lighter-weight version isn't of much interest now - a number of
> other issues have convinced me that lightening the stub further isn't
> the way to go.
The remote protocol has had a long standing conflict between two
different register abstractions:
- the G model - things are just a large raw buffer
- the P model - registers can be individually identified
Truth is, both can and should be accomodated:
- fat stubs that can chat to gdb in terms of specific register numbers
- thin stubs that can just transfer the raw buffer (or part there of)
Trying to select one over the other has been a mistake - they are both
correct and equally valid.
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
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
1 sibling, 1 reply; 27+ messages in thread
From: Andrew Cagney @ 2003-09-09 4:51 UTC (permalink / raw)
To: Jim Blandy; +Cc: Daniel Jacobowitz, Mark Kettenis, gdb
> Daniel Jacobowitz <drow@mvista.com> writes:
>
>> struct regset
>> {
>> void (*supply_regset)(struct regcache *, const void *, size_t, int);
>> void (*read_regset)(struct regcache *, void *, size_t, int);
>> };
>
>
> If you want to allow people to define regset formats via the CLI, it
> seems to me you probably want some kind of closure argument in there,
> like this:
>
> struct regset
> {
> /* Always pass this to the supply_regset and read_regset
> functions below as their first argument. */
> void *closure;
> void (*supply_regset)(void *closure,
> struct regcache *, const void *, size_t, int);
> void (*read_regset)(void *closure,
> struct regcache *, void *, size_t, int);
> };
>
> This gives you the hook you need to have a single function for all
> CLI-defined regsets, interpreting the layout the user supplies to the
> CLI command.
Er, this isn't a closure (at least not in the sense specified on bfd@).
Rather this is an object and so might as well be implemented in more
of an object style - pass the "struct regset" as the first parameter.
enjoy,
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-09 4:51 ` Andrew Cagney
@ 2003-09-09 17:15 ` Jim Blandy
2003-09-09 19:16 ` Andrew Cagney
0 siblings, 1 reply; 27+ messages in thread
From: Jim Blandy @ 2003-09-09 17:15 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Daniel Jacobowitz, Mark Kettenis, gdb
Andrew Cagney <ac131313@redhat.com> writes:
> > Daniel Jacobowitz <drow@mvista.com> writes:
> >
> >> struct regset
> >> {
> >> void (*supply_regset)(struct regcache *, const void *, size_t, int);
> >> void (*read_regset)(struct regcache *, void *, size_t, int);
> >> };
> > If you want to allow people to define regset formats via the CLI, it
> > seems to me you probably want some kind of closure argument in there,
> > like this:
> > struct regset
> > {
> > /* Always pass this to the supply_regset and read_regset
> > functions below as their first argument. */
> > void *closure;
> > void (*supply_regset)(void *closure,
> > struct regcache *, const void *, size_t, int);
> > void (*read_regset)(void *closure,
> > struct regcache *, void *, size_t, int);
> > };
> > This gives you the hook you need to have a single function for all
> > CLI-defined regsets, interpreting the layout the user supplies to the
> > CLI command.
>
> Er, this isn't a closure (at least not in the sense specified on
> bfd@). Rather this is an object and so might as well be implemented in
> more of an object style - pass the "struct regset" as the first
> parameter.
Not sure I think the distinction is too meaningful. You should
probably post a specific suggestion that shows what you're after.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC] Register sets
2003-09-09 17:15 ` Jim Blandy
@ 2003-09-09 19:16 ` Andrew Cagney
0 siblings, 0 replies; 27+ messages in thread
From: Andrew Cagney @ 2003-09-09 19:16 UTC (permalink / raw)
To: Jim Blandy; +Cc: Daniel Jacobowitz, Mark Kettenis, gdb
> Andrew Cagney <ac131313@redhat.com> writes:
>> Er, this isn't a closure (at least not in the sense specified on
>> bfd@). Rather this is an object and so might as well be implemented in
>> more of an object style - pass the "struct regset" as the first
>> parameter.
>
>
> Not sure I think the distinction is too meaningful.
Sorry, can you expand?
> You should
> probably post a specific suggestion that shows what you're after.
Take a quick glance at any one of GDB's objects (regcache, gdbarch,
reggroups, serial, ...) and the basic technique should be clear.
Andrew
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2003-09-09 19:16 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-23 22:50 [RFC] Register sets Mark Kettenis
2003-08-24 16:43 ` Daniel Jacobowitz
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox