diff options
author | K. Richard Pixley <rich@cygnus> | 1992-10-21 04:57:35 +0000 |
---|---|---|
committer | K. Richard Pixley <rich@cygnus> | 1992-10-21 04:57:35 +0000 |
commit | ca0487229b98f00278971ed0fda7bb258091bbd9 (patch) | |
tree | 0c0623d584a96c35d8a31ca2c210c1c32c0d0285 /gdb | |
parent | 6142210d1d7bcfafaa2a31327b97a354024719c1 (diff) | |
download | gdb-ca0487229b98f00278971ed0fda7bb258091bbd9.zip gdb-ca0487229b98f00278971ed0fda7bb258091bbd9.tar.gz gdb-ca0487229b98f00278971ed0fda7bb258091bbd9.tar.bz2 |
hppa native support
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/.Sanitize | 6 | ||||
-rw-r--r-- | gdb/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/config/hppabsd.mh | 4 | ||||
-rw-r--r-- | gdb/config/hppabsd.mt | 2 | ||||
-rw-r--r-- | gdb/config/hppahpux.mh | 4 | ||||
-rw-r--r-- | gdb/config/hppahpux.mt | 2 | ||||
-rw-r--r-- | gdb/doc/gdbint.texinfo | 4 | ||||
-rw-r--r-- | gdb/hppab-nat.c | 395 | ||||
-rw-r--r-- | gdb/hppab-tdep.c | 1 | ||||
-rw-r--r-- | gdb/hppah-nat.c | 397 | ||||
-rw-r--r-- | gdb/hppah-tdep.c | 1 | ||||
-rw-r--r-- | gdb/nm-hppab.h | 25 | ||||
-rw-r--r-- | gdb/nm-hppah.h | 24 | ||||
-rw-r--r-- | gdb/xm-hppab.h | 6 | ||||
-rw-r--r-- | gdb/xm-hppah.h | 6 |
16 files changed, 875 insertions, 21 deletions
diff --git a/gdb/.Sanitize b/gdb/.Sanitize index 6025169..3079abd 100644 --- a/gdb/.Sanitize +++ b/gdb/.Sanitize @@ -98,10 +98,10 @@ h8300-tdep.c hp300ux-xdep.c hppa-pinsn.c hppab-core.c +hppab-nat.c hppab-tdep.c -hppab-xdep.c +hppah-nat.c hppah-tdep.c -hppah-xdep.c i386-pinsn.c i386-stub.c i386-tdep.c @@ -145,6 +145,8 @@ news-xdep.c nindy-share nindy-tdep.c nm-delta88.h +nm-hppab.h +nm-hppah.h nm-i386bsd.h nm-i386mach.h nm-i386v.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a6a983b..e8fdb1b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +Tue Oct 20 21:32:18 1992 K. Richard Pixley (rich@sendai.cygnus.com) + + hppa native support (untested). + + * config/hppahpux.mh, config/hppabsd.mh (XDEPFILES): now empty. + (NAT_FILE, NATDEPFILES): new macros. + * config/hppabsd.mt (TDEPFILES): removed exec.o and hppab-core.o. + * config/hppahpux.mt (TDEPFILES): removed exec.o. + * xm-hppa[bh].h (REGISTER_U_ADDR, U_REGS_OFFSET): removed. + * nm-hppa[bh].h, hppa[bh]-nat.c: new files. + * hppa[bh]-xdep.c: removed. + * hppa[bh]h-tdep.c: do not include ptrace.h. + * Makefile.in (HFILES): added nm-hppa[bh].h. + + * doc/gdbint.texinfo: add PUSH_DUMMY_FRAME, POP_FRAME. + Tue Oct 20 00:01:46 1992 Stu Grossman (grossman at cygnus.com) * mips-nat.c: Straighten out include files. Work around diff --git a/gdb/Makefile.in b/gdb/Makefile.in index b514f7e..a4f15cc 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -255,7 +255,8 @@ HFILES= breakpoint.h buildsym.h call-cmds.h command.h defs.h \ xm-m68k.h xm-sparc.h xm-sysv4.h xm-vax.h \ nm-i386bsd.h nm-i386mach.h nm-i386v.h nm-i386v4.h nm-irix3.h \ nm-irix4.h nm-linux.h nm-m88k.h nm-mips.h nm-news.h nm-rs6000.h \ - nm-sun2.h nm-sun3.h nm-sun386.h nm-sun4os4.h nm-trash.h nm-ultra3.h + nm-sun2.h nm-sun3.h nm-sun386.h nm-sun4os4.h nm-trash.h \ + nm-ultra3.h nm-hppab.h nm-hppah.h REMOTE_EXAMPLES = m68k-stub.c i386-stub.c sparc-stub.c rem-multi.shar diff --git a/gdb/config/hppabsd.mh b/gdb/config/hppabsd.mh index 701af04..2efde1a 100644 --- a/gdb/config/hppabsd.mh +++ b/gdb/config/hppabsd.mh @@ -1,3 +1,5 @@ # Host: Hewlett-Packard PA-RISC machine, running BSD -XDEPFILES= hppab-xdep.o coredep.o corelow.o +XDEPFILES= XM_FILE= xm-hppab.h +NAT_FILE= nm-hppab.h +NATDEPFILES= hppab-nat.o coredep.o corelow.o exec.o hppab-core.o diff --git a/gdb/config/hppabsd.mt b/gdb/config/hppabsd.mt index a0aa1f2..1260ab7 100644 --- a/gdb/config/hppabsd.mt +++ b/gdb/config/hppabsd.mt @@ -1,4 +1,4 @@ # TARGET: HP PA-RISC running bsd -TDEPFILES= hppa-pinsn.o hppab-tdep.o exec.o hppab-core.o +TDEPFILES= hppa-pinsn.o hppab-tdep.o TM_FILE= tm-hppab.h diff --git a/gdb/config/hppahpux.mh b/gdb/config/hppahpux.mh index 4d203a2..96b0b15 100644 --- a/gdb/config/hppahpux.mh +++ b/gdb/config/hppahpux.mh @@ -1,6 +1,8 @@ # Host: Hewlett-Packard PA-RISC machine, running HPUX TERMCAP = -lcurses -XDEPFILES= hppah-xdep.o coredep.o corelow.o +XDEPFILES= XM_FILE= xm-hppah.h +NAT_FILE= nm-hppah.h +NATDEPFILES= exec.o coredep.o corelow.o REGEX=regex.o REGEX1=regex.o diff --git a/gdb/config/hppahpux.mt b/gdb/config/hppahpux.mt index 0850108..b8f2f8f 100644 --- a/gdb/config/hppahpux.mt +++ b/gdb/config/hppahpux.mt @@ -1,3 +1,3 @@ # TARGET: HP PA-RISC running hpux -TDEPFILES= hppa-pinsn.o hppah-tdep.o exec.o +TDEPFILES= hppa-pinsn.o hppah-tdep.o TM_FILE= tm-hppah.h diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo index 63e1a05..c3188b0 100644 --- a/gdb/doc/gdbint.texinfo +++ b/gdb/doc/gdbint.texinfo @@ -1582,6 +1582,10 @@ system. These macros and their meanings are: Eliminate host conditionals from this list as they are identified.} @table @code +@item PUSH_DUMMY_FRAME +Used in @samp{call_function_by_hand} to create an artificial stack frame. +@item POP_FRAME +Used in @samp{call_function_by_hand} to remove an artificial stack frame. @item ALIGN_SIZE alloca.c @item BLOCK_ADDRESS_FUNCTION_RELATIVE diff --git a/gdb/hppab-nat.c b/gdb/hppab-nat.c new file mode 100644 index 0000000..752b370 --- /dev/null +++ b/gdb/hppab-nat.c @@ -0,0 +1,395 @@ +/* Machine-dependent hooks for the unix child process stratum. This + code is for the HP PA-RISC cpu. + + Copyright 1986, 1987, 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + + Contributed by the Center for Software Science at the + University of Utah (pa-gdb-bugs@cs.utah.edu). + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "inferior.h" + +#ifndef PT_ATTACH +#define PT_ATTACH PTRACE_ATTACH +#endif +#ifndef PT_DETACH +#define PT_DETACH PTRACE_DETACH +#endif + +/* This function simply calls ptrace with the given arguments. + It exists so that all calls to ptrace are isolated in this + machine-dependent file. */ +#ifdef WANT_NATIVE_TARGET +int +call_ptrace (request, pid, addr, data) + int request, pid; + PTRACE_ARG3_TYPE addr; + int data; +{ + return ptrace (request, pid, addr, data); +} +#endif /* WANT_NATIVE_TARGET */ + +#ifdef DEBUG_PTRACE +/* For the rest of the file, use an extra level of indirection */ +/* This lets us breakpoint usefully on call_ptrace. */ +#define ptrace call_ptrace +#endif + +void +kill_inferior () +{ + if (inferior_pid == 0) + return; + ptrace (PT_KILL, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0); + wait ((int *)0); + target_mourn_inferior (); +} + +#ifdef ATTACH_DETACH +/* Nonzero if we are debugging an attached process rather than + an inferior. */ +extern int attach_flag; + +/* Start debugging the process whose number is PID. */ +int +attach (pid) + int pid; +{ + errno = 0; + ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0); + if (errno) + perror_with_name ("ptrace"); + attach_flag = 1; + return pid; +} + +/* Stop debugging the process whose number is PID + and continue it with signal number SIGNAL. + SIGNAL = 0 means just continue it. */ + +void +detach (signal) + int signal; +{ + errno = 0; + ptrace (PT_DETACH, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal); + if (errno) + perror_with_name ("ptrace"); + attach_flag = 0; +} +#endif /* ATTACH_DETACH */ + + + +#if !defined (FETCH_INFERIOR_REGISTERS) + +/* KERNEL_U_ADDR is the amount to subtract from u.u_ar0 + to get the offset in the core file of the register values. */ +#if defined (KERNEL_U_ADDR_BSD) +/* Get kernel_u_addr using BSD-style nlist(). */ +CORE_ADDR kernel_u_addr; + +#include <a.out.gnu.h> /* For struct nlist */ + +void +_initialize_kernel_u_addr () +{ + struct nlist names[2]; + + names[0].n_un.n_name = "_u"; + names[1].n_un.n_name = NULL; + if (nlist ("/vmunix", names) == 0) + kernel_u_addr = names[0].n_value; + else + fatal ("Unable to get kernel u area address."); +} +#endif /* KERNEL_U_ADDR_BSD. */ + +#if defined (KERNEL_U_ADDR_HPUX) +/* Get kernel_u_addr using HPUX-style nlist(). */ +CORE_ADDR kernel_u_addr; + +struct hpnlist { + char * n_name; + long n_value; + unsigned char n_type; + unsigned char n_length; + short n_almod; + short n_unused; +}; +static struct hpnlist nl[] = {{ "_u", -1, }, { (char *) 0, }}; + +/* read the value of the u area from the hp-ux kernel */ +void _initialize_kernel_u_addr () +{ + struct user u; + nlist ("/hp-ux", &nl); + kernel_u_addr = nl[0].n_value; +} +#endif /* KERNEL_U_ADDR_HPUX. */ + +#if !defined (offsetof) +#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) +#endif + +/* U_REGS_OFFSET is the offset of the registers within the u area. */ +#if !defined (U_REGS_OFFSET) +#define U_REGS_OFFSET \ + ptrace (PT_READ_U, inferior_pid, \ + (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \ + - KERNEL_U_ADDR +#endif + +/* Registers we shouldn't try to fetch. */ +#if !defined (CANNOT_FETCH_REGISTER) +#define CANNOT_FETCH_REGISTER(regno) 0 +#endif + +/* Fetch one register. */ + +static void +fetch_register (regno) + int regno; +{ + register unsigned int regaddr; + char buf[MAX_REGISTER_RAW_SIZE]; + char mess[128]; /* For messages */ + register int i; + + /* Offset of registers within the u area. */ + unsigned int offset; + + if (CANNOT_FETCH_REGISTER (regno)) + { + bzero (buf, REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ + supply_register (regno, buf); + return; + } + + offset = U_REGS_OFFSET; + + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + errno = 0; + *(int *) &buf[i] = ptrace (PT_RUREGS, inferior_pid, + (PTRACE_ARG3_TYPE) regaddr, 0); + regaddr += sizeof (int); + if (errno != 0) + { + sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno); + perror_with_name (mess); + } + } + supply_register (regno, buf); +} + +#endif /* !defined (FETCH_INFERIOR_REGISTERS). */ +/* Fetch all registers, or just one, from the child process. */ + +#ifndef FETCH_INFERIOR_REGISTERS +void +fetch_inferior_registers (regno) + int regno; +{ + if (regno == -1) + for (regno = 0; regno < NUM_REGS; regno++) + fetch_register (regno); + else + fetch_register (regno); +} + +/* Registers we shouldn't try to store. */ +#if !defined (CANNOT_STORE_REGISTER) +#define CANNOT_STORE_REGISTER(regno) 0 +#endif + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + +void +store_inferior_registers (regno) + int regno; +{ + register unsigned int regaddr; + char buf[80]; + extern char registers[]; + register int i; + + unsigned int offset = U_REGS_OFFSET; + + if (regno >= 0) + { + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) + { + errno = 0; + ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + *(int *) ®isters[REGISTER_BYTE (regno) + i]); + if (errno != 0) + { + sprintf (buf, "writing register number %d(%d)", regno, i); + perror_with_name (buf); + } + regaddr += sizeof(int); + } + } + else + { + for (regno = 0; regno < NUM_REGS; regno++) + { + if (CANNOT_STORE_REGISTER (regno)) + continue; + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) + { + errno = 0; + ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + *(int *) ®isters[REGISTER_BYTE (regno) + i]); + if (errno != 0) + { + sprintf (buf, "writing register number %d(%d)", regno, i); + perror_with_name (buf); + } + regaddr += sizeof(int); + } + } + } + return; +} +#endif /* !defined(FETCH_INFERIOR_REGISTERS) */ + +/* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + +void +child_resume (step, signal) + int step; + int signal; +{ + errno = 0; + + /* An address of (PTRACE_ARG3_TYPE) 1 tells ptrace to continue from where + it was. (If GDB wanted it to start some other way, we have already + written a new PC value to the child.) */ + + if (step) + ptrace (PT_STEP, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal); + else + ptrace (PT_CONTINUE, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal); + + if (errno) + perror_with_name ("ptrace"); +} + +/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory + in the NEW_SUN_PTRACE case. + It ought to be straightforward. But it appears that writing did + not write the data that I specified. I cannot understand where + it got the data that it actually did write. */ + +/* Copy LEN bytes to or from inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. Copy to inferior if + WRITE is nonzero. + + Returns the length copied, which is either the LEN argument or zero. + This xfer function does not do partial moves, since child_ops + doesn't allow memory operations to cross below us in the target stack + anyway. */ + +int +child_xfer_memory (memaddr, myaddr, len, write, target) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; + struct target_ops *target; /* ignored */ +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + + if (write) + { + /* Fill start and end extra bytes of buffer with existing memory data. */ + + if (addr != memaddr || len < (int)sizeof (int)) { + /* Need part of initial word -- fetch it. */ + buffer[0] = ptrace (PT_READ_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, + 0); + } + + if (count > 1) /* FIXME, avoid if even boundary */ + { + buffer[count - 1] + = ptrace (PT_READ_I, inferior_pid, + (PTRACE_ARG3_TYPE) (addr + (count - 1) * sizeof (int)), + 0); + } + + /* Copy data to be written over corresponding part of buffer */ + + bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, + buffer[i]); + if (errno) + { + /* Using the appropriate one (I or D) is necessary for + Gould NP1, at least. */ + errno = 0; + ptrace (PT_WRITE_I, inferior_pid, (PTRACE_ARG3_TYPE) addr, + buffer[i]); + } + if (errno) + return 0; + } + } + else + { + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + buffer[i] = ptrace (PT_READ_I, inferior_pid, + (PTRACE_ARG3_TYPE) addr, 0); + if (errno) + return 0; + QUIT; + } + + /* Copy appropriate bytes out of the buffer. */ + bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); + } + return len; +} + diff --git a/gdb/hppab-tdep.c b/gdb/hppab-tdep.c index 8fe6d28..39d01cb 100644 --- a/gdb/hppab-tdep.c +++ b/gdb/hppab-tdep.c @@ -50,7 +50,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*#include <sys/user.h> After a.out.h */ #include <sys/file.h> #include <sys/stat.h> -#include <sys/ptrace.h> #include <machine/psl.h> #ifdef KERNELDEBUG diff --git a/gdb/hppah-nat.c b/gdb/hppah-nat.c new file mode 100644 index 0000000..4a85fe1 --- /dev/null +++ b/gdb/hppah-nat.c @@ -0,0 +1,397 @@ +/* Machine-dependent hooks for the unix child process stratum. This + code is for the HP PA-RISC cpu. + + Copyright 1986, 1987, 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + + Contributed by the Center for Software Science at the + University of Utah (pa-gdb-bugs@cs.utah.edu). + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#include "defs.h" +#include "inferior.h" + +#ifndef PT_ATTACH +#define PT_ATTACH PTRACE_ATTACH +#endif +#ifndef PT_DETACH +#define PT_DETACH PTRACE_DETACH +#endif + +/* This function simply calls ptrace with the given arguments. + It exists so that all calls to ptrace are isolated in this + machine-dependent file. */ +#ifdef WANT_NATIVE_TARGET +int +call_ptrace (request, pid, addr, data) + int request, pid; + PTRACE_ARG3_TYPE addr; + int data; +{ + return ptrace (request, pid, addr, data, 0); +} +#endif /* WANT_NATIVE_TARGET */ + +#ifdef DEBUG_PTRACE +/* For the rest of the file, use an extra level of indirection */ +/* This lets us breakpoint usefully on call_ptrace. */ +#define ptrace call_ptrace +#endif + +void +kill_inferior () +{ + if (inferior_pid == 0) + return; + ptrace (PT_EXIT, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0, 0); /* PT_EXIT = PT_KILL ? */ + wait ((int *)0); + target_mourn_inferior (); +} + +#ifdef ATTACH_DETACH +/* Nonzero if we are debugging an attached process rather than + an inferior. */ +extern int attach_flag; + +/* Start debugging the process whose number is PID. */ +int +attach (pid) + int pid; +{ + errno = 0; + ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0, 0); + if (errno) + perror_with_name ("ptrace"); + attach_flag = 1; + return pid; +} + +/* Stop debugging the process whose number is PID + and continue it with signal number SIGNAL. + SIGNAL = 0 means just continue it. */ + +void +detach (signal) + int signal; +{ + errno = 0; + ptrace (PT_DETACH, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal, 0); + if (errno) + perror_with_name ("ptrace"); + attach_flag = 0; +} +#endif /* ATTACH_DETACH */ + +/* Fetch all registers, or just one, from the child process. */ + +void +fetch_inferior_registers (regno) + int regno; +{ + if (regno == -1) + for (regno = 0; regno < NUM_REGS; regno++) + fetch_register (regno); + else + fetch_register (regno); +} + +/* Registers we shouldn't try to store. */ +#if !defined (CANNOT_STORE_REGISTER) +#define CANNOT_STORE_REGISTER(regno) 0 +#endif + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + +void +store_inferior_registers (regno) + int regno; +{ + register unsigned int regaddr; + char buf[80]; + extern char registers[]; + register int i; + + unsigned int offset = U_REGS_OFFSET; + + if (regno >= 0) + { + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) + { + errno = 0; + ptrace (PT_WUAREA, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + *(int *) ®isters[REGISTER_BYTE (regno) + i], 0); + if (errno != 0) + { + sprintf (buf, "writing register number %d(%d)", regno, i); + perror_with_name (buf); + } + regaddr += sizeof(int); + } + } + else + { + for (regno = 0; regno < NUM_REGS; regno++) + { + if (CANNOT_STORE_REGISTER (regno)) + continue; + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) + { + errno = 0; + ptrace (PT_WUAREA, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + *(int *) ®isters[REGISTER_BYTE (regno) + i], 0); + if (errno != 0) + { + sprintf (buf, "writing register number %d(%d)", regno, i); + perror_with_name (buf); + } + regaddr += sizeof(int); + } + } + } + return; +} + +/* KERNEL_U_ADDR is the amount to subtract from u.u_ar0 + to get the offset in the core file of the register values. */ +#if defined (KERNEL_U_ADDR_BSD) +/* Get kernel_u_addr using BSD-style nlist(). */ +CORE_ADDR kernel_u_addr; + +#include <a.out.gnu.h> /* For struct nlist */ + +void +_initialize_kernel_u_addr () +{ + struct nlist names[2]; + + names[0].n_un.n_name = "_u"; + names[1].n_un.n_name = NULL; + if (nlist ("/vmunix", names) == 0) + kernel_u_addr = names[0].n_value; + else + fatal ("Unable to get kernel u area address."); +} +#endif /* KERNEL_U_ADDR_BSD. */ + +#if defined (KERNEL_U_ADDR_HPUX) +/* Get kernel_u_addr using HPUX-style nlist(). */ +CORE_ADDR kernel_u_addr; + +struct hpnlist { + char * n_name; + long n_value; + unsigned char n_type; + unsigned char n_length; + short n_almod; + short n_unused; +}; +static struct hpnlist nl[] = {{ "_u", -1, }, { (char *) 0, }}; + +/* read the value of the u area from the hp-ux kernel */ +void _initialize_kernel_u_addr () +{ + struct user u; + nlist ("/hp-ux", &nl); + kernel_u_addr = nl[0].n_value; +} +#endif /* KERNEL_U_ADDR_HPUX. */ + +#if !defined (offsetof) +#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) +#endif + +/* U_REGS_OFFSET is the offset of the registers within the u area. */ +#if !defined (U_REGS_OFFSET) +#define U_REGS_OFFSET \ + ptrace (PT_READ_U, inferior_pid, \ + (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0, 0) \ + - KERNEL_U_ADDR +#endif + +/* Registers we shouldn't try to fetch. */ +#if !defined (CANNOT_FETCH_REGISTER) +#define CANNOT_FETCH_REGISTER(regno) 0 +#endif + +/* Fetch one register. */ + +static void +fetch_register (regno) + int regno; +{ + register unsigned int regaddr; + char buf[MAX_REGISTER_RAW_SIZE]; + char mess[128]; /* For messages */ + register int i; + + /* Offset of registers within the u area. */ + unsigned int offset; + + if (CANNOT_FETCH_REGISTER (regno)) + { + bzero (buf, REGISTER_RAW_SIZE (regno)); /* Supply zeroes */ + supply_register (regno, buf); + return; + } + + offset = U_REGS_OFFSET; + + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + errno = 0; + *(int *) &buf[i] = ptrace (PT_RUREGS, inferior_pid, + (PTRACE_ARG3_TYPE) regaddr, 0, 0); + regaddr += sizeof (int); + if (errno != 0) + { + sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno); + perror_with_name (mess); + } + } + supply_register (regno, buf); +} + + + +/* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + +void +child_resume (step, signal) + int step; + int signal; +{ + errno = 0; + + /* An address of (PTRACE_ARG3_TYPE) 1 tells ptrace to continue from where + it was. (If GDB wanted it to start some other way, we have already + written a new PC value to the child.) */ + + if (step) + ptrace (PT_SINGLE, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal, 0); + else + ptrace (PT_CONTIN, inferior_pid, (PTRACE_ARG3_TYPE) 1, signal, 0); + + if (errno) + perror_with_name ("ptrace"); +} + +/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory + in the NEW_SUN_PTRACE case. + It ought to be straightforward. But it appears that writing did + not write the data that I specified. I cannot understand where + it got the data that it actually did write. */ + +/* Copy LEN bytes to or from inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. Copy to inferior if + WRITE is nonzero. + + Returns the length copied, which is either the LEN argument or zero. + This xfer function does not do partial moves, since child_ops + doesn't allow memory operations to cross below us in the target stack + anyway. */ + +int +child_xfer_memory (memaddr, myaddr, len, write, target) + CORE_ADDR memaddr; + char *myaddr; + int len; + int write; + struct target_ops *target; /* ignored */ +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + + if (write) + { + /* Fill start and end extra bytes of buffer with existing memory data. */ + + if (addr != memaddr || len < (int)sizeof (int)) { + /* Need part of initial word -- fetch it. */ + buffer[0] = ptrace (PT_RIUSER, inferior_pid, + (PTRACE_ARG3_TYPE) addr, 0, 0); + } + + if (count > 1) /* FIXME, avoid if even boundary */ + { + buffer[count - 1] + = ptrace (PT_RIUSER, inferior_pid, + (PTRACE_ARG3_TYPE) (addr + (count - 1) * sizeof (int)), + 0, 0); + } + + /* Copy data to be written over corresponding part of buffer */ + + bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (int)) + { +#if 0 +/* The HP-UX kernel crashes if you use PT_WDUSER to write into the text + segment. FIXME -- does it work to write into the data segment using + WIUSER, or do these idiots really expect us to figure out which segment + the address is in, so we can use a separate system call for it??! */ + errno = 0; + ptrace (PT_WDUSER, inferior_pid, (PTRACE_ARG3_TYPE) addr, + buffer[i], 0); + if (errno) +#endif + { + /* Using the appropriate one (I or D) is necessary for + Gould NP1, at least. */ + errno = 0; + ptrace (PT_WIUSER, inferior_pid, (PTRACE_ARG3_TYPE) addr, + buffer[i], 0); + } + if (errno) + return 0; + } + } + else + { + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + buffer[i] = ptrace (PT_RIUSER, inferior_pid, + (PTRACE_ARG3_TYPE) addr, 0, 0); + if (errno) + return 0; + QUIT; + } + + /* Copy appropriate bytes out of the buffer. */ + bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); + } + return len; +} + diff --git a/gdb/hppah-tdep.c b/gdb/hppah-tdep.c index 27bf9e9..8b7dc61 100644 --- a/gdb/hppah-tdep.c +++ b/gdb/hppah-tdep.c @@ -50,7 +50,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*#include <sys/user.h> After a.out.h */ #include <sys/file.h> #include <sys/stat.h> -#include <sys/ptrace.h> #include <machine/psl.h> #ifdef KERNELDEBUG diff --git a/gdb/nm-hppab.h b/gdb/nm-hppab.h new file mode 100644 index 0000000..9dccb8f --- /dev/null +++ b/gdb/nm-hppab.h @@ -0,0 +1,25 @@ +/* HPPA PA-RISC machine native support for BSD, for GDB. + Copyright 1991, 1992 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define U_REGS_OFFSET 0 + +/* What a coincidence! */ +#define REGISTER_U_ADDR(addr, blockend, regno) \ +{ addr = (int)(blockend) + REGISTER_BYTE (regno);} + diff --git a/gdb/nm-hppah.h b/gdb/nm-hppah.h new file mode 100644 index 0000000..6977a12 --- /dev/null +++ b/gdb/nm-hppah.h @@ -0,0 +1,24 @@ +/* Native support for HPPA-RISC machine running HPUX, for GDB. + Copyright 1991, 1992 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define U_REGS_OFFSET 0 + +/* What a coincidence! */ +#define REGISTER_U_ADDR(addr, blockend, regno) \ +{ addr = (int)(blockend) + REGISTER_BYTE (regno);} diff --git a/gdb/xm-hppab.h b/gdb/xm-hppab.h index f326876..22f67d7 100644 --- a/gdb/xm-hppab.h +++ b/gdb/xm-hppab.h @@ -35,12 +35,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define KERNEL_U_ADDR 0 -/* What a coincidence! */ -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ addr = (int)(blockend) + REGISTER_BYTE (regno);} - -#define U_REGS_OFFSET 0 - #ifndef SEEK_SET # define SEEK_SET 0 /* Set file pointer to "offset" */ # define SEEK_CUR 1 /* Set file pointer to current plus "offset" */ diff --git a/gdb/xm-hppah.h b/gdb/xm-hppah.h index 462d088..0c10fb6 100644 --- a/gdb/xm-hppah.h +++ b/gdb/xm-hppah.h @@ -41,12 +41,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define KERNEL_U_ADDR 0 -/* What a coincidence! */ -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ addr = (int)(blockend) + REGISTER_BYTE (regno);} - -#define U_REGS_OFFSET 0 - /* HP uses non-ANSI definitions, but with void * results. */ #define MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */ extern void * |