From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21158 invoked by alias); 24 Jan 2002 10:02:30 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 21116 invoked from network); 24 Jan 2002 10:02:27 -0000 Received: from unknown (HELO Cantor.suse.de) (213.95.15.193) by sources.redhat.com with SMTP; 24 Jan 2002 10:02:27 -0000 Received: from Hermes.suse.de (Hermes.suse.de [213.95.15.136]) by Cantor.suse.de (Postfix) with ESMTP id 6E9601E4F0; Thu, 24 Jan 2002 10:59:43 +0100 (MET) X-Authentication-Warning: sykes.suse.de: schwab set sender to schwab@suse.de using -f To: gdb-patches@sources.redhat.com Subject: Updates for m68k-linux target X-Yow: I have accepted Provolone into my life! From: Andreas Schwab Date: Thu, 24 Jan 2002 02:02:00 -0000 Message-ID: User-Agent: Gnus/5.090005 (Oort Gnus v0.05) Emacs/21.2.50 (ia64-suse-linux) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2002-01/txt/msg00720.txt.bz2 This patch updates the ptrace interface for the m68k-linux target. Ok to check in? Andreas. 2002-01-24 Andreas Schwab * config/m68k/tm-m68k.h (LAST_FPU_CTRL_REGNUM): Define. * m68klinux-nat.c: Fix ptrace interface for fetching/storing registers and add support for PTRACE_GETREGS. Index: src/gdb/config/m68k/tm-m68k.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/config/m68k/tm-m68k.h,v retrieving revision 1.8 diff -u -a -u -r1.8 src/gdb/config/m68k/tm-m68k.h --- src/gdb/config/m68k/tm-m68k.h 2002/01/05 04:30:34 1.8 +++ src/gdb/config/m68k/tm-m68k.h 2002/01/19 22:29:37 @@ -194,6 +194,7 @@ #define FPC_REGNUM 26 /* 68881 control register */ #define FPS_REGNUM 27 /* 68881 status register */ #define FPI_REGNUM 28 /* 68881 iaddr register */ +#define LAST_FPU_CTRL_REGNUM 28 =20 /* Store the address of the place in which to copy the structure the subroutine will return. This is called from call_function. */ Index: src/gdb/m68klinux-nat.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/m68klinux-nat.c,v retrieving revision 1.6 diff -u -a -u -r1.6 src/gdb/m68klinux-nat.c --- src/gdb/m68klinux-nat.c 2001/07/11 18:39:11 1.6 +++ src/gdb/m68klinux-nat.c 2002/01/19 22:27:53 @@ -32,11 +32,16 @@ #include #include #include +#include #include #include #include #include =20 +#ifdef HAVE_SYS_REG_H +#include +#endif + #include #include "gdb_stat.h" =20 @@ -57,6 +62,26 @@ 45, 46, 47 }; =20 +/* Which ptrace request retrieves which registers? + These apply to the corresponding SET requests as well. */ +#define NUM_GREGS (18) +#define MAX_NUM_REGS (NUM_GREGS + 11) +#define GETREGS_SUPPLIES(regno) \ + (0 <=3D (regno) && (regno) < NUM_GREGS) +#define GETFPREGS_SUPPLIES(regno) \ + (FP0_REGNUM <=3D (regno) && (regno) <=3D LAST_FPU_CTRL_REGNUM) + +/* Does the current host support the GETREGS request? */ +int have_ptrace_getregs =3D +#ifdef HAVE_PTRACE_GETREGS + 1 +#else + 0 +#endif +; + +=0C + /* BLOCKEND is the value of u.u_ar0, and points to the place where GS is stored. */ =20 @@ -87,32 +112,240 @@ void supply_gregset (elf_gregset_t *gregsetp) { + elf_greg_t *regp =3D (elf_greg_t *) gregsetp; int regi; =20 for (regi =3D D0_REGNUM; regi <=3D SP_REGNUM; regi++) - supply_register (regi, (char *) (*gregsetp + regmap[regi])); - supply_register (PS_REGNUM, (char *) (*gregsetp + PT_SR)); - supply_register (PC_REGNUM, (char *) (*gregsetp + PT_PC)); + supply_register (regi, (char *) ®p[regmap[regi]]); + supply_register (PS_REGNUM, (char *) ®p[PT_SR]); + supply_register (PC_REGNUM, (char *) ®p[PT_PC]); } + +/* Convert the valid general-purpose register values in GDB's register + array to `struct user' format and store them in *GREGSETP. The + array VALID indicates which register values are valid. If VALID is + NULL, all registers are assumed to be valid. */ =20 -/* Given a pointer to a floating point register set in /proc format - (fpregset_t *), unpack the register contents and supply them as gdb's - idea of the current floating point register values. */ +static void +convert_to_gregset (elf_gregset_t *gregsetp, char *valid) +{ + elf_greg_t *regp =3D (elf_greg_t *) gregsetp; + int regi; =20 + for (regi =3D 0; regi < NUM_GREGS; regi++) + if (! valid || valid[regi]) + regp[regmap[regi]] =3D *(int *) ®isters[REGISTER_BYTE (regi)]; +} + +/* Fill register REGNO (if it is a general-purpose register) in + *GREGSETPS with the value in GDB's register array. If REGNO is -1, + do this for all registers. */ void +fill_gregset (elf_gregset_t *gregsetp, int regno) +{ + if (regno =3D=3D -1) + { + convert_to_gregset (gregsetp, NULL); + return; + } + + if (GETREGS_SUPPLIES (regno)) + { + char valid[NUM_GREGS]; + + memset (valid, 0, sizeof (valid)); + valid[regno] =3D 1; + + convert_to_gregset (gregsetp, valid); + } +} + +#ifdef HAVE_PTRACE_GETREGS + +/* Fetch all general-purpose registers from process/thread TID and + store their values in GDB's register array. */ + +static void +fetch_regs (int tid) +{ + elf_gregset_t regs; + int ret; + + ret =3D ptrace (PTRACE_GETREGS, tid, 0, (int) ®s); + if (ret < 0) + { + if (errno =3D=3D EIO) + { + /* The kernel we're running on doesn't support the GETREGS + request. Reset `have_ptrace_getregs'. */ + have_ptrace_getregs =3D 0; + return; + } + + warning ("Couldn't get registers."); + return; + } + + supply_gregset (®s); +} + +/* Store all valid general-purpose registers in GDB's register array + into the process/thread specified by TID. */ + +static void +store_regs (int tid) +{ + elf_gregset_t regs; + int ret; + + ret =3D ptrace (PTRACE_GETREGS, tid, 0, (int) ®s); + if (ret < 0) + { + warning ("Couldn't get registers."); + return; + } + + convert_to_gregset (®s, register_valid); + + ret =3D ptrace (PTRACE_SETREGS, tid, 0, (int) ®s); + if (ret < 0) + { + warning ("Couldn't write registers."); + return; + } +} + +#else + +static void fetch_regs (int tid) {} +static void store_regs (int tid) {} + +#endif + +=0C +/* Transfering floating-point registers between GDB, inferiors and cores. = */ + +/* What is the address of fpN within the floating-point register set F? */ +#define FPREG_ADDR(f, n) ((char *) &(f)->fpregs[(n) * 3]) + +/* Fill GDB's register array with the floating-point register values in + *FPREGSETP. */ + +void supply_fpregset (elf_fpregset_t *fpregsetp) { int regi; =20 for (regi =3D FP0_REGNUM; regi < FPC_REGNUM; regi++) - supply_register (regi, (char *) &fpregsetp->fpregs[(regi - FP0_REGNUM)= * 3]); + supply_register (regi, FPREG_ADDR (fpregsetp, regi - FP0_REGNUM)); supply_register (FPC_REGNUM, (char *) &fpregsetp->fpcntl[0]); supply_register (FPS_REGNUM, (char *) &fpregsetp->fpcntl[1]); supply_register (FPI_REGNUM, (char *) &fpregsetp->fpcntl[2]); } =20 +/* Convert the valid floating-point register values in GDB's register + array to `struct user' format and store them in *FPREGSETP. The + array VALID indicates which register values are valid. If VALID is + NULL, all registers are assumed to be valid. */ + +static void +convert_to_fpregset (elf_fpregset_t *fpregsetp, char *valid) +{ + int reg; + + /* Fill in the floating-point registers. */ + for (reg =3D 0; reg < 8; reg++) + if (!valid || valid[FP0_REGNUM + reg]) + memcpy (FPREG_ADDR (fpregsetp, reg), + ®isters[REGISTER_BYTE (FP0_REGNUM + reg)], + REGISTER_RAW_SIZE(FP0_REGNUM + reg)); + + /* Fill in the floating-point control registers. */ + for (reg =3D 0; reg < 3; reg++) + if (!valid || valid[FPC_REGNUM + reg]) + fpregsetp->fpcntl[reg] + =3D *(int *) ®isters[REGISTER_BYTE (FPC_REGNUM + reg)]; +} + +/* Fill register REGNO (if it is a floating-point register) in + *FPREGSETP with the value in GDB's register array. If REGNO is -1, + do this for all registers. */ + +void +fill_fpregset (elf_fpregset_t *fpregsetp, int regno) +{ + if (regno =3D=3D -1) + { + convert_to_fpregset (fpregsetp, NULL); + return; + } + + if (GETFPREGS_SUPPLIES (regno)) + { + char valid[MAX_NUM_REGS]; +=20=20=20=20=20=20 + memset (valid, 0, sizeof (valid)); + valid[regno] =3D 1; +=09=20=20=20=20=20=20 + convert_to_fpregset (fpregsetp, valid); + } +} + +#ifdef HAVE_PTRACE_GETREGS + +/* Fetch all floating-point registers from process/thread TID and store + thier values in GDB's register array. */ + +static void +fetch_fpregs (int tid) +{ + elf_fpregset_t fpregs; + int ret; + + ret =3D ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs); + if (ret < 0) + { + warning ("Couldn't get floating point status."); + return; + } + + supply_fpregset (&fpregs); +} + +/* Store all valid floating-point registers in GDB's register array + into the process/thread specified by TID. */ + +static void +store_fpregs (int tid) +{ + elf_fpregset_t fpregs; + int ret; + + ret =3D ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs); + if (ret < 0) + { + warning ("Couldn't get floating point status."); + return; + } + + convert_to_fpregset (&fpregs, register_valid); + + ret =3D ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs); + if (ret < 0) + { + warning ("Couldn't write floating point status."); + return; + } +} + +#else + +static void fetch_fpregs (int tid) {} +static void store_fpregs (int tid) {} + #endif =20 +#endif =0C /* Interpreting register set info found in core files. */ =20 --=20 Andreas Schwab, SuSE Labs, schwab@suse.de SuSE GmbH, Deutschherrnstr. 15-19, D-90429 N=FCrnberg Key fingerprint =3D 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."