Re: RFA: use constructor to build 'struct regset' objects

Jim Blandy
2004-05-17T21:32:00Z

Jim Blandy <jimb@redhat.com> writes:
> 2004-05-17 Jim Blandy <jimb@redhat.com>
>
> Use a constructor function to create regset structures.
> * regset.h (supply_regset_ftype): New typedef.
> (struct regset): Use supply_regset_ftype.
> (readonly_regset_xmalloc): New declaration.
> * regset.c: New file.
> * am64-tdep.c (amd64_regset_from_core_section): Use
> readonly_regset_xmalloc to construct regset structures.
> * amd64obsd-tdep.c (amd64obsd_regset_from_core_section): Same.
> * i386-tdep.c (i386_regset_from_core_section): Same.
> * i386nbsd-tdep.c (i386nbsd_aout_regset_from_core_section): Same.
> * i386obsd-tdep.c (i386obsd_aout_regset_from_core_section): Same.
> * sparc64fbsd-tdep.c (sparc64fbsd_init_abi): Same.
> * sparc64nbsd-tdep.c (sparc64nbsd_init_abi): Same.
> * sparc64obsd-tdep.c (sparc64obsd_init_abi): Same.
> * sparcnbsd-tdep.c (sparc32nbsd_init_abi): Same.
> * Makefile.in (COMMON_OBS): Add regset.o.
> (regset.o): New rule.

Sorry --- this needs more explanation.

At the moment, 'struct regset' contains a pointer to a function that
extracts register values from a register set in some target-specific
format, and stores them in a regcache. I'd like to extend 'struct
regset' to include a function pointer for going the other direction:
filling a target-specific register set structure with values from a
register cache.

This patch is a preliminary step for that: once we have a centralized
constructor function, we can add more function pointer fields to
'struct regset' and have them initialized properly without updating
every point that builds a target-specific regset structure. Code
calling 'readonly_regset_malloc' would get a regset with a 'fill'
function set to some value indicating "this regset does not support
filling". Then, targets could add filling functions as they get
around to it, calling a different constructor function expecting an
additional function pointer argument.

Having a regset writing function could be used for better gcore
support, but I'm immediately interested in using it to improve GDB's
thread support:

The libthread_db library provides functions for fetching and restoring
gregset and fpregset structures, as well as a user-defined catchall
structure referred to as the 'xregs' structure. GDB only uses the
gregset and fpregset functions at the moment, so registers that aren't
carried by either of those structures are inaccessible in multi-
threaded programs. For example, on my Linux system, GDB can't print
SSE registers in programs that use threads, but it can in programs
that are not linked against -lpthread. I have a test script for this,
which I'll submit in a bit.

I've got further patches for GDB that implement the xregs functions.
Also, since glibc's libthread_db doesn't implement the xregs functions
(why bother? GDB doesn't use them!), I've got a patch for that, too.
Everything checks (and produces) the appropriate error codes for
compatibility with older libthread_dbs that don't support the xregs
functions, so the GDB and glibc patches are independent of each other.

Then, I've got a patch that adds a gdbarch method that thread-db.c
and proc-service.c can call to find an xregset descriptor for the
current architecture (if it has one).

The final step is a patch that actually provides an xregset descriptor
for the E500, a PowerPC variant with 64-bit GPRS, but 32-bit gregset
entries. That's not a great reference implementation --- why isn't
E500 Linux's gregset big enough to actually hold its gprs? But
something similar would also solve the SSE case, in a more exemplary
fashion. I may write up a patch for that, but I haven't yet.

So, that's the story. What do people think?

Is 'readonly_regset_xmalloc' a good name, or would something like
'supplyonly_regset_malloc' be better? I mean, both 'supply' and
'fill' functions read one thing and write another; if you don't
already know the plot, it's not clear which direction a 'readonly'
regset would go.