aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorK. Richard Pixley <rich@cygnus>1992-10-21 04:57:35 +0000
committerK. Richard Pixley <rich@cygnus>1992-10-21 04:57:35 +0000
commitca0487229b98f00278971ed0fda7bb258091bbd9 (patch)
tree0c0623d584a96c35d8a31ca2c210c1c32c0d0285 /gdb
parent6142210d1d7bcfafaa2a31327b97a354024719c1 (diff)
downloadgdb-ca0487229b98f00278971ed0fda7bb258091bbd9.zip
gdb-ca0487229b98f00278971ed0fda7bb258091bbd9.tar.gz
gdb-ca0487229b98f00278971ed0fda7bb258091bbd9.tar.bz2
hppa native support
Diffstat (limited to 'gdb')
-rw-r--r--gdb/.Sanitize6
-rw-r--r--gdb/ChangeLog16
-rw-r--r--gdb/Makefile.in3
-rw-r--r--gdb/config/hppabsd.mh4
-rw-r--r--gdb/config/hppabsd.mt2
-rw-r--r--gdb/config/hppahpux.mh4
-rw-r--r--gdb/config/hppahpux.mt2
-rw-r--r--gdb/doc/gdbint.texinfo4
-rw-r--r--gdb/hppab-nat.c395
-rw-r--r--gdb/hppab-tdep.c1
-rw-r--r--gdb/hppah-nat.c397
-rw-r--r--gdb/hppah-tdep.c1
-rw-r--r--gdb/nm-hppab.h25
-rw-r--r--gdb/nm-hppah.h24
-rw-r--r--gdb/xm-hppab.h6
-rw-r--r--gdb/xm-hppah.h6
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 *) &registers[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 *) &registers[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 *) &registers[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 *) &registers[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 *