From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17945 invoked by alias); 20 Dec 2001 18:33:53 -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 17922 invoked from network); 20 Dec 2001 18:33:48 -0000 Received: from unknown (HELO cygnus.com) (205.180.230.5) by sources.redhat.com with SMTP; 20 Dec 2001 18:33:48 -0000 Received: from rtl.cygnus.com (cse.cygnus.com [205.180.230.236]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id KAA06038; Thu, 20 Dec 2001 10:33:44 -0800 (PST) Received: (from ezannoni@localhost) by rtl.cygnus.com (8.11.2/8.11.0) id fBKHkcd02071; Thu, 20 Dec 2001 12:46:38 -0500 X-Authentication-Warning: localhost.localdomain: ezannoni set sender to ezannoni@cygnus.com using -f From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15394.9214.178652.70165@localhost.localdomain> Date: Thu, 20 Dec 2001 10:33:00 -0000 To: gdb-patches@sources.redhat.com CC: kevinb@cygnus.com Subject: [RFA] Define FETCH_INFERIOR_REGISTERS for ppc linux. X-Mailer: VM 7.00 under Emacs 20.7.1 X-SW-Source: 2001-12/txt/msg00527.txt.bz2 This patch is a subset of the changes initially submitted in: http://sources.redhat.com/ml/gdb-patches/2001-11/msg00548.html Nothing in this patch has to do with AltiVec registers. I included only the part that moves the fetch/store inferior registers machinery from infptrace.c to ppc-linux-nat.c. With that, it became possible to clean up some macros from config/powerpc/nm-linux.h and get rid of the use of core-aout.c. Given the discussions we had in the original thread, these changes become quite straightforward. Tested on ppc-linux native and aix4.3 (for paranoia's sake). OK? Elena 2001-12-20 Elena Zannoni * ppc-linux-nat.c (ppc_ptrace_cannot_fetch_store_register): New function. (fetch_register): New function. (fetch_ppc_registers): New function. (fetch_inferior_registers): New function. (store_register): New function. (store_ppc_registers): New function. (store_inferior_registers): New function. (ppc_register_u_addr): Eliminate ustart parameter and its uses. Make static. (PT_READ_U, PT_WRITE_U, PTRACE_XFER_TYPE): Define if needed. Include sys/ptrace.h. * config/powerpc/nm-linux.h (FETCH_INFERIOR_REGISTERS): Define. (U_REGS_OFFSET, REGISTER_U_ADDR): Delete. * config/powerpc/linux.mh (NATDEPFILES): Delete core-aout.o. Index: ppc-linux-nat.c =================================================================== RCS file: /cvs/uberbaum/gdb/ppc-linux-nat.c,v retrieving revision 1.12 diff -u -p -r1.12 ppc-linux-nat.c --- ppc-linux-nat.c 2001/12/09 21:39:53 1.12 +++ ppc-linux-nat.c 2001/12/20 17:42:04 @@ -32,11 +32,24 @@ #include #include #include +#include /* Prototypes for supply_gregset etc. */ #include "gregset.h" #include "ppc-tdep.h" +#ifndef PT_READ_U +#define PT_READ_U PTRACE_PEEKUSR +#endif +#ifndef PT_WRITE_U +#define PT_WRITE_U PTRACE_POKEUSR +#endif + +/* Default the type of the ptrace transfer to int. */ +#ifndef PTRACE_XFER_TYPE +#define PTRACE_XFER_TYPE int +#endif + int kernel_u_size (void) { @@ -57,38 +70,160 @@ PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, /* *INDENT_ON * */ int -ppc_register_u_addr (int ustart, int regno) +ppc_register_u_addr (int regno) { int u_addr = -1; /* General purpose registers occupy 1 slot each in the buffer */ if (regno >= gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum && regno <= gdbarch_tdep (current_gdbarch)->ppc_gplast_regnum ) - u_addr = (ustart + (PT_R0 + regno) * 4); + u_addr = ((PT_R0 + regno) * 4); /* Floating point regs: 2 slots each */ if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM) - u_addr = (ustart + (PT_FPR0 + (regno - FP0_REGNUM) * 2) * 4); + u_addr = ((PT_FPR0 + (regno - FP0_REGNUM) * 2) * 4); /* UISA special purpose registers: 1 slot each */ if (regno == PC_REGNUM) - u_addr = ustart + PT_NIP * 4; + u_addr = PT_NIP * 4; if (regno == gdbarch_tdep (current_gdbarch)->ppc_lr_regnum) - u_addr = ustart + PT_LNK * 4; + u_addr = PT_LNK * 4; if (regno == gdbarch_tdep (current_gdbarch)->ppc_cr_regnum) - u_addr = ustart + PT_CCR * 4; + u_addr = PT_CCR * 4; if (regno == gdbarch_tdep (current_gdbarch)->ppc_xer_regnum) - u_addr = ustart + PT_XER * 4; + u_addr = PT_XER * 4; if (regno == gdbarch_tdep (current_gdbarch)->ppc_ctr_regnum) - u_addr = ustart + PT_CTR * 4; + u_addr = PT_CTR * 4; if (regno == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) - u_addr = ustart + PT_MQ * 4; + u_addr = PT_MQ * 4; if (regno == gdbarch_tdep (current_gdbarch)->ppc_ps_regnum) - u_addr = ustart + PT_MSR * 4; + u_addr = PT_MSR * 4; return u_addr; } +static int +ppc_ptrace_cannot_fetch_store_register (int regno) +{ + return (ppc_register_u_addr (regno) == -1); +} + +static void +fetch_register (int regno) +{ + /* This isn't really an address. But ptrace thinks of it as one. */ + char mess[128]; /* For messages */ + register int i; + unsigned int offset; /* Offset of registers within the u area. */ + char *buf = alloca (MAX_REGISTER_RAW_SIZE); + int tid; + CORE_ADDR regaddr = ppc_register_u_addr (regno); + + if (regaddr == -1) + { + memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ + supply_register (regno, buf); + return; + } + + /* Overload thread id onto process id */ + if ((tid = TIDGET (inferior_ptid)) == 0) + tid = PIDGET (inferior_ptid); /* no thread id, just use process id */ + + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) + { + errno = 0; + *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid, + (PTRACE_ARG3_TYPE) regaddr, 0); + regaddr += sizeof (PTRACE_XFER_TYPE); + if (errno != 0) + { + sprintf (mess, "reading register %s (#%d)", + REGISTER_NAME (regno), regno); + perror_with_name (mess); + } + } + supply_register (regno, buf); +} + +static void +fetch_ppc_registers (void) +{ + int i; + int last_register = gdbarch_tdep (current_gdbarch)->ppc_mq_regnum; + + for (i = 0; i <= last_register; i++) + fetch_register (i); +} + +/* Fetch registers from the child process. Fetch all registers if + regno == -1, otherwise fetch all general registers or all floating + point registers depending upon the value of regno. */ +void +fetch_inferior_registers (int regno) +{ + if (regno == -1) + fetch_ppc_registers (); + else + fetch_register (regno); +} + +/* Store one register. */ +static void +store_register (int regno) +{ + /* This isn't really an address. But ptrace thinks of it as one. */ + CORE_ADDR regaddr = ppc_register_u_addr (regno); + char mess[128]; /* For messages */ + register int i; + unsigned int offset; /* Offset of registers within the u area. */ + int tid; + char *buf = alloca (MAX_REGISTER_RAW_SIZE); + + if (regaddr == -1) + { + return; + } + + /* Overload thread id onto process id */ + if ((tid = TIDGET (inferior_ptid)) == 0) + tid = PIDGET (inferior_ptid); /* no thread id, just use process id */ + + regcache_collect (regno, buf); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) + { + errno = 0; + ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr, + *(PTRACE_XFER_TYPE *) & buf[i]); + regaddr += sizeof (PTRACE_XFER_TYPE); + if (errno != 0) + { + sprintf (mess, "writing register %s (#%d)", + REGISTER_NAME (regno), regno); + perror_with_name (mess); + } + } +} + +static void +store_ppc_registers (void) +{ + int i; + int last_register = gdbarch_tdep (current_gdbarch)->ppc_mq_regnum; + + for (i = 0; i <= last_register; i++) + store_register (i); +} + +void +store_inferior_registers (int regno) +{ + if (regno >= 0) + store_register (regno); + else + store_ppc_registers (); +} + void supply_gregset (gdb_gregset_t *gregsetp) { @@ -111,7 +246,6 @@ supply_gregset (gdb_gregset_t *gregsetp) (char *) (regp + PT_MQ)); supply_register (gdbarch_tdep (current_gdbarch)->ppc_ps_regnum, (char *) (regp + PT_MSR)); - } Index: config/powerpc/linux.mh =================================================================== RCS file: /cvs/uberbaum/gdb/config/powerpc/linux.mh,v retrieving revision 1.6 diff -u -p -r1.6 linux.mh --- linux.mh 2000/10/30 22:33:32 1.6 +++ linux.mh 2001/12/20 17:42:05 @@ -6,7 +6,7 @@ XM_CLIBS= NAT_FILE= nm-linux.h NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \ -core-aout.o core-regset.o ppc-linux-nat.o proc-service.o thread-db.o lin-lwp.o +core-regset.o ppc-linux-nat.o proc-service.o thread-db.o lin-lwp.o LOADLIBES = -ldl -rdynamic Index: config/powerpc/nm-linux.h =================================================================== RCS file: /cvs/uberbaum/gdb/config/powerpc/nm-linux.h,v retrieving revision 1.9 diff -u -p -r1.9 nm-linux.h --- nm-linux.h 2001/11/20 16:36:44 1.9 +++ nm-linux.h 2001/12/20 17:42:05 @@ -28,10 +28,6 @@ Foundation, Inc., 675 Mass Ave, Cambridg #define KERNEL_U_SIZE kernel_u_size() extern int kernel_u_size (void); -#define U_REGS_OFFSET 0 - -extern int ppc_register_u_addr (int, int); -#define REGISTER_U_ADDR(addr, blockend, regno) \ - (addr) = ppc_register_u_addr ((blockend),(regno)); +#define FETCH_INFERIOR_REGISTERS #endif /* #ifndef NM_LINUX_H */