prgregset_t vs gdb_gregset_t on Linux: not the same!
Daniel Jacobowitz
dmj+@andrew.cmu.edu
Sat Jun 9 15:42:00 GMT 2001
On Sat, Jun 09, 2001 at 09:01:49PM +0200, Mark Kettenis wrote:
> Daniel Jacobowitz <dmj+@andrew.cmu.edu> writes:
>
> > On Fri, Jun 08, 2001 at 01:27:30PM -0700, Daniel Jacobowitz wrote:
> > > In proc-service.c, we call fill_gregset and supply_gregset with a
> > > prgregset_t cast to a gdb_gregset_t *. The problem is, they really are
> > > different. We can mostly get away with this, because in almost all cases
> > > glibc won't do anything with the gregset except pass it back to gdb again
> > > (if the process has terminated, it will memset something the size of a
> > > prgregset_t, though...).
> >
> > The matching question here is that core-regset.c's fetch_core_registers
> > calls supply_gregset with a gregset_t, but supply_gregset is prototyped
> > with a gdb_gregset_t. That doesn't work very well either.
>
> It's a mess. Linux should have three different regset types:
>
> * elf_gregset_t: The type used for register sets in ELF core dumps.
> Should be defined by <sys/procfs.h>.
>
> * prgregset_t: The type used for register sets in the
> <proc_service.h> debugging interface.
>
> * gregset_t: The type used for register sets in machine contexts.
> Should be defined in <sys/ucontext.h>.
>
> On many Linux ports the elf_gregset_t and gregset_t types differ, and
> apparently the MIPS port is one of them. The type prgregset_t is
> equivalent to one of them, but which one? To make matters worse
> <linux/elfcore.h> has a
>
> typedef elf_gregset_t gregset_t;
>
> which means that there might be two different types bearing the same
> name. Which type you get depends on what headers you include.
Right. Nothing in GDB that I can find and nothing in sys/, bits/, or
straight usr/include/ gets <linux/elfcore.h>, fortunately.
> The first thing you'll need to do is cleanup up the glibc headers for
> MIPS. The important headers are <sys/procfs.h>, <sys/ucontext.h> and
> <sys/user.h>. Avoid including Linux kernel headers and copy the few
> definitions that you really need. Avoid cross-includes. I cleaned up
> the i386 headers some time ago. Take a look at those to see what I
> mean.
The only two kernel headers we get right now in the relevant portions
are <asm/elf.h> and <asm/user.h>; asm/elf.h gives us the reasonable
definition of elf_gregset_t, and asm/user.h gives us struct user, which
gives us the offsets into an elf_gregset_t for particular registers.
> Then for GDB you need to make sure that gdb_gregset_t is equivalent to
> elf_gregset_t. The file config/nm-linux.h makes sure it is by
> defining GDB_GREGSET_T. You should include this file from
> config/mips/nm-linux (or whatever your native configuration header is
> called).
Yep, already got that.
> The proc-service.c module assumes that gdb_gregset_t and prgregset_t
> are equivalent types. Preferably, you should fix glibc such that that
> is the case. You might need to change the version of the
> libthread_db.so library if you're worried about backward compatibility.
Do you think I could get away with this? I can't (as much as I'm
tempted) change the actual gregset_t, since it is used in things like
ucontext_t. But since nothing uses a prgregset_t outside of thread_db,
that might be possible.
libc people? Is something like this reasonable for
sysdeps/unix/sysv/linux/mips/sys/procfs.h, possibly with a libthread_db
version bump (although since I doubt anything successfully uses
thread_db on mips yet...):
- typedef gregset_t prgregset_t;
- typedef fpregset_t prfpregset_t;
+ typedef elf_gregset_t prgregset_t;
+ typedef elf_fpregset_t prfpregset_t;
I notice that a lot of platforms have these two as separate types.
prgregset_t is elf_gregset_t: i386, hppa, s390, sparc
prgregset_t is gregset_t: powerpc, alpha, mips, ia64, and all others
(linux/sys/procfs.h - I guess that's m68k and sh)
Since we only use prgregset_t for thread_db, I think elf_gregset_t is
more appropriate. I don't entirely understand why gregset_t and
elf_gregset_t are different, though. What we really want to return
is what we get from ptrace, which seems to be closer to elf_gregset_t
on most platforms.
> We could add conversion routines for prgregset_t in GDB, but I'd like
> to avoid that.
I'm not sure we could, though - a prgegset_t is too small to hold what
we want to put in a gdb_gregset_t!
--
Daniel Jacobowitz Debian GNU/Linux Developer
Monta Vista Software Debian Security Team
More information about the Libc-alpha
mailing list