This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: [RFC] Register sets
- From: Daniel Jacobowitz <drow at mvista dot com>
- To: Mark Kettenis <kettenis at chello dot nl>
- Cc: gdb at sources dot redhat dot com
- Date: Thu, 4 Sep 2003 08:55:15 -0400
- Subject: Re: [RFC] Register sets
- References: <200308232249.h7NMnvhh090154@elgar.kettenis.dyndns.org> <20030824164347.GA17520@nevyn.them.org> <200308252234.h7PMYqFu001245@elgar.kettenis.dyndns.org> <3F4B8173.1000302@redhat.com> <20030826165547.GA22836@nevyn.them.org> <86he3xrkjb.fsf@elgar.kettenis.dyndns.org>
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