OSDN Git Service

* hppah-nat.c: Remove file.
authorkettenis <kettenis>
Sat, 18 Dec 2004 17:36:32 +0000 (17:36 +0000)
committerkettenis <kettenis>
Sat, 18 Dec 2004 17:36:32 +0000 (17:36 +0000)
* infttrace.h: Remove file.
* infttrace.c: Remove file.
* Makefile.in (ALLDEPFILES): Remove hppah-nat.c
(infttrace_h): Remove variable.
(hppah-nat.o, infttrace.o): Remove dependencies.
* configure.host (hppa*64*-*-hpux11*): Remove.
* config/pa/hpux11w.mh: Remove file.
* config/pa/nm-hppah.h: Remove file.
* config/pa/nm-hppah11.h: Remove file.

gdb/ChangeLog
gdb/Makefile.in
gdb/config/pa/hpux11w.mh [deleted file]
gdb/config/pa/nm-hppah.h [deleted file]
gdb/config/pa/nm-hppah11.h [deleted file]
gdb/configure.host
gdb/hppah-nat.c [deleted file]
gdb/infttrace.c [deleted file]
gdb/infttrace.h [deleted file]

index 284ef8d..d35510f 100644 (file)
@@ -1,5 +1,16 @@
 2004-12-18  Mark Kettenis  <kettenis@gnu.org>
 
+       * hppah-nat.c: Remove file.
+       * infttrace.h: Remove file.
+       * infttrace.c: Remove file.
+       * Makefile.in (ALLDEPFILES): Remove hppah-nat.c
+       (infttrace_h): Remove variable.
+       (hppah-nat.o, infttrace.o): Remove dependencies.
+       * configure.host (hppa*64*-*-hpux11*): Remove.
+       * config/pa/hpux11w.mh: Remove file.
+       * config/pa/nm-hppah.h: Remove file.
+       * config/pa/nm-hppah11.h: Remove file.
+
        * config/djgpp/fnchange.lst: Resolve name clash between
        ../bfd/elf32-arm.c and ../bfd/elf32-arc.c, i386-sol2-nat.c and
        i386-sol2-tdep.c, mips64obsd-nat.c and mips64obsd-tdep.c,
index c113e8e..dda01ce 100644 (file)
@@ -711,7 +711,6 @@ inferior_h = inferior.h $(breakpoint_h) $(target_h) $(frame_h)
 inf_loop_h = inf-loop.h
 inflow_h = inflow.h $(terminal_h)
 inf_ptrace_h = inf-ptrace.h
-infttrace_h = infttrace.h
 inf_ttrace_h = inf-ttrace.h
 interps_h = interps.h
 jv_lang_h = jv-lang.h
@@ -1372,9 +1371,9 @@ ALLDEPFILES = \
        glibc-tdep.c \
        go32-nat.c h8300-tdep.c \
        hppa-tdep.c hppa-hpux-tdep.c hppa-hpux-nat.c \
-       hppah-nat.c hpread.c \
        hppa-linux-tdep.c hppa-linux-nat.c \
        hppabsd-nat.c hppabsd-tdep.c \
+       hpread.c \
        i386-tdep.c i386v-nat.c i386-linux-nat.c \
        i386v4-nat.c i386-cygwin-tdep.c \
        i386bsd-nat.c i386bsd-tdep.c i386fbsd-nat.c i386fbsd-tdep.c \
@@ -1968,9 +1967,6 @@ hppabsd-nat.o: hppabsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
 hppabsd-tdep.o: hppabsd-tdep.c $(defs_h) $(arch_utils_h) $(osabi_h) \
        $(regcache_h) $(regset_h) $(gdb_assert_h) $(gdb_string_h) \
        $(hppa_tdep_h) $(solib_svr4_h)
-hppah-nat.o: hppah-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
-       $(gdb_wait_h) $(regcache_h) $(gdb_string_h) $(infttrace_h) \
-       $(hppa_tdep_h)
 hppa-hpux-nat.o: hppa-hpux-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
        $(target_h) $(gdb_assert_h) $(hppa_tdep_h) $(inf_ptrace_h) \
        $(inf_ttrace_h)
@@ -2103,9 +2099,6 @@ infrun.o: infrun.c $(defs_h) $(gdb_string_h) $(symtab_h) $(frame_h) \
 inftarg.o: inftarg.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
        $(gdbcore_h) $(command_h) $(gdb_stat_h) $(observer_h) $(gdb_wait_h) \
        $(inflow_h)
-infttrace.o: infttrace.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
-       $(gdb_string_h) $(gdb_wait_h) $(command_h) $(gdbthread_h) \
-       $(infttrace_h) $(gdbcore_h)
 interps.o: interps.c $(defs_h) $(gdbcmd_h) $(ui_out_h) $(event_loop_h) \
        $(event_top_h) $(interps_h) $(completer_h) $(gdb_string_h) \
        $(gdb_events_h) $(gdb_assert_h) $(top_h)
diff --git a/gdb/config/pa/hpux11w.mh b/gdb/config/pa/hpux11w.mh
deleted file mode 100644 (file)
index 8b85c42..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# Host: Hewlett-Packard PA-RISC machine, running HPUX 11.00
-
-# FIXME: cagney/2002-04-07: gdb/366: The -Dvfork=fork hack below is
-# stop GDB hanging on HP/UX.  For some reason vfork() hangs yet fork()
-# doesn't ....
-
-MH_CFLAGS = -Dvfork=fork
-
-NAT_FILE= nm-hppah11.h
-NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o \
-       infttrace.o
diff --git a/gdb/config/pa/nm-hppah.h b/gdb/config/pa/nm-hppah.h
deleted file mode 100644 (file)
index 24d0256..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Native support for HPPA-RISC machine running HPUX, for GDB.
-   Copyright 1991, 1992, 1994, 1996, 1998, 1999, 2000, 2002
-   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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-struct target_ops;
-
-#define U_REGS_OFFSET 0
-
-#define KERNEL_U_ADDR 0
-
-/* What a coincidence! */
-#define REGISTER_U_ADDR(addr, blockend, regno)                         \
-{ addr = (int)(blockend) + DEPRECATED_REGISTER_BYTE (regno);}
-
-/* This isn't really correct, because ptrace is actually a 32-bit
-   interface.  However, the modern HP-UX targets all really use
-   ttrace, which is a 64-bit interface --- a debugger running in
-   either 32- or 64-bit mode can debug a 64-bit process.  BUT, the
-   code doesn't use ttrace directly --- it calls call_ptrace instead,
-   which is supposed to be drop-in substitute for ptrace.  In other
-   words, they access a 64-bit system call (ttrace) through a
-   compatibility layer which is allegedly a 32-bit interface.
-
-   So I don't feel the least bit guilty about this.  */
-#define PTRACE_ARG3_TYPE CORE_ADDR
-
-/* We need to figure out where the text region is so that we use the
-   appropriate ptrace operator to manipulate text.  Simply
-   reading/writing user space will crap out HPUX.  */
-#define DEPRECATED_HPUX_TEXT_END deprecated_hpux_text_end
-extern void deprecated_hpux_text_end (struct target_ops *exec_ops);
-
-/* In hppah-nat.c: */
-#define FETCH_INFERIOR_REGISTERS
-#define CHILD_XFER_MEMORY
-#define CHILD_FOLLOW_FORK
-
-/* In infptrace.c or infttrace.c: */
-#define CHILD_PID_TO_EXEC_FILE
-#define CHILD_POST_STARTUP_INFERIOR
-#define CHILD_ACKNOWLEDGE_CREATED_INFERIOR
-#define CHILD_INSERT_FORK_CATCHPOINT
-#define CHILD_REMOVE_FORK_CATCHPOINT
-#define CHILD_INSERT_VFORK_CATCHPOINT
-#define CHILD_REMOVE_VFORK_CATCHPOINT
-#define CHILD_INSERT_EXEC_CATCHPOINT
-#define CHILD_REMOVE_EXEC_CATCHPOINT
-#define CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL
-#define CHILD_POST_ATTACH
-#define CHILD_THREAD_ALIVE
-#define CHILD_PID_TO_STR
-#define CHILD_WAIT
-struct target_waitstatus;
-extern ptid_t child_wait (ptid_t, struct target_waitstatus *);
-
-extern int hppa_require_attach (int);
-extern int hppa_require_detach (int, int);
-
-/* So we can cleanly use code in infptrace.c.  */
-#define PT_KILL                PT_EXIT
-#define PT_STEP                PT_SINGLE
-#define PT_CONTINUE    PT_CONTIN
-
-/* FIXME HP MERGE : Previously, PT_RDUAREA. this is actually fixed
-   in gdb-hp-snapshot-980509  */
-#define PT_READ_U      PT_RUAREA
-#define PT_WRITE_U     PT_WUAREA
-#define PT_READ_I      PT_RIUSER
-#define PT_READ_D      PT_RDUSER
-#define PT_WRITE_I     PT_WIUSER
-#define PT_WRITE_D     PT_WDUSER
-
-/* In infptrace or infttrace.c: */
-
-/* Starting with HP-UX 10.30, support is provided (in the form of
-   ttrace requests) for memory-protection-based hardware watchpoints.
-
-   The 10.30 implementation of these functions reside in infttrace.c.
-
-   Stubs of these functions will be provided in infptrace.c, so that
-   10.20 will at least link.  However, the "can I use a fast watchpoint?"
-   query will always return "No" for 10.20. */
-
-/* The PA can watch any number of locations (generic routines already check
-   that all intermediates are in watchable memory locations). */
-extern int hppa_can_use_hw_watchpoint (int type, int cnt, int ot);
-#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
-        hppa_can_use_hw_watchpoint(type, cnt, ot)
-
-/* The PA can also watch memory regions of arbitrary size, since we're
-   using a page-protection scheme.  (On some targets, apparently watch
-   registers are used, which can only accomodate regions of
-   DEPRECATED_REGISTER_SIZE.)  */
-#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_count) \
-        (1)
-
-/* On HP-UX, we're using page-protection to implement hardware watchpoints.
-   When an instruction attempts to write to a write-protected memory page,
-   a SIGBUS is raised.  At that point, the write has not actually occurred.
-
-   We must therefore remove page-protections; single-step the inferior (to
-   allow the write to happen); restore page-protections; and check whether
-   any watchpoint triggered.
-
-   If none did, then the write was to a "nearby" location that just happens
-   to fall on the same page as a watched location, and so can be ignored.
-
-   The only intended client of this macro is wait_for_inferior(), in infrun.c.
-   When HAVE_NONSTEPPABLE_WATCHPOINT is true, that function will take care
-   of the stepping & etc. */
-
-#define STOPPED_BY_WATCHPOINT(W) \
-        ((W.kind == TARGET_WAITKIND_STOPPED) && \
-         (stop_signal == TARGET_SIGNAL_BUS) && \
-         ! stepped_after_stopped_by_watchpoint && \
-         bpstat_have_active_hw_watchpoints ())
-
-/* Our implementation of "hardware" watchpoints uses memory page-protection
-   faults.  However, HP-UX has unfortunate interactions between these and
-   system calls; basically, it's unsafe to have page protections on when a
-   syscall is running.  Therefore, we also ask for notification of syscall
-   entries and returns.  When the inferior enters a syscall, we disable
-   h/w watchpoints.  When the inferior returns from a syscall, we reenable
-   h/w watchpoints.
-
-   infptrace.c supplies dummy versions of these; infttrace.c is where the
-   meaningful implementations are.
- */
-#define TARGET_ENABLE_HW_WATCHPOINTS(pid) \
-        hppa_enable_page_protection_events (pid)
-extern void hppa_enable_page_protection_events (int);
-
-#define TARGET_DISABLE_HW_WATCHPOINTS(pid) \
-        hppa_disable_page_protection_events (pid)
-extern void hppa_disable_page_protection_events (int);
-
-/* Use these macros for watchpoint insertion/deletion.  */
-extern int hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len,
-                                     int type);
-#define target_insert_watchpoint(addr, len, type) \
-        hppa_insert_hw_watchpoint (PIDGET (inferior_ptid), addr, (LONGEST)(len), type)
-
-extern int hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len,
-                                     int type);
-#define target_remove_watchpoint(addr, len, type) \
-        hppa_remove_hw_watchpoint (PIDGET (inferior_ptid), addr, (LONGEST)(len), type)
-
-/* We call our k-thread processes "threads", rather
- * than processes.  So we need a new way to print
- * the string.  Code is in hppah-nat.c.
- */
-
-extern char *child_pid_to_str (ptid_t);
-
-#define target_tid_to_str( ptid ) \
-        hppa_tid_to_str( ptid )
-extern char *hppa_tid_to_str (ptid_t);
-
-/* For this, ID can be either a process or thread ID, and the function
-   will describe it appropriately, returning the description as a printable
-   string.
-
-   The function that implements this macro is defined in infptrace.c and
-   infttrace.c.
- */
-#define target_pid_or_tid_to_str(ID) \
-        hppa_pid_or_tid_to_str (ID)
-extern char *hppa_pid_or_tid_to_str (ptid_t);
-
-/* This is used when handling events caused by a call to vfork().  On ptrace-
-   based HP-UXs, when you resume the vforked child, the parent automagically
-   begins running again.  To prevent this runaway, this function is used.
-
-   Note that for vfork on HP-UX, we receive three events of interest:
-
-   1. the vfork event for the new child process
-   2. the exit or exec event of the new child process (actually, you get
-   two exec events on ptrace-based HP-UXs)
-   3. the vfork event for the original parent process
-
-   The first is always received first.  The other two may be received in any
-   order; HP-UX doesn't guarantee an order.
- */
-#define ENSURE_VFORKING_PARENT_REMAINS_STOPPED(PID) \
-        hppa_ensure_vforking_parent_remains_stopped (PID)
-extern void hppa_ensure_vforking_parent_remains_stopped (int);
-
-/* This is used when handling events caused by a call to vfork().
-
-   On ttrace-based HP-UXs, the parent vfork and child exec arrive more or less
-   together.  That is, you could do two wait()s without resuming either parent
-   or child, and get both events.
-
-   On ptrace-based HP-UXs, you must resume the child after its exec event is
-   delivered or you won't get the parent's vfork.  I.e., you can't just wait()
-   and get the parent vfork, after receiving the child exec.
- */
-#define RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK() \
-        hppa_resume_execd_vforking_child_to_get_parent_vfork ()
-extern int hppa_resume_execd_vforking_child_to_get_parent_vfork (void);
-
-#define HPUXHPPA
-
-#define MAY_FOLLOW_EXEC (1)
-
-#include "infttrace.h" /* For parent_attach_all.  */
diff --git a/gdb/config/pa/nm-hppah11.h b/gdb/config/pa/nm-hppah11.h
deleted file mode 100644 (file)
index 7a73c24..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Native support for HPPA-RISC machine running HPUX 11.x, for GDB.
-   Copyright 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#define GDB_NATIVE_HPUX_11
-
-#include "pa/nm-hppah.h"
index c2901b9..faf94a7 100644 (file)
@@ -50,7 +50,6 @@ arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu)
                        gdb_host=nbsdelf ;;
 arm*-*-netbsd*)                gdb_host=nbsdaout ;;
 
-hppa*64*-*-hpux11*)    gdb_host=hpux11w ;;
 hppa*-*-hpux* | hppa*-*-hiux*)
                        gdb_host=hpux ;;
 hppa*-*-linux*)                gdb_host=linux ;;
diff --git a/gdb/hppah-nat.c b/gdb/hppah-nat.c
deleted file mode 100644 (file)
index bf6af6d..0000000
+++ /dev/null
@@ -1,1440 +0,0 @@
-/* Native support code for HPUX PA-RISC, for GDB the GNU debugger.
-
-   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1998, 1999, 2000, 2001, 2004 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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-
-#include "defs.h"
-#include "inferior.h"
-#include "target.h"
-#include <sys/ptrace.h>
-#include "gdbcore.h"
-#include "gdb_wait.h"
-#include "regcache.h"
-#include "gdb_string.h"
-#include "infttrace.h"
-#include <signal.h>
-
-#include "hppa-tdep.h"
-
-static CORE_ADDR text_end;
-
-void
-deprecated_hpux_text_end (struct target_ops *exec_ops)
-{
-  struct section_table *p;
-
-  /* Set text_end to the highest address of the end of any readonly
-     code section.  */
-  /* FIXME: The comment above does not match the code.  The code
-     checks for sections with are either code *or* readonly.  */
-  text_end = (CORE_ADDR) 0;
-  for (p = exec_ops->to_sections; p < exec_ops->to_sections_end; p++)
-    if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
-       & (SEC_CODE | SEC_READONLY))
-      {
-       if (text_end < p->endaddr)
-         text_end = p->endaddr;
-      }
-}
-
-
-static void fetch_register (int);
-
-void
-fetch_inferior_registers (int regno)
-{
-  if (regno == -1)
-    for (regno = 0; regno < NUM_REGS; regno++)
-      fetch_register (regno);
-  else
-    fetch_register (regno);
-}
-
-/* Our own version of the offsetof macro, since we can't assume ANSI C.  */
-#define HPPAH_OFFSETOF(type, member) ((int) (&((type *) 0)->member))
-
-/* 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 (int regno)
-{
-  unsigned int regaddr;
-  char buf[80];
-  int i;
-  unsigned int offset = U_REGS_OFFSET;
-  int scratch;
-
-  if (regno >= 0)
-    {
-      unsigned int addr, len, offset;
-
-      if (CANNOT_STORE_REGISTER (regno))
-       return;
-
-      offset = 0;
-      len = register_size (current_gdbarch, regno);
-
-      /* Requests for register zero actually want the save_state's
-        ss_flags member.  As RM says: "Oh, what a hack!"  */
-      if (regno == 0)
-       {
-         save_state_t ss;
-         addr = HPPAH_OFFSETOF (save_state_t, ss_flags);
-         len = sizeof (ss.ss_flags);
-
-         /* Note that ss_flags is always an int, no matter what
-            register_size (0) says.  Assuming all HP-UX PA machines
-            are big-endian, put it at the least significant end of
-            the value, and zap the rest of the buffer.  */
-         offset = register_size (current_gdbarch, 0) - len;
-       }
-
-      /* Floating-point registers come from the ss_fpblock area.  */
-      else if (regno >= HPPA_FP0_REGNUM)
-       addr = HPPAH_OFFSETOF (save_state_t, ss_fpblock) 
-              + ((regno - HPPA_FP0_REGNUM) 
-                 * register_size (current_gdbarch, regno));
-
-      /* Wide registers come from the ss_wide area.
-        I think it's more PC to test (ss_flags & SS_WIDEREGS) to select
-        between ss_wide and ss_narrow than to use the raw register size.
-        But checking ss_flags would require an extra ptrace call for
-        every register reference.  Bleah.  */
-      else if (len == 8)
-       addr = HPPAH_OFFSETOF (save_state_t, ss_wide) 
-              + regno * 8;
-
-      /* Narrow registers come from the ss_narrow area.  Note that
-        ss_narrow starts with gr1, not gr0.  */
-      else if (len == 4)
-       addr = HPPAH_OFFSETOF (save_state_t, ss_narrow)
-              + (regno - 1) * 4;
-      else
-       internal_error (__FILE__, __LINE__,
-                       "hppah-nat.c (write_register): unexpected register size");
-
-#ifdef GDB_TARGET_IS_HPPA_20W
-      /* Unbelieveable.  The PC head and tail must be written in 64bit hunks
-        or we will get an error.  Worse yet, the oddball ptrace/ttrace
-        layering will not allow us to perform a 64bit register store.
-
-        What a crock.  */
-      if ((regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM) && len == 8)
-       {
-         CORE_ADDR temp;
-
-         regcache_raw_read (current_regcache, regno, &temp);
-
-         /* Set the priv level (stored in the low two bits of the PC.  */
-         temp |= 0x3;
-
-         ttrace_write_reg_64 (PIDGET (inferior_ptid), (CORE_ADDR)addr,
-                              (CORE_ADDR)&temp);
-
-         /* If we fail to write the PC, give a true error instead of
-            just a warning.  */
-          if (errno != 0)
-           {
-             char *err = safe_strerror (errno);
-             char *msg = alloca (strlen (err) + 128);
-             sprintf (msg, "writing `%s' register: %s",
-                       REGISTER_NAME (regno), err);
-             perror_with_name (msg);
-           }
-         return;
-       }
-
-      /* Another crock.  HPUX complains if you write a nonzero value to
-        the high part of IPSW.  What will it take for HP to catch a
-        clue about building sensible interfaces?  */
-     if (regno == HPPA_IPSW_REGNUM && len == 8)
-       {
-         int temp = 0;
-
-         regcache_raw_write_part (current_regcache, regno, 0,
-                                  sizeof (int), &temp);
-       }
-#endif
-
-      for (i = 0; i < len; i += sizeof (int))
-       {
-         int temp;
-
-         errno = 0;
-         regcache_raw_read_part (current_regcache, regno, i,
-                                 sizeof (int), &temp);
-         call_ptrace (PT_WUREGS, PIDGET (inferior_ptid),
-                      (PTRACE_ARG3_TYPE) addr + i,
-                      temp);
-         if (errno != 0)
-           {
-             /* Warning, not error, in case we are attached; sometimes
-                the kernel doesn't let us at the registers. */
-             char *err = safe_strerror (errno);
-             char *msg = alloca (strlen (err) + 128);
-             sprintf (msg, "writing `%s' register: %s",
-                       REGISTER_NAME (regno), err);
-             /* If we fail to write the PC, give a true error instead of
-                just a warning.  */
-             if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM)
-               perror_with_name (msg);
-             else
-               warning (msg);
-             return;
-           }
-       }
-    }
-  else
-    for (regno = 0; regno < NUM_REGS; regno++)
-      store_inferior_registers (regno);
-}
-
-
-/* Fetch a register's value from the process's U area.  */
-static void
-fetch_register (int regno)
-{
-  char buf[MAX_REGISTER_SIZE];
-  unsigned int addr, len, offset;
-  int i;
-
-  offset = 0;
-  len = register_size (current_gdbarch, regno);
-
-  /* Requests for register zero actually want the save_state's
-     ss_flags member.  As RM says: "Oh, what a hack!"  */
-  if (regno == 0)
-    {
-      save_state_t ss;
-      addr = HPPAH_OFFSETOF (save_state_t, ss_flags);
-      len = sizeof (ss.ss_flags);
-
-      /* Note that ss_flags is always an int, no matter what
-        register_size (0) says.  Assuming all HP-UX PA machines are
-        big-endian, put it at the least significant end of the value,
-        and zap the rest of the buffer.  */
-      offset = register_size (current_gdbarch, 0) - len;
-      memset (buf, 0, sizeof (buf));
-    }
-
-  /* Floating-point registers come from the ss_fpblock area.  */
-  else if (regno >= HPPA_FP0_REGNUM)
-    addr = (HPPAH_OFFSETOF (save_state_t, ss_fpblock) 
-           + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (HPPA_FP0_REGNUM)));
-
-  /* Wide registers come from the ss_wide area.
-     I think it's more PC to test (ss_flags & SS_WIDEREGS) to select
-     between ss_wide and ss_narrow than to use the raw register size.
-     But checking ss_flags would require an extra ptrace call for
-     every register reference.  Bleah.  */
-  else if (len == 8)
-    addr = (HPPAH_OFFSETOF (save_state_t, ss_wide) 
-           + DEPRECATED_REGISTER_BYTE (regno));
-
-  /* Narrow registers come from the ss_narrow area.  Note that
-     ss_narrow starts with gr1, not gr0.  */
-  else if (len == 4)
-    addr = (HPPAH_OFFSETOF (save_state_t, ss_narrow)
-           + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (1)));
-
-  else
-    internal_error (__FILE__, __LINE__,
-                   "hppa-nat.c (fetch_register): unexpected register size");
-
-  for (i = 0; i < len; i += sizeof (int))
-    {
-      errno = 0;
-      /* Copy an int from the U area to buf.  Fill the least
-         significant end if len != raw_size.  */
-      * (int *) &buf[offset + i] =
-         call_ptrace (PT_RUREGS, PIDGET (inferior_ptid),
-                      (PTRACE_ARG3_TYPE) addr + i, 0);
-      if (errno != 0)
-       {
-         /* Warning, not error, in case we are attached; sometimes
-            the kernel doesn't let us at the registers. */
-         char *err = safe_strerror (errno);
-         char *msg = alloca (strlen (err) + 128);
-         sprintf (msg, "reading `%s' register: %s",
-                  REGISTER_NAME (regno), err);
-         warning (msg);
-         return;
-       }
-    }
-
-  /* If we're reading an address from the instruction address queue,
-     mask out the bottom two bits --- they contain the privilege
-     level.  */
-  if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM)
-    buf[len - 1] &= ~0x3;
-
-  regcache_raw_supply (current_regcache, regno, buf);
-}
-
-
-/* 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
-   deprecated_child_ops doesn't allow memory operations to cross below
-   us in the target stack anyway.  TARGET is ignored.  */
-
-int
-child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                  struct mem_attrib *mem,
-                  struct target_ops *target)
-{
-  int i;
-  /* Round starting address down to longword boundary.  */
-  CORE_ADDR addr = memaddr & - (CORE_ADDR)(sizeof (int));
-  /* Round ending address up; get number of longwords that makes.  */
-  int count
-  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
-
-  /* Allocate buffer of that many longwords.
-     Note -- do not use alloca to allocate this buffer since there is no
-     guarantee of when the buffer will actually be deallocated.
-
-     This routine can be called over and over with the same call chain;
-     this (in effect) would pile up all those alloca requests until a call
-     to alloca was made from a point higher than this routine in the
-     call chain.  */
-  int *buffer = (int *) xmalloc (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] = call_ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER,
-                                  PIDGET (inferior_ptid),
-                                  (PTRACE_ARG3_TYPE) addr, 0);
-       }
-
-      if (count > 1)           /* FIXME, avoid if even boundary */
-       {
-         buffer[count - 1]
-           = call_ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER,
-                          PIDGET (inferior_ptid),
-                          (PTRACE_ARG3_TYPE) (addr
-                                              + (count - 1) * sizeof (int)),
-                          0);
-       }
-
-      /* Copy data to be written over corresponding part of buffer */
-      memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
-
-      /* Write the entire buffer.  */
-      for (i = 0; i < count; i++, addr += sizeof (int))
-       {
-         int pt_status;
-         int pt_request;
-         /* 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;
-         pt_request = (addr < text_end) ? PT_WIUSER : PT_WDUSER;
-         pt_status = call_ptrace (pt_request,
-                                  PIDGET (inferior_ptid),
-                                  (PTRACE_ARG3_TYPE) addr,
-                                  buffer[i]);
-
-         /* Did we fail?  Might we've guessed wrong about which
-            segment this address resides in?  Try the other request,
-            and see if that works...  */
-         if ((pt_status == -1) && errno)
-           {
-             errno = 0;
-             pt_request = (pt_request == PT_WIUSER) ? PT_WDUSER : PT_WIUSER;
-             pt_status = call_ptrace (pt_request,
-                                      PIDGET (inferior_ptid),
-                                      (PTRACE_ARG3_TYPE) addr,
-                                      buffer[i]);
-
-             /* No, we still fail.  Okay, time to punt. */
-             if ((pt_status == -1) && errno)
-               {
-                 xfree (buffer);
-                 return 0;
-               }
-           }
-       }
-    }
-  else
-    {
-      /* Read all the longwords */
-      for (i = 0; i < count; i++, addr += sizeof (int))
-       {
-         errno = 0;
-         buffer[i] = call_ptrace (addr < text_end ? PT_RIUSER : PT_RDUSER,
-                                  PIDGET (inferior_ptid),
-                                  (PTRACE_ARG3_TYPE) addr, 0);
-         if (errno)
-           {
-             xfree (buffer);
-             return 0;
-           }
-         QUIT;
-       }
-
-      /* Copy appropriate bytes out of the buffer.  */
-      memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
-    }
-  xfree (buffer);
-  return len;
-}
-
-char *saved_child_execd_pathname = NULL;
-int saved_vfork_pid;
-enum {
-  STATE_NONE,
-  STATE_GOT_CHILD,
-  STATE_GOT_EXEC,
-  STATE_GOT_PARENT,
-  STATE_FAKE_EXEC
-} saved_vfork_state = STATE_NONE;
-
-int
-child_follow_fork (int follow_child)
-{
-  ptid_t last_ptid;
-  struct target_waitstatus last_status;
-  int has_vforked;
-  int parent_pid, child_pid;
-
-  get_last_target_status (&last_ptid, &last_status);
-  has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
-  parent_pid = ptid_get_pid (last_ptid);
-  child_pid = last_status.value.related_pid;
-
-  /* At this point, if we are vforking, breakpoints were already
-     detached from the child in child_wait; and the child has already
-     called execve().  If we are forking, both the parent and child
-     have breakpoints inserted.  */
-
-  if (! follow_child)
-    {
-      if (! has_vforked)
-       {
-         detach_breakpoints (child_pid);
-#ifdef SOLIB_REMOVE_INFERIOR_HOOK
-         SOLIB_REMOVE_INFERIOR_HOOK (child_pid);
-#endif
-       }
-
-      /* Detach from the child. */
-      printf_unfiltered ("Detaching after fork from %s\n",
-                        target_pid_to_str (pid_to_ptid (child_pid)));
-      hppa_require_detach (child_pid, 0);
-
-      /* The parent and child of a vfork share the same address space.
-        Also, on some targets the order in which vfork and exec events
-        are received for parent in child requires some delicate handling
-        of the events.
-
-        For instance, on ptrace-based HPUX we receive the child's vfork
-        event first, at which time the parent has been suspended by the
-        OS and is essentially untouchable until the child's exit or second
-        exec event arrives.  At that time, the parent's vfork event is
-        delivered to us, and that's when we see and decide how to follow
-        the vfork.  But to get to that point, we must continue the child
-        until it execs or exits.  To do that smoothly, all breakpoints
-        must be removed from the child, in case there are any set between
-        the vfork() and exec() calls.  But removing them from the child
-        also removes them from the parent, due to the shared-address-space
-        nature of a vfork'd parent and child.  On HPUX, therefore, we must
-        take care to restore the bp's to the parent before we continue it.
-        Else, it's likely that we may not stop in the expected place.  (The
-        worst scenario is when the user tries to step over a vfork() call;
-        the step-resume bp must be restored for the step to properly stop
-        in the parent after the call completes!)
-
-        Sequence of events, as reported to gdb from HPUX:
-
-        Parent        Child           Action for gdb to take
-        -------------------------------------------------------
-        1                VFORK               Continue child
-        2                EXEC
-        3                EXEC or EXIT
-        4  VFORK
-
-        Now that the child has safely exec'd or exited, we must restore
-        the parent's breakpoints before we continue it.  Else, we may
-        cause it run past expected stopping points.  */
-
-      if (has_vforked)
-       reattach_breakpoints (parent_pid);
-    }
-  else
-    {
-      /* Needed to keep the breakpoint lists in sync.  */
-      if (! has_vforked)
-       detach_breakpoints (child_pid);
-
-      /* Before detaching from the parent, remove all breakpoints from it. */
-      remove_breakpoints ();
-
-      /* Also reset the solib inferior hook from the parent. */
-#ifdef SOLIB_REMOVE_INFERIOR_HOOK
-      SOLIB_REMOVE_INFERIOR_HOOK (PIDGET (inferior_ptid));
-#endif
-
-      /* Detach from the parent. */
-      target_detach (NULL, 1);
-
-      /* Attach to the child. */
-      printf_unfiltered ("Attaching after fork to %s\n",
-                        target_pid_to_str (pid_to_ptid (child_pid)));
-      hppa_require_attach (child_pid);
-      inferior_ptid = pid_to_ptid (child_pid);
-
-      /* If we vforked, then we've also execed by now.  The exec will be
-        reported momentarily.  follow_exec () will handle breakpoints, so
-        we don't have to..  */
-      if (!has_vforked)
-       follow_inferior_reset_breakpoints ();
-    }
-
-  if (has_vforked)
-    {
-      /* If we followed the parent, don't try to follow the child's exec.  */
-      if (saved_vfork_state != STATE_GOT_PARENT
-         && saved_vfork_state != STATE_FAKE_EXEC)
-       fprintf_unfiltered (gdb_stdout,
-                           "hppa: post follow vfork: confused state\n");
-
-      if (! follow_child || saved_vfork_state == STATE_GOT_PARENT)
-       saved_vfork_state = STATE_NONE;
-      else
-       return 1;
-    }
-  return 0;
-}
-
-/* Format a process id, given PID.  Be sure to terminate
-   this with a null--it's going to be printed via a "%s".  */
-char *
-child_pid_to_str (ptid_t ptid)
-{
-  /* Static because address returned */
-  static char buf[30];
-  pid_t pid = PIDGET (ptid);
-
-  /* Extra NUL for paranoia's sake */
-  sprintf (buf, "process %d%c", pid, '\0');
-
-  return buf;
-}
-
-/* Format a thread id, given TID.  Be sure to terminate
-   this with a null--it's going to be printed via a "%s".
-
-   Note: This is a core-gdb tid, not the actual system tid.
-   See infttrace.c for details.  */
-char *
-hppa_tid_to_str (ptid_t ptid)
-{
-  /* Static because address returned */
-  static char buf[30];
-  /* This seems strange, but when I did the ptid conversion, it looked
-     as though a pid was always being passed.  - Kevin Buettner  */
-  pid_t tid = PIDGET (ptid);
-
-  /* Extra NULLs for paranoia's sake */
-  sprintf (buf, "system thread %d%c", tid, '\0');
-
-  return buf;
-}
-
-/*## */
-/* Enable HACK for ttrace work.  In
- * infttrace.c/require_notification_of_events,
- * this is set to 0 so that the loop in child_wait
- * won't loop.
- */
-int not_same_real_pid = 1;
-/*## */
-
-/* Wait for child to do something.  Return pid of child, or -1 in case
-   of error; store status through argument pointer OURSTATUS.  */
-
-ptid_t
-child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
-{
-  int save_errno;
-  int status;
-  char *execd_pathname = NULL;
-  int exit_status;
-  int related_pid;
-  int syscall_id;
-  enum target_waitkind kind;
-  int pid;
-
-  if (saved_vfork_state == STATE_FAKE_EXEC)
-    {
-      saved_vfork_state = STATE_NONE;
-      ourstatus->kind = TARGET_WAITKIND_EXECD;
-      ourstatus->value.execd_pathname = saved_child_execd_pathname;
-      return inferior_ptid;
-    }
-
-  do
-    {
-      set_sigint_trap ();      /* Causes SIGINT to be passed on to the
-                                  attached process. */
-      set_sigio_trap ();
-
-      pid = ptrace_wait (inferior_ptid, &status);
-
-      save_errno = errno;
-
-      clear_sigio_trap ();
-
-      clear_sigint_trap ();
-
-      if (pid == -1)
-       {
-         if (save_errno == EINTR)
-           continue;
-
-         fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
-                             safe_strerror (save_errno));
-
-         /* Claim it exited with unknown signal.  */
-         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-         ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
-         return pid_to_ptid (-1);
-       }
-
-      /* Did it exit?
-       */
-      if (target_has_exited (pid, status, &exit_status))
-       {
-         /* ??rehrauer: For now, ignore this. */
-         continue;
-       }
-
-      if (!target_thread_alive (pid_to_ptid (pid)))
-       {
-         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
-         return pid_to_ptid (pid);
-       }
-
-      if (hpux_has_forked (pid, &related_pid))
-       {
-         /* Ignore the parent's fork event.  */
-         if (pid == PIDGET (inferior_ptid))
-           {
-             ourstatus->kind = TARGET_WAITKIND_IGNORE;
-             return inferior_ptid;
-           }
-
-         /* If this is the child's fork event, report that the
-            process has forked.  */
-         if (related_pid == PIDGET (inferior_ptid))
-           {
-             ourstatus->kind = TARGET_WAITKIND_FORKED;
-             ourstatus->value.related_pid = pid;
-             return inferior_ptid;
-           }
-       }
-
-      if (hpux_has_vforked (pid, &related_pid))
-       {
-         if (pid == PIDGET (inferior_ptid))
-           {
-             if (saved_vfork_state == STATE_GOT_CHILD)
-               saved_vfork_state = STATE_GOT_PARENT;
-             else if (saved_vfork_state == STATE_GOT_EXEC)
-               saved_vfork_state = STATE_FAKE_EXEC;
-             else
-               fprintf_unfiltered (gdb_stdout,
-                                   "hppah: parent vfork: confused\n");
-           }
-         else if (related_pid == PIDGET (inferior_ptid))
-           {
-             if (saved_vfork_state == STATE_NONE)
-               saved_vfork_state = STATE_GOT_CHILD;
-             else
-               fprintf_unfiltered (gdb_stdout,
-                                   "hppah: child vfork: confused\n");
-           }
-         else
-           fprintf_unfiltered (gdb_stdout,
-                               "hppah: unknown vfork: confused\n");
-
-         if (saved_vfork_state == STATE_GOT_CHILD)
-           {
-             child_post_startup_inferior (pid_to_ptid (pid));
-             detach_breakpoints (pid);
-#ifdef SOLIB_REMOVE_INFERIOR_HOOK
-             SOLIB_REMOVE_INFERIOR_HOOK (pid);
-#endif
-             child_resume (pid_to_ptid (pid), 0, TARGET_SIGNAL_0);
-             ourstatus->kind = TARGET_WAITKIND_IGNORE;
-             return pid_to_ptid (related_pid);
-           }
-         else if (saved_vfork_state == STATE_FAKE_EXEC)
-           {
-             ourstatus->kind = TARGET_WAITKIND_VFORKED;
-             ourstatus->value.related_pid = related_pid;
-             return pid_to_ptid (pid);
-           }
-         else
-           {
-             /* We saw the parent's vfork, but we haven't seen the exec yet.
-                Wait for it, for simplicity's sake.  It should be pending.  */
-             saved_vfork_pid = related_pid;
-             ourstatus->kind = TARGET_WAITKIND_IGNORE;
-             return pid_to_ptid (pid);
-           }
-       }
-
-      if (hpux_has_execd (pid, &execd_pathname))
-       {
-         /* On HP-UX, events associated with a vforking inferior come in
-            threes: a vfork event for the child (always first), followed
-            a vfork event for the parent and an exec event for the child.
-            The latter two can come in either order.  Make sure we get
-            both.  */
-         if (saved_vfork_state != STATE_NONE)
-           {
-             if (saved_vfork_state == STATE_GOT_CHILD)
-               {
-                 saved_vfork_state = STATE_GOT_EXEC;
-                 /* On HP/UX with ptrace, the child must be resumed before
-                    the parent vfork event is delivered.  A single-step
-                    suffices.  */
-                 if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ())
-                   target_resume (pid_to_ptid (pid), 1, TARGET_SIGNAL_0);
-                 ourstatus->kind = TARGET_WAITKIND_IGNORE;
-               }
-             else if (saved_vfork_state == STATE_GOT_PARENT)
-               {
-                 saved_vfork_state = STATE_FAKE_EXEC;
-                 ourstatus->kind = TARGET_WAITKIND_VFORKED;
-                 ourstatus->value.related_pid = saved_vfork_pid;
-               }
-             else
-               fprintf_unfiltered (gdb_stdout,
-                                   "hppa: exec: unexpected state\n");
-
-             saved_child_execd_pathname = execd_pathname;
-
-             return inferior_ptid;
-           }
-         
-         /* Are we ignoring initial exec events?  (This is likely because
-            we're in the process of starting up the inferior, and another
-            (older) mechanism handles those.)  If so, we'll report this
-            as a regular stop, not an exec.
-          */
-         if (inferior_ignoring_startup_exec_events)
-           {
-             inferior_ignoring_startup_exec_events--;
-           }
-         else
-           {
-             ourstatus->kind = TARGET_WAITKIND_EXECD;
-             ourstatus->value.execd_pathname = execd_pathname;
-             return pid_to_ptid (pid);
-           }
-       }
-
-      /* All we must do with these is communicate their occurrence
-         to wait_for_inferior...
-       */
-      if (hpux_has_syscall_event (pid, &kind, &syscall_id))
-       {
-         ourstatus->kind = kind;
-         ourstatus->value.syscall_id = syscall_id;
-         return pid_to_ptid (pid);
-       }
-
-      /*##  } while (pid != PIDGET (inferior_ptid)); ## *//* Some other child died or stopped */
-/* hack for thread testing */
-    }
-  while ((pid != PIDGET (inferior_ptid)) && not_same_real_pid);
-/*## */
-
-  store_waitstatus (ourstatus, status);
-  return pid_to_ptid (pid);
-}
-
-#if !defined (GDB_NATIVE_HPUX_11)
-
-/* The following code is a substitute for the infttrace.c versions used
-   with ttrace() in HPUX 11.  */
-
-/* This value is an arbitrary integer. */
-#define PT_VERSION 123456
-
-/* This semaphore is used to coordinate the child and parent processes
-   after a fork(), and before an exec() by the child.  See
-   parent_attach_all for details.  */
-
-typedef struct
-{
-  int parent_channel[2];       /* Parent "talks" to [1], child "listens" to [0] */
-  int child_channel[2];                /* Child "talks" to [1], parent "listens" to [0] */
-}
-startup_semaphore_t;
-
-#define SEM_TALK (1)
-#define SEM_LISTEN (0)
-
-static startup_semaphore_t startup_semaphore;
-
-#ifdef PT_SETTRC
-/* This function causes the caller's process to be traced by its
-   parent.  This is intended to be called after GDB forks itself,
-   and before the child execs the target.
-
-   Note that HP-UX ptrace is rather funky in how this is done.
-   If the parent wants to get the initial exec event of a child,
-   it must set the ptrace event mask of the child to include execs.
-   (The child cannot do this itself.)  This must be done after the
-   child is forked, but before it execs.
-
-   To coordinate the parent and child, we implement a semaphore using
-   pipes.  After SETTRC'ing itself, the child tells the parent that
-   it is now traceable by the parent, and waits for the parent's
-   acknowledgement.  The parent can then set the child's event mask,
-   and notify the child that it can now exec.
-
-   (The acknowledgement by parent happens as a result of a call to
-   child_acknowledge_created_inferior.)  */
-
-int
-parent_attach_all (int pid, PTRACE_ARG3_TYPE addr, int data)
-{
-  int pt_status = 0;
-
-  /* We need a memory home for a constant.  */
-  int tc_magic_child = PT_VERSION;
-  int tc_magic_parent = 0;
-
-  /* The remainder of this function is only useful for HPUX 10.0 and
-     later, as it depends upon the ability to request notification
-     of specific kinds of events by the kernel.  */
-#if defined(PT_SET_EVENT_MASK)
-
-  /* Notify the parent that we're potentially ready to exec(). */
-  write (startup_semaphore.child_channel[SEM_TALK],
-        &tc_magic_child,
-        sizeof (tc_magic_child));
-
-  /* Wait for acknowledgement from the parent. */
-  read (startup_semaphore.parent_channel[SEM_LISTEN],
-       &tc_magic_parent,
-       sizeof (tc_magic_parent));
-  if (tc_magic_child != tc_magic_parent)
-    warning ("mismatched semaphore magic");
-
-  /* Discard our copy of the semaphore. */
-  (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.parent_channel[SEM_TALK]);
-  (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.child_channel[SEM_TALK]);
-#endif
-
-  return 0;
-}
-#endif
-
-int
-hppa_require_attach (int pid)
-{
-  int pt_status;
-  CORE_ADDR pc;
-  CORE_ADDR pc_addr;
-  unsigned int regs_offset;
-
-  /* Are we already attached?  There appears to be no explicit way to
-     answer this via ptrace, so we try something which should be
-     innocuous if we are attached.  If that fails, then we assume
-     we're not attached, and so attempt to make it so. */
-
-  errno = 0;
-  regs_offset = U_REGS_OFFSET;
-  pc_addr = register_addr (PC_REGNUM, regs_offset);
-  pc = call_ptrace (PT_READ_U, pid, (PTRACE_ARG3_TYPE) pc_addr, 0);
-
-  if (errno)
-    {
-      errno = 0;
-      pt_status = call_ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0);
-
-      if (errno)
-       return -1;
-
-      /* Now we really are attached. */
-      errno = 0;
-    }
-  attach_flag = 1;
-  return pid;
-}
-
-int
-hppa_require_detach (int pid, int signal)
-{
-  errno = 0;
-  call_ptrace (PT_DETACH, pid, (PTRACE_ARG3_TYPE) 1, signal);
-  errno = 0;                   /* Ignore any errors. */
-  return pid;
-}
-
-/* Since ptrace doesn't support memory page-protection events, which
-   are used to implement "hardware" watchpoints on HP-UX, these are
-   dummy versions, which perform no useful work.  */
-
-void
-hppa_enable_page_protection_events (int pid)
-{
-}
-
-void
-hppa_disable_page_protection_events (int pid)
-{
-}
-
-int
-hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
-{
-  error ("Hardware watchpoints not implemented on this platform.");
-}
-
-int
-hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
-{
-  error ("Hardware watchpoints not implemented on this platform.");
-}
-
-int
-hppa_can_use_hw_watchpoint (int type, int cnt, int ot)
-{
-  return 0;
-}
-
-int
-hppa_range_profitable_for_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len)
-{
-  error ("Hardware watchpoints not implemented on this platform.");
-}
-
-char *
-hppa_pid_or_tid_to_str (ptid_t id)
-{
-  /* In the ptrace world, there are only processes. */
-  return child_pid_to_str (id);
-}
-
-void
-hppa_ensure_vforking_parent_remains_stopped (int pid)
-{
-  /* This assumes that the vforked parent is presently stopped, and
-     that the vforked child has just delivered its first exec event.
-     Calling kill() this way will cause the SIGTRAP to be delivered as
-     soon as the parent is resumed, which happens as soon as the
-     vforked child is resumed.  See wait_for_inferior for the use of
-     this function.  */
-  kill (pid, SIGTRAP);
-}
-
-int
-hppa_resume_execd_vforking_child_to_get_parent_vfork (void)
-{
-  return 1;                    /* Yes, the child must be resumed. */
-}
-
-void
-require_notification_of_events (int pid)
-{
-#if defined(PT_SET_EVENT_MASK)
-  int pt_status;
-  ptrace_event_t ptrace_events;
-  int nsigs;
-  int signum;
-
-  /* Instruct the kernel as to the set of events we wish to be
-     informed of.  (This support does not exist before HPUX 10.0.
-     We'll assume if PT_SET_EVENT_MASK has not been defined by
-     <sys/ptrace.h>, then we're being built on pre-10.0.)  */
-  memset (&ptrace_events, 0, sizeof (ptrace_events));
-
-  /* Note: By default, all signals are visible to us.  If we wish
-     the kernel to keep certain signals hidden from us, we do it
-     by calling sigdelset (ptrace_events.pe_signals, signal) for
-     each such signal here, before doing PT_SET_EVENT_MASK.  */
-  /* RM: The above comment is no longer true. We start with ignoring
-     all signals, and then add the ones we are interested in. We could
-     do it the other way: start by looking at all signals and then
-     deleting the ones that we aren't interested in, except that
-     multiple gdb signals may be mapped to the same host signal
-     (eg. TARGET_SIGNAL_IO and TARGET_SIGNAL_POLL both get mapped to
-     signal 22 on HPUX 10.20) We want to be notified if we are
-     interested in either signal.  */
-  sigfillset (&ptrace_events.pe_signals);
-
-  /* RM: Let's not bother with signals we don't care about */
-  nsigs = (int) TARGET_SIGNAL_LAST;
-  for (signum = nsigs; signum > 0; signum--)
-    {
-      if ((signal_stop_state (signum)) ||
-         (signal_print_state (signum)) ||
-         (!signal_pass_state (signum)))
-       {
-         if (target_signal_to_host_p (signum))
-           sigdelset (&ptrace_events.pe_signals,
-                      target_signal_to_host (signum));
-       }
-    }
-
-  ptrace_events.pe_set_event = 0;
-
-  ptrace_events.pe_set_event |= PTRACE_SIGNAL;
-  ptrace_events.pe_set_event |= PTRACE_EXEC;
-  ptrace_events.pe_set_event |= PTRACE_FORK;
-  ptrace_events.pe_set_event |= PTRACE_VFORK;
-  /* ??rehrauer: Add this one when we're prepared to catch it...
-     ptrace_events.pe_set_event |= PTRACE_EXIT;
-   */
-
-  errno = 0;
-  pt_status = call_ptrace (PT_SET_EVENT_MASK,
-                          pid,
-                          (PTRACE_ARG3_TYPE) & ptrace_events,
-                          sizeof (ptrace_events));
-  if (errno)
-    perror_with_name ("ptrace");
-  if (pt_status < 0)
-    return;
-#endif
-}
-
-void
-require_notification_of_exec_events (int pid)
-{
-#if defined(PT_SET_EVENT_MASK)
-  int pt_status;
-  ptrace_event_t ptrace_events;
-
-  /* Instruct the kernel as to the set of events we wish to be
-     informed of.  (This support does not exist before HPUX 10.0.
-     We'll assume if PT_SET_EVENT_MASK has not been defined by
-     <sys/ptrace.h>, then we're being built on pre-10.0.)  */
-  memset (&ptrace_events, 0, sizeof (ptrace_events));
-
-  /* Note: By default, all signals are visible to us.  If we wish
-     the kernel to keep certain signals hidden from us, we do it
-     by calling sigdelset (ptrace_events.pe_signals, signal) for
-     each such signal here, before doing PT_SET_EVENT_MASK.  */
-  sigemptyset (&ptrace_events.pe_signals);
-
-  ptrace_events.pe_set_event = 0;
-
-  ptrace_events.pe_set_event |= PTRACE_EXEC;
-  /* ??rehrauer: Add this one when we're prepared to catch it...
-     ptrace_events.pe_set_event |= PTRACE_EXIT;
-   */
-
-  errno = 0;
-  pt_status = call_ptrace (PT_SET_EVENT_MASK,
-                          pid,
-                          (PTRACE_ARG3_TYPE) & ptrace_events,
-                          sizeof (ptrace_events));
-  if (errno)
-    perror_with_name ("ptrace");
-  if (pt_status < 0)
-    return;
-#endif
-}
-
-/* This function is called by the parent process, with pid being the
-   ID of the child process, after the debugger has forked.  */
-
-void
-child_acknowledge_created_inferior (int pid)
-{
-  /* We need a memory home for a constant.  */
-  int tc_magic_parent = PT_VERSION;
-  int tc_magic_child = 0;
-
-  /* The remainder of this function is only useful for HPUX 10.0 and
-     later, as it depends upon the ability to request notification
-     of specific kinds of events by the kernel.  */
-#if defined(PT_SET_EVENT_MASK)
-  /* Wait for the child to tell us that it has forked. */
-  read (startup_semaphore.child_channel[SEM_LISTEN],
-       &tc_magic_child,
-       sizeof (tc_magic_child));
-
-  /* Notify the child that it can exec.
-
-     In the infttrace.c variant of this function, we set the child's
-     event mask after the fork but before the exec.  In the ptrace
-     world, it seems we can't set the event mask until after the exec.  */
-  write (startup_semaphore.parent_channel[SEM_TALK],
-        &tc_magic_parent,
-        sizeof (tc_magic_parent));
-
-  /* We'd better pause a bit before trying to set the event mask,
-     though, to ensure that the exec has happened.  We don't want to
-     wait() on the child, because that'll screw up the upper layers
-     of gdb's execution control that expect to see the exec event.
-
-     After an exec, the child is no longer executing gdb code.  Hence,
-     we can't have yet another synchronization via the pipes.  We'll
-     just sleep for a second, and hope that's enough delay...  */
-  sleep (1);
-
-  /* Instruct the kernel as to the set of events we wish to be
-     informed of.  */
-  require_notification_of_exec_events (pid);
-
-  /* Discard our copy of the semaphore. */
-  (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.parent_channel[SEM_TALK]);
-  (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.child_channel[SEM_TALK]);
-#endif
-}
-
-void
-child_post_startup_inferior (ptid_t ptid)
-{
-  require_notification_of_events (PIDGET (ptid));
-}
-
-void
-child_post_attach (int pid)
-{
-  require_notification_of_events (pid);
-}
-
-int
-child_insert_fork_catchpoint (int pid)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_SET_EVENT_MASK)
-  error ("Unable to catch forks prior to HPUX 10.0");
-#else
-  /* Enable reporting of fork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.  */
-  return 0;
-#endif
-}
-
-int
-child_remove_fork_catchpoint (int pid)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_SET_EVENT_MASK)
-  error ("Unable to catch forks prior to HPUX 10.0");
-#else
-  /* Disable reporting of fork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.  */
-  return 0;
-#endif
-}
-
-int
-child_insert_vfork_catchpoint (int pid)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_SET_EVENT_MASK)
-  error ("Unable to catch vforks prior to HPUX 10.0");
-#else
-  /* Enable reporting of vfork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.  */
-  return 0;
-#endif
-}
-
-int
-child_remove_vfork_catchpoint (int pid)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_SET_EVENT_MASK)
-  error ("Unable to catch vforks prior to HPUX 10.0");
-#else
-  /* Disable reporting of vfork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.  */
-  return 0;
-#endif
-}
-
-int
-hpux_has_forked (int pid, int *childpid)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_GET_PROCESS_STATE)
-  *childpid = 0;
-  return 0;
-#else
-  int pt_status;
-  ptrace_state_t ptrace_state;
-
-  errno = 0;
-  pt_status = call_ptrace (PT_GET_PROCESS_STATE,
-                          pid,
-                          (PTRACE_ARG3_TYPE) & ptrace_state,
-                          sizeof (ptrace_state));
-  if (errno)
-    perror_with_name ("ptrace");
-  if (pt_status < 0)
-    return 0;
-
-  if (ptrace_state.pe_report_event & PTRACE_FORK)
-    {
-      *childpid = ptrace_state.pe_other_pid;
-      return 1;
-    }
-
-  return 0;
-#endif
-}
-
-int
-hpux_has_vforked (int pid, int *childpid)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_GET_PROCESS_STATE)
-  *childpid = 0;
-  return 0;
-
-#else
-  int pt_status;
-  ptrace_state_t ptrace_state;
-
-  errno = 0;
-  pt_status = call_ptrace (PT_GET_PROCESS_STATE,
-                          pid,
-                          (PTRACE_ARG3_TYPE) & ptrace_state,
-                          sizeof (ptrace_state));
-  if (errno)
-    perror_with_name ("ptrace");
-  if (pt_status < 0)
-    return 0;
-
-  if (ptrace_state.pe_report_event & PTRACE_VFORK)
-    {
-      *childpid = ptrace_state.pe_other_pid;
-      return 1;
-    }
-
-  return 0;
-#endif
-}
-
-int
-child_insert_exec_catchpoint (int pid)
-{
-  /* This request is only available on HPUX 10.0 and later.   */
-#if !defined(PT_SET_EVENT_MASK)
-  error ("Unable to catch execs prior to HPUX 10.0");
-
-#else
-  /* Enable reporting of exec events from the kernel.  */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.  */
-  return 0;
-#endif
-}
-
-int
-child_remove_exec_catchpoint (int pid)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_SET_EVENT_MASK)
-  error ("Unable to catch execs prior to HPUX 10.0");
-
-#else
-  /* Disable reporting of exec events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.  */
-  return 0;
-#endif
-}
-
-int
-hpux_has_execd (int pid, char **execd_pathname)
-{
-  /* This request is only available on HPUX 10.0 and later.  */
-#if !defined(PT_GET_PROCESS_STATE)
-  *execd_pathname = NULL;
-  return 0;
-
-#else
-  int pt_status;
-  ptrace_state_t ptrace_state;
-
-  errno = 0;
-  pt_status = call_ptrace (PT_GET_PROCESS_STATE,
-                          pid,
-                          (PTRACE_ARG3_TYPE) & ptrace_state,
-                          sizeof (ptrace_state));
-  if (errno)
-    perror_with_name ("ptrace");
-  if (pt_status < 0)
-    return 0;
-
-  if (ptrace_state.pe_report_event & PTRACE_EXEC)
-    {
-      char *exec_file = target_pid_to_exec_file (pid);
-      *execd_pathname = savestring (exec_file, strlen (exec_file));
-      return 1;
-    }
-
-  return 0;
-#endif
-}
-
-int
-child_reported_exec_events_per_exec_call (void)
-{
-  return 2;                    /* ptrace reports the event twice per call. */
-}
-
-int
-hpux_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
-{
-  /* This request is only available on HPUX 10.30 and later, via
-     the ttrace interface.  */
-
-  *kind = TARGET_WAITKIND_SPURIOUS;
-  *syscall_id = -1;
-  return 0;
-}
-
-char *
-child_pid_to_exec_file (int pid)
-{
-  static char exec_file_buffer[1024];
-  int pt_status;
-  CORE_ADDR top_of_stack;
-  char four_chars[4];
-  int name_index;
-  int i;
-  ptid_t saved_inferior_ptid;
-  int done;
-
-#ifdef PT_GET_PROCESS_PATHNAME
-  /* As of 10.x HP-UX, there's an explicit request to get the pathname. */
-  pt_status = call_ptrace (PT_GET_PROCESS_PATHNAME,
-                          pid,
-                          (PTRACE_ARG3_TYPE) exec_file_buffer,
-                          sizeof (exec_file_buffer) - 1);
-  if (pt_status == 0)
-    return exec_file_buffer;
-#endif
-
-  /* It appears that this request is broken prior to 10.30.
-     If it fails, try a really, truly amazingly gross hack
-     that DDE uses, of pawing through the process' data
-     segment to find the pathname.  */
-
-  top_of_stack = 0x7b03a000;
-  name_index = 0;
-  done = 0;
-
-  /* On the chance that pid != inferior_ptid, set inferior_ptid
-     to pid, so that (grrrr!) implicit uses of inferior_ptid get
-     the right id.  */
-
-  saved_inferior_ptid = inferior_ptid;
-  inferior_ptid = pid_to_ptid (pid);
-
-  /* Try to grab a null-terminated string. */
-  while (!done)
-    {
-      if (target_read_memory (top_of_stack, four_chars, 4) != 0)
-       {
-         inferior_ptid = saved_inferior_ptid;
-         return NULL;
-       }
-      for (i = 0; i < 4; i++)
-       {
-         exec_file_buffer[name_index++] = four_chars[i];
-         done = (four_chars[i] == '\0');
-         if (done)
-           break;
-       }
-      top_of_stack += 4;
-    }
-
-  if (exec_file_buffer[0] == '\0')
-    {
-      inferior_ptid = saved_inferior_ptid;
-      return NULL;
-    }
-
-  inferior_ptid = saved_inferior_ptid;
-  return exec_file_buffer;
-}
-
-void
-pre_fork_inferior (void)
-{
-  int status;
-
-  status = pipe (startup_semaphore.parent_channel);
-  if (status < 0)
-    {
-      warning ("error getting parent pipe for startup semaphore");
-      return;
-    }
-
-  status = pipe (startup_semaphore.child_channel);
-  if (status < 0)
-    {
-      warning ("error getting child pipe for startup semaphore");
-      return;
-    }
-}
-\f
-
-/* Check to see if the given thread is alive.
-
-   This is a no-op, as ptrace doesn't support threads, so we just
-   return "TRUE".  */
-
-int
-child_thread_alive (ptid_t ptid)
-{
-  return 1;
-}
-
-#endif /* ! GDB_NATIVE_HPUX_11 */
diff --git a/gdb/infttrace.c b/gdb/infttrace.c
deleted file mode 100644 (file)
index 4171651..0000000
+++ /dev/null
@@ -1,5596 +0,0 @@
-/* Low level Unix child interface to ttrace, for GDB when running under HP-UX.
-
-   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1998, 1999, 2000, 2001, 2003, 2004 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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include "defs.h"
-#include "frame.h"
-#include "inferior.h"
-#include "target.h"
-#include "gdb_string.h"
-#include "gdb_wait.h"
-#include "command.h"
-#include "gdbthread.h"
-#include "infttrace.h"
-
-/* We need pstat functionality so that we can get the exec file
-   for a process we attach to.
-
-   According to HP, we should use the 64bit interfaces, so we
-   define _PSTAT64 to achieve this.  */
-#define _PSTAT64
-#include <sys/pstat.h>
-
-/* Some hackery to work around a use of the #define name NO_FLAGS
- * in both gdb and HPUX (bfd.h and /usr/include/machine/vmparam.h).
- */
-#ifdef  NO_FLAGS
-#define INFTTRACE_TEMP_HACK NO_FLAGS
-#undef  NO_FLAGS
-#endif
-
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-
-#include <sys/ttrace.h>
-#include <sys/mman.h>
-
-#ifndef NO_PTRACE_H
-#ifdef PTRACE_IN_WRONG_PLACE
-#include <ptrace.h>
-#else
-#include <sys/ptrace.h>
-#endif
-#endif /* NO_PTRACE_H */
-
-/* Second half of the hackery above.  Non-ANSI C, so
- * we can't use "#error", alas.
- */
-#ifdef NO_FLAGS
-#if (NO_FLAGS != INFTTRACE_TEMP_HACK )
-  /* #error "Hackery to remove warning didn't work right" */
-#else
-  /* Ok, new def'n of NO_FLAGS is same as old one; no action needed. */
-#endif
-#else
-  /* #error "Didn't get expected re-definition of NO_FLAGS" */
-#define NO_FLAGS INFTTRACE_TEMP_HACK
-#endif
-
-#if !defined (PT_SETTRC)
-#define PT_SETTRC      0       /* Make process traceable by parent */
-#endif
-#if !defined (PT_READ_I)
-#define PT_READ_I      1       /* Read word from text space */
-#endif
-#if !defined (PT_READ_D)
-#define        PT_READ_D       2       /* Read word from data space */
-#endif
-#if !defined (PT_READ_U)
-#define PT_READ_U      3       /* Read word from kernel user struct */
-#endif
-#if !defined (PT_WRITE_I)
-#define PT_WRITE_I     4       /* Write word to text space */
-#endif
-#if !defined (PT_WRITE_D)
-#define PT_WRITE_D     5       /* Write word to data space */
-#endif
-#if !defined (PT_WRITE_U)
-#define PT_WRITE_U     6       /* Write word to kernel user struct */
-#endif
-#if !defined (PT_CONTINUE)
-#define PT_CONTINUE    7       /* Continue after signal */
-#endif
-#if !defined (PT_STEP)
-#define PT_STEP                9       /* Set flag for single stepping */
-#endif
-#if !defined (PT_KILL)
-#define PT_KILL                8       /* Send child a SIGKILL signal */
-#endif
-
-#ifndef PT_ATTACH
-#define PT_ATTACH PTRACE_ATTACH
-#endif
-#ifndef PT_DETACH
-#define PT_DETACH PTRACE_DETACH
-#endif
-
-#include "gdbcore.h"
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h>
-#endif
-
-/* This semaphore is used to coordinate the child and parent processes
-   after a fork(), and before an exec() by the child.  See parent_attach_all
-   for details.
- */
-typedef struct
-  {
-    int parent_channel[2];     /* Parent "talks" to [1], child "listens" to [0] */
-    int child_channel[2];      /* Child "talks" to [1], parent "listens" to [0] */
-  }
-startup_semaphore_t;
-
-#define SEM_TALK (1)
-#define SEM_LISTEN (0)
-
-static startup_semaphore_t startup_semaphore;
-
-/* See can_touch_threads_of_process for details. */
-static int vforking_child_pid = 0;
-static int vfork_in_flight = 0;
-
-/* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise.
- */
-#define TT_OK( _status, _errno ) \
-    (((_status) == 1) && ((_errno) == 0))
-
-#define TTRACE_ARG_TYPE uint64_t
-
-/* When supplied as the "addr" operand, ttrace interprets this
-   to mean, "from the current address".
- */
-#define TT_USE_CURRENT_PC ((TTRACE_ARG_TYPE) TT_NOPC)
-
-/* When supplied as the "addr", "data" or "addr2" operand for most
-   requests, ttrace interprets this to mean, "pay no heed to this
-   argument".
- */
-#define TT_NIL ((TTRACE_ARG_TYPE) TT_NULLARG)
-
-/* This is capable of holding the value of a 32-bit register.  The
-   value is always left-aligned in the buffer; i.e., [0] contains
-   the most-significant byte of the register's value, and [sizeof(reg)]
-   contains the least-significant value.
-
-   ??rehrauer: Yes, this assumes that an int is 32-bits on HP-UX, and
-   that registers are 32-bits on HP-UX.  The latter assumption changes
-   with PA2.0.
- */
-typedef int register_value_t;
-
-/********************************************************************
-
-                 How this works:
-
-   1.  Thread numbers
-
-   The rest of GDB sees threads as being things with different
-   "pid" (process id) values.  See "thread.c" for details.  The
-   separate threads will be seen and reacted to if infttrace passes
-   back different pid values (for _events_).  See wait_for_inferior
-   in inftarg.c.
-
-   So infttrace is going to use thread ids externally, pretending
-   they are process ids, and keep track internally so that it can
-   use the real process id (and thread id) when calling ttrace.
-
-   The data structure that supports this is a linked list of the
-   current threads.  Since at some date infttrace will have to
-   deal with multiple processes, each list element records its
-   corresponding pid, rather than having a single global.
-
-   Note that the list is only approximately current; that's ok, as
-   it's up to date when we need it (we hope!).  Also, it can contain
-   dead threads, as there's no harm if it does.
-
-   The approach taken here is to bury the translation from external
-   to internal inside "call_ttrace" and a few other places.
-
-   There are some wrinkles:
-
-   o  When GDB forks itself to create the debug target process,
-      there's only a pid of 0 around in the child, so the
-      TT_PROC_SETTRC operation uses a more direct call to ttrace;
-      Similiarly, the initial setting of the event mask happens
-      early as  well, and so is also special-cased, and an attach
-      uses a real pid;
-
-   o  We define an unthreaded application as having a "pseudo"
-      thread;
-
-   o  To keep from confusing the rest of GDB, we don't switch
-      the PID for the pseudo thread to a TID.  A table will help:
-
-      Rest of GDB sees these PIDs:     pid   tid1  tid2  tid3 ...
-                                        
-      Our thread list stores:          pid   pid   pid   pid  ...
-                                       tid0  tid1  tid2  tid3
-      
-      Ttrace sees these TIDS:          tid0  tid1  tid2  tid3 ...
-
-      Both pid and tid0 will map to tid0, as there are infttrace.c-internal
-      calls to ttrace using tid0.
-
-   2. Step and Continue
-
-   Since we're implementing the "stop the world" model, sub-model
-   "other threads run during step", we have some stuff to do:
-
-   o  User steps require continuing all threads other than the
-      one the user is stepping;
-
-   o  Internal debugger steps (such as over a breakpoint or watchpoint,
-      but not out of a library load thunk) require stepping only
-      the selected thread; this means that we have to report the
-      step finish on that thread, which can lead to complications;
-
-   o  When a thread is created, it is created running, rather
-      than stopped--so we have to stop it.
-
-   The OS doesn't guarantee the stopped thread list will be stable,
-   no does it guarantee where on the stopped thread list a thread
-   that is single-stepped will wind up: it's possible that it will
-   be off the list for a while, it's possible the step will complete
-   and it will be re-posted to the end...
-
-   This means we have to scan the stopped thread list, build up
-   a work-list, and then run down the work list; we can't do the
-   step/continue during the scan.
-
-   3. Buffering events
-
-   Then there's the issue of waiting for an event.  We do this by
-   noticing how many events are reported at the end of each wait.
-   From then on, we "fake" all resumes and steps, returning instantly,
-   and don't do another wait.  Once all pending events are reported,
-   we can really resume again.
-
-   To keep this hidden, all the routines which know about tids and
-   pids or real events and simulated ones are static (file-local).
-
-   This code can make lots of calls to ttrace, in particular it
-   can spin down the list of thread states more than once.  If this
-   becomes a performance hit, the spin could be done once and the
-   various "tsp" blocks saved, keeping all later spins in this
-   process.
-
-   The O/S doesn't promise to keep the list straight, and so we must
-   re-scan a lot.  By observation, it looks like a single-step/wait
-   puts the stepped thread at the end of the list but doesn't change
-   it otherwise.
-
-****************************************************************
-*/
-
-/* Uncomment these to turn on various debugging output */
-/* #define THREAD_DEBUG */
-/* #define WAIT_BUFFER_DEBUG */
-/* #define PARANOIA */
-
-
-#define INFTTRACE_ALL_THREADS (-1)
-#define INFTTRACE_STEP        (1)
-#define INFTTRACE_CONTINUE    (0)
-
-/* FIX: this is used in inftarg.c/child_wait, in a hack.
- */
-extern int not_same_real_pid;
-
-/* This is used to count buffered events.
- */
-static unsigned int more_events_left = 0;
-
-/* Process state.
- */
-typedef enum process_state_enum
-  {
-    STOPPED,
-    FAKE_STEPPING,
-    FAKE_CONTINUE,             /* For later use */
-    RUNNING,
-    FORKING,
-    VFORKING
-  }
-process_state_t;
-
-static process_state_t process_state = STOPPED;
-
-/* User-specified stepping modality.
- */
-typedef enum stepping_mode_enum
-  {
-    DO_DEFAULT,                        /* ...which is a continue! */
-    DO_STEP,
-    DO_CONTINUE
-  }
-stepping_mode_t;
-
-/* Action to take on an attach, depends on
- * what kind (user command, fork, vfork).
- *
- * At the moment, this is either:
- *
- * o  continue with a SIGTRAP signal, or
- *
- * o  leave stopped.
- */
-typedef enum attach_continue_enum
-  {
-    DO_ATTACH_CONTINUE,
-    DONT_ATTACH_CONTINUE
-  }
-attach_continue_t;
-
-/* This flag is true if we are doing a step-over-bpt
- * with buffered events.  We will have to be sure to
- * report the right thread, as otherwise the spaghetti
- * code in "infrun.c/wait_for_inferior" will get
- * confused.
- */
-static int doing_fake_step = 0;
-static lwpid_t fake_step_tid = 0;
-\f
-
-/****************************************************
- * Thread information structure routines and types. *
- ****************************************************
- */
-typedef
-struct thread_info_struct
-  {
-    int am_pseudo;             /* This is a pseudo-thread for the process. */
-    int pid;                   /* Process ID */
-    lwpid_t tid;               /* Thread  ID */
-    int handled;               /* 1 if a buffered event was handled. */
-    int seen;                  /* 1 if this thread was seen on a traverse. */
-    int terminated;            /* 1 if thread has terminated. */
-    int have_signal;           /* 1 if signal to be sent */
-    enum target_signal signal_value;   /* Signal to send */
-    int have_start;            /* 1 if alternate starting address */
-    stepping_mode_t stepping_mode;     /* Whether to step or continue */
-    CORE_ADDR start;           /* Where to start */
-    int have_state;            /* 1 if the event state has been set */
-    ttstate_t last_stop_state; /* The most recently-waited event for this thread. */
-    struct thread_info_struct
-     *next;                    /* All threads are linked via this field. */
-    struct thread_info_struct
-     *next_pseudo;             /* All pseudo-threads are linked via this field. */
-  }
-thread_info;
-
-typedef
-struct thread_info_header_struct
-  {
-    int count;
-    thread_info *head;
-    thread_info *head_pseudo;
-
-  }
-thread_info_header;
-
-static thread_info_header thread_head =
-{0, NULL, NULL};
-static thread_info_header deleted_threads =
-{0, NULL, NULL};
-
-static ptid_t saved_real_ptid;
-\f
-
-/*************************************************
- *          Debugging support functions          *
- *************************************************
- */
-CORE_ADDR
-get_raw_pc (lwpid_t ttid)
-{
-  unsigned long pc_val;
-  int offset;
-  int res;
-
-  offset = register_addr (PC_REGNUM, U_REGS_OFFSET);
-  res = read_from_register_save_state (
-                                       ttid,
-                                       (TTRACE_ARG_TYPE) offset,
-                                       (char *) &pc_val,
-                                       sizeof (pc_val));
-  if (res <= 0)
-    {
-      return (CORE_ADDR) pc_val;
-    }
-  else
-    {
-      return (CORE_ADDR) 0;
-    }
-}
-
-static char *
-get_printable_name_of_stepping_mode (stepping_mode_t mode)
-{
-  switch (mode)
-    {
-    case DO_DEFAULT:
-      return "DO_DEFAULT";
-    case DO_STEP:
-      return "DO_STEP";
-    case DO_CONTINUE:
-      return "DO_CONTINUE";
-    default:
-      return "?unknown mode?";
-    }
-}
-
-/* This function returns a pointer to a string describing the
- * ttrace event being reported.
- */
-char *
-get_printable_name_of_ttrace_event (ttevents_t event)
-{
-  /* This enumeration is "gappy", so don't use a table. */
-  switch (event)
-    {
-
-    case TTEVT_NONE:
-      return "TTEVT_NONE";
-    case TTEVT_SIGNAL:
-      return "TTEVT_SIGNAL";
-    case TTEVT_FORK:
-      return "TTEVT_FORK";
-    case TTEVT_EXEC:
-      return "TTEVT_EXEC";
-    case TTEVT_EXIT:
-      return "TTEVT_EXIT";
-    case TTEVT_VFORK:
-      return "TTEVT_VFORK";
-    case TTEVT_SYSCALL_RETURN:
-      return "TTEVT_SYSCALL_RETURN";
-    case TTEVT_LWP_CREATE:
-      return "TTEVT_LWP_CREATE";
-    case TTEVT_LWP_TERMINATE:
-      return "TTEVT_LWP_TERMINATE";
-    case TTEVT_LWP_EXIT:
-      return "TTEVT_LWP_EXIT";
-    case TTEVT_LWP_ABORT_SYSCALL:
-      return "TTEVT_LWP_ABORT_SYSCALL";
-    case TTEVT_SYSCALL_ENTRY:
-      return "TTEVT_SYSCALL_ENTRY";
-    case TTEVT_SYSCALL_RESTART:
-      return "TTEVT_SYSCALL_RESTART";
-    default:
-      return "?new event?";
-    }
-}
-\f
-
-/* This function translates the ttrace request enumeration into
- * a character string that is its printable (aka "human readable")
- * name.
- */
-char *
-get_printable_name_of_ttrace_request (ttreq_t request)
-{
-  if (!IS_TTRACE_REQ (request))
-    return "?bad req?";
-
-  /* This enumeration is "gappy", so don't use a table. */
-  switch (request)
-    {
-    case TT_PROC_SETTRC:
-      return "TT_PROC_SETTRC";
-    case TT_PROC_ATTACH:
-      return "TT_PROC_ATTACH";
-    case TT_PROC_DETACH:
-      return "TT_PROC_DETACH";
-    case TT_PROC_RDTEXT:
-      return "TT_PROC_RDTEXT";
-    case TT_PROC_WRTEXT:
-      return "TT_PROC_WRTEXT";
-    case TT_PROC_RDDATA:
-      return "TT_PROC_RDDATA";
-    case TT_PROC_WRDATA:
-      return "TT_PROC_WRDATA";
-    case TT_PROC_STOP:
-      return "TT_PROC_STOP";
-    case TT_PROC_CONTINUE:
-      return "TT_PROC_CONTINUE";
-    case TT_PROC_GET_PATHNAME:
-      return "TT_PROC_GET_PATHNAME";
-    case TT_PROC_GET_EVENT_MASK:
-      return "TT_PROC_GET_EVENT_MASK";
-    case TT_PROC_SET_EVENT_MASK:
-      return "TT_PROC_SET_EVENT_MASK";
-    case TT_PROC_GET_FIRST_LWP_STATE:
-      return "TT_PROC_GET_FIRST_LWP_STATE";
-    case TT_PROC_GET_NEXT_LWP_STATE:
-      return "TT_PROC_GET_NEXT_LWP_STATE";
-    case TT_PROC_EXIT:
-      return "TT_PROC_EXIT";
-    case TT_PROC_GET_MPROTECT:
-      return "TT_PROC_GET_MPROTECT";
-    case TT_PROC_SET_MPROTECT:
-      return "TT_PROC_SET_MPROTECT";
-    case TT_PROC_SET_SCBM:
-      return "TT_PROC_SET_SCBM";
-    case TT_LWP_STOP:
-      return "TT_LWP_STOP";
-    case TT_LWP_CONTINUE:
-      return "TT_LWP_CONTINUE";
-    case TT_LWP_SINGLE:
-      return "TT_LWP_SINGLE";
-    case TT_LWP_RUREGS:
-      return "TT_LWP_RUREGS";
-    case TT_LWP_WUREGS:
-      return "TT_LWP_WUREGS";
-    case TT_LWP_GET_EVENT_MASK:
-      return "TT_LWP_GET_EVENT_MASK";
-    case TT_LWP_SET_EVENT_MASK:
-      return "TT_LWP_SET_EVENT_MASK";
-    case TT_LWP_GET_STATE:
-      return "TT_LWP_GET_STATE";
-    default:
-      return "?new req?";
-    }
-}
-\f
-
-/* This function translates the process state enumeration into
- * a character string that is its printable (aka "human readable")
- * name.
- */
-static char *
-get_printable_name_of_process_state (process_state_t process_state)
-{
-  switch (process_state)
-    {
-    case STOPPED:
-      return "STOPPED";
-    case FAKE_STEPPING:
-      return "FAKE_STEPPING";
-    case RUNNING:
-      return "RUNNING";
-    case FORKING:
-      return "FORKING";
-    case VFORKING:
-      return "VFORKING";
-    default:
-      return "?some unknown state?";
-    }
-}
-
-/* Set a ttrace thread state to a safe, initial state.
- */
-static void
-clear_ttstate_t (ttstate_t *tts)
-{
-  tts->tts_pid = 0;
-  tts->tts_lwpid = 0;
-  tts->tts_user_tid = 0;
-  tts->tts_event = TTEVT_NONE;
-}
-
-/* Copy ttrace thread state TTS_FROM into TTS_TO.
- */
-static void
-copy_ttstate_t (ttstate_t *tts_to, ttstate_t *tts_from)
-{
-  memcpy ((char *) tts_to, (char *) tts_from, sizeof (*tts_to));
-}
-
-/* Are there any live threads we know about?
- */
-static int
-any_thread_records (void)
-{
-  return (thread_head.count > 0);
-}
-
-/* Create, fill in and link in a thread descriptor.
- */
-static thread_info *
-create_thread_info (int pid, lwpid_t tid)
-{
-  thread_info *new_p;
-  thread_info *p;
-  int thread_count_of_pid;
-
-  new_p = xmalloc (sizeof (thread_info));
-  new_p->pid = pid;
-  new_p->tid = tid;
-  new_p->have_signal = 0;
-  new_p->have_start = 0;
-  new_p->have_state = 0;
-  clear_ttstate_t (&new_p->last_stop_state);
-  new_p->am_pseudo = 0;
-  new_p->handled = 0;
-  new_p->seen = 0;
-  new_p->terminated = 0;
-  new_p->next = NULL;
-  new_p->next_pseudo = NULL;
-  new_p->stepping_mode = DO_DEFAULT;
-
-  if (0 == thread_head.count)
-    {
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("First thread, pid %d tid %d!\n", pid, tid);
-#endif
-      saved_real_ptid = inferior_ptid;
-    }
-  else
-    {
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("Subsequent thread, pid %d tid %d\n", pid, tid);
-#endif
-    }
-
-  /* Another day, another thread...
-   */
-  thread_head.count++;
-
-  /* The new thread always goes at the head of the list.
-   */
-  new_p->next = thread_head.head;
-  thread_head.head = new_p;
-
-  /* Is this the "pseudo" thread of a process?  It is if there's
-   * no other thread for this process on the list.  (Note that this
-   * accomodates multiple processes, such as we see even for simple
-   * cases like forking "non-threaded" programs.)
-   */
-  p = thread_head.head;
-  thread_count_of_pid = 0;
-  while (p)
-    {
-      if (p->pid == new_p->pid)
-       thread_count_of_pid++;
-      p = p->next;
-    }
-
-  /* Did we see any other threads for this pid?  (Recall that we just
-   * added this thread to the list...)
-   */
-  if (thread_count_of_pid == 1)
-    {
-      new_p->am_pseudo = 1;
-      new_p->next_pseudo = thread_head.head_pseudo;
-      thread_head.head_pseudo = new_p;
-    }
-
-  return new_p;
-}
-
-/* Get rid of our thread info.
- */
-static void
-clear_thread_info (void)
-{
-  thread_info *p;
-  thread_info *q;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("Clearing all thread info\n");
-#endif
-
-  p = thread_head.head;
-  while (p)
-    {
-      q = p;
-      p = p->next;
-      xfree (q);
-    }
-
-  thread_head.head = NULL;
-  thread_head.head_pseudo = NULL;
-  thread_head.count = 0;
-
-  p = deleted_threads.head;
-  while (p)
-    {
-      q = p;
-      p = p->next;
-      xfree (q);
-    }
-
-  deleted_threads.head = NULL;
-  deleted_threads.head_pseudo = NULL;
-  deleted_threads.count = 0;
-
-  /* No threads, so can't have pending events.
-   */
-  more_events_left = 0;
-}
-
-/* Given a tid, find the thread block for it.
- */
-static thread_info *
-find_thread_info (lwpid_t tid)
-{
-  thread_info *p;
-
-  for (p = thread_head.head; p; p = p->next)
-    {
-      if (p->tid == tid)
-       {
-         return p;
-       }
-    }
-
-  for (p = deleted_threads.head; p; p = p->next)
-    {
-      if (p->tid == tid)
-       {
-         return p;
-       }
-    }
-
-  return NULL;
-}
-
-/* For any but the pseudo thread, this maps to the
- * thread ID.  For the pseudo thread, if you pass either
- * the thread id or the PID, you get the pseudo thread ID.
- *
- * We have to be prepared for core gdb to ask about
- * deleted threads.  We do the map, but we don't like it.
- */
-static lwpid_t
-map_from_gdb_tid (lwpid_t gdb_tid)
-{
-  thread_info *p;
-
-  /* First assume gdb_tid really is a tid, and try to find a
-   * matching entry on the threads list.
-   */
-  for (p = thread_head.head; p; p = p->next)
-    {
-      if (p->tid == gdb_tid)
-       return gdb_tid;
-    }
-
-  /* It doesn't appear to be a tid; perhaps it's really a pid?
-   * Try to find a "pseudo" thread entry on the threads list.
-   */
-  for (p = thread_head.head_pseudo; p != NULL; p = p->next_pseudo)
-    {
-      if (p->pid == gdb_tid)
-       return p->tid;
-    }
-
-  /* Perhaps it's the tid of a deleted thread we may still
-   * have some knowledge of?
-   */
-  for (p = deleted_threads.head; p; p = p->next)
-    {
-      if (p->tid == gdb_tid)
-       return gdb_tid;
-    }
-
-  /* Or perhaps it's the pid of a deleted process we may still
-   * have knowledge of?
-   */
-  for (p = deleted_threads.head_pseudo; p != NULL; p = p->next_pseudo)
-    {
-      if (p->pid == gdb_tid)
-       return p->tid;
-    }
-
-  return 0;                    /* Error? */
-}
-
-/* Map the other way: from a real tid to the
- * "pid" known by core gdb.  This tid may be
- * for a thread that just got deleted, so we
- * also need to consider deleted threads.
- */
-static lwpid_t
-map_to_gdb_tid (lwpid_t real_tid)
-{
-  thread_info *p;
-
-  for (p = thread_head.head; p; p = p->next)
-    {
-      if (p->tid == real_tid)
-       {
-         if (p->am_pseudo)
-           return p->pid;
-         else
-           return real_tid;
-       }
-    }
-
-  for (p = deleted_threads.head; p; p = p->next)
-    {
-      if (p->tid == real_tid)
-       if (p->am_pseudo)
-         return p->pid;        /* Error? */
-       else
-         return real_tid;
-    }
-
-  return 0;                    /* Error?  Never heard of this thread! */
-}
-
-/* Do any threads have saved signals?
- */
-static int
-saved_signals_exist (void)
-{
-  thread_info *p;
-
-  for (p = thread_head.head; p; p = p->next)
-    {
-      if (p->have_signal)
-       {
-         return 1;
-       }
-    }
-
-  return 0;
-}
-
-/* Is this the tid for the zero-th thread?
- */
-static int
-is_pseudo_thread (lwpid_t tid)
-{
-  thread_info *p = find_thread_info (tid);
-  if (NULL == p || p->terminated)
-    return 0;
-  else
-    return p->am_pseudo;
-}
-
-/* Is this thread terminated?
- */
-static int
-is_terminated (lwpid_t tid)
-{
-  thread_info *p = find_thread_info (tid);
-
-  if (NULL != p)
-    return p->terminated;
-
-  return 0;
-}
-
-/* Is this pid a real PID or a TID?
- */
-static int
-is_process_id (int pid)
-{
-  lwpid_t tid;
-  thread_info *tinfo;
-  pid_t this_pid;
-  int this_pid_count;
-
-  /* What does PID really represent?
-   */
-  tid = map_from_gdb_tid (pid);
-  if (tid <= 0)
-    return 0;                  /* Actually, is probably an error... */
-
-  tinfo = find_thread_info (tid);
-
-  /* Does it appear to be a true thread?
-   */
-  if (!tinfo->am_pseudo)
-    return 0;
-
-  /* Else, it looks like it may be a process.  See if there's any other
-   * threads with the same process ID, though.  If there are, then TID
-   * just happens to be the first thread of several for this process.
-   */
-  this_pid = tinfo->pid;
-  this_pid_count = 0;
-  for (tinfo = thread_head.head; tinfo; tinfo = tinfo->next)
-    {
-      if (tinfo->pid == this_pid)
-       this_pid_count++;
-    }
-
-  return (this_pid_count == 1);
-}
-
-
-/* Add a thread to our info.  Prevent duplicate entries.
- */
-static thread_info *
-add_tthread (int pid, lwpid_t tid)
-{
-  thread_info *p;
-
-  p = find_thread_info (tid);
-  if (NULL == p)
-    p = create_thread_info (pid, tid);
-
-  return p;
-}
-
-/* Notice that a thread was deleted.
- */
-static void
-del_tthread (lwpid_t tid)
-{
-  thread_info *p;
-  thread_info *chase;
-
-  if (thread_head.count <= 0)
-    {
-      error ("Internal error in thread database.");
-      return;
-    }
-
-  chase = NULL;
-  for (p = thread_head.head; p; p = p->next)
-    {
-      if (p->tid == tid)
-       {
-
-#ifdef THREAD_DEBUG
-         if (debug_on)
-           printf ("Delete here: %d \n", tid);
-#endif
-
-         if (p->am_pseudo)
-           {
-             /*
-              * Deleting a main thread is ok if we're doing
-              * a parent-follow on a child; this is odd but
-              * not wrong.  It apparently _doesn't_ happen
-              * on the child-follow, as we don't just delete
-              * the pseudo while keeping the rest of the
-              * threads around--instead, we clear out the whole
-              * thread list at once.
-              */
-             thread_info *q;
-             thread_info *q_chase;
-
-             q_chase = NULL;
-             for (q = thread_head.head_pseudo; q; q = q->next)
-               {
-                 if (q == p)
-                   {
-                     /* Remove from pseudo list.
-                      */
-                     if (q_chase == NULL)
-                       thread_head.head_pseudo = p->next_pseudo;
-                     else
-                       q_chase->next = p->next_pseudo;
-                   }
-                 else
-                   q_chase = q;
-               }
-           }
-
-         /* Remove from live list.
-          */
-         thread_head.count--;
-
-         if (NULL == chase)
-           thread_head.head = p->next;
-         else
-           chase->next = p->next;
-
-         /* Add to deleted thread list.
-          */
-         p->next = deleted_threads.head;
-         deleted_threads.head = p;
-         deleted_threads.count++;
-         if (p->am_pseudo)
-           {
-             p->next_pseudo = deleted_threads.head_pseudo;
-             deleted_threads.head_pseudo = p;
-           }
-         p->terminated = 1;
-
-         return;
-       }
-
-      else
-       chase = p;
-    }
-}
-
-/* Get the pid for this tid. (Has to be a real TID!).
- */
-static int
-get_pid_for (lwpid_t tid)
-{
-  thread_info *p;
-
-  for (p = thread_head.head; p; p = p->next)
-    {
-      if (p->tid == tid)
-       {
-         return p->pid;
-       }
-    }
-
-  for (p = deleted_threads.head; p; p = p->next)
-    {
-      if (p->tid == tid)
-       {
-         return p->pid;
-       }
-    }
-
-  return 0;
-}
-
-/* Note that this thread's current event has been handled.
- */
-static void
-set_handled (int pid, lwpid_t tid)
-{
-  thread_info *p;
-
-  p = find_thread_info (tid);
-  if (NULL == p)
-    p = add_tthread (pid, tid);
-
-  p->handled = 1;
-}
-
-/* Was this thread's current event handled?
- */
-static int
-was_handled (lwpid_t tid)
-{
-  thread_info *p;
-
-  p = find_thread_info (tid);
-  if (NULL != p)
-    return p->handled;
-
-  return 0;                    /* New threads have not been handled */
-}
-
-/* Set this thread to unhandled.
- */
-static void
-clear_handled (lwpid_t tid)
-{
-  thread_info *p;
-
-#ifdef WAIT_BUFFER_DEBUG
-  if (debug_on)
-    printf ("clear_handled %d\n", (int) tid);
-#endif
-
-  p = find_thread_info (tid);
-  if (p == NULL)
-    error ("Internal error: No thread state to clear?");
-
-  p->handled = 0;
-}
-
-/* Set all threads to unhandled.
- */
-static void
-clear_all_handled (void)
-{
-  thread_info *p;
-
-#ifdef WAIT_BUFFER_DEBUG
-  if (debug_on)
-    printf ("clear_all_handled\n");
-#endif
-
-  for (p = thread_head.head; p; p = p->next)
-    {
-      p->handled = 0;
-    }
-
-  for (p = deleted_threads.head; p; p = p->next)
-    {
-      p->handled = 0;
-    }
-}
-
-/* Set this thread to default stepping mode.
- */
-static void
-clear_stepping_mode (lwpid_t tid)
-{
-  thread_info *p;
-
-#ifdef WAIT_BUFFER_DEBUG
-  if (debug_on)
-    printf ("clear_stepping_mode %d\n", (int) tid);
-#endif
-
-  p = find_thread_info (tid);
-  if (p == NULL)
-    error ("Internal error: No thread state to clear?");
-
-  p->stepping_mode = DO_DEFAULT;
-}
-
-/* Set all threads to do default continue on resume.
- */
-static void
-clear_all_stepping_mode (void)
-{
-  thread_info *p;
-
-#ifdef WAIT_BUFFER_DEBUG
-  if (debug_on)
-    printf ("clear_all_stepping_mode\n");
-#endif
-
-  for (p = thread_head.head; p; p = p->next)
-    {
-      p->stepping_mode = DO_DEFAULT;
-    }
-
-  for (p = deleted_threads.head; p; p = p->next)
-    {
-      p->stepping_mode = DO_DEFAULT;
-    }
-}
-
-/* Set all threads to unseen on this pass.
- */
-static void
-set_all_unseen (void)
-{
-  thread_info *p;
-
-  for (p = thread_head.head; p; p = p->next)
-    {
-      p->seen = 0;
-    }
-}
-
-#if (defined( THREAD_DEBUG ) || defined( PARANOIA ))
-/* debugging routine.
- */
-static void
-print_tthread (thread_info *p)
-{
-  printf (" Thread pid %d, tid %d", p->pid, p->tid);
-  if (p->have_state)
-    printf (", event is %s",
-        get_printable_name_of_ttrace_event (p->last_stop_state.tts_event));
-
-  if (p->am_pseudo)
-    printf (", pseudo thread");
-
-  if (p->have_signal)
-    printf (", have signal 0x%x", p->signal_value);
-
-  if (p->have_start)
-    printf (", have start at 0x%x", p->start);
-
-  printf (", step is %s", get_printable_name_of_stepping_mode (p->stepping_mode));
-
-  if (p->handled)
-    printf (", handled");
-  else
-    printf (", not handled");
-
-  if (p->seen)
-    printf (", seen");
-  else
-    printf (", not seen");
-
-  printf ("\n");
-}
-
-static void
-print_tthreads (void)
-{
-  thread_info *p;
-
-  if (thread_head.count == 0)
-    printf ("Thread list is empty\n");
-  else
-    {
-      printf ("Thread list has ");
-      if (thread_head.count == 1)
-       printf ("1 entry:\n");
-      else
-       printf ("%d entries:\n", thread_head.count);
-      for (p = thread_head.head; p; p = p->next)
-       {
-         print_tthread (p);
-       }
-    }
-
-  if (deleted_threads.count == 0)
-    printf ("Deleted thread list is empty\n");
-  else
-    {
-      printf ("Deleted thread list has ");
-      if (deleted_threads.count == 1)
-       printf ("1 entry:\n");
-      else
-       printf ("%d entries:\n", deleted_threads.count);
-
-      for (p = deleted_threads.head; p; p = p->next)
-       {
-         print_tthread (p);
-       }
-    }
-}
-#endif
-
-/* Update the thread list based on the "seen" bits.
- */
-static void
-update_thread_list (void)
-{
-  thread_info *p;
-  thread_info *chase;
-
-  chase = NULL;
-  for (p = thread_head.head; p; p = p->next)
-    {
-      /* Is this an "unseen" thread which really happens to be a process?
-         If so, is it inferior_ptid and is a vfork in flight?  If yes to
-         all, then DON'T REMOVE IT!  We're in the midst of moving a vfork
-         operation, which is a multiple step thing, to the point where we
-         can touch the parent again.  We've most likely stopped to examine
-         the child at a late stage in the vfork, and if we're not following
-         the child, we'd best not treat the parent as a dead "thread"...
-       */
-      if ((!p->seen) && p->am_pseudo && vfork_in_flight
-         && (p->pid != vforking_child_pid))
-       p->seen = 1;
-
-      if (!p->seen)
-       {
-         /* Remove this one
-          */
-
-#ifdef THREAD_DEBUG
-         if (debug_on)
-           printf ("Delete unseen thread: %d \n", p->tid);
-#endif
-         del_tthread (p->tid);
-       }
-    }
-}
-\f
-
-
-/************************************************
- *            O/S call wrappers                 *
- ************************************************
- */
-
-/* This function simply calls ttrace with the given arguments.  
- * It exists so that all calls to ttrace are isolated.  All
- * parameters should be as specified by "man 2 ttrace".
- *
- * No other "raw" calls to ttrace should exist in this module.
- */
-static int
-call_real_ttrace (ttreq_t request, pid_t pid, lwpid_t tid, TTRACE_ARG_TYPE addr,
-                 TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
-{
-  int tt_status;
-
-  errno = 0;
-  tt_status = ttrace (request, pid, tid, addr, data, addr2);
-
-#ifdef THREAD_DEBUG
-  if (errno)
-    {
-      /* Don't bother for a known benign error: if you ask for the
-       * first thread state, but there is only one thread and it's
-       * not stopped, ttrace complains.
-       *
-       * We have this inside the #ifdef because our caller will do
-       * this check for real.
-       */
-      if (request != TT_PROC_GET_FIRST_LWP_STATE
-         || errno != EPROTO)
-       {
-         if (debug_on)
-           printf ("TT fail for %s, with pid %d, tid %d, status %d \n",
-                   get_printable_name_of_ttrace_request (request),
-                   pid, tid, tt_status);
-       }
-    }
-#endif
-
-#if 0
-  /* ??rehrauer: It would probably be most robust to catch and report
-   * failed requests here.  However, some clients of this interface
-   * seem to expect to catch & deal with them, so we'd best not.
-   */
-  if (errno)
-    {
-      strcpy (reason_for_failure, "ttrace (");
-      strcat (reason_for_failure, get_printable_name_of_ttrace_request (request));
-      strcat (reason_for_failure, ")");
-      printf ("ttrace error, errno = %d\n", errno);
-      perror_with_name (reason_for_failure);
-    }
-#endif
-
-  return tt_status;
-}
-\f
-
-/* This function simply calls ttrace_wait with the given arguments.  
- * It exists so that all calls to ttrace_wait are isolated.
- *
- * No "raw" calls to ttrace_wait should exist elsewhere.
- */
-static int
-call_real_ttrace_wait (int pid, lwpid_t tid, ttwopt_t option, ttstate_t *tsp,
-                      size_t tsp_size)
-{
-  int ttw_status;
-  thread_info *tinfo = NULL;
-
-  errno = 0;
-  ttw_status = ttrace_wait (pid, tid, option, tsp, tsp_size);
-
-  if (errno)
-    {
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("TW fail with pid %d, tid %d \n", pid, tid);
-#endif
-
-      perror_with_name ("ttrace wait");
-    }
-
-  return ttw_status;
-}
-\f
-
-/* A process may have one or more kernel threads, of which all or
-   none may be stopped.  This function returns the ID of the first
-   kernel thread in a stopped state, or 0 if none are stopped.
-
-   This function can be used with get_process_next_stopped_thread_id
-   to iterate over the IDs of all stopped threads of this process.
- */
-static lwpid_t
-get_process_first_stopped_thread_id (int pid, ttstate_t *thread_state)
-{
-  int tt_status;
-
-  tt_status = call_real_ttrace (TT_PROC_GET_FIRST_LWP_STATE,
-                               (pid_t) pid,
-                               (lwpid_t) TT_NIL,
-                               (TTRACE_ARG_TYPE) thread_state,
-                               (TTRACE_ARG_TYPE) sizeof (*thread_state),
-                               TT_NIL);
-
-  if (errno)
-    {
-      if (errno == EPROTO)
-       {
-         /* This is an error we can handle: there isn't any stopped
-          * thread.  This happens when we're re-starting the application
-          * and it has only one thread.  GET_NEXT handles the case of
-          * no more stopped threads well; GET_FIRST doesn't.  (A ttrace
-          * "feature".)
-          */
-         tt_status = 1;
-         errno = 0;
-         return 0;
-       }
-      else
-       perror_with_name ("ttrace");
-    }
-
-  if (tt_status < 0)
-    /* Failed somehow.
-     */
-    return 0;
-
-  return thread_state->tts_lwpid;
-}
-\f
-
-/* This function returns the ID of the "next" kernel thread in a
-   stopped state, or 0 if there are none.  "Next" refers to the
-   thread following that of the last successful call to this
-   function or to get_process_first_stopped_thread_id, using
-   the value of thread_state returned by that call.
-
-   This function can be used with get_process_first_stopped_thread_id
-   to iterate over the IDs of all stopped threads of this process.
- */
-static lwpid_t
-get_process_next_stopped_thread_id (int pid, ttstate_t *thread_state)
-{
-  int tt_status;
-
-  tt_status = call_real_ttrace (
-                                TT_PROC_GET_NEXT_LWP_STATE,
-                                (pid_t) pid,
-                                (lwpid_t) TT_NIL,
-                                (TTRACE_ARG_TYPE) thread_state,
-                                (TTRACE_ARG_TYPE) sizeof (*thread_state),
-                                TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace");
-
-  if (tt_status < 0)
-    /* Failed
-     */
-    return 0;
-
-  else if (tt_status == 0)
-    {
-      /* End of list, no next state.  Don't return the
-       * tts_lwpid, as it's a meaningless "240".
-       *
-       * This is an HPUX "feature".
-       */
-      return 0;
-    }
-
-  return thread_state->tts_lwpid;
-}
-
-/* ??rehrauer: Eventually this function perhaps should be calling
-   pid_to_thread_id.  However, that function currently does nothing
-   for HP-UX.  Even then, I'm not clear whether that function
-   will return a "kernel" thread ID, or a "user" thread ID.  If
-   the former, we can just call it here.  If the latter, we must
-   map from the "user" tid to a "kernel" tid.
-
-   NOTE: currently not called.
- */
-static lwpid_t
-get_active_tid_of_pid (int pid)
-{
-  ttstate_t thread_state;
-
-  return get_process_first_stopped_thread_id (pid, &thread_state);
-}
-
-/* This function returns 1 if tt_request is a ttrace request that
- * operates upon all threads of a (i.e., the entire) process.
- */
-int
-is_process_ttrace_request (ttreq_t tt_request)
-{
-  return IS_TTRACE_PROCREQ (tt_request);
-}
-\f
-
-/* This function translates a thread ttrace request into
- * the equivalent process request for a one-thread process.
- */
-static ttreq_t
-make_process_version (ttreq_t request)
-{
-  if (!IS_TTRACE_REQ (request))
-    {
-      error ("Internal error, bad ttrace request made\n");
-      return -1;
-    }
-
-  switch (request)
-    {
-    case TT_LWP_STOP:
-      return TT_PROC_STOP;
-
-    case TT_LWP_CONTINUE:
-      return TT_PROC_CONTINUE;
-
-    case TT_LWP_GET_EVENT_MASK:
-      return TT_PROC_GET_EVENT_MASK;
-
-    case TT_LWP_SET_EVENT_MASK:
-      return TT_PROC_SET_EVENT_MASK;
-
-    case TT_LWP_SINGLE:
-    case TT_LWP_RUREGS:
-    case TT_LWP_WUREGS:
-    case TT_LWP_GET_STATE:
-      return -1;               /* No equivalent */
-
-    default:
-      return request;
-    }
-}
-\f
-
-/* This function translates the "pid" used by the rest of
- * gdb to a real pid and a tid.  It then calls "call_real_ttrace"
- * with the given arguments.
- *
- * In general, other parts of this module should call this
- * function when they are dealing with external users, who only
- * have tids to pass (but they call it "pid" for historical
- * reasons).
- */
-static int
-call_ttrace (ttreq_t request, int gdb_tid, TTRACE_ARG_TYPE addr,
-            TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
-{
-  lwpid_t real_tid;
-  int real_pid;
-  ttreq_t new_request;
-  int tt_status;
-  char reason_for_failure[100];        /* Arbitrary size, should be big enough. */
-
-#ifdef THREAD_DEBUG
-  int is_interesting = 0;
-
-  if (TT_LWP_RUREGS == request)
-    {
-      is_interesting = 1;      /* Adjust code here as desired */
-    }
-
-  if (is_interesting && 0 && debug_on)
-    {
-      if (!is_process_ttrace_request (request))
-       {
-         printf ("TT: Thread request, tid is %d", gdb_tid);
-         printf ("== SINGLE at %x", addr);
-       }
-      else
-       {
-         printf ("TT: Process request, tid is %d\n", gdb_tid);
-         printf ("==! SINGLE at %x", addr);
-       }
-    }
-#endif
-
-  /* The initial SETTRC and SET_EVENT_MASK calls (and all others
-   * which happen before any threads get set up) should go
-   * directly to "call_real_ttrace", so they don't happen here.
-   *
-   * But hardware watchpoints do a SET_EVENT_MASK, so we can't
-   * rule them out....
-   */
-#ifdef THREAD_DEBUG
-  if (request == TT_PROC_SETTRC && debug_on)
-    printf ("Unexpected call for TT_PROC_SETTRC\n");
-#endif
-
-  /* Sometimes we get called with a bogus tid (e.g., if a
-   * thread has terminated, we return 0; inftarg later asks
-   * whether the thread has exited/forked/vforked).
-   */
-  if (gdb_tid == 0)
-    {
-      errno = ESRCH;           /* ttrace's response would probably be "No such process". */
-      return -1;
-    }
-
-  /* All other cases should be able to expect that there are
-   * thread records.
-   */
-  if (!any_thread_records ())
-    {
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       warning ("No thread records for ttrace call");
-#endif
-      errno = ESRCH;           /* ttrace's response would be "No such process". */
-      return -1;
-    }
-
-  /* OK, now the task is to translate the incoming tid into
-   * a pid/tid pair.
-   */
-  real_tid = map_from_gdb_tid (gdb_tid);
-  real_pid = get_pid_for (real_tid);
-
-  /* Now check the result.  "Real_pid" is NULL if our list
-   * didn't find it.  We have some tricks we can play to fix
-   * this, however.
-   */
-  if (0 == real_pid)
-    {
-      ttstate_t thread_state;
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("No saved pid for tid %d\n", gdb_tid);
-#endif
-
-      if (is_process_ttrace_request (request))
-       {
-
-         /* Ok, we couldn't get a tid.  Try to translate to
-          * the equivalent process operation.  We expect this
-          * NOT to happen, so this is a desparation-type
-          * move.  It can happen if there is an internal
-          * error and so no "wait()" call is ever done.
-          */
-         new_request = make_process_version (request);
-         if (new_request == -1)
-           {
-
-#ifdef THREAD_DEBUG
-             if (debug_on)
-               printf ("...and couldn't make process version of thread operation\n");
-#endif
-
-             /* Use hacky saved pid, which won't always be correct
-              * in the multi-process future.  Use tid as thread,
-              * probably dooming this to failure.  FIX!
-              */
-             if (! ptid_equal (saved_real_ptid, null_ptid))
-               {
-#ifdef THREAD_DEBUG
-                 if (debug_on)
-                   printf ("...using saved pid %d\n",
-                           PIDGET (saved_real_ptid));
-#endif
-
-                 real_pid = PIDGET (saved_real_ptid);
-                 real_tid = gdb_tid;
-               }
-
-             else
-               error ("Unable to perform thread operation");
-           }
-
-         else
-           {
-             /* Sucessfully translated this to a process request,
-              * which needs no thread value.
-              */
-             real_pid = gdb_tid;
-             real_tid = 0;
-             request = new_request;
-
-#ifdef THREAD_DEBUG
-             if (debug_on)
-               {
-                 printf ("Translated thread request to process request\n");
-                 if (ptid_equal (saved_real_ptid, null_ptid))
-                   printf ("...but there's no saved pid\n");
-
-                 else
-                   {
-                     if (gdb_tid != PIDGET (saved_real_ptid))
-                       printf ("...but have the wrong pid (%d rather than %d)\n",
-                               gdb_tid, PIDGET (saved_real_ptid));
-                   }
-               }
-#endif
-           }                   /* Translated to a process request */
-       }                       /* Is a process request */
-
-      else
-       {
-         /* We have to have a thread.  Ooops.
-          */
-         error ("Thread request with no threads (%s)",
-                get_printable_name_of_ttrace_request (request));
-       }
-    }
-
-  /* Ttrace doesn't like to see tid values on process requests,
-   * even if we have the right one.
-   */
-  if (is_process_ttrace_request (request))
-    {
-      real_tid = 0;
-    }
-
-#ifdef THREAD_DEBUG
-  if (is_interesting && 0 && debug_on)
-    {
-      printf ("    now tid %d, pid %d\n", real_tid, real_pid);
-      printf ("    request is %s\n", get_printable_name_of_ttrace_request (request));
-    }
-#endif
-
-  /* Finally, the (almost) real call.
-   */
-  tt_status = call_real_ttrace (request, real_pid, real_tid, addr, data, addr2);
-
-#ifdef THREAD_DEBUG
-  if (is_interesting && debug_on)
-    {
-      if (!TT_OK (tt_status, errno)
-         && !(tt_status == 0 & errno == 0))
-       printf (" got error (errno==%d, status==%d)\n", errno, tt_status);
-    }
-#endif
-
-  return tt_status;
-}
-
-
-/* Stop all the threads of a process.
-
- * NOTE: use of TT_PROC_STOP can cause a thread with a real event
- *       to get a TTEVT_NONE event, discarding the old event.  Be
- *       very careful, and only call TT_PROC_STOP when you mean it!
- */
-static void
-stop_all_threads_of_process (pid_t real_pid)
-{
-  int ttw_status;
-
-  ttw_status = call_real_ttrace (TT_PROC_STOP,
-                                (pid_t) real_pid,
-                                (lwpid_t) TT_NIL,
-                                (TTRACE_ARG_TYPE) TT_NIL,
-                                (TTRACE_ARG_TYPE) TT_NIL,
-                                TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace stop of other threads");
-}
-
-
-/* Under some circumstances, it's unsafe to attempt to stop, or even
-   query the state of, a process' threads.
-
-   In ttrace-based HP-UX, an example is a vforking child process.  The
-   vforking parent and child are somewhat fragile, w/r/t what we can do
-   what we can do to them with ttrace, until after the child exits or
-   execs, or until the parent's vfork event is delivered.  Until that
-   time, we must not try to stop the process' threads, or inquire how
-   many there are, or even alter its data segments, or it typically dies
-   with a SIGILL.  Sigh.
-
-   This function returns 1 if this stopped process, and the event that
-   we're told was responsible for its current stopped state, cannot safely
-   have its threads examined.
- */
-#define CHILD_VFORKED(evt,pid) \
-  (((evt) == TTEVT_VFORK) && ((pid) != PIDGET (inferior_ptid)))
-#define CHILD_URPED(evt,pid) \
-  ((((evt) == TTEVT_EXEC) || ((evt) == TTEVT_EXIT)) && ((pid) != vforking_child_pid))
-#define PARENT_VFORKED(evt,pid) \
-  (((evt) == TTEVT_VFORK) && ((pid) == PIDGET (inferior_ptid)))
-
-static int
-can_touch_threads_of_process (int pid, ttevents_t stopping_event)
-{
-  if (CHILD_VFORKED (stopping_event, pid))
-    {
-      vforking_child_pid = pid;
-      vfork_in_flight = 1;
-    }
-
-  else if (vfork_in_flight &&
-          (PARENT_VFORKED (stopping_event, pid) ||
-           CHILD_URPED (stopping_event, pid)))
-    {
-      vfork_in_flight = 0;
-      vforking_child_pid = 0;
-    }
-
-  return !vfork_in_flight;
-}
-
-
-/* If we can find an as-yet-unhandled thread state of a
- * stopped thread of this process return 1 and set "tsp".
- * Return 0 if we can't.
- *
- * If this function is used when the threads of PIS haven't
- * been stopped, undefined behaviour is guaranteed!
- */
-static int
-select_stopped_thread_of_process (int pid, ttstate_t *tsp)
-{
-  lwpid_t candidate_tid, tid;
-  ttstate_t candidate_tstate, tstate;
-
-  /* If we're not allowed to touch the process now, then just
-   * return the current value of *TSP.
-   *
-   * This supports "vfork".  It's ok, really, to double the
-   * current event (the child EXEC, we hope!).
-   */
-  if (!can_touch_threads_of_process (pid, tsp->tts_event))
-    return 1;
-
-  /* Decide which of (possibly more than one) events to
-   * return as the first one.  We scan them all so that
-   * we always return the result of a fake-step first.
-   */
-  candidate_tid = 0;
-  for (tid = get_process_first_stopped_thread_id (pid, &tstate);
-       tid != 0;
-       tid = get_process_next_stopped_thread_id (pid, &tstate))
-    {
-      /* TTEVT_NONE events are uninteresting to our clients.  They're
-       * an artifact of our "stop the world" model--the thread is
-       * stopped because we stopped it.
-       */
-      if (tstate.tts_event == TTEVT_NONE)
-       {
-         set_handled (pid, tstate.tts_lwpid);
-       }
-
-      /* Did we just single-step a single thread, without letting any
-       * of the others run?  Is this an event for that thread?
-       *
-       * If so, we believe our client would prefer to see this event
-       * over any others.  (Typically the client wants to just push
-       * one thread a little farther forward, and then go around
-       * checking for what all threads are doing.)
-       */
-      else if (doing_fake_step && (tstate.tts_lwpid == fake_step_tid))
-       {
-#ifdef WAIT_BUFFER_DEBUG
-         /* It's possible here to see either a SIGTRAP (due to
-          * successful completion of a step) or a SYSCALL_ENTRY
-          * (due to a step completion with active hardware
-          * watchpoints).
-          */
-         if (debug_on)
-           printf ("Ending fake step with tid %d, state %s\n",
-                   tstate.tts_lwpid,
-                   get_printable_name_of_ttrace_event (tstate.tts_event));
-#endif
-
-         /* Remember this one, and throw away any previous
-          * candidate.
-          */
-         candidate_tid = tstate.tts_lwpid;
-         candidate_tstate = tstate;
-       }
-
-#ifdef FORGET_DELETED_BPTS
-
-      /* We can't just do this, as if we do, and then wind
-       * up the loop with no unhandled events, we need to
-       * handle that case--the appropriate reaction is to
-       * just continue, but there's no easy way to do that.
-       *
-       * Better to put this in the ttrace_wait call--if, when
-       * we fake a wait, we update our events based on the
-       * breakpoint_here_pc call and find there are no more events,
-       * then we better continue and so on.
-       *
-       * Or we could put it in the next/continue fake.
-       * But it has to go in the buffering code, not in the
-       * real go/wait code.
-       */
-      else if ((TTEVT_SIGNAL == tstate.tts_event)
-              && (5 == tstate.tts_u.tts_signal.tts_signo)
-              && (0 != get_raw_pc (tstate.tts_lwpid))
-              && !breakpoint_here_p (get_raw_pc (tstate.tts_lwpid)))
-       {
-         /*
-          * If the user deleted a breakpoint while this
-          * breakpoint-hit event was buffered, we can forget
-          * it now.
-          */
-#ifdef WAIT_BUFFER_DEBUG
-         if (debug_on)
-           printf ("Forgetting deleted bp hit for thread %d\n",
-                   tstate.tts_lwpid);
-#endif
-
-         set_handled (pid, tstate.tts_lwpid);
-       }
-#endif
-
-      /* Else, is this the first "unhandled" event?  If so,
-       * we believe our client wants to see it (if we don't
-       * see a fake-step later on in the scan).
-       */
-      else if (!was_handled (tstate.tts_lwpid) && candidate_tid == 0)
-       {
-         candidate_tid = tstate.tts_lwpid;
-         candidate_tstate = tstate;
-       }
-
-      /* This is either an event that has already been "handled",
-       * and thus we believe is uninteresting to our client, or we
-       * already have a candidate event.  Ignore it...
-       */
-    }
-
-  /* What do we report?
-   */
-  if (doing_fake_step)
-    {
-      if (candidate_tid == fake_step_tid)
-       {
-         /* Fake step.
-          */
-         tstate = candidate_tstate;
-       }
-      else
-       {
-         warning ("Internal error: fake-step failed to complete.");
-         return 0;
-       }
-    }
-  else if (candidate_tid != 0)
-    {
-      /* Found a candidate unhandled event.
-       */
-      tstate = candidate_tstate;
-    }
-  else if (tid != 0)
-    {
-      warning ("Internal error in call of ttrace_wait.");
-      return 0;
-    }
-  else
-    {
-      warning ("Internal error: no unhandled thread event to select");
-      return 0;
-    }
-
-  copy_ttstate_t (tsp, &tstate);
-  return 1;
-}                              /* End of select_stopped_thread_of_process */
-
-#ifdef PARANOIA
-/* Check our internal thread data against the real thing.
- */
-static void
-check_thread_consistency (pid_t real_pid)
-{
-  int tid;                     /* really lwpid_t */
-  ttstate_t tstate;
-  thread_info *p;
-
-  /* Spin down the O/S list of threads, checking that they
-   * match what we've got.
-   */
-  for (tid = get_process_first_stopped_thread_id (real_pid, &tstate);
-       tid != 0;
-       tid = get_process_next_stopped_thread_id (real_pid, &tstate))
-    {
-
-      p = find_thread_info (tid);
-
-      if (NULL == p)
-       {
-         warning ("No internal thread data for thread %d.", tid);
-         continue;
-       }
-
-      if (!p->seen)
-       {
-         warning ("Inconsistent internal thread data for thread %d.", tid);
-       }
-
-      if (p->terminated)
-       {
-         warning ("Thread %d is not terminated, internal error.", tid);
-         continue;
-       }
-
-
-#define TT_COMPARE( fld ) \
-            tstate.fld != p->last_stop_state.fld
-
-      if (p->have_state)
-       {
-         if (TT_COMPARE (tts_pid)
-             || TT_COMPARE (tts_lwpid)
-             || TT_COMPARE (tts_user_tid)
-             || TT_COMPARE (tts_event)
-             || TT_COMPARE (tts_flags)
-             || TT_COMPARE (tts_scno)
-             || TT_COMPARE (tts_scnargs))
-           {
-             warning ("Internal thread data for thread %d is wrong.", tid);
-             continue;
-           }
-       }
-    }
-}
-#endif /* PARANOIA */
-\f
-
-/* This function wraps calls to "call_real_ttrace_wait" so
- * that a actual wait is only done when all pending events
- * have been reported.
- *
- * Note that typically it is called with a pid of "0", i.e. 
- * the "don't care" value.
- *
- * Return value is the status of the pseudo wait.
- */
-static int
-call_ttrace_wait (int pid, ttwopt_t option, ttstate_t *tsp, size_t tsp_size)
-{
-  /* This holds the actual, for-real, true process ID.
-   */
-  static int real_pid;
-
-  /* As an argument to ttrace_wait, zero pid
-   * means "Any process", and zero tid means
-   * "Any thread of the specified process".
-   */
-  int wait_pid = 0;
-  lwpid_t wait_tid = 0;
-  lwpid_t real_tid;
-
-  int ttw_status = 0;          /* To be returned */
-
-  thread_info *tinfo = NULL;
-
-  if (pid != 0)
-    {
-      /* Unexpected case.
-       */
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("TW: Pid to wait on is %d\n", pid);
-#endif
-
-      if (!any_thread_records ())
-       error ("No thread records for ttrace call w. specific pid");
-
-      /* OK, now the task is to translate the incoming tid into
-       * a pid/tid pair.
-       */
-      real_tid = map_from_gdb_tid (pid);
-      real_pid = get_pid_for (real_tid);
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("==TW: real pid %d, real tid %d\n", real_pid, real_tid);
-#endif
-    }
-
-
-  /* Sanity checks and set-up.
-   *                             Process State
-   *
-   *                        Stopped   Running    Fake-step  (v)Fork
-   *                      \________________________________________
-   *                      |
-   *  No buffered events  |  error     wait       wait      wait
-   *                      |
-   *  Buffered events     |  debuffer  error      wait      debuffer (?)
-   *
-   */
-  if (more_events_left == 0)
-    {
-
-      if (process_state == RUNNING)
-       {
-         /* OK--normal call of ttrace_wait with no buffered events.
-          */
-         ;
-       }
-      else if (process_state == FAKE_STEPPING)
-       {
-         /* Ok--call of ttrace_wait to support
-          * fake stepping with no buffered events.
-          *
-          * But we better be fake-stepping!
-          */
-         if (!doing_fake_step)
-           {
-             warning ("Inconsistent thread state.");
-           }
-       }
-      else if ((process_state == FORKING)
-              || (process_state == VFORKING))
-       {
-         /* Ok--there are two processes, so waiting
-          * for the second while the first is stopped
-          * is ok.  Handled bits stay as they were.
-          */
-         ;
-       }
-      else if (process_state == STOPPED)
-       {
-         warning ("Process not running at wait call.");
-       }
-      else
-       /* No known state.
-        */
-       warning ("Inconsistent process state.");
-    }
-
-  else
-    {
-      /* More events left
-       */
-      if (process_state == STOPPED)
-       {
-         /* OK--buffered events being unbuffered.
-          */
-         ;
-       }
-      else if (process_state == RUNNING)
-       {
-         /* An error--shouldn't have buffered events
-          * when running.
-          */
-         warning ("Trying to continue with buffered events:");
-       }
-      else if (process_state == FAKE_STEPPING)
-       {
-         /*
-          * Better be fake-stepping!
-          */
-         if (!doing_fake_step)
-           {
-             warning ("Losing buffered thread events!\n");
-           }
-       }
-      else if ((process_state == FORKING)
-              || (process_state == VFORKING))
-       {
-         /* Ok--there are two processes, so waiting
-          * for the second while the first is stopped
-          * is ok.  Handled bits stay as they were.
-          */
-         ;
-       }
-      else
-       warning ("Process in unknown state with buffered events.");
-    }
-
-  /* Sometimes we have to wait for a particular thread
-   * (if we're stepping over a bpt).  In that case, we
-   * _know_ it's going to complete the single-step we
-   * asked for (because we're only doing the step under
-   * certain very well-understood circumstances), so it
-   * can't block.
-   */
-  if (doing_fake_step)
-    {
-      wait_tid = fake_step_tid;
-      wait_pid = get_pid_for (fake_step_tid);
-
-#ifdef WAIT_BUFFER_DEBUG
-      if (debug_on)
-       printf ("Doing a wait after a fake-step for %d, pid %d\n",
-               wait_tid, wait_pid);
-#endif
-    }
-
-  if (more_events_left == 0    /* No buffered events, need real ones. */
-      || process_state != STOPPED)
-    {
-      /* If there are no buffered events, and so we need
-       * real ones, or if we are FORKING, VFORKING, 
-       * FAKE_STEPPING or RUNNING, and thus have to do
-       * a real wait, then do a real wait.
-       */
-
-#ifdef WAIT_BUFFER_DEBUG
-      /* Normal case... */
-      if (debug_on)
-       printf ("TW: do it for real; pid %d, tid %d\n", wait_pid, wait_tid);
-#endif
-
-      /* The actual wait call.
-       */
-      ttw_status = call_real_ttrace_wait (wait_pid, wait_tid, option, tsp, tsp_size);
-
-      /* Note that the routines we'll call will be using "call_real_ttrace",
-       * not "call_ttrace", and thus need the real pid rather than the pseudo-tid
-       * the rest of the world uses (which is actually the tid).
-       */
-      real_pid = tsp->tts_pid;
-
-      /* For most events: Stop the world!
-
-       * It's sometimes not safe to stop all threads of a process.
-       * Sometimes it's not even safe to ask for the thread state
-       * of a process!
-       */
-      if (can_touch_threads_of_process (real_pid, tsp->tts_event))
-       {
-         /* If we're really only stepping a single thread, then don't
-          * try to stop all the others -- we only do this single-stepping
-          * business when all others were already stopped...and the stop
-          * would mess up other threads' events.
-          *
-          * Similiarly, if there are other threads with events,
-          * don't do the stop.
-          */
-         if (!doing_fake_step)
-           {
-             if (more_events_left > 0)
-               warning ("Internal error in stopping process");
-
-             stop_all_threads_of_process (real_pid);
-
-             /* At this point, we could scan and update_thread_list(),
-              * and only use the local list for the rest of the
-              * module! We'd get rid of the scans in the various
-              * continue routines (adding one in attach).  It'd
-              * be great--UPGRADE ME!
-              */
-           }
-       }
-
-#ifdef PARANOIA
-      else if (debug_on)
-       {
-         if (more_events_left > 0)
-           printf ("== Can't stop process; more events!\n");
-         else
-           printf ("== Can't stop process!\n");
-       }
-#endif
-
-      process_state = STOPPED;
-
-#ifdef WAIT_BUFFER_DEBUG
-      if (debug_on)
-       printf ("Process set to STOPPED\n");
-#endif
-    }
-
-  else
-    {
-      /* Fake a call to ttrace_wait.  The process must be
-       * STOPPED, as we aren't going to do any wait.
-       */
-#ifdef WAIT_BUFFER_DEBUG
-      if (debug_on)
-       printf ("TW: fake it\n");
-#endif
-
-      if (process_state != STOPPED)
-       {
-         warning ("Process not stopped at wait call, in state '%s'.\n",
-                  get_printable_name_of_process_state (process_state));
-       }
-
-      if (doing_fake_step)
-       error ("Internal error in stepping over breakpoint");
-
-      ttw_status = 0;          /* Faking it is always successful! */
-    }                          /* End of fake or not? if */
-
-  /* Pick an event to pass to our caller.  Be paranoid.
-   */
-  if (!select_stopped_thread_of_process (real_pid, tsp))
-    warning ("Can't find event, using previous event.");
-
-  else if (tsp->tts_event == TTEVT_NONE)
-    warning ("Internal error: no thread has a real event.");
-
-  else if (doing_fake_step)
-    {
-      if (fake_step_tid != tsp->tts_lwpid)
-       warning ("Internal error in stepping over breakpoint.");
-
-      /* This wait clears the (current) fake-step if there was one.
-       */
-      doing_fake_step = 0;
-      fake_step_tid = 0;
-    }
-
-  /* We now have a correct tsp and ttw_status for the thread
-   * which we want to report.  So it's "handled"!  This call
-   * will add it to our list if it's not there already.
-   */
-  set_handled (real_pid, tsp->tts_lwpid);
-
-  /* Save a copy of the ttrace state of this thread, in our local
-     thread descriptor.
-
-     This caches the state.  The implementation of queries like
-     hpux_has_execd can then use this cached state, rather than
-     be forced to make an explicit ttrace call to get it.
-
-     (Guard against the condition that this is the first time we've
-     waited on, i.e., seen this thread, and so haven't yet entered
-     it into our list of threads.)
-   */
-  tinfo = find_thread_info (tsp->tts_lwpid);
-  if (tinfo != NULL)
-    {
-      copy_ttstate_t (&tinfo->last_stop_state, tsp);
-      tinfo->have_state = 1;
-    }
-
-  return ttw_status;
-}                              /* call_ttrace_wait */
-
-#if defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
-int
-child_reported_exec_events_per_exec_call (void)
-{
-  return 1;                    /* ttrace reports the event once per call. */
-}
-#endif
-\f
-
-
-/* Our implementation of hardware watchpoints involves making memory
-   pages write-protected.  We must remember a page's original permissions,
-   and we must also know when it is appropriate to restore a page's
-   permissions to its original state.
-
-   We use a "dictionary" of hardware-watched pages to do this.  Each
-   hardware-watched page is recorded in the dictionary.  Each page's
-   dictionary entry contains the original permissions and a reference
-   count.  Pages are hashed into the dictionary by their start address.
-
-   When hardware watchpoint is set on page X for the first time, page X
-   is added to the dictionary with a reference count of 1.  If other
-   hardware watchpoints are subsequently set on page X, its reference
-   count is incremented.  When hardware watchpoints are removed from
-   page X, its reference count is decremented.  If a page's reference
-   count drops to 0, it's permissions are restored and the page's entry
-   is thrown out of the dictionary.
- */
-typedef struct memory_page
-{
-  CORE_ADDR page_start;
-  int reference_count;
-  int original_permissions;
-  struct memory_page *next;
-  struct memory_page *previous;
-}
-memory_page_t;
-
-#define MEMORY_PAGE_DICTIONARY_BUCKET_COUNT  128
-
-static struct
-  {
-    LONGEST page_count;
-    int page_size;
-    int page_protections_allowed;
-    /* These are just the heads of chains of actual page descriptors. */
-    memory_page_t buckets[MEMORY_PAGE_DICTIONARY_BUCKET_COUNT];
-  }
-memory_page_dictionary;
-
-
-static void
-require_memory_page_dictionary (void)
-{
-  int i;
-
-  /* Is the memory page dictionary ready for use?  If so, we're done. */
-  if (memory_page_dictionary.page_count >= (LONGEST) 0)
-    return;
-
-  /* Else, initialize it. */
-  memory_page_dictionary.page_count = (LONGEST) 0;
-
-  for (i = 0; i < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; i++)
-    {
-      memory_page_dictionary.buckets[i].page_start = (CORE_ADDR) 0;
-      memory_page_dictionary.buckets[i].reference_count = 0;
-      memory_page_dictionary.buckets[i].next = NULL;
-      memory_page_dictionary.buckets[i].previous = NULL;
-    }
-}
-
-
-static void
-retire_memory_page_dictionary (void)
-{
-  memory_page_dictionary.page_count = (LONGEST) - 1;
-}
-
-
-/* Write-protect the memory page that starts at this address.
-
-   Returns the original permissions of the page.
- */
-static int
-write_protect_page (int pid, CORE_ADDR page_start)
-{
-  int tt_status;
-  int original_permissions;
-  int new_permissions;
-
-  tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
-                          pid,
-                          (TTRACE_ARG_TYPE) page_start,
-                          TT_NIL,
-                          (TTRACE_ARG_TYPE) & original_permissions);
-  if (errno || (tt_status < 0))
-    {
-      return 0;                        /* What else can we do? */
-    }
-
-  /* We'll also write-protect the page now, if that's allowed. */
-  if (memory_page_dictionary.page_protections_allowed)
-    {
-      new_permissions = original_permissions & ~PROT_WRITE;
-      tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
-                              pid,
-                              (TTRACE_ARG_TYPE) page_start,
-                        (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
-                              (TTRACE_ARG_TYPE) new_permissions);
-      if (errno || (tt_status < 0))
-       {
-         return 0;             /* What else can we do? */
-       }
-    }
-
-  return original_permissions;
-}
-
-
-/* Unwrite-protect the memory page that starts at this address, restoring
-   (what we must assume are) its original permissions.
- */
-static void
-unwrite_protect_page (int pid, CORE_ADDR page_start, int original_permissions)
-{
-  int tt_status;
-
-  tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
-                          pid,
-                          (TTRACE_ARG_TYPE) page_start,
-                        (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
-                          (TTRACE_ARG_TYPE) original_permissions);
-  if (errno || (tt_status < 0))
-    {
-      return;                  /* What else can we do? */
-    }
-}
-
-
-/* Memory page-protections are used to implement "hardware" watchpoints
-   on HP-UX.
-
-   For every memory page that is currently being watched (i.e., that
-   presently should be write-protected), write-protect it.
- */
-void
-hppa_enable_page_protection_events (int pid)
-{
-  int bucket;
-
-  memory_page_dictionary.page_protections_allowed = 1;
-
-  for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
-    {
-      memory_page_t *page;
-
-      page = memory_page_dictionary.buckets[bucket].next;
-      while (page != NULL)
-       {
-         page->original_permissions = write_protect_page (pid, page->page_start);
-         page = page->next;
-       }
-    }
-}
-
-
-/* Memory page-protections are used to implement "hardware" watchpoints
-   on HP-UX.
-
-   For every memory page that is currently being watched (i.e., that
-   presently is or should be write-protected), un-write-protect it.
- */
-void
-hppa_disable_page_protection_events (int pid)
-{
-  int bucket;
-
-  for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
-    {
-      memory_page_t *page;
-
-      page = memory_page_dictionary.buckets[bucket].next;
-      while (page != NULL)
-       {
-         unwrite_protect_page (pid, page->page_start, page->original_permissions);
-         page = page->next;
-       }
-    }
-
-  memory_page_dictionary.page_protections_allowed = 0;
-}
-
-/* Count the number of outstanding events.  At this
- * point, we have selected one thread and its event
- * as the one to be "reported" upwards to core gdb.
- * That thread is already marked as "handled".
- *
- * Note: we could just scan our own thread list.  FIXME!
- */
-static int
-count_unhandled_events (int real_pid, lwpid_t real_tid)
-{
-  ttstate_t tstate;
-  lwpid_t ttid;
-  int events_left;
-
-  /* Ok, find out how many threads have real events to report.
-   */
-  events_left = 0;
-  ttid = get_process_first_stopped_thread_id (real_pid, &tstate);
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    {
-      if (ttid == 0)
-       printf ("Process %d has no threads\n", real_pid);
-      else
-       printf ("Process %d has these threads:\n", real_pid);
-    }
-#endif
-
-  while (ttid > 0)
-    {
-      if (tstate.tts_event != TTEVT_NONE
-         && !was_handled (ttid))
-       {
-         /* TTEVT_NONE implies we just stopped it ourselves
-          * because we're the stop-the-world guys, so it's
-          * not an event from our point of view.
-          *
-          * If "was_handled" is true, this is an event we
-          * already handled, so don't count it.
-          *
-          * Note that we don't count the thread with the
-          * currently-reported event, as it's already marked
-          * as handled.
-          */
-         events_left++;
-       }
-
-#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
-      if (debug_on)
-       {
-         if (ttid == real_tid)
-           printf ("*");       /* Thread we're reporting */
-         else
-           printf (" ");
-
-         if (tstate.tts_event != TTEVT_NONE)
-           printf ("+");       /* Thread with a real event */
-         else
-           printf (" ");
-
-         if (was_handled (ttid))
-           printf ("h");       /* Thread has been handled */
-         else
-           printf (" ");
-
-         printf (" %d, with event %s", ttid,
-                 get_printable_name_of_ttrace_event (tstate.tts_event));
-
-         if (tstate.tts_event == TTEVT_SIGNAL
-             && 5 == tstate.tts_u.tts_signal.tts_signo)
-           {
-             CORE_ADDR pc_val;
-
-             pc_val = get_raw_pc (ttid);
-
-             if (pc_val > 0)
-               printf (" breakpoint at 0x%x\n", pc_val);
-             else
-               printf (" bpt, can't fetch pc.\n");
-           }
-         else
-           printf ("\n");
-       }
-#endif
-
-      ttid = get_process_next_stopped_thread_id (real_pid, &tstate);
-    }
-
-#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
-  if (debug_on)
-    if (events_left > 0)
-      printf ("There are thus %d pending events\n", events_left);
-#endif
-
-  return events_left;
-}
-
-/* This function is provided as a sop to clients that are calling
- * ptrace_wait to wait for a process to stop.  (see the
- * implementation of child_wait.)  Return value is the pid for
- * the event that ended the wait.
- *
- * Note: used by core gdb and so uses the pseudo-pid (really tid).
- */
-int
-ptrace_wait (ptid_t ptid, int *status)
-{
-  ttstate_t tsp;
-  int ttwait_return;
-  int real_pid;
-  ttstate_t state;
-  lwpid_t real_tid;
-  int return_pid;
-
-  /* The ptrace implementation of this also ignores pid.
-   */
-  *status = 0;
-
-  ttwait_return = call_ttrace_wait (0, TTRACE_WAITOK, &tsp, sizeof (tsp));
-  if (ttwait_return < 0)
-    {
-      /* ??rehrauer: It appears that if our inferior exits and we
-         haven't asked for exit events, that we're not getting any
-         indication save a negative return from ttrace_wait and an
-         errno set to ESRCH?
-       */
-      if (errno == ESRCH)
-       {
-         *status = 0;          /* WIFEXITED */
-         return PIDGET (inferior_ptid);
-       }
-
-      warning ("Call of ttrace_wait returned with errno %d.",
-              errno);
-      *status = ttwait_return;
-      return PIDGET (inferior_ptid);
-    }
-
-  real_pid = tsp.tts_pid;
-  real_tid = tsp.tts_lwpid;
-
-  /* One complication is that the "tts_event" structure has
-   * a set of flags, and more than one can be set.  So we
-   * either have to force an order (as we do here), or handle
-   * more than one flag at a time.
-   */
-  if (tsp.tts_event & TTEVT_LWP_CREATE)
-    {
-
-      /* Unlike what you might expect, this event is reported in
-       * the _creating_ thread, and the _created_ thread (whose tid
-       * we have) is still running.  So we have to stop it.  This
-       * has already been done in "call_ttrace_wait", but should we
-       * ever abandon the "stop-the-world" model, here's the command
-       * to use:
-       *
-       *    call_ttrace( TT_LWP_STOP, real_tid, TT_NIL, TT_NIL, TT_NIL );
-       *
-       * Note that this would depend on being called _after_ "add_tthread"
-       * below for the tid-to-pid translation to be done in "call_ttrace".
-       */
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("New thread: pid %d, tid %d, creator tid %d\n",
-               real_pid, tsp.tts_u.tts_thread.tts_target_lwpid,
-               real_tid);
-#endif
-
-      /* Now we have to return the tid of the created thread, not
-       * the creating thread, or "wait_for_inferior" won't know we
-       * have a new "process" (thread).  Plus we should record it
-       * right, too.
-       */
-      real_tid = tsp.tts_u.tts_thread.tts_target_lwpid;
-
-      add_tthread (real_pid, real_tid);
-    }
-
-  else if ((tsp.tts_event & TTEVT_LWP_TERMINATE)
-          || (tsp.tts_event & TTEVT_LWP_EXIT))
-    {
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("Thread dies: %d\n", real_tid);
-#endif
-
-      del_tthread (real_tid);
-    }
-
-  else if (tsp.tts_event & TTEVT_EXEC)
-    {
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("Pid %d has zero'th thread %d; inferior pid is %d\n",
-               real_pid, real_tid, PIDGET (inferior_ptid));
-#endif
-
-      add_tthread (real_pid, real_tid);
-    }
-
-#ifdef THREAD_DEBUG
-  else if (debug_on)
-    {
-      printf ("Process-level event %s, using tid %d\n",
-             get_printable_name_of_ttrace_event (tsp.tts_event),
-             real_tid);
-
-      /* OK to do this, as "add_tthread" won't add
-       * duplicate entries.  Also OK not to do it,
-       * as this event isn't one which can change the
-       * thread state.
-       */
-      add_tthread (real_pid, real_tid);
-    }
-#endif
-
-
-  /* How many events are left to report later?
-   * In a non-stop-the-world model, this isn't needed.
-   *
-   * Note that it's not always safe to query the thread state of a process,
-   * which is what count_unhandled_events does.  (If unsafe, we're left with
-   * no other resort than to assume that no more events remain...)
-   */
-  if (can_touch_threads_of_process (real_pid, tsp.tts_event))
-    more_events_left = count_unhandled_events (real_pid, real_tid);
-
-  else
-    {
-      if (more_events_left > 0)
-       warning ("Vfork or fork causing loss of %d buffered events.",
-                more_events_left);
-
-      more_events_left = 0;
-    }
-
-  /* Attempt to translate the ttrace_wait-returned status into the
-     ptrace equivalent.
-
-     ??rehrauer: This is somewhat fragile.  We really ought to rewrite
-     clients that expect to pick apart a ptrace wait status, to use
-     something a little more abstract.
-   */
-  if ((tsp.tts_event & TTEVT_EXEC)
-      || (tsp.tts_event & TTEVT_FORK)
-      || (tsp.tts_event & TTEVT_VFORK))
-    {
-      /* Forks come in pairs (parent and child), so core gdb
-       * will do two waits.  Be ready to notice this.
-       */
-      if (tsp.tts_event & TTEVT_FORK)
-       {
-         process_state = FORKING;
-
-#ifdef WAIT_BUFFER_DEBUG
-         if (debug_on)
-           printf ("Process set to FORKING\n");
-#endif
-       }
-      else if (tsp.tts_event & TTEVT_VFORK)
-       {
-         process_state = VFORKING;
-
-#ifdef WAIT_BUFFER_DEBUG
-         if (debug_on)
-           printf ("Process set to VFORKING\n");
-#endif
-       }
-
-      /* Make an exec or fork look like a breakpoint.  Definitely a hack,
-         but I don't think non HP-UX-specific clients really carefully
-         inspect the first events they get after inferior startup, so
-         it probably almost doesn't matter what we claim this is.
-       */
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("..a process 'event'\n");
-#endif
-
-      /* Also make fork and exec events look like bpts, so they can be caught.
-       */
-      *status = 0177 | (_SIGTRAP << 8);
-    }
-
-  /* Special-cases: We ask for syscall entry and exit events to implement
-     "fast" (aka "hardware") watchpoints.
-
-     When we get a syscall entry, we want to disable page-protections,
-     and resume the inferior; this isn't an event we wish for
-     wait_for_inferior to see.  Note that we must resume ONLY the
-     thread that reported the syscall entry; we don't want to allow
-     other threads to run with the page protections off, as they might
-     then be able to write to watch memory without it being caught.
-
-     When we get a syscall exit, we want to reenable page-protections,
-     but we don't want to resume the inferior; this is an event we wish
-     wait_for_inferior to see.  Make it look like the signal we normally
-     get for a single-step completion.  This should cause wait_for_inferior
-     to evaluate whether any watchpoint triggered.
-
-     Or rather, that's what we'd LIKE to do for syscall exit; we can't,
-     due to some HP-UX "features".  Some syscalls have problems with
-     write-protections on some pages, and some syscalls seem to have
-     pending writes to those pages at the time we're getting the return
-     event.  So, we'll single-step the inferior to get out of the syscall,
-     and then reenable protections.
-
-     Note that we're intentionally allowing the syscall exit case to
-     fall through into the succeeding cases, as sometimes we single-
-     step out of one syscall only to immediately enter another...
-   */
-  else if ((tsp.tts_event & TTEVT_SYSCALL_ENTRY)
-          || (tsp.tts_event & TTEVT_SYSCALL_RETURN))
-    {
-      /* Make a syscall event look like a breakpoint.  Same comments
-         as for exec & fork events.
-       */
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("..a syscall 'event'\n");
-#endif
-
-      /* Also make syscall events look like bpts, so they can be caught.
-       */
-      *status = 0177 | (_SIGTRAP << 8);
-    }
-
-  else if ((tsp.tts_event & TTEVT_LWP_CREATE)
-          || (tsp.tts_event & TTEVT_LWP_TERMINATE)
-          || (tsp.tts_event & TTEVT_LWP_EXIT))
-    {
-      /* Make a thread event look like a breakpoint.  Same comments
-       * as for exec & fork events.
-       */
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("..a thread 'event'\n");
-#endif
-
-      /* Also make thread events look like bpts, so they can be caught.
-       */
-      *status = 0177 | (_SIGTRAP << 8);
-    }
-
-  else if ((tsp.tts_event & TTEVT_EXIT))
-    {                          /* WIFEXITED */
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("..an exit\n");
-#endif
-
-      /* Prevent rest of gdb from thinking this is
-       * a new thread if for some reason it's never
-       * seen the main thread before.
-       */
-      inferior_ptid = pid_to_ptid (map_to_gdb_tid (real_tid)); /* HACK, FIX */
-
-      *status = 0 | (tsp.tts_u.tts_exit.tts_exitcode);
-    }
-
-  else if (tsp.tts_event & TTEVT_SIGNAL)
-    {                          /* WIFSTOPPED */
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("..a signal, %d\n", tsp.tts_u.tts_signal.tts_signo);
-#endif
-
-      *status = 0177 | (tsp.tts_u.tts_signal.tts_signo << 8);
-    }
-
-  else
-    {                          /* !WIFSTOPPED */
-
-      /* This means the process or thread terminated.  But we should've
-         caught an explicit exit/termination above.  So warn (this is
-         really an internal error) and claim the process or thread
-         terminated with a SIGTRAP.
-       */
-
-      warning ("process_wait: unknown process state");
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("Process-level event %s, using tid %d\n",
-               get_printable_name_of_ttrace_event (tsp.tts_event),
-               real_tid);
-#endif
-
-      *status = _SIGTRAP;
-    }
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("Done waiting, pid is %d, tid %d\n", real_pid, real_tid);
-#endif
-
-  /* All code external to this module uses the tid, but calls
-   * it "pid".  There's some tweaking so that the outside sees
-   * the first thread as having the same number as the starting
-   * pid.
-   */
-  return_pid = map_to_gdb_tid (real_tid);
-
-  if (real_tid == 0 || return_pid == 0)
-    {
-      warning ("Internal error: process-wait failed.");
-    }
-
-  return return_pid;
-}
-\f
-
-/* This function causes the caller's process to be traced by its
-   parent.  This is intended to be called after GDB forks itself,
-   and before the child execs the target.  Despite the name, it
-   is called by the child.
-
-   Note that HP-UX ttrace is rather funky in how this is done.
-   If the parent wants to get the initial exec event of a child,
-   it must set the ttrace event mask of the child to include execs.
-   (The child cannot do this itself.)  This must be done after the
-   child is forked, but before it execs.
-
-   To coordinate the parent and child, we implement a semaphore using
-   pipes.  After SETTRC'ing itself, the child tells the parent that
-   it is now traceable by the parent, and waits for the parent's
-   acknowledgement.  The parent can then set the child's event mask,
-   and notify the child that it can now exec.
-
-   (The acknowledgement by parent happens as a result of a call to
-   child_acknowledge_created_inferior.)
- */
-int
-parent_attach_all (int p1, PTRACE_ARG3_TYPE p2, int p3)
-{
-  int tt_status;
-
-  /* We need a memory home for a constant, to pass it to ttrace.
-     The value of the constant is arbitrary, so long as both
-     parent and child use the same value.  Might as well use the
-     "magic" constant provided by ttrace...
-   */
-  uint64_t tc_magic_child = TT_VERSION;
-  uint64_t tc_magic_parent = 0;
-
-  tt_status = call_real_ttrace (
-                                TT_PROC_SETTRC,
-                                (int) TT_NIL,
-                                (lwpid_t) TT_NIL,
-                                TT_NIL,
-                                (TTRACE_ARG_TYPE) TT_VERSION,
-                                TT_NIL);
-
-  if (tt_status < 0)
-    return tt_status;
-
-  /* Notify the parent that we're potentially ready to exec(). */
-  write (startup_semaphore.child_channel[SEM_TALK],
-        &tc_magic_child,
-        sizeof (tc_magic_child));
-
-  /* Wait for acknowledgement from the parent. */
-  read (startup_semaphore.parent_channel[SEM_LISTEN],
-       &tc_magic_parent,
-       sizeof (tc_magic_parent));
-
-  if (tc_magic_child != tc_magic_parent)
-    warning ("mismatched semaphore magic");
-
-  /* Discard our copy of the semaphore. */
-  (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.parent_channel[SEM_TALK]);
-  (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.child_channel[SEM_TALK]);
-
-  return tt_status;
-}
-
-/* Despite being file-local, this routine is dealing with
- * actual process IDs, not thread ids.  That's because it's
- * called before the first "wait" call, and there's no map
- * yet from tids to pids.
- *
- * When it is called, a forked child is running, but waiting on
- * the semaphore.  If you stop the child and re-start it,
- * things get confused, so don't do that!  An attached child is
- * stopped.
- *
- * Since this is called after either attach or run, we
- * have to be the common part of both.
- */
-static void
-require_notification_of_events (int real_pid)
-{
-  int tt_status;
-  ttevent_t notifiable_events;
-
-  lwpid_t tid;
-  ttstate_t thread_state;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("Require notif, pid is %d\n", real_pid);
-#endif
-
-  /* Temporary HACK: tell inftarg.c/child_wait to not
-   * loop until pids are the same.
-   */
-  not_same_real_pid = 0;
-
-  sigemptyset (&notifiable_events.tte_signals);
-  notifiable_events.tte_opts = TTEO_NONE;
-
-  /* This ensures that forked children inherit their parent's
-   * event mask, which we're setting here.
-   *
-   * NOTE: if you debug gdb with itself, then the ultimate
-   *       debuggee gets flags set by the outermost gdb, as
-   *       a child of a child will still inherit.
-   */
-  notifiable_events.tte_opts |= TTEO_PROC_INHERIT;
-
-  notifiable_events.tte_events = TTEVT_DEFAULT;
-  notifiable_events.tte_events |= TTEVT_SIGNAL;
-  notifiable_events.tte_events |= TTEVT_EXEC;
-  notifiable_events.tte_events |= TTEVT_EXIT;
-  notifiable_events.tte_events |= TTEVT_FORK;
-  notifiable_events.tte_events |= TTEVT_VFORK;
-  notifiable_events.tte_events |= TTEVT_LWP_CREATE;
-  notifiable_events.tte_events |= TTEVT_LWP_EXIT;
-  notifiable_events.tte_events |= TTEVT_LWP_TERMINATE;
-
-  tt_status = call_real_ttrace (
-                                TT_PROC_SET_EVENT_MASK,
-                                real_pid,
-                                (lwpid_t) TT_NIL,
-                                (TTRACE_ARG_TYPE) & notifiable_events,
-                              (TTRACE_ARG_TYPE) sizeof (notifiable_events),
-                                TT_NIL);
-}
-
-static void
-require_notification_of_exec_events (int real_pid)
-{
-  int tt_status;
-  ttevent_t notifiable_events;
-
-  lwpid_t tid;
-  ttstate_t thread_state;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("Require notif, pid is %d\n", real_pid);
-#endif
-
-  /* Temporary HACK: tell inftarg.c/child_wait to not
-   * loop until pids are the same.
-   */
-  not_same_real_pid = 0;
-
-  sigemptyset (&notifiable_events.tte_signals);
-  notifiable_events.tte_opts = TTEO_NOSTRCCHLD;
-
-  /* This ensures that forked children don't inherit their parent's
-   * event mask, which we're setting here.
-   */
-  notifiable_events.tte_opts &= ~TTEO_PROC_INHERIT;
-
-  notifiable_events.tte_events = TTEVT_DEFAULT;
-  notifiable_events.tte_events |= TTEVT_EXEC;
-  notifiable_events.tte_events |= TTEVT_EXIT;
-
-  tt_status = call_real_ttrace (
-                                TT_PROC_SET_EVENT_MASK,
-                                real_pid,
-                                (lwpid_t) TT_NIL,
-                                (TTRACE_ARG_TYPE) & notifiable_events,
-                              (TTRACE_ARG_TYPE) sizeof (notifiable_events),
-                                TT_NIL);
-}
-\f
-
-/* This function is called by the parent process, with pid being the
- * ID of the child process, after the debugger has forked.
- */
-void
-child_acknowledge_created_inferior (int pid)
-{
-  /* We need a memory home for a constant, to pass it to ttrace.
-     The value of the constant is arbitrary, so long as both
-     parent and child use the same value.  Might as well use the
-     "magic" constant provided by ttrace...
-   */
-  uint64_t tc_magic_parent = TT_VERSION;
-  uint64_t tc_magic_child = 0;
-
-  /* Wait for the child to tell us that it has forked. */
-  read (startup_semaphore.child_channel[SEM_LISTEN],
-       &tc_magic_child,
-       sizeof (tc_magic_child));
-
-  /* Clear thread info now.  We'd like to do this in
-   * "require...", but that messes up attach.
-   */
-  clear_thread_info ();
-
-  /* Tell the "rest of gdb" that the initial thread exists.
-   * This isn't really a hack.  Other thread-based versions
-   * of gdb (e.g. gnu-nat.c) seem to do the same thing.
-   *
-   * Q: Why don't we also add this thread to the local
-   *    list via "add_tthread"?
-   *
-   * A: Because we don't know the tid, and can't stop the
-   *    the process safely to ask what it is.  Anyway, we'll
-   *    add it when it gets the EXEC event.
-   */
-  add_thread (pid_to_ptid (pid));              /* in thread.c */
-
-  /* We can now set the child's ttrace event mask.
-   */
-  require_notification_of_exec_events (pid);
-
-  /* Tell ourselves that the process is running.
-   */
-  process_state = RUNNING;
-
-  /* Notify the child that it can exec. */
-  write (startup_semaphore.parent_channel[SEM_TALK],
-        &tc_magic_parent,
-        sizeof (tc_magic_parent));
-
-  /* Discard our copy of the semaphore. */
-  (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.parent_channel[SEM_TALK]);
-  (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
-  (void) close (startup_semaphore.child_channel[SEM_TALK]);
-}
-
-
-/*
- * arrange for notification of all events by
- * calling require_notification_of_events.
- */
-void
-child_post_startup_inferior (ptid_t ptid)
-{
-  require_notification_of_events (PIDGET (ptid));
-}
-
-/* From here on, we should expect tids rather than pids.
- */
-static void
-hppa_enable_catch_fork (int tid)
-{
-  int tt_status;
-  ttevent_t ttrace_events;
-
-  /* Get the set of events that are currently enabled.
-   */
-  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace");
-
-  /* Add forks to that set. */
-  ttrace_events.tte_events |= TTEVT_FORK;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("enable fork, tid is %d\n", tid);
-#endif
-
-  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace");
-}
-
-
-static void
-hppa_disable_catch_fork (int tid)
-{
-  int tt_status;
-  ttevent_t ttrace_events;
-
-  /* Get the set of events that are currently enabled.
-   */
-  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-
-  if (errno)
-    perror_with_name ("ttrace");
-
-  /* Remove forks from that set. */
-  ttrace_events.tte_events &= ~TTEVT_FORK;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("disable fork, tid is %d\n", tid);
-#endif
-
-  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-
-  if (errno)
-    perror_with_name ("ttrace");
-}
-
-
-#if defined(CHILD_INSERT_FORK_CATCHPOINT)
-int
-child_insert_fork_catchpoint (int tid)
-{
-  /* Enable reporting of fork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.
-   */
-  return 0;
-}
-#endif
-
-
-#if defined(CHILD_REMOVE_FORK_CATCHPOINT)
-int
-child_remove_fork_catchpoint (int tid)
-{
-  /* Disable reporting of fork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.
-   */
-  return 0;
-}
-#endif
-
-
-static void
-hppa_enable_catch_vfork (int tid)
-{
-  int tt_status;
-  ttevent_t ttrace_events;
-
-  /* Get the set of events that are currently enabled.
-   */
-  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-
-  if (errno)
-    perror_with_name ("ttrace");
-
-  /* Add vforks to that set. */
-  ttrace_events.tte_events |= TTEVT_VFORK;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("enable vfork, tid is %d\n", tid);
-#endif
-
-  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-
-  if (errno)
-    perror_with_name ("ttrace");
-}
-
-
-static void
-hppa_disable_catch_vfork (int tid)
-{
-  int tt_status;
-  ttevent_t ttrace_events;
-
-  /* Get the set of events that are currently enabled. */
-  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-
-  if (errno)
-    perror_with_name ("ttrace");
-
-  /* Remove vforks from that set. */
-  ttrace_events.tte_events &= ~TTEVT_VFORK;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("disable vfork, tid is %d\n", tid);
-#endif
-  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
-                          tid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-
-  if (errno)
-    perror_with_name ("ttrace");
-}
-
-
-#if defined(CHILD_INSERT_VFORK_CATCHPOINT)
-int
-child_insert_vfork_catchpoint (int tid)
-{
-  /* Enable reporting of vfork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.
-   */
-  return 0;
-}
-#endif
-
-
-#if defined(CHILD_REMOVE_VFORK_CATCHPOINT)
-int
-child_remove_vfork_catchpoint (int tid)
-{
-  /* Disable reporting of vfork events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.
-   */
-  return 0;
-}
-#endif
-
-/* Q: Do we need to map the returned process ID to a thread ID?
-
- * A: I don't think so--here we want a _real_ pid.  Any later
- *    operations will call "require_notification_of_events" and
- *    start the mapping.
- */
-int
-hpux_has_forked (int tid, int *childpid)
-{
-  int tt_status;
-  ttstate_t ttrace_state;
-  thread_info *tinfo;
-
-  /* Do we have cached thread state that we can consult?  If so, use it. */
-  tinfo = find_thread_info (map_from_gdb_tid (tid));
-  if (tinfo != NULL)
-    {
-      copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
-    }
-
-  /* Nope, must read the thread's current state */
-  else
-    {
-      tt_status = call_ttrace (TT_LWP_GET_STATE,
-                              tid,
-                              (TTRACE_ARG_TYPE) & ttrace_state,
-                              (TTRACE_ARG_TYPE) sizeof (ttrace_state),
-                              TT_NIL);
-
-      if (errno)
-       perror_with_name ("ttrace");
-
-      if (tt_status < 0)
-       return 0;
-    }
-
-  if (ttrace_state.tts_event & TTEVT_FORK)
-    {
-      *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
-      return 1;
-    }
-
-  return 0;
-}
-
-/* See hpux_has_forked for pid discussion.
- */
-int
-hpux_has_vforked (int tid, int *childpid)
-{
-  int tt_status;
-  ttstate_t ttrace_state;
-  thread_info *tinfo;
-
-  /* Do we have cached thread state that we can consult?  If so, use it. */
-  tinfo = find_thread_info (map_from_gdb_tid (tid));
-  if (tinfo != NULL)
-    copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
-
-  /* Nope, must read the thread's current state */
-  else
-    {
-      tt_status = call_ttrace (TT_LWP_GET_STATE,
-                              tid,
-                              (TTRACE_ARG_TYPE) & ttrace_state,
-                              (TTRACE_ARG_TYPE) sizeof (ttrace_state),
-                              TT_NIL);
-
-      if (errno)
-       perror_with_name ("ttrace");
-
-      if (tt_status < 0)
-       return 0;
-    }
-
-  if (ttrace_state.tts_event & TTEVT_VFORK)
-    {
-      *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
-      return 1;
-    }
-
-  return 0;
-}
-
-
-#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
-int
-child_insert_exec_catchpoint (int tid)
-{
-  /* Enable reporting of exec events from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.
-   */
-  return 0;
-}
-#endif
-
-
-#if defined(CHILD_REMOVE_EXEC_CATCHPOINT)
-int
-child_remove_exec_catchpoint (int tid)
-{
-  /* Disable reporting of execevents from the kernel. */
-  /* ??rehrauer: For the moment, we're always enabling these events,
-     and just ignoring them if there's no catchpoint to catch them.
-   */
-  return 0;
-}
-#endif
-
-
-int
-hpux_has_execd (int tid, char **execd_pathname)
-{
-  int tt_status;
-  ttstate_t ttrace_state;
-  thread_info *tinfo;
-
-  /* Do we have cached thread state that we can consult?  If so, use it. */
-  tinfo = find_thread_info (map_from_gdb_tid (tid));
-  if (tinfo != NULL)
-    copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
-
-  /* Nope, must read the thread's current state */
-  else
-    {
-      tt_status = call_ttrace (TT_LWP_GET_STATE,
-                              tid,
-                              (TTRACE_ARG_TYPE) & ttrace_state,
-                              (TTRACE_ARG_TYPE) sizeof (ttrace_state),
-                              TT_NIL);
-
-      if (errno)
-       perror_with_name ("ttrace");
-
-      if (tt_status < 0)
-       return 0;
-    }
-
-  if (ttrace_state.tts_event & TTEVT_EXEC)
-    {
-      /* See child_pid_to_exec_file in this file: this is a macro.
-       */
-      char *exec_file = target_pid_to_exec_file (tid);
-
-      *execd_pathname = savestring (exec_file, strlen (exec_file));
-      return 1;
-    }
-
-  return 0;
-}
-
-
-int
-hpux_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
-{
-  int tt_status;
-  ttstate_t ttrace_state;
-  thread_info *tinfo;
-
-  /* Do we have cached thread state that we can consult?  If so, use it. */
-  tinfo = find_thread_info (map_from_gdb_tid (pid));
-  if (tinfo != NULL)
-    copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
-
-  /* Nope, must read the thread's current state */
-  else
-    {
-      tt_status = call_ttrace (TT_LWP_GET_STATE,
-                              pid,
-                              (TTRACE_ARG_TYPE) & ttrace_state,
-                              (TTRACE_ARG_TYPE) sizeof (ttrace_state),
-                              TT_NIL);
-
-      if (errno)
-       perror_with_name ("ttrace");
-
-      if (tt_status < 0)
-       return 0;
-    }
-
-  *kind = TARGET_WAITKIND_SPURIOUS;    /* Until proven otherwise... */
-  *syscall_id = -1;
-
-  if (ttrace_state.tts_event & TTEVT_SYSCALL_ENTRY)
-    *kind = TARGET_WAITKIND_SYSCALL_ENTRY;
-  else if (ttrace_state.tts_event & TTEVT_SYSCALL_RETURN)
-    *kind = TARGET_WAITKIND_SYSCALL_RETURN;
-  else
-    return 0;
-
-  *syscall_id = ttrace_state.tts_scno;
-  return 1;
-}
-\f
-
-
-#if defined(CHILD_THREAD_ALIVE)
-
-/* Check to see if the given thread is alive.
-
- * We'll trust the thread list, as the more correct
- * approach of stopping the process and spinning down
- * the OS's thread list is _very_ expensive.
- *
- * May need a FIXME for that reason.
- */
-int
-child_thread_alive (ptid_t ptid)
-{
-  lwpid_t gdb_tid = PIDGET (ptid);
-  lwpid_t tid;
-
-  /* This spins down the lists twice.
-   * Possible peformance improvement here!
-   */
-  tid = map_from_gdb_tid (gdb_tid);
-  return !is_terminated (tid);
-}
-
-#endif
-\f
-
-
-/* This function attempts to read the specified number of bytes from the
-   save_state_t that is our view into the hardware registers, starting at
-   ss_offset, and ending at ss_offset + sizeof_buf - 1
-
-   If this function succeeds, it deposits the fetched bytes into buf,
-   and returns 0.
-
-   If it fails, it returns a negative result.  The contents of buf are
-   undefined it this function fails.
- */
-int
-read_from_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
-                              int sizeof_buf)
-{
-  int tt_status;
-  register_value_t register_value = 0;
-
-  tt_status = call_ttrace (TT_LWP_RUREGS,
-                          tid,
-                          ss_offset,
-                          (TTRACE_ARG_TYPE) sizeof_buf,
-                          (TTRACE_ARG_TYPE) buf);
-
-  if (tt_status == 1)
-    /* Map ttrace's version of success to our version.
-     * Sometime ttrace returns 0, but that's ok here.
-     */
-    return 0;
-
-  return tt_status;
-}
-\f
-
-/* This function attempts to write the specified number of bytes to the
-   save_state_t that is our view into the hardware registers, starting at
-   ss_offset, and ending at ss_offset + sizeof_buf - 1
-
-   If this function succeeds, it deposits the bytes in buf, and returns 0.
-
-   If it fails, it returns a negative result.  The contents of the save_state_t
-   are undefined it this function fails.
- */
-int
-write_to_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
-                             int sizeof_buf)
-{
-  int tt_status;
-  register_value_t register_value = 0;
-
-  tt_status = call_ttrace (TT_LWP_WUREGS,
-                          tid,
-                          ss_offset,
-                          (TTRACE_ARG_TYPE) sizeof_buf,
-                          (TTRACE_ARG_TYPE) buf);
-  return tt_status;
-}
-\f
-
-/* This function is a sop to the largeish number of direct calls
-   to call_ptrace that exist in other files.  Rather than create
-   functions whose name abstracts away from ptrace, and change all
-   the present callers of call_ptrace, we'll do the expedient (and
-   perhaps only practical) thing.
-
-   Note HP-UX explicitly disallows a mix of ptrace & ttrace on a traced
-   process.  Thus, we must translate all ptrace requests into their
-   process-specific, ttrace equivalents.
- */
-int
-call_ptrace (int pt_request, int gdb_tid, PTRACE_ARG3_TYPE addr, int data)
-{
-  ttreq_t tt_request;
-  TTRACE_ARG_TYPE tt_addr = (TTRACE_ARG_TYPE) addr;
-  TTRACE_ARG_TYPE tt_data = (TTRACE_ARG_TYPE) data;
-  TTRACE_ARG_TYPE tt_addr2 = TT_NIL;
-  int tt_status;
-  register_value_t register_value;
-  int read_buf;
-
-  /* Perform the necessary argument translation.  Note that some
-     cases are funky enough in the ttrace realm that we handle them
-     very specially.
-   */
-  switch (pt_request)
-    {
-      /* The following cases cannot conveniently be handled conveniently
-         by merely adjusting the ptrace arguments and feeding into the
-         generic call to ttrace at the bottom of this function.
-
-         Note that because all branches of this switch end in "return",
-         there's no need for any "break" statements.
-       */
-    case PT_SETTRC:
-      return parent_attach_all (0, 0, 0);
-
-    case PT_RUREGS:
-      tt_status = read_from_register_save_state (gdb_tid,
-                                                tt_addr,
-                                                &register_value,
-                                                sizeof (register_value));
-      if (tt_status < 0)
-       return tt_status;
-      return register_value;
-
-    case PT_WUREGS:
-      register_value = (int) tt_data;
-      tt_status = write_to_register_save_state (gdb_tid,
-                                               tt_addr,
-                                               &register_value,
-                                               sizeof (register_value));
-      return tt_status;
-      break;
-
-    case PT_READ_I:
-      tt_status = call_ttrace (TT_PROC_RDTEXT, /* Implicit 4-byte xfer becomes block-xfer. */
-                              gdb_tid,
-                              tt_addr,
-                              (TTRACE_ARG_TYPE) 4,
-                              (TTRACE_ARG_TYPE) & read_buf);
-      if (tt_status < 0)
-       return tt_status;
-      return read_buf;
-
-    case PT_READ_D:
-      tt_status = call_ttrace (TT_PROC_RDDATA, /* Implicit 4-byte xfer becomes block-xfer. */
-                              gdb_tid,
-                              tt_addr,
-                              (TTRACE_ARG_TYPE) 4,
-                              (TTRACE_ARG_TYPE) & read_buf);
-      if (tt_status < 0)
-       return tt_status;
-      return read_buf;
-
-    case PT_ATTACH:
-      tt_status = call_real_ttrace (TT_PROC_ATTACH,
-                                   map_from_gdb_tid (gdb_tid),
-                                   (lwpid_t) TT_NIL,
-                                   tt_addr,
-                                   (TTRACE_ARG_TYPE) TT_VERSION,
-                                   tt_addr2);
-      if (tt_status < 0)
-       return tt_status;
-      return tt_status;
-
-      /* The following cases are handled by merely adjusting the ptrace
-         arguments and feeding into the generic call to ttrace.
-       */
-    case PT_DETACH:
-      tt_request = TT_PROC_DETACH;
-      break;
-
-    case PT_WRITE_I:
-      tt_request = TT_PROC_WRTEXT;     /* Translates 4-byte xfer to block-xfer. */
-      tt_data = 4;             /* This many bytes. */
-      tt_addr2 = (TTRACE_ARG_TYPE) & data;     /* Address of xfer source. */
-      break;
-
-    case PT_WRITE_D:
-      tt_request = TT_PROC_WRDATA;     /* Translates 4-byte xfer to block-xfer. */
-      tt_data = 4;             /* This many bytes. */
-      tt_addr2 = (TTRACE_ARG_TYPE) & data;     /* Address of xfer source. */
-      break;
-
-    case PT_RDTEXT:
-      tt_request = TT_PROC_RDTEXT;
-      break;
-
-    case PT_RDDATA:
-      tt_request = TT_PROC_RDDATA;
-      break;
-
-    case PT_WRTEXT:
-      tt_request = TT_PROC_WRTEXT;
-      break;
-
-    case PT_WRDATA:
-      tt_request = TT_PROC_WRDATA;
-      break;
-
-    case PT_CONTINUE:
-      tt_request = TT_PROC_CONTINUE;
-      break;
-
-    case PT_STEP:
-      tt_request = TT_LWP_SINGLE;      /* Should not be making this request? */
-      break;
-
-    case PT_KILL:
-      tt_request = TT_PROC_EXIT;
-      break;
-
-    case PT_GET_PROCESS_PATHNAME:
-      tt_request = TT_PROC_GET_PATHNAME;
-      break;
-
-    default:
-      tt_request = pt_request; /* Let ttrace be the one to complain. */
-      break;
-    }
-
-  return call_ttrace (tt_request,
-                     gdb_tid,
-                     tt_addr,
-                     tt_data,
-                     tt_addr2);
-}
-
-/* Kill that pesky process!
- */
-void
-kill_inferior (void)
-{
-  int tid;
-  int wait_status;
-  thread_info *t;
-  thread_info **paranoia;
-  int para_count, i;
-
-  if (PIDGET (inferior_ptid) == 0)
-    return;
-
-  /* Walk the list of "threads", some of which are "pseudo threads",
-     aka "processes".  For each that is NOT inferior_ptid, stop it,
-     and detach it.
-
-     You see, we may not have just a single process to kill.  If we're
-     restarting or quitting or detaching just after the inferior has
-     forked, then we've actually two processes to clean up.
-
-     But we can't just call target_mourn_inferior() for each, since that
-     zaps the target vector.
-   */
-
-  paranoia = (thread_info **) xmalloc (thread_head.count *
-                                      sizeof (thread_info *));
-  para_count = 0;
-
-  t = thread_head.head;
-  while (t)
-    {
-
-      paranoia[para_count] = t;
-      for (i = 0; i < para_count; i++)
-       {
-         if (t->next == paranoia[i])
-           {
-             warning ("Bad data in gdb's thread data; repairing.");
-             t->next = 0;
-           }
-       }
-      para_count++;
-
-      if (t->am_pseudo && (t->pid != PIDGET (inferior_ptid)))
-       {
-         call_ttrace (TT_PROC_EXIT,
-                      t->pid,
-                      TT_NIL,
-                      TT_NIL,
-                      TT_NIL);
-       }
-      t = t->next;
-    }
-
-  xfree (paranoia);
-
-  call_ttrace (TT_PROC_EXIT,
-              PIDGET (inferior_ptid),
-              TT_NIL,
-              TT_NIL,
-              TT_NIL);
-  target_mourn_inferior ();
-  clear_thread_info ();
-}
-
-
-#ifndef DEPRECATED_CHILD_RESUME
-
-/* Sanity check a thread about to be continued.
- */
-static void
-thread_dropping_event_check (thread_info *p)
-{
-  if (!p->handled)
-    {
-      /*
-       * This seems to happen when we "next" over a
-       * "fork()" while following the parent.  If it's
-       * the FORK event, that's ok.  If it's a SIGNAL
-       * in the unfollowed child, that's ok to--but
-       * how can we know that's what's going on?
-       *
-       * FIXME!
-       */
-      if (p->have_state)
-       {
-         if (p->last_stop_state.tts_event == TTEVT_FORK)
-           {
-             /* Ok */
-             ;
-           }
-         else if (p->last_stop_state.tts_event == TTEVT_SIGNAL)
-           {
-             /* Ok, close eyes and let it happen.
-              */
-             ;
-           }
-         else
-           {
-             /* This shouldn't happen--we're dropping a
-              * real event.
-              */
-             warning ("About to continue process %d, thread %d with unhandled event %s.",
-                      p->pid, p->tid,
-                      get_printable_name_of_ttrace_event (
-                                            p->last_stop_state.tts_event));
-
-#ifdef PARANOIA
-             if (debug_on)
-               print_tthread (p);
-#endif
-           }
-       }
-      else
-       {
-         /* No saved state, have to assume it failed.
-          */
-         warning ("About to continue process %d, thread %d with unhandled event.",
-                  p->pid, p->tid);
-#ifdef PARANOIA
-         if (debug_on)
-           print_tthread (p);
-#endif
-       }
-    }
-
-}                              /* thread_dropping_event_check */
-
-/* Use a loop over the threads to continue all the threads but
- * the one specified, which is to be stepped.
- */
-static void
-threads_continue_all_but_one (lwpid_t gdb_tid, int signal)
-{
-  thread_info *p;
-  int thread_signal;
-  lwpid_t real_tid;
-  lwpid_t scan_tid;
-  ttstate_t state;
-  int real_pid;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("Using loop over threads to step/resume with signals\n");
-#endif
-
-  /* First update the thread list.
-   */
-  set_all_unseen ();
-  real_tid = map_from_gdb_tid (gdb_tid);
-  real_pid = get_pid_for (real_tid);
-
-  scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
-  while (0 != scan_tid)
-    {
-
-#ifdef THREAD_DEBUG
-      /* FIX: later should check state is stopped;
-       * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED
-       */
-      if (debug_on)
-       if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED)
-         printf ("About to continue non-stopped thread %d\n", scan_tid);
-#endif
-
-      p = find_thread_info (scan_tid);
-      if (NULL == p)
-       {
-         add_tthread (real_pid, scan_tid);
-         p = find_thread_info (scan_tid);
-
-         /* This is either a newly-created thread or the
-          * result of a fork; in either case there's no
-          * actual event to worry about.
-          */
-         p->handled = 1;
-
-         if (state.tts_event != TTEVT_NONE)
-           {
-             /* Oops, do need to worry!
-              */
-             warning ("Unexpected thread with \"%s\" event.",
-                      get_printable_name_of_ttrace_event (state.tts_event));
-           }
-       }
-      else if (scan_tid != p->tid)
-       error ("Bad data in thread database.");
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       if (p->terminated)
-         printf ("Why are we continuing a dead thread?\n");
-#endif
-
-      p->seen = 1;
-
-      scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
-    }
-
-  /* Remove unseen threads.
-   */
-  update_thread_list ();
-
-  /* Now run down the thread list and continue or step.
-   */
-  for (p = thread_head.head; p; p = p->next)
-    {
-
-      /* Sanity check.
-       */
-      thread_dropping_event_check (p);
-
-      /* Pass the correct signals along.
-       */
-      if (p->have_signal)
-       {
-         thread_signal = p->signal_value;
-         p->have_signal = 0;
-       }
-      else
-       thread_signal = 0;
-
-      if (p->tid != real_tid)
-       {
-         /*
-          * Not the thread of interest, so continue it
-          * as the user expects.
-          */
-         if (p->stepping_mode == DO_STEP)
-           {
-             /* Just step this thread.
-              */
-             call_ttrace (
-                           TT_LWP_SINGLE,
-                           p->tid,
-                           TT_USE_CURRENT_PC,
-                           (TTRACE_ARG_TYPE) target_signal_to_host (signal),
-                           TT_NIL);
-           }
-         else
-           {
-             /* Regular continue (default case).
-              */
-             call_ttrace (
-                           TT_LWP_CONTINUE,
-                           p->tid,
-                           TT_USE_CURRENT_PC,
-                   (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
-                           TT_NIL);
-           }
-       }
-      else
-       {
-         /* Step the thread of interest.
-          */
-         call_ttrace (
-                       TT_LWP_SINGLE,
-                       real_tid,
-                       TT_USE_CURRENT_PC,
-                       (TTRACE_ARG_TYPE) target_signal_to_host (signal),
-                       TT_NIL);
-       }
-    }                          /* Loop over threads */
-}                              /* End threads_continue_all_but_one */
-
-/* Use a loop over the threads to continue all the threads.
- * This is done when a signal must be sent to any of the threads.
- */
-static void
-threads_continue_all_with_signals (lwpid_t gdb_tid, int signal)
-{
-  thread_info *p;
-  int thread_signal;
-  lwpid_t real_tid;
-  lwpid_t scan_tid;
-  ttstate_t state;
-  int real_pid;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("Using loop over threads to resume with signals\n");
-#endif
-
-  /* Scan and update thread list.
-   */
-  set_all_unseen ();
-  real_tid = map_from_gdb_tid (gdb_tid);
-  real_pid = get_pid_for (real_tid);
-
-  scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
-  while (0 != scan_tid)
-    {
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED)
-         warning ("About to continue non-stopped thread %d\n", scan_tid);
-#endif
-
-      p = find_thread_info (scan_tid);
-      if (NULL == p)
-       {
-         add_tthread (real_pid, scan_tid);
-         p = find_thread_info (scan_tid);
-
-         /* This is either a newly-created thread or the
-          * result of a fork; in either case there's no
-          * actual event to worry about.
-          */
-         p->handled = 1;
-
-         if (state.tts_event != TTEVT_NONE)
-           {
-             /* Oops, do need to worry!
-              */
-             warning ("Unexpected thread with \"%s\" event.",
-                      get_printable_name_of_ttrace_event (state.tts_event));
-           }
-       }
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       if (p->terminated)
-         printf ("Why are we continuing a dead thread? (1)\n");
-#endif
-
-      p->seen = 1;
-
-      scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
-    }
-
-  /* Remove unseen threads from our list.
-   */
-  update_thread_list ();
-
-  /* Continue the threads.
-   */
-  for (p = thread_head.head; p; p = p->next)
-    {
-
-      /* Sanity check.
-       */
-      thread_dropping_event_check (p);
-
-      /* Pass the correct signals along.
-       */
-      if (p->tid == real_tid)
-       {
-         thread_signal = signal;
-         p->have_signal = 0;
-       }
-      else if (p->have_signal)
-       {
-         thread_signal = p->signal_value;
-         p->have_signal = 0;
-       }
-      else
-       thread_signal = 0;
-
-      if (p->stepping_mode == DO_STEP)
-       {
-         call_ttrace (
-                       TT_LWP_SINGLE,
-                       p->tid,
-                       TT_USE_CURRENT_PC,
-                       (TTRACE_ARG_TYPE) target_signal_to_host (signal),
-                       TT_NIL);
-       }
-      else
-       {
-         /* Continue this thread (default case).
-          */
-         call_ttrace (
-                       TT_LWP_CONTINUE,
-                       p->tid,
-                       TT_USE_CURRENT_PC,
-                   (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
-                       TT_NIL);
-       }
-    }
-}                              /* End threads_continue_all_with_signals */
-
-/* Step one thread only.  
- */
-static void
-thread_fake_step (lwpid_t tid, enum target_signal signal)
-{
-  thread_info *p;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    {
-      printf ("Doing a fake-step over a bpt, etc. for %d\n", tid);
-
-      if (is_terminated (tid))
-       printf ("Why are we continuing a dead thread? (4)\n");
-    }
-#endif
-
-  if (doing_fake_step)
-    warning ("Step while step already in progress.");
-
-  /* See if there's a saved signal value for this
-   * thread to be passed on, but no current signal.
-   */
-  p = find_thread_info (tid);
-  if (p != NULL)
-    {
-      if (p->have_signal && signal == TARGET_SIGNAL_0)
-       {
-         /* Pass on a saved signal.
-          */
-         signal = p->signal_value;
-       }
-
-      p->have_signal = 0;
-    }
-
-  if (!p->handled)
-    warning ("Internal error: continuing unhandled thread.");
-
-  call_ttrace (TT_LWP_SINGLE,
-              tid,
-              TT_USE_CURRENT_PC,
-              (TTRACE_ARG_TYPE) target_signal_to_host (signal),
-              TT_NIL);
-
-  /* Do bookkeeping so "call_ttrace_wait" knows it has to wait
-   * for this thread only, and clear any saved signal info.
-   */
-  doing_fake_step = 1;
-  fake_step_tid = tid;
-
-}                              /* End thread_fake_step */
-
-/* Continue one thread when a signal must be sent to it.
- */
-static void
-threads_continue_one_with_signal (lwpid_t gdb_tid, int signal)
-{
-  thread_info *p;
-  lwpid_t real_tid;
-  int real_pid;
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("Continuing one thread with a signal\n");
-#endif
-
-  real_tid = map_from_gdb_tid (gdb_tid);
-  real_pid = get_pid_for (real_tid);
-
-  p = find_thread_info (real_tid);
-  if (NULL == p)
-    {
-      add_tthread (real_pid, real_tid);
-    }
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    if (p->terminated)
-      printf ("Why are we continuing a dead thread? (2)\n");
-#endif
-
-  if (!p->handled)
-    warning ("Internal error: continuing unhandled thread.");
-
-  p->have_signal = 0;
-
-  call_ttrace (TT_LWP_CONTINUE,
-              gdb_tid,
-              TT_USE_CURRENT_PC,
-              (TTRACE_ARG_TYPE) target_signal_to_host (signal),
-              TT_NIL);
-}
-#endif
-
-#ifndef DEPRECATED_CHILD_RESUME
-
-/* Resume execution of the inferior process.
-
- * This routine is in charge of setting the "handled" bits. 
- *
- *   If STEP is zero,      continue it.
- *   If STEP is nonzero,   single-step it.
- *   
- *   If SIGNAL is nonzero, give it that signal.
- *
- *   If TID is -1,         apply to all threads.
- *   If TID is not -1,     apply to specified thread.
- *   
- *           STEP
- *      \      !0                        0
- *  TID  \________________________________________________
- *       |
- *   -1  |   Step current            Continue all threads
- *       |   thread and              (but which gets any
- *       |   continue others         signal?--We look at
- *       |                           "inferior_ptid")
- *       |
- *    N  |   Step _this_ thread      Continue _this_ thread
- *       |   and leave others        and leave others 
- *       |   stopped; internally     stopped; used only for
- *       |   used by gdb, never      hardware watchpoints
- *       |   a user command.         and attach, never a
- *       |                           user command.
- */
-void
-child_resume (ptid_t ptid, int step, enum target_signal signal)
-{
-  int resume_all_threads;
-  lwpid_t tid;
-  process_state_t new_process_state;
-  lwpid_t gdb_tid = PIDGET (ptid);
-
-  resume_all_threads =
-    (gdb_tid == INFTTRACE_ALL_THREADS) ||
-    (vfork_in_flight);
-
-  if (resume_all_threads)
-    {
-      /* Resume all threads, but first pick a tid value
-       * so we can get the pid when in call_ttrace doing
-       * the map.
-       */
-      if (vfork_in_flight)
-       tid = vforking_child_pid;
-      else
-       tid = map_from_gdb_tid (PIDGET (inferior_ptid));
-    }
-  else
-    tid = map_from_gdb_tid (gdb_tid);
-
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    {
-      if (more_events_left)
-       printf ("More events; ");
-
-      if (signal != 0)
-       printf ("Sending signal %d; ", signal);
-
-      if (resume_all_threads)
-       {
-         if (step == 0)
-           printf ("Continue process %d\n", tid);
-         else
-           printf ("Step/continue thread %d\n", tid);
-       }
-      else
-       {
-         if (step == 0)
-           printf ("Continue thread %d\n", tid);
-         else
-           printf ("Step just thread %d\n", tid);
-       }
-
-      if (vfork_in_flight)
-       printf ("Vfork in flight\n");
-    }
-#endif
-
-  if (process_state == RUNNING)
-    warning ("Internal error in resume logic; doing resume or step anyway.");
-
-  if (!step                    /* Asked to continue...       */
-      && resume_all_threads    /* whole process..            */
-      && signal != 0           /* with a signal...           */
-      && more_events_left > 0)
-    {                          /* but we can't yet--save it! */
-
-      /* Continue with signal means we have to set the pending
-       * signal value for this thread.
-       */
-      thread_info *k;
-
-#ifdef THREAD_DEBUG
-      if (debug_on)
-       printf ("Saving signal %d for thread %d\n", signal, tid);
-#endif
-
-      k = find_thread_info (tid);
-      if (k != NULL)
-       {
-         k->have_signal = 1;
-         k->signal_value = signal;
-
-#ifdef THREAD_DEBUG
-         if (debug_on)
-           if (k->terminated)
-             printf ("Why are we continuing a dead thread? (3)\n");
-#endif
-
-       }
-
-#ifdef THREAD_DEBUG
-      else if (debug_on)
-       {
-         printf ("No thread info for tid %d\n", tid);
-       }
-#endif
-    }
-
-  /* Are we faking this "continue" or "step"?
-
-   * We used to do steps by continuing all the threads for 
-   * which the events had been handled already.  While
-   * conceptually nicer (hides it all in a lower level), this
-   * can lead to starvation and a hang (e.g. all but one thread
-   * are unhandled at a breakpoint just before a "join" operation,
-   * and one thread is in the join, and the user wants to step that
-   * thread).
-   */
-  if (resume_all_threads       /* Whole process, therefore user command */
-      && more_events_left > 0)
-    {                          /* But we can't do this yet--fake it! */
-      thread_info *p;
-
-      if (!step)
-       {
-         /* No need to do any notes on a per-thread
-          * basis--we're done!
-          */
-#ifdef WAIT_BUFFER_DEBUG
-         if (debug_on)
-           printf ("Faking a process resume.\n");
-#endif
-
-         return;
-       }
-      else
-       {
-
-#ifdef WAIT_BUFFER_DEBUG
-         if (debug_on)
-           printf ("Faking a process step.\n");
-#endif
-
-       }
-
-      p = find_thread_info (tid);
-      if (p == NULL)
-       {
-         warning ("No thread information for tid %d, 'next' command ignored.\n", tid);
-         return;
-       }
-      else
-       {
-
-#ifdef THREAD_DEBUG
-         if (debug_on)
-           if (p->terminated)
-             printf ("Why are we continuing a dead thread? (3.5)\n");
-#endif
-
-         if (p->stepping_mode != DO_DEFAULT)
-           {
-             warning ("Step or continue command applied to thread which is already stepping or continuing; command ignored.");
-
-             return;
-           }
-
-         if (step)
-           p->stepping_mode = DO_STEP;
-         else
-           p->stepping_mode = DO_CONTINUE;
-
-         return;
-       }                       /* Have thread info */
-    }                          /* Must fake step or go */
-
-  /* Execept for fake-steps, from here on we know we are
-   * going to wind up with a running process which will
-   * need a real wait.
-   */
-  new_process_state = RUNNING;
-
-  /* An address of TT_USE_CURRENT_PC tells ttrace 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 this system does not support PT_STEP, a higher level function will
-   * have called single_step() to transmute the step request into a
-   * continue request (by setting breakpoints on all possible successor
-   * instructions), so we don't have to worry about that here.
-   */
-  if (step)
-    {
-      if (resume_all_threads)
-       {
-         /*
-          * Regular user step: other threads get a "continue".
-          */
-         threads_continue_all_but_one (tid, signal);
-         clear_all_handled ();
-         clear_all_stepping_mode ();
-       }
-
-      else
-       {
-         /* "Fake step": gdb is stepping one thread over a
-          * breakpoint, watchpoint, or out of a library load
-          * event, etc.  The rest just stay where they are.
-          *
-          * Also used when there are pending events: we really
-          * step the current thread, but leave the rest stopped.
-          * Users can't request this, but "wait_for_inferior"
-          * does--a lot!
-          */
-         thread_fake_step (tid, signal);
-
-         /* Clear the "handled" state of this thread, because
-          * we'll soon get a new event for it.  Other events
-          * stay as they were.
-          */
-         clear_handled (tid);
-         clear_stepping_mode (tid);
-         new_process_state = FAKE_STEPPING;
-       }
-    }
-
-  else
-    {
-      /* TT_LWP_CONTINUE can pass signals to threads, TT_PROC_CONTINUE can't.
-        Therefore, we really can't use TT_PROC_CONTINUE here.
-
-        Consider a process which stopped due to signal which gdb decides
-        to handle and not pass on to the inferior.  In that case we must
-        clear the pending signal by restarting the inferior using
-        TT_LWP_CONTINUE and pass zero as the signal number.  Else the
-        pending signal will be passed to the inferior.  interrupt.exp
-        in the testsuite does this precise thing and fails due to the
-        unwanted signal delivery to the inferior.  */
-      /* drow/2002-12-05: However, note that we must use TT_PROC_CONTINUE
-        if we are tracing a vfork.  */
-      if (vfork_in_flight)
-       {
-         call_ttrace (TT_PROC_CONTINUE, tid, TT_NIL, TT_NIL, TT_NIL);
-         clear_all_handled ();
-         clear_all_stepping_mode ();
-       }
-      else if (resume_all_threads)
-       {
-#ifdef THREAD_DEBUG
-         if (debug_on)
-           printf ("Doing a continue by loop of all threads\n");
-#endif
-
-         threads_continue_all_with_signals (tid, signal);
-
-         clear_all_handled ();
-         clear_all_stepping_mode ();
-       }
-      else
-       {
-#ifdef THREAD_DEBUG
-         printf ("Doing a continue w/signal of just thread %d\n", tid);
-#endif
-
-         threads_continue_one_with_signal (tid, signal);
-
-         /* Clear the "handled" state of this thread, because we
-            will soon get a new event for it.  Other events can
-            stay as they were.  */
-         clear_handled (tid);
-         clear_stepping_mode (tid);
-       }
-    }
-
-  process_state = new_process_state;
-
-#ifdef WAIT_BUFFER_DEBUG
-  if (debug_on)
-    printf ("Process set to %s\n",
-           get_printable_name_of_process_state (process_state));
-#endif
-
-}
-#endif /* DEPRECATED_CHILD_RESUME */
-\f
-/*
- * Like it says.
- *
- * One worry is that we may not be attaching to "inferior_ptid"
- * and thus may not want to clear out our data.  FIXME?
- * 
- */
-static void
-update_thread_state_after_attach (int pid, attach_continue_t kind_of_go)
-{
-  int tt_status;
-  ttstate_t thread_state;
-  lwpid_t a_thread;
-  lwpid_t tid;
-
-  /* The process better be stopped.
-   */
-  if (process_state != STOPPED
-      && process_state != VFORKING)
-    warning ("Internal error attaching.");
-
-  /* Clear out old tthread info and start over.  This has the
-   * side effect of ensuring that the TRAP is reported as being
-   * in the right thread (re-mapped from tid to pid).
-   *
-   * It's because we need to add the tthread _now_ that we
-   * need to call "clear_thread_info" _now_, and that's why
-   * "require_notification_of_events" doesn't clear the thread
-   * info (it's called later than this routine).
-   */
-  clear_thread_info ();
-  a_thread = 0;
-
-  for (tid = get_process_first_stopped_thread_id (pid, &thread_state);
-       tid != 0;
-       tid = get_process_next_stopped_thread_id (pid, &thread_state))
-    {
-      thread_info *p;
-
-      if (a_thread == 0)
-       {
-         a_thread = tid;
-#ifdef THREAD_DEBUG
-         if (debug_on)
-           printf ("Attaching to process %d, thread %d\n",
-                   pid, a_thread);
-#endif
-       }
-
-      /* Tell ourselves and the "rest of gdb" that this thread
-       * exists.
-       *
-       * This isn't really a hack.  Other thread-based versions
-       * of gdb (e.g. gnu-nat.c) seem to do the same thing.
-       *
-       * We don't need to do mapping here, as we know this
-       * is the first thread and thus gets the real pid
-       * (and is "inferior_ptid").
-       *
-       * NOTE: it probably isn't the originating thread,
-       *       but that doesn't matter (we hope!).
-       */
-      add_tthread (pid, tid);
-      p = find_thread_info (tid);
-      if (NULL == p)           /* ?We just added it! */
-       error ("Internal error adding a thread on attach.");
-
-      copy_ttstate_t (&p->last_stop_state, &thread_state);
-      p->have_state = 1;
-
-      if (DO_ATTACH_CONTINUE == kind_of_go)
-       {
-         /*
-          * If we are going to CONTINUE afterwards,
-          * raising a SIGTRAP, don't bother trying to
-          * handle this event.  But check first!
-          */
-         switch (p->last_stop_state.tts_event)
-           {
-
-           case TTEVT_NONE:
-             /* Ok to set this handled.
-              */
-             break;
-
-           default:
-             warning ("Internal error; skipping event %s on process %d, thread %d.",
-                      get_printable_name_of_ttrace_event (
-                                             p->last_stop_state.tts_event),
-                      p->pid, p->tid);
-           }
-
-         set_handled (pid, tid);
-
-       }
-      else
-       {
-         /* There will be no "continue" opertion, so the
-          * process remains stopped.  Don't set any events
-          * handled except the "gimmies".
-          */
-         switch (p->last_stop_state.tts_event)
-           {
-
-           case TTEVT_NONE:
-             /* Ok to ignore this.
-              */
-             set_handled (pid, tid);
-             break;
-
-           case TTEVT_EXEC:
-           case TTEVT_FORK:
-             /* Expected "other" FORK or EXEC event from a
-              * fork or vfork.
-              */
-             break;
-
-           default:
-             printf ("Internal error: failed to handle event %s on process %d, thread %d.",
-                     get_printable_name_of_ttrace_event (
-                                             p->last_stop_state.tts_event),
-                     p->pid, p->tid);
-           }
-       }
-
-      add_thread (pid_to_ptid (pid));          /* in thread.c */
-    }
-
-#ifdef PARANOIA
-  if (debug_on)
-    print_tthreads ();
-#endif
-
-  /* One mustn't call ttrace_wait() after attaching via ttrace,
-     'cause the process is stopped already.
-
-     However, the upper layers of gdb's execution control will
-     want to wait after attaching (but not after forks, in
-     which case they will be doing a "target_resume", anticipating
-     a later TTEVT_EXEC or TTEVT_FORK event).
-
-     To make this attach() implementation more compatible with
-     others, we'll make the attached-to process raise a SIGTRAP.
-
-     Issue: this continues only one thread.  That could be
-     dangerous if the thread is blocked--the process won't run
-     and no trap will be raised.  FIX! (check state.tts_flags?
-     need one that's either TTS_WASRUNNING--but we've stopped
-     it and made it TTS_WASSUSPENDED.  Hum...FIXME!)
-   */
-  if (DO_ATTACH_CONTINUE == kind_of_go)
-    {
-      tt_status = call_real_ttrace (
-                                    TT_LWP_CONTINUE,
-                                    pid,
-                                    a_thread,
-                                    TT_USE_CURRENT_PC,
-              (TTRACE_ARG_TYPE) target_signal_to_host (TARGET_SIGNAL_TRAP),
-                                    TT_NIL);
-      if (errno)
-       perror_with_name ("ttrace");
-
-      clear_handled (a_thread);        /* So TRAP will be reported. */
-
-      /* Now running.
-       */
-      process_state = RUNNING;
-    }
-
-  attach_flag = 1;
-}
-\f
-
-/* Start debugging the process whose number is PID.
- * (A _real_ pid).
- */
-int
-attach (int pid)
-{
-  int tt_status;
-
-  tt_status = call_real_ttrace (
-                                TT_PROC_ATTACH,
-                                pid,
-                                (lwpid_t) TT_NIL,
-                                TT_NIL,
-                                (TTRACE_ARG_TYPE) TT_VERSION,
-                                TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace attach");
-
-  /* If successful, the process is now stopped.
-   */
-  process_state = STOPPED;
-
-  /* Our caller ("attach_command" in "infcmd.c")
-   * expects to do a "wait_for_inferior" after
-   * the attach, so make sure the inferior is
-   * running when we're done.
-   */
-  update_thread_state_after_attach (pid, DO_ATTACH_CONTINUE);
-
-  return pid;
-}
-
-
-#if defined(CHILD_POST_ATTACH)
-void
-child_post_attach (int pid)
-{
-#ifdef THREAD_DEBUG
-  if (debug_on)
-    printf ("child-post-attach call\n");
-#endif
-
-  require_notification_of_events (pid);
-}
-#endif
-
-
-/* Stop debugging the process whose number is PID
-   and continue it with signal number SIGNAL.
-   SIGNAL = 0 means just continue it.
- */
-void
-detach (int signal)
-{
-  errno = 0;
-  call_ttrace (TT_PROC_DETACH,
-              PIDGET (inferior_ptid),
-              TT_NIL,
-              (TTRACE_ARG_TYPE) signal,
-              TT_NIL);
-  attach_flag = 0;
-
-  clear_thread_info ();
-
-  /* Process-state? */
-}
-\f
-
-/* Default the type of the ttrace transfer to int.  */
-#ifndef TTRACE_XFER_TYPE
-#define TTRACE_XFER_TYPE int
-#endif
-
-void
-_initialize_kernel_u_addr (void)
-{
-}
-
-#if !defined (CHILD_XFER_MEMORY)
-/* NOTE! I tried using TTRACE_READDATA, etc., to read and write memory
-   in the NEW_SUN_TTRACE 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.  TARGET is ignored.
-
-   Returns the length copied, which is either the LEN argument or
-   zero.  This xfer function does not do partial moves, since
-   deprecated_child_ops doesn't allow memory operations to cross below
-   us in the target stack anyway.  */
-
-int
-child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                  struct mem_attrib *attrib,
-                  struct target_ops *target)
-{
-  int i;
-  /* Round starting address down to longword boundary.  */
-  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (TTRACE_XFER_TYPE);
-  /* Round ending address up; get number of longwords that makes.  */
-  int count
-  = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1)
-  / sizeof (TTRACE_XFER_TYPE);
-  /* Allocate buffer of that many longwords.  */
-  /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
-     because it uses alloca to allocate a buffer of arbitrary size.
-     For very large xfers, this could crash GDB's stack.  */
-  TTRACE_XFER_TYPE *buffer
-    = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
-
-  if (write)
-    {
-      /* Fill start and end extra bytes of buffer with existing memory data.  */
-
-      if (addr != memaddr || len < (int) sizeof (TTRACE_XFER_TYPE))
-       {
-         /* Need part of initial word -- fetch it.  */
-         buffer[0] = call_ttrace (TT_LWP_RDTEXT,
-                                  PIDGET (inferior_ptid),
-                                  (TTRACE_ARG_TYPE) addr,
-                                  TT_NIL,
-                                  TT_NIL);
-       }
-
-      if (count > 1)           /* FIXME, avoid if even boundary */
-       {
-         buffer[count - 1] = call_ttrace (TT_LWP_RDTEXT,
-                                          PIDGET (inferior_ptid),
-                                          ((TTRACE_ARG_TYPE)
-                         (addr + (count - 1) * sizeof (TTRACE_XFER_TYPE))),
-                                          TT_NIL,
-                                          TT_NIL);
-       }
-
-      /* Copy data to be written over corresponding part of buffer */
-
-      memcpy ((char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
-             myaddr,
-             len);
-
-      /* Write the entire buffer.  */
-
-      for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
-       {
-         errno = 0;
-         call_ttrace (TT_LWP_WRDATA,
-                      PIDGET (inferior_ptid),
-                      (TTRACE_ARG_TYPE) addr,
-                      (TTRACE_ARG_TYPE) buffer[i],
-                      TT_NIL);
-         if (errno)
-           {
-             /* Using the appropriate one (I or D) is necessary for
-                Gould NP1, at least.  */
-             errno = 0;
-             call_ttrace (TT_LWP_WRTEXT,
-                          PIDGET (inferior_ptid),
-                          (TTRACE_ARG_TYPE) addr,
-                          (TTRACE_ARG_TYPE) buffer[i],
-                          TT_NIL);
-           }
-         if (errno)
-           return 0;
-       }
-    }
-  else
-    {
-      /* Read all the longwords */
-      for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
-       {
-         errno = 0;
-         buffer[i] = call_ttrace (TT_LWP_RDTEXT,
-                                  PIDGET (inferior_ptid),
-                                  (TTRACE_ARG_TYPE) addr,
-                                  TT_NIL,
-                                  TT_NIL);
-         if (errno)
-           return 0;
-         QUIT;
-       }
-
-      /* Copy appropriate bytes out of the buffer.  */
-      memcpy (myaddr,
-             (char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
-             len);
-    }
-  return len;
-}
-\f
-
-static void
-udot_info (void)
-{
-  int udot_off;                        /* Offset into user struct */
-  int udot_val;                        /* Value from user struct at udot_off */
-  char mess[128];              /* For messages */
-
-  if (!target_has_execution)
-    {
-      error ("The program is not being run.");
-    }
-
-#if !defined (KERNEL_U_SIZE)
-
-  /* Adding support for this command is easy.  Typically you just add a
-     routine, called "kernel_u_size" that returns the size of the user
-     struct, to the appropriate *-nat.c file and then add to the native
-     config file "#define KERNEL_U_SIZE kernel_u_size()" */
-  error ("Don't know how large ``struct user'' is in this version of gdb.");
-
-#else
-
-  for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
-    {
-      if ((udot_off % 24) == 0)
-       {
-         if (udot_off > 0)
-           {
-             printf_filtered ("\n");
-           }
-         printf_filtered ("%04x:", udot_off);
-       }
-      udot_val = call_ttrace (TT_LWP_RUREGS,
-                             PIDGET (inferior_ptid),
-                             (TTRACE_ARG_TYPE) udot_off,
-                             TT_NIL,
-                             TT_NIL);
-      if (errno != 0)
-       {
-         sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
-         perror_with_name (mess);
-       }
-      /* Avoid using nonportable (?) "*" in print specs */
-      printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
-    }
-  printf_filtered ("\n");
-
-#endif
-}
-#endif /* !defined (CHILD_XFER_MEMORY).  */
-
-
-/* TTrace version of "target_pid_to_exec_file"
- */
-char *
-child_pid_to_exec_file (int tid)
-{
-  int tt_status;
-  static char exec_file_buffer[1024];
-  pid_t pid;
-  static struct pst_status buf;
-
-  /* On various versions of hpux11, this may fail due to a supposed
-     kernel bug.  We have alternate methods to get this information
-     (ie pstat).  */
-  tt_status = call_ttrace (TT_PROC_GET_PATHNAME,
-                          tid,
-                          (uint64_t) exec_file_buffer,
-                          sizeof (exec_file_buffer) - 1,
-                          0);
-  if (tt_status >= 0)
-    return exec_file_buffer;
-
-  /* Try to get process information via pstat and extract the filename
-     from the pst_cmd field within the pst_status structure.  */
-  if (pstat_getproc (&buf, sizeof (struct pst_status), 0, tid) != -1)
-    {
-      char *p = buf.pst_cmd;
-
-      while (*p && *p != ' ')
-       p++;
-      *p = 0;
-
-      return (buf.pst_cmd);
-    }
-
-  return (NULL);
-}
-
-void
-pre_fork_inferior (void)
-{
-  int status;
-
-  status = pipe (startup_semaphore.parent_channel);
-  if (status < 0)
-    {
-      warning ("error getting parent pipe for startup semaphore");
-      return;
-    }
-
-  status = pipe (startup_semaphore.child_channel);
-  if (status < 0)
-    {
-      warning ("error getting child pipe for startup semaphore");
-      return;
-    }
-}
-
-/* Called from child_follow_fork in hppah-nat.c.
- *
- * This seems to be intended to attach after a fork or
- * vfork, while "attach" is used to attach to a pid
- * given by the user.  The check for an existing attach
- * seems odd--it always fails in our test system.
- */
-int
-hppa_require_attach (int pid)
-{
-  int tt_status;
-  CORE_ADDR pc;
-  CORE_ADDR pc_addr;
-  unsigned int regs_offset;
-  process_state_t old_process_state = process_state;
-
-  /* Are we already attached?  There appears to be no explicit
-   * way to answer this via ttrace, so we try something which
-   * should be innocuous if we are attached.  If that fails,
-   * then we assume we're not attached, and so attempt to make
-   * it so.
-   */
-  errno = 0;
-  tt_status = call_real_ttrace (TT_PROC_STOP,
-                               pid,
-                               (lwpid_t) TT_NIL,
-                               (TTRACE_ARG_TYPE) TT_NIL,
-                               (TTRACE_ARG_TYPE) TT_NIL,
-                               TT_NIL);
-
-  if (errno)
-    {
-      /* No change to process-state!
-       */
-      errno = 0;
-      pid = attach (pid);
-    }
-  else
-    {
-      /* If successful, the process is now stopped.  But if
-       * we're VFORKING, the parent is still running, so don't
-       * change the process state.
-       */
-      if (process_state != VFORKING)
-       process_state = STOPPED;
-
-      /* If we were already attached, you'd think that we
-       * would need to start going again--but you'd be wrong,
-       * as the fork-following code is actually in the middle
-       * of the "resume" routine in in "infrun.c" and so
-       * will (almost) immediately do a resume.
-       *
-       * On the other hand, if we are VFORKING, which means
-       * that the child and the parent share a process for a
-       * while, we know that "resume" won't be resuming
-       * until the child EXEC event is seen.  But we still
-       * don't want to continue, as the event is already
-       * there waiting.
-       */
-      update_thread_state_after_attach (pid, DONT_ATTACH_CONTINUE);
-    }                          /* STOP succeeded */
-
-  return pid;
-}
-
-int
-hppa_require_detach (int pid, int signal)
-{
-  int tt_status;
-
-  /* If signal is non-zero, we must pass the signal on to the active
-     thread prior to detaching.  We do this by continuing the threads
-     with the signal.
-   */
-  if (signal != 0)
-    {
-      errno = 0;
-      threads_continue_all_with_signals (pid, signal);
-    }
-
-  errno = 0;
-  tt_status = call_ttrace (TT_PROC_DETACH,
-                          pid,
-                          TT_NIL,
-                          TT_NIL,
-                          TT_NIL);
-
-  errno = 0;                   /* Ignore any errors. */
-
-  /* process_state? */
-
-  return pid;
-}
-
-/* Given the starting address of a memory page, hash it to a bucket in
-   the memory page dictionary.
- */
-static int
-get_dictionary_bucket_of_page (CORE_ADDR page_start)
-{
-  int hash;
-
-  hash = (page_start / memory_page_dictionary.page_size);
-  hash = hash % MEMORY_PAGE_DICTIONARY_BUCKET_COUNT;
-
-  return hash;
-}
-
-
-/* Given a memory page's starting address, get (i.e., find an existing
-   or create a new) dictionary entry for the page.  The page will be
-   write-protected when this function returns, but may have a reference
-   count of 0 (if the page was newly-added to the dictionary).
- */
-static memory_page_t *
-get_dictionary_entry_of_page (int pid, CORE_ADDR page_start)
-{
-  int bucket;
-  memory_page_t *page = NULL;
-  memory_page_t *previous_page = NULL;
-
-  /* We're going to be using the dictionary now, than-kew. */
-  require_memory_page_dictionary ();
-
-  /* Try to find an existing dictionary entry for this page.  Hash
-     on the page's starting address.
-   */
-  bucket = get_dictionary_bucket_of_page (page_start);
-  page = &memory_page_dictionary.buckets[bucket];
-  while (page != NULL)
-    {
-      if (page->page_start == page_start)
-       break;
-      previous_page = page;
-      page = page->next;
-    }
-
-  /* Did we find a dictionary entry for this page?  If not, then
-     add it to the dictionary now.
-   */
-  if (page == NULL)
-    {
-      /* Create a new entry. */
-      page = (memory_page_t *) xmalloc (sizeof (memory_page_t));
-      page->page_start = page_start;
-      page->reference_count = 0;
-      page->next = NULL;
-      page->previous = NULL;
-
-      /* We'll write-protect the page now, if that's allowed. */
-      page->original_permissions = write_protect_page (pid, page_start);
-
-      /* Add the new entry to the dictionary. */
-      page->previous = previous_page;
-      previous_page->next = page;
-
-      memory_page_dictionary.page_count++;
-    }
-
-  return page;
-}
-
-
-static void
-remove_dictionary_entry_of_page (int pid, memory_page_t *page)
-{
-  /* Restore the page's original permissions. */
-  unwrite_protect_page (pid, page->page_start, page->original_permissions);
-
-  /* Kick the page out of the dictionary. */
-  if (page->previous != NULL)
-    page->previous->next = page->next;
-  if (page->next != NULL)
-    page->next->previous = page->previous;
-
-  /* Just in case someone retains a handle to this after it's freed. */
-  page->page_start = (CORE_ADDR) 0;
-
-  memory_page_dictionary.page_count--;
-
-  xfree (page);
-}
-
-
-static void
-hppa_enable_syscall_events (int pid)
-{
-  int tt_status;
-  ttevent_t ttrace_events;
-
-  /* Get the set of events that are currently enabled. */
-  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
-                          pid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace");
-
-  /* Add syscall events to that set. */
-  ttrace_events.tte_events |= TTEVT_SYSCALL_ENTRY;
-  ttrace_events.tte_events |= TTEVT_SYSCALL_RETURN;
-
-  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
-                          pid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace");
-}
-
-
-static void
-hppa_disable_syscall_events (int pid)
-{
-  int tt_status;
-  ttevent_t ttrace_events;
-
-  /* Get the set of events that are currently enabled. */
-  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
-                          pid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace");
-
-  /* Remove syscall events from that set. */
-  ttrace_events.tte_events &= ~TTEVT_SYSCALL_ENTRY;
-  ttrace_events.tte_events &= ~TTEVT_SYSCALL_RETURN;
-
-  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
-                          pid,
-                          (TTRACE_ARG_TYPE) & ttrace_events,
-                          (TTRACE_ARG_TYPE) sizeof (ttrace_events),
-                          TT_NIL);
-  if (errno)
-    perror_with_name ("ttrace");
-}
-
-
-/* The address range beginning with START and ending with START+LEN-1
-   (inclusive) is to be watched via page-protection by a new watchpoint.
-   Set protection for all pages that overlap that range.
-
-   Note that our caller sets TYPE to:
-   0 for a bp_hardware_watchpoint,
-   1 for a bp_read_watchpoint,
-   2 for a bp_access_watchpoint
-
-   (Yes, this is intentionally (though lord only knows why) different
-   from the TYPE that is passed to hppa_remove_hw_watchpoint.)
- */
-int
-hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
-{
-  CORE_ADDR page_start;
-  int dictionary_was_empty;
-  int page_size;
-  int page_id;
-  LONGEST range_size_in_pages;
-
-  if (type != 0)
-    error ("read or access hardware watchpoints not supported on HP-UX");
-
-  /* Examine all pages in the address range. */
-  require_memory_page_dictionary ();
-
-  dictionary_was_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
-
-  page_size = memory_page_dictionary.page_size;
-  page_start = (start / page_size) * page_size;
-  range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
-
-  for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
-    {
-      memory_page_t *page;
-
-      /* This gets the page entered into the dictionary if it was
-         not already entered.
-       */
-      page = get_dictionary_entry_of_page (pid, page_start);
-      page->reference_count++;
-    }
-
-  /* Our implementation depends on seeing calls to kernel code, for the
-     following reason.  Here we ask to be notified of syscalls.
-
-     When a protected page is accessed by user code, HP-UX raises a SIGBUS.
-     Fine.
-
-     But when kernel code accesses the page, it doesn't give a SIGBUS.
-     Rather, the system call that touched the page fails, with errno=EFAULT.
-     Not good for us.
-
-     We could accomodate this "feature" by asking to be notified of syscall
-     entries & exits; upon getting an entry event, disabling page-protections;
-     upon getting an exit event, reenabling page-protections and then checking
-     if any watchpoints triggered.
-
-     However, this turns out to be a real performance loser.  syscalls are
-     usually a frequent occurrence.  Having to unprotect-reprotect all watched
-     pages, and also to then read all watched memory locations and compare for
-     triggers, can be quite expensive.
-
-     Instead, we'll only ask to be notified of syscall exits.  When we get
-     one, we'll check whether errno is set.  If not, or if it's not EFAULT,
-     we can just continue the inferior.
-
-     If errno is set upon syscall exit to EFAULT, we must perform some fairly
-     hackish stuff to determine whether the failure really was due to a
-     page-protect trap on a watched location.
-   */
-  if (dictionary_was_empty)
-    hppa_enable_syscall_events (pid);
-
-  return 1;
-}
-
-
-/* The address range beginning with START and ending with START+LEN-1
-   (inclusive) was being watched via page-protection by a watchpoint
-   which has been removed.  Remove protection for all pages that
-   overlap that range, which are not also being watched by other
-   watchpoints.
- */
-int
-hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
-{
-  CORE_ADDR page_start;
-  int dictionary_is_empty;
-  int page_size;
-  int page_id;
-  LONGEST range_size_in_pages;
-
-  if (type != 0)
-    error ("read or access hardware watchpoints not supported on HP-UX");
-
-  /* Examine all pages in the address range. */
-  require_memory_page_dictionary ();
-
-  page_size = memory_page_dictionary.page_size;
-  page_start = (start / page_size) * page_size;
-  range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
-
-  for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
-    {
-      memory_page_t *page;
-
-      page = get_dictionary_entry_of_page (pid, page_start);
-      page->reference_count--;
-
-      /* Was this the last reference of this page?  If so, then we
-         must scrub the entry from the dictionary, and also restore
-         the page's original permissions.
-       */
-      if (page->reference_count == 0)
-       remove_dictionary_entry_of_page (pid, page);
-    }
-
-  dictionary_is_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
-
-  /* If write protections are currently disallowed, then that implies that
-     wait_for_inferior believes that the inferior is within a system call.
-     Since we want to see both syscall entry and return, it's clearly not
-     good to disable syscall events in this state!
-
-     ??rehrauer: Yeah, it'd be better if we had a specific flag that said,
-     "inferior is between syscall events now".  Oh well.
-   */
-  if (dictionary_is_empty && memory_page_dictionary.page_protections_allowed)
-    hppa_disable_syscall_events (pid);
-
-  return 1;
-}
-
-
-/* Could we implement a watchpoint of this type via our available
-   hardware support?
-
-   This query does not consider whether a particular address range
-   could be so watched, but just whether support is generally available
-   for such things.  See hppa_range_profitable_for_hw_watchpoint for a
-   query that answers whether a particular range should be watched via
-   hardware support.
- */
-int
-hppa_can_use_hw_watchpoint (int type, int cnt, int ot)
-{
-  return (type == bp_hardware_watchpoint);
-}
-
-
-/* Assuming we could set a hardware watchpoint on this address, do
-   we think it would be profitable ("a good idea") to do so?  If not,
-   we can always set a regular (aka single-step & test) watchpoint
-   on the address...
- */
-int
-hppa_range_profitable_for_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len)
-{
-  int range_is_stack_based;
-  int range_is_accessible;
-  CORE_ADDR page_start;
-  int page_size;
-  int page;
-  LONGEST range_size_in_pages;
-
-  /* ??rehrauer: For now, say that all addresses are potentially
-     profitable.  Possibly later we'll want to test the address
-     for "stackness"?
-   */
-  range_is_stack_based = 0;
-
-  /* If any page in the range is inaccessible, then we cannot
-     really use hardware watchpointing, even though our client
-     thinks we can.  In that case, it's actually an error to
-     attempt to use hw watchpoints, so we'll tell our client
-     that the range is "unprofitable", and hope that they listen...
-   */
-  range_is_accessible = 1;     /* Until proven otherwise. */
-
-  /* Examine all pages in the address range. */
-  errno = 0;
-  page_size = sysconf (_SC_PAGE_SIZE);
-
-  /* If we can't determine page size, we're hosed.  Tell our
-     client it's unprofitable to use hw watchpoints for this
-     range.
-   */
-  if (errno || (page_size <= 0))
-    {
-      errno = 0;
-      return 0;
-    }
-
-  page_start = (start / page_size) * page_size;
-  range_size_in_pages = len / (LONGEST) page_size;
-
-  for (page = 0; page < range_size_in_pages; page++, page_start += page_size)
-    {
-      int tt_status;
-      int page_permissions;
-
-      /* Is this page accessible? */
-      errno = 0;
-      tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
-                              pid,
-                              (TTRACE_ARG_TYPE) page_start,
-                              TT_NIL,
-                              (TTRACE_ARG_TYPE) & page_permissions);
-      if (errno || (tt_status < 0))
-       {
-         errno = 0;
-         range_is_accessible = 0;
-         break;
-       }
-
-      /* Yes, go for another... */
-    }
-
-  return (!range_is_stack_based && range_is_accessible);
-}
-
-
-char *
-hppa_pid_or_tid_to_str (ptid_t ptid)
-{
-  static char buf[100];                /* Static because address returned. */
-  pid_t id = PIDGET (ptid);
-
-  /* Does this appear to be a process?  If so, print it that way. */
-  if (is_process_id (id))
-    return child_pid_to_str (ptid);
-
-  /* Else, print both the GDB thread number and the system thread id. */
-  sprintf (buf, "thread %d (", pid_to_thread_id (ptid));
-  strcat (buf, hppa_tid_to_str (ptid));
-  strcat (buf, ")\0");
-
-  return buf;
-}
-\f
-
-void
-hppa_ensure_vforking_parent_remains_stopped (int pid)
-{
-  /* Nothing to do when using ttrace.  Only the ptrace-based implementation
-     must do real work.
-   */
-}
-
-
-int
-hppa_resume_execd_vforking_child_to_get_parent_vfork (void)
-{
-  return 0;                    /* No, the parent vfork is available now. */
-}
-\f
-
-/* Write a register as a 64bit value.  This may be necessary if the
-   native OS is too braindamaged to allow some (or all) registers to
-   be written in 32bit hunks such as hpux11 and the PC queue registers.
-
-   This is horribly gross and disgusting.  */
-int
-ttrace_write_reg_64 (int gdb_tid, CORE_ADDR dest_addr, CORE_ADDR src_addr)
-{
-  pid_t        pid;
-  lwpid_t      tid;
-  int                  tt_status;
-
-  tid = map_from_gdb_tid (gdb_tid);
-  pid = get_pid_for (tid);
-
-  errno = 0;
-  tt_status = ttrace (TT_LWP_WUREGS, 
-                     pid, 
-                     tid, 
-                     (TTRACE_ARG_TYPE) dest_addr, 
-                     8, 
-                     (TTRACE_ARG_TYPE) src_addr );
-
-#ifdef THREAD_DEBUG
-  if (errno)
-    {
-      /* Don't bother for a known benign error: if you ask for the
-         first thread state, but there is only one thread and it's
-         not stopped, ttrace complains.
-        
-         We have this inside the #ifdef because our caller will do
-         this check for real.  */
-      if( request != TT_PROC_GET_FIRST_LWP_STATE
-          ||  errno   != EPROTO )
-        {
-          if( debug_on )
-            printf( "TT fail for %s, with pid %d, tid %d, status %d \n",
-                    get_printable_name_of_ttrace_request (TT_LWP_WUREGS),
-                    pid, tid, tt_status );
-        }
-    }
-#endif
-
-  return tt_status;
-}
-
-void
-_initialize_infttrace (void)
-{
-  /* Initialize the ttrace-based hardware watchpoint implementation. */
-  memory_page_dictionary.page_count = (LONGEST) - 1;
-  memory_page_dictionary.page_protections_allowed = 1;
-
-  errno = 0;
-  memory_page_dictionary.page_size = sysconf (_SC_PAGE_SIZE);
-
-  /* We do a lot of casts from pointers to TTRACE_ARG_TYPE; make sure
-     this is okay.  */
-  if (sizeof (TTRACE_ARG_TYPE) < sizeof (void *))
-    internal_error (__FILE__, __LINE__, "failed internal consistency check");
-
-  if (errno || (memory_page_dictionary.page_size <= 0))
-    perror_with_name ("sysconf");
-}
diff --git a/gdb/infttrace.h b/gdb/infttrace.h
deleted file mode 100644 (file)
index c505b64..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Low level Unix child interface to ttrace, for GDB when running under HP-UX.
-
-   Copyright 2003, 2004 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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#ifndef INFTTRACE_H
-#define INFTTRACE_H
-
-enum target_waitkind;
-
-extern int parent_attach_all (int, PTRACE_ARG3_TYPE, int);
-extern pid_t hppa_switched_threads (pid_t gdb_pid);
-extern int hpux_has_forked (int pid, int *childpid);
-extern int hpux_has_vforked (int pid, int *childpid);
-extern int hpux_has_execd (int pid, char **execd_pathname);
-extern int hpux_has_syscall_event (int pid, enum target_waitkind *kind,
-                                  int *syscall_id);
-extern int ttrace_write_reg_64 (int, CORE_ADDR, CORE_ADDR);
-
-#endif