* [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 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-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-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-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 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 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-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-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 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-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
* 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
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