From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28627 invoked by alias); 23 Aug 2003 22:50:15 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 28570 invoked from network); 23 Aug 2003 22:49:58 -0000 Received: from unknown (HELO walton.kettenis.dyndns.org) (213.93.115.144) by sources.redhat.com with SMTP; 23 Aug 2003 22:49:58 -0000 Received: from elgar.kettenis.dyndns.org (elgar.kettenis.dyndns.org [192.168.0.2]) by walton.kettenis.dyndns.org (8.12.6p2/8.12.5) with ESMTP id h7NMnv0j006485 for ; Sun, 24 Aug 2003 00:49:57 +0200 (CEST) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: from elgar.kettenis.dyndns.org (localhost [127.0.0.1]) by elgar.kettenis.dyndns.org (8.12.6p2/8.12.6) with ESMTP id h7NMnvSN090157 for ; Sun, 24 Aug 2003 00:49:57 +0200 (CEST) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: (from kettenis@localhost) by elgar.kettenis.dyndns.org (8.12.6p2/8.12.6/Submit) id h7NMnvhh090154; Sun, 24 Aug 2003 00:49:57 +0200 (CEST) Date: Sat, 23 Aug 2003 22:50:00 -0000 Message-Id: <200308232249.h7NMnvhh090154@elgar.kettenis.dyndns.org> From: Mark Kettenis To: gdb@sources.redhat.com Subject: [RFC] Register sets X-SW-Source: 2003-08/txt/msg00273.txt.bz2 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 _supply_ (struct regcache *regcache, const void *regs, int regnum); for supplying register REGNUM from register set REGS into the cache REGCACHE, and void _collect_ (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