Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [Patch] The rest of the QNX files for native i386
@ 2003-02-26 21:51 Kris Warkentin
  0 siblings, 0 replies; only message in thread
From: Kris Warkentin @ 2003-02-26 21:51 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1179 bytes --]

Okay.  Here is the big one.  The config files were small and easy to
examine.  This one, not so much.  I've done all of what was suggested as far
as separating remote from native.  I've also cleaned up the #ifdefs, added
copyright notices, run indent, changed debug reporting code to be activated
at runtime rather than compile time, etc. etc. etc.

There is no longer any requirement for the remote stuff at all -
remote-nto.c and dsmsgs.h are not included in this patch.  I'm not planning
on going away as a maintainer so what I'm kind of hoping to do is to get
these files in (since they don't affect anyone else) and then, if anyone
else feels like commenting on things that need to be fixed, it can be done
on the tree.

With Andrew's permission, if this is accepted, I'd also like to add myself
as Host/Native maintainer for our platform.

Cheers,

Kris

ChangeLog

    * i386-nto-tdep.c: New file.  i386 specific support for QNX Neutrino.
    * nto-procfs.c: New file. Neutrino procfs routines.
    * nto-share/debug.h: New file.  Neutrino procfs interface.
    * nto-tdep.c: New file. Neutrino target support routines.
    * nto-tdep.h: New file. Neutrino target header.

[-- Attachment #2: nto_diff.txt --]
[-- Type: text/plain, Size: 77173 bytes --]

diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/i386-nto-tdep.c src/gdb/i386-nto-tdep.c
*** src.orig/gdb/i386-nto-tdep.c	Wed Dec 31 19:00:00 1969
--- src/gdb/i386-nto-tdep.c	Mon Feb 24 16:58:16 2003
***************
*** 0 ****
--- 1,422 ----
+ /* i386-nto-tdep.c - i386 specific functionality for QNX Neutrino */
+ 
+ /* Copyright 2003 Free Software Foundation */
+ 
+ /* This code was donated by QNX Software Systems Ltd. */
+ 
+ #include "defs.h"
+ #include "gdb_string.h"
+ #include <fcntl.h>
+ #include "frame.h"
+ #include "inferior.h"
+ #include "bfd.h"
+ #include "symfile.h"
+ #include "target.h"
+ #include "gdb_wait.h"
+ #include "gdbcmd.h"
+ #include "objfiles.h"
+ #include "gdb-stabs.h"
+ #include "gdbthread.h"
+ #include "regcache.h"
+ #include "solib-svr4.h"
+ #include "dcache.h"
+ #include "i386-tdep.h"
+ #include "nto-tdep.h"
+ #include "osabi.h"
+ 
+ #ifdef USG
+ #include <sys/types.h>
+ #endif
+ 
+ #include <signal.h>
+ #include "serial.h"
+ 
+ #include "nto-share/debug.h"
+ 
+ /* Prototypes for i387_supply_fsave etc.  */
+ #include "i387-tdep.h"
+ 
+ #ifndef FPC_REGNUM
+ #define FPC_REGNUM (FP0_REGNUM + 8)
+ #endif
+ 
+ #define NUM_GPREGS 13
+ static int gdb_to_nto[NUM_GPREGS] =
+   { 7, 6, 5, 4, 11, 2, 1, 0, 8, 10, 9, 12, -1 };
+ 
+ #define GDB_TO_OS(x)	((x >= 0 && x < NUM_GPREGS) ? gdb_to_nto[x] : -1)
+ 
+ #ifndef X86_CPU_FXSR
+ #define X86_CPU_FXSR (1L << 12)
+ #endif
+ 
+ extern unsigned nto_cpuinfo_flags;
+ extern int nto_cpuinfo_valid;
+ extern int nto_ostype, nto_cputype;
+ /*
+ 	Given a register return an id that represents the Neutrino regset it came from
+ 	if reg == -1 update all regsets
+ 	$MJC
+  */
+ 
+ enum QNX_REGS
+ {
+   QNX_REGS_GP = 0,
+   QNX_REGS_FP = 1,
+   QNX_REGS_END = 2
+ };
+ 
+ unsigned
+ nto_get_regset_id (int regno)
+ {
+   unsigned regset;
+   if (regno == -1)
+     {				/* return size so we can enumerate */
+       regset = 2;
+     }
+   else if (regno < FP0_REGNUM)
+     {
+       regset = 0;
+     }
+   else if (regno < FPC_REGNUM)
+     {
+       regset = 1;
+     }
+   else
+     {
+       regset = -1;		/* error */
+     }
+   return regset;
+ }
+ 
+ /* Tell GDB about the regset contained in the 'data' buffer  */
+ static void
+ gp_regset_fetch (char *data)
+ {
+   unsigned first_regno;
+   for (first_regno = 0; first_regno < FP0_REGNUM; first_regno++)
+     {
+       int regno = GDB_TO_OS (first_regno);
+       int const minusone = -1;
+ 
+       if (data == NULL || regno == -1)
+ 	{
+ 	  supply_register (first_regno, (char *) &minusone);
+ 	}
+       else
+ 	{
+ 	  supply_register (first_regno, &data[regno * 4]);
+ 	}
+     }
+ }
+ 
+ /* get 8087 data */
+ static void
+ fp_regset_fetch (char *data)
+ {
+   if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
+     i387_supply_fxsave (data);
+   else
+     i387_supply_fsave (data);
+ }
+ 
+ void
+ nto_cpu_regset_fetch (int endian, int regset, void *data)
+ {
+   endian = endian;		/* x86, don't care about endian */
+ 
+   switch (regset)
+     {
+     case QNX_REGS_GP:		/* QNX has different ordering of GP regs GDB */
+       gp_regset_fetch ((char *) data);
+       break;
+     case QNX_REGS_FP:
+       fp_regset_fetch ((char *) data);
+       break;
+     }
+ }
+ 
+ /* get regset characteristics */
+ unsigned
+ nto_get_regset_area (unsigned regset, char *subcmd)
+ {
+   unsigned length = 0;
+   switch (regset)
+     {
+     case QNX_REGS_GP:
+       *subcmd = NTO_REG_GENERAL;
+       length = NUM_GPREGS * sizeof (unsigned);
+       break;
+     case QNX_REGS_FP:
+       *subcmd = NTO_REG_FLOAT;
+       /* FIXME: should we calculate based on fxsave/fsave? */
+       length = 512;
+       break;
+     default:
+       length = 0;
+     }
+   return length;
+ }
+ 
+ /*-
+ 	Given the first and last register number, figure out the size/len
+ 	of the Neutrino register save area to ask for/tell about. Also set
+ 	the register set that's being dealt with in *subcmd. Watch out for
+ 	the range crossing a register set boundry.
+  */
+ 
+ unsigned
+ nto_cpu_register_area (first_regno, last_regno, subcmd, off, len)
+      unsigned first_regno;
+      unsigned last_regno;
+      unsigned char *subcmd;
+      unsigned *off;
+      unsigned *len;
+ {
+   int regno = -1;
+ 
+   if (first_regno < FP0_REGNUM)
+     {
+       if (last_regno >= FP0_REGNUM)
+ 	last_regno = FP0_REGNUM - 1;
+       *subcmd = NTO_REG_GENERAL;
+       regno = GDB_TO_OS (first_regno);
+       *off = regno * sizeof (unsigned);
+       if (regno == -1)
+ 	*len = 0;
+       else
+ 	*len = (last_regno - first_regno + 1) * sizeof (unsigned);
+     }
+   else if (first_regno == FP_REGNUM)
+     {
+       /* Frame Pointer Psuedo-register */
+       *off = SP_REGNUM * sizeof (unsigned);
+       *len = sizeof (unsigned);
+       return FP_REGNUM;
+     }
+   else if (first_regno >= FP0_REGNUM && first_regno < FPC_REGNUM)
+     {
+       unsigned off_adjust, regsize;
+ 
+       if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
+ 	{
+ 	  off_adjust = 32;
+ 	  regsize = 16;
+ 	}
+       else
+ 	{
+ 	  off_adjust = 28;
+ 	  regsize = 10;
+ 	}
+ 
+       if (last_regno >= FPC_REGNUM)
+ 	last_regno = FPC_REGNUM - 1;
+       *subcmd = NTO_REG_FLOAT;
+       *off = (first_regno - FP0_REGNUM) * regsize + off_adjust;
+       *len = (last_regno - first_regno + 1) * 10;
+       /* Why 10?  GDB only stores 10 bytes per FP register so if we're
+        * sending a register back to the target, we only want pdebug to write
+        * 10 bytes so as not to clobber the reserved 6 bytes in the fxsave
+        * structure.  The astute reader will note that this will fail if we
+        * try to send a range of fpregs rather than 1 at a time but, as far
+        * as I know, there is no way to send more than one fpreg at a time
+        * anyway.  If this turns out to be wrong, we may need to put more code
+        * in pdebug to deal with this - perhaps by masking off part of the
+        * register when it writes it in.*/
+     }
+   else
+     {
+       *len = 0;
+       return last_regno;
+     }
+   return last_regno;
+ }
+ 
+ /* Tell GDB about the registers contained in the 'data' buffer  */
+ 
+ void
+ nto_cpu_register_fetch (endian, first_regno, last_regno, data)
+      int endian;
+      unsigned first_regno;
+      unsigned last_regno;
+      void *data;
+ {
+   fprintf_unfiltered (gdb_stderr, "warning: nto_cpu_register_fetch called \
+ 			in remote-nto-i386.c.  This shouldn't happen\n");
+   /* If remote-nto-i386.c calls nto_supply_register in remote-nto.c,
+    * then remote-nto.c calls nto_cpu_register_fetch.  Since this never
+    * happens, this function is left unimplemented. */
+ }
+ 
+ /* Build the Neutrino register set info into the 'data' buffer */
+ 
+ int
+ nto_cpu_register_store (endian, first_regno, last_regno, data)
+      int endian;
+      unsigned first_regno;
+      unsigned last_regno;
+      void *data;
+ {
+   /* Mostly (always?) you're only storing one at a time */
+   if (first_regno == last_regno)
+     {
+       regcache_collect (first_regno, data);
+       return 1;
+     }
+   /* Floating point is the same for gdb and target */
+   if (first_regno >= FP0_REGNUM)
+     {
+       for (; first_regno <= last_regno; first_regno++)
+ 	{
+ 	  regcache_collect (first_regno, data);
+ 	  (char *) data += REGISTER_RAW_SIZE (first_regno);
+ 	}
+       return 1;
+     }
+   /* GP registers are mapped differently for NTO than GDB */
+   for (; first_regno <= last_regno; first_regno++)
+     {
+       int regnum = GDB_TO_OS (first_regno);
+       if (regnum == -1)
+ 	continue;
+       regcache_collect (first_regno,
+ 			(char *) data + sizeof (unsigned) * regnum);
+     }
+   return 1;
+ }
+ 
+ /* nto_supply_* are used by nto_procfs.c and nto_core-regset.c */
+ void
+ nto_supply_gregset (gregsetp)
+      nto_gregset_t *gregsetp;
+ {
+   register int regi, i = 0;
+   register unsigned *regp = (unsigned *) gregsetp;
+ 
+   for (regi = 0; regi < (NUM_REGS - FP0_REGNUM); regi++)
+     {
+       i = GDB_TO_OS (regi);
+       supply_register (regi, (char *) &regp[i]);
+     }
+ }
+ 
+ void
+ nto_supply_fpregset (fpregsetp)
+      nto_fpregset_t *fpregsetp;
+ {
+   if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
+     i387_supply_fxsave ((char *) fpregsetp);
+   else
+     i387_supply_fsave ((char *) fpregsetp);
+ }
+ 
+ /* Fetch (and possibly build) an appropriate link_map_offsets
+    structure for native x86 targets using the struct offsets
+    defined in link.h (but without actual reference to that file).
+ 
+    This makes it possible to access x86 shared libraries from a GDB
+    that was not built on an x86 host (for cross debugging).  */
+ 
+ static struct link_map_offsets *
+ i386_nto_svr4_fetch_link_map_offsets (void)
+ {
+   static struct link_map_offsets lmo;
+   static struct link_map_offsets *lmp = NULL;
+ 
+   if (lmp == NULL)
+     {
+       lmp = &lmo;
+ 
+       lmo.r_debug_size = 8;	/* The actual size is 20 bytes, but
+ 				   this is all we need.  */
+       lmo.r_map_offset = 4;
+       lmo.r_map_size = 4;
+ 
+       lmo.link_map_size = 20;	/* The actual size is 552 bytes, but
+ 				   this is all we need.  */
+       lmo.l_addr_offset = 0;
+       lmo.l_addr_size = 4;
+ 
+       lmo.l_name_offset = 4;
+       lmo.l_name_size = 4;
+ 
+       lmo.l_next_offset = 12;
+       lmo.l_next_size = 4;
+ 
+       lmo.l_prev_offset = 16;
+       lmo.l_prev_size = 4;
+     }
+ 
+   return lmp;
+ }
+ 
+ struct link_map_offsets *
+ nto_fetch_link_map_offsets (void)
+ {
+   return i386_nto_svr4_fetch_link_map_offsets ();
+ }
+ 
+ static int
+ i386_nto_pc_in_sigtramp (CORE_ADDR pc, char *name)
+ {
+   return name && strcmp ("__signalstub", name) == 0;
+ }
+ 
+ static CORE_ADDR
+ i386_nto_sigcontext_addr (struct frame_info *frame)
+ {
+   int sigcontext_offset = 136;
+ 
+   if (get_next_frame (frame))
+     return get_frame_base (get_next_frame (frame)) + sigcontext_offset;
+ 
+   return read_register (SP_REGNUM) + sigcontext_offset;
+ }
+ 
+ static void
+ i386_nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+ {
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ 
+   /* NTO uses ELF.  */
+   i386_elf_init_abi (info, gdbarch);
+ 
+   /* neutrino rewinds to look more normal */
+   set_gdbarch_decr_pc_after_break (gdbarch, 0);
+ 
+   /* NTO has shared libraries.  */
+   set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+ 
+   set_gdbarch_pc_in_sigtramp (gdbarch, i386_nto_pc_in_sigtramp);
+   tdep->sigcontext_addr = i386_nto_sigcontext_addr;
+   tdep->sc_pc_offset = 56;
+   tdep->sc_sp_offset = 68;
+ 
+   /* setjmp()'s return PC saved in EDX (5) */
+   tdep->jb_pc_offset = 5 * sizeof (int);
+ 
+   set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ 					 i386_nto_svr4_fetch_link_map_offsets);
+ 
+   /* Our loader handles solib relocations slightly differently than svr4 */
+   TARGET_SO_RELOCATE_SECTION_ADDRESSES = nto_relocate_section_addresses;
+ 
+   /* Supply a nice function to find our solibs */
+   TARGET_SO_FIND_AND_OPEN_SOLIB = nto_find_and_open_solib;
+ 
+ /* After a watchpoint trap, the PC points to the instruction after
+    the one that caused the trap.  Therefore we don't need to step over it.
+    But we do need to reset the status register to avoid another trap.  */
+   HAVE_CONTINUABLE_WATCHPOINT = 1;
+ }
+ 
+ void
+ _initialize_i386_nto_tdep (void)
+ {
+   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
+ 			  i386_nto_init_abi);
+ 
+   /* read our extra gdbinit file */
+   nto_source_extra_gdbinit (".ntox86-gdbinit");
+ }
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/nto-procfs.c src/gdb/nto-procfs.c
*** src.orig/gdb/nto-procfs.c	Wed Dec 31 19:00:00 1969
--- src/gdb/nto-procfs.c	Wed Feb 26 16:41:07 2003
***************
*** 0 ****
--- 1,1506 ----
+ /* Copyright 2003 Free Software Foundation */
+ 
+ /* This code was donated by QNX Software Systems Ltd. */
+ 
+ /* Machine independent support for QNX Neutrino /proc (process file system)
+    for GDB.  Written by Colin Burgess at QNX Software Systems Limited.  */
+ 
+ #include "defs.h"
+ 
+ #include <errno.h>
+ #include <string.h>
+ #include <fcntl.h>
+ #include <spawn.h>
+ #include <sys/debug.h>
+ #include "nto-share/debug.h"
+ #include <sys/procfs.h>
+ #include <sys/neutrino.h>
+ #include <sys/types.h>
+ #include <sys/syspage.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <sys/netmgr.h>
+ 
+ #include "defs.h"
+ #include "gdb_string.h"
+ #include "gdbcore.h"
+ #include "frame.h"
+ #include "inferior.h"
+ #include "bfd.h"
+ #include "symfile.h"
+ #include "target.h"
+ #include "gdb_wait.h"
+ #include "gdbcmd.h"
+ #include "objfiles.h"
+ #include "gdb-stabs.h"
+ #include "gdbthread.h"
+ #include "nto-tdep.h"
+ #include "dcache.h"
+ #include "gdb_stat.h"
+ #include "command.h"
+ 
+ #define NULL_PID		0
+ #define _DEBUG_FLAG_TRACE	(_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|_DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY)
+ 
+ static struct target_ops procfs_ops;
+ 
+ int ctl_fd;
+ 
+ static void (*ofunc) ();
+ 
+ static procfs_run run;
+ 
+ static void procfs_open PARAMS ((char *, int));
+ 
+ static int procfs_can_run PARAMS ((void));
+ 
+ static ptid_t procfs_wait PARAMS ((ptid_t, struct target_waitstatus *));
+ 
+ static int procfs_xfer_memory
+ PARAMS ((CORE_ADDR, char *, int, int, struct mem_attrib * attrib,
+ 	 struct target_ops *));
+ 
+ static void procfs_fetch_registers PARAMS ((int));
+ 
+ static void notice_signals (void);
+ 
+ static void init_procfs_ops PARAMS ((void));
+ 
+ static ptid_t do_attach PARAMS ((ptid_t ptid));
+ 
+ static int procfs_can_use_hw_breakpoint PARAMS ((int, int, int));
+ 
+ static int procfs_insert_hw_breakpoint PARAMS ((CORE_ADDR, char *));
+ 
+ static int procfs_remove_hw_breakpoint PARAMS ((CORE_ADDR addr, char *));
+ 
+ static int procfs_insert_hw_watchpoint
+ PARAMS ((CORE_ADDR addr, int len, int type));
+ 
+ static int procfs_remove_hw_watchpoint
+ PARAMS ((CORE_ADDR addr, int len, int type));
+ 
+ static int procfs_stopped_by_watchpoint PARAMS ((void));
+ 
+ /* 
+    These two globals are only ever set in procfs_open(), but are
+    referenced elsewhere.  'nto_procfs_node' is a flag used to say
+    whether we are local, or we should get the current node descriptor
+    for the remote QNX node.
+ */
+ static char nto_procfs_path[PATH_MAX] = { "/proc" };
+ static unsigned nto_procfs_node = ND_LOCAL_NODE;
+ 
+ /* 
+    This is a simple wrapper for the netmgr_strtond() function.  It is
+    only called from the QNX_NODE macro declared below.  The reason for
+    the macro and function are because QNX node descriptors are transient,
+    so we have to re-acquire them every time.
+ */
+ static unsigned
+ procfs_nto_node (unsigned node)
+ {
+   if (node == -1)
+     {
+       error ("Lost the QNX node.  Debug session probably over.");
+       /* NOTREACHED */
+     }
+   return (node);
+ }
+ 
+ /* 
+    This define returns the current QNX Node, or -1 on error.  It calls the above
+    function which is a simple wrapper for the error() call.
+ */
+ #define QNX_NODE (ND_NODE_CMP(nto_procfs_node, ND_LOCAL_NODE) == 0 ? ND_LOCAL_NODE : \
+                    procfs_nto_node(netmgr_strtond(nto_procfs_path, 0)))
+ 
+ /* 
+    This is called when we call 'target procfs <arg>' from the (gdb) prompt.
+    For QNX6 (nto), the only valid arg will be a QNX node string, 
+    eg: "/net/some_node".  If arg is not a valid QNX node, we will
+    default to local. 
+ */
+ static void
+ procfs_open (arg, from_tty)
+      char *arg;
+      int from_tty;
+ {
+   char *nodestr;
+   char *endstr;
+   char buffer[50];
+   int fd, total_size;
+   procfs_sysinfo *sysinfo;
+ 
+   /* Set the default node used for spawning to this one,
+      and only override it if there is a valid arg. */
+ 
+   nto_procfs_node = ND_LOCAL_NODE;
+   nodestr = arg ? strdup (arg) : arg;
+ 
+   init_thread_list ();
+ 
+   if (nodestr)
+     {
+       nto_procfs_node = netmgr_strtond (nodestr, &endstr);
+       if (nto_procfs_node == -1)
+ 	{
+ 	  if (errno == ENOTSUP)
+ 	    printf_filtered ("QNX Net Manager not found.\n");
+ 	  printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr,
+ 			   errno, strerror (errno));
+ 	  xfree (nodestr);
+ 	  nodestr = NULL;
+ 	  nto_procfs_node = ND_LOCAL_NODE;
+ 	}
+       else if (*endstr)
+ 	{
+ 	  if (*(endstr - 1) == '/')
+ 	    *(endstr - 1) = 0;
+ 	  else
+ 	    *endstr = 0;
+ 	}
+     }
+   sprintf (nto_procfs_path, "%s%s", nodestr ? nodestr : "", "/proc");
+   if (nodestr)
+     xfree (nodestr);
+ 
+   fd = open (nto_procfs_path, O_RDONLY);
+   if (fd == -1)
+     {
+       printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
+ 		       strerror (errno));
+       error ("Invalid procfs arg");
+       /* NOTREACHED */
+     }
+ 
+   sysinfo = (void *) buffer;
+   if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
+     {
+       printf_filtered ("Error getting size: %d (%s)\n", errno,
+ 		       strerror (errno));
+       close (fd);
+       error ("Devctl failed.");
+       /* NOTREACHED */
+     }
+   else
+     {
+       total_size = sysinfo->total_size;
+       if (!(sysinfo = alloca (total_size)))
+ 	{
+ 	  printf_filtered ("Memory error: %d (%s)\n", errno,
+ 			   strerror (errno));
+ 	  close (fd);
+ 	  error ("alloca failed.");
+ 	  /* NOTREACHED */
+ 	}
+       else
+ 	{
+ 	  if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
+ 	    {
+ 	      printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
+ 			       strerror (errno));
+ 	      close (fd);
+ 	      error ("Devctl failed.");
+ 	      /* NOTREACHED */
+ 	    }
+ 	  else
+ 	    {
+ 	      if (sysinfo->type != nto_map_arch_to_cputype(TARGET_ARCHITECTURE->arch_name))
+ 		{
+ 		  close (fd);
+ 		  error ("Invalid target CPU.");
+ 		  /* NOTREACHED */
+ 		}
+ 	    }
+ 	}
+     }
+   close (fd);
+   printf_filtered ("Debugging using %s\n", nto_procfs_path);
+ 
+ }
+ 
+ static void
+ procfs_set_thread (ptid)
+      ptid_t ptid;
+ {
+   pid_t tid;
+ 
+   tid = ptid_get_tid (inferior_ptid);
+   devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
+ }
+ 
+ /*  Return nonzero if the thread TH is still alive.  */
+ static int
+ procfs_thread_alive (ptid_t ptid)
+ {
+   pid_t tid;
+ 
+   tid = ptid_get_tid (ptid);
+   if (devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0) == EOK)
+     return 1;
+   return 0;
+ }
+ 
+ 
+ void
+ procfs_find_new_threads (void)
+ {
+   procfs_status status;
+   pid_t pid;
+   ptid_t ptid;
+ 
+   if (ctl_fd == -1)
+     return;
+ 
+   pid = ptid_get_pid (inferior_ptid);
+ 
+   for (status.tid = 1;; ++status.tid)
+     {
+       if (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) !=
+ 	  EOK && status.tid != 0)
+ 	{
+ 	  break;
+ 	}
+       ptid = ptid_build (pid, 0, status.tid);
+       if (!in_thread_list (ptid))
+ 	add_thread (ptid);
+     }
+   return;
+ }
+ 
+ void
+ procfs_pidlist (char *args, int from_tty)
+ {
+   static DIR *dp = NULL;
+   struct dirent *dirp = NULL;
+   int fd = -1;
+   char buf[512];
+   procfs_info *pidinfo = NULL;
+   procfs_debuginfo *info = NULL;
+   procfs_status *status = NULL;
+   pid_t num_threads = 0;
+   pid_t pid;
+   char name[512];
+ 
+   dp = opendir (nto_procfs_path);
+   if (dp == NULL)
+     {
+       printf ("failed to opendir \"%s\" - %d (%s)", nto_procfs_path, errno,
+ 	      strerror (errno));
+       return;
+     }
+ 
+   /* start scan at first pid */
+   rewinddir (dp);
+ 
+   do
+     {
+       /* Get the right pid and procfs path for the pid */
+       do
+ 	{
+ 	  if ((dirp = readdir (dp)) == NULL)
+ 	    {
+ 	      closedir (dp);
+ 	      return;
+ 	    }
+ 	  strcat (strcat
+ 		  (strcat (strcpy (buf, nto_procfs_path), "/"), dirp->d_name),
+ 		  "/as");
+ 	}
+       while ((pid = atoi (dirp->d_name)) == 0);
+ 
+       /* open the procfs path */
+       if ((fd = open (buf, O_RDONLY)) == -1)
+ 	{
+ 	  printf ("failed to open %s - %d (%s)\n", buf, errno,
+ 		  strerror (errno));
+ 	  closedir (dp);
+ 	  return;
+ 	}
+ 
+       pidinfo = (procfs_info *) buf;
+       if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
+ 	{
+ 	  printf ("devctl DCMD_PROC_INFO failed - %d (%s)\n", errno,
+ 		  strerror (errno));
+ 	  break;
+ 	}
+       num_threads = pidinfo->num_threads;
+ 
+       info = (procfs_debuginfo *) buf;
+       if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK)
+ 	strcpy (name, "unavailable");
+       else
+ 	strcpy (name, info->path);
+ 
+       /* Collect state info on all the threads. */
+       status = (procfs_status *) buf;
+       for (status->tid = 1; status->tid <= num_threads; status->tid++)
+ 	{
+ 	  if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK
+ 	      && status->tid != 0)
+ 	    break;
+ 	  if (status->tid != 0)
+ 	    printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
+ 	}
+       close (fd);
+     }
+   while (dirp != NULL);
+ 
+   close (fd);
+   closedir (dp);
+   return;
+ }
+ 
+ 
+ void
+ procfs_meminfo (char *args, int from_tty)
+ {
+   procfs_mapinfo *mapinfos = NULL;
+   static int num_mapinfos = 0;
+   procfs_mapinfo *mapinfo_p, *mapinfo_p2;
+   int flags = ~0, err, num, i, j;
+ 
+   struct
+   {
+     procfs_debuginfo info;
+     char buff[_POSIX_PATH_MAX];
+   } map;
+ 
+   struct info
+   {
+     unsigned addr;
+     unsigned size;
+     unsigned flags;
+     unsigned debug_vaddr;
+     unsigned long long offset;
+   };
+ 
+   struct printinfo
+   {
+     unsigned long long ino;
+     unsigned dev;
+     struct info text;
+     struct info data;
+     char name[256];
+   } printme;
+ 
+ 
+   /* Get the number of map entrys */
+   if ((err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num)) != EOK)
+     {
+       printf ("failed devctl num mapinfos - %d (%s)\n", err, strerror (err));
+       return;
+     }
+ 
+   mapinfos = xmalloc (num * sizeof (procfs_mapinfo));
+ 
+   num_mapinfos = num;
+   mapinfo_p = mapinfos;
+ 
+   /* fill the map entrys  */
+   if ((err =
+        devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p,
+ 	       num * sizeof (procfs_mapinfo), &num)) != EOK)
+     {
+       printf ("failed devctl mapinfos - %d (%s)\n", err, strerror (err));
+       xfree (mapinfos);
+       return;
+     }
+ 
+   num = min (num, num_mapinfos);
+ 
+   /* Run through the list of mapinfo's, and store the data and text info
+      so we can print it at the bottom of the loop. */
+   for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++)
+     {
+       if (!(mapinfo_p->flags & flags))
+ 	mapinfo_p->ino = 0;
+ 
+       if (mapinfo_p->ino == 0)	/* already visited */
+ 	continue;
+ 
+       map.info.vaddr = mapinfo_p->vaddr;
+ 
+       if ((err =
+ 	   devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0)) != EOK)
+ 	continue;
+ 
+       memset (&printme, 0, sizeof printme);
+       printme.dev = mapinfo_p->dev;
+       printme.ino = mapinfo_p->ino;
+       printme.text.addr = mapinfo_p->vaddr;
+       printme.text.size = mapinfo_p->size;
+       printme.text.flags = mapinfo_p->flags;
+       printme.text.offset = mapinfo_p->offset;
+       printme.text.debug_vaddr = map.info.vaddr;
+       strcpy (printme.name, map.info.path);
+ 
+       /* check for matching data */
+       for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++)
+ 	{
+ 	  if (mapinfo_p2->vaddr != mapinfo_p->vaddr &&
+ 	      mapinfo_p2->ino == mapinfo_p->ino
+ 	      && mapinfo_p2->dev == mapinfo_p->dev)
+ 	    {
+ 	      map.info.vaddr = mapinfo_p2->vaddr;
+ 	      if ((err =
+ 		   devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map),
+ 			   0)) != EOK)
+ 		continue;
+ 
+ 	      if (strcmp (map.info.path, printme.name))
+ 		{
+ 		  continue;
+ 		}
+ 
+ 	      /*
+ 	       * lower debug_vaddr is always text, if nessessary, swap
+ 	       */
+ 	      if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
+ 		{
+ 		  memcpy (&(printme.data), &(printme.text),
+ 			  sizeof (printme.data));
+ 		  printme.text.addr = mapinfo_p2->vaddr;
+ 		  printme.text.size = mapinfo_p2->size;
+ 		  printme.text.flags = mapinfo_p2->flags;
+ 		  printme.text.offset = mapinfo_p2->offset;
+ 		  printme.text.debug_vaddr = map.info.vaddr;
+ 		}
+ 	      else
+ 		{
+ 		  printme.data.addr = mapinfo_p2->vaddr;
+ 		  printme.data.size = mapinfo_p2->size;
+ 		  printme.data.flags = mapinfo_p2->flags;
+ 		  printme.data.offset = mapinfo_p2->offset;
+ 		  printme.data.debug_vaddr = map.info.vaddr;
+ 		}
+ 	      mapinfo_p2->ino = 0;
+ 	    }
+ 	}
+       mapinfo_p->ino = 0;
+ 
+       printf_filtered ("%s\n", printme.name);
+       printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size,
+ 		       printme.text.addr);
+       printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
+       printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
+       printf_filtered ("\t\toffset=%016llx\n", printme.text.offset);
+       if (printme.data.size)
+ 	{
+ 	  printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
+ 			   printme.data.addr);
+ 	  printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
+ 	  printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
+ 	  printf_filtered ("\t\toffset=%016llx\n", printme.data.offset);
+ 	}
+       printf_filtered ("\tdev=0x%x\n", printme.dev);
+       printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
+     }
+   xfree (mapinfos);
+   return;
+ }
+ 
+ /* Print status information about what we're accessing.  */
+ 
+ static void
+ procfs_files_info (ignore)
+      struct target_ops *ignore;
+ {
+   printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
+ 		     attach_flag ? "attached" : "child",
+ 		     target_pid_to_str (inferior_ptid), nto_procfs_path);
+ }
+ 
+ /* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
+ static int
+ procfs_can_run ()
+ {
+   return 1;
+ }
+ 
+ /* Attach to process PID, then initialize for debugging it */
+ static void
+ procfs_attach (args, from_tty)
+      char *args;
+      int from_tty;
+ {
+   char *exec_file;
+   int pid;
+ 
+   if (!args)
+     error_no_arg ("process-id to attach");
+ 
+   pid = atoi (args);
+ 
+   if (pid == getpid ())
+     error ("Attaching GDB to itself is not a good idea...");
+ 
+   if (from_tty)
+     {
+       exec_file = (char *) get_exec_file (0);
+ 
+       if (exec_file)
+ 	printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
+ 			   target_pid_to_str (pid_to_ptid (pid)));
+       else
+ 	printf_unfiltered ("Attaching to %s\n",
+ 			   target_pid_to_str (pid_to_ptid (pid)));
+ 
+       gdb_flush (gdb_stdout);
+     }
+   inferior_ptid = do_attach (pid_to_ptid (pid));
+   push_target (&procfs_ops);
+ }
+ 
+ static ptid_t
+ do_attach (ptid_t ptid)
+ {
+   procfs_status status;
+   struct sigevent event;
+   char path[100];
+ 
+   sprintf (path, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
+   ctl_fd = open (path, O_RDWR);
+   if (ctl_fd == -1)
+     {
+       error ("Couldn't open proc file %s, error %d (%s)", path, errno,
+ 	     strerror (errno));
+       /* NOTREACHED */
+     }
+   if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
+     {
+       error ("Couldn't stop process");
+       /* NOTREACHED */
+     }
+ 
+   /* Define a sigevent for process stopped notification. */
+   event.sigev_notify = SIGEV_SIGNAL_THREAD;
+   event.sigev_signo = SIGUSR1;
+   event.sigev_code = 0;
+   event.sigev_value.sival_ptr = NULL;
+   event.sigev_priority = -1;
+   devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
+ 
+   if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK)
+     {
+       if (status.flags & _DEBUG_FLAG_STOPPED)
+ 	{
+ 	  SignalKill (QNX_NODE, PIDGET (ptid), 0, SIGCONT, 0, 0);
+ 	}
+     }
+   attach_flag = 1;
+   nto_init_solib_search_path ();
+   return ptid;
+ }
+ 
+ /* Ask the user what to do when an interrupt is received.  */
+ 
+ static void
+ interrupt_query ()
+ {
+   target_terminal_ours ();
+ 
+   if (query ("Interrupted while waiting for the program.\n\
+ Give up (and stop debugging it)? "))
+     {
+       target_mourn_inferior ();
+       throw_exception (RETURN_QUIT);
+     }
+ 
+   target_terminal_inferior ();
+ }
+ 
+ /* The user typed ^C twice.  */
+ static void
+ nto_interrupt_twice (signo)
+      int signo;
+ {
+   signal (signo, ofunc);
+   interrupt_query ();
+   signal (signo, nto_interrupt_twice);
+ }
+ 
+ static void
+ nto_interrupt (int signo)
+ {
+   /* If this doesn't work, try more severe steps.  */
+   signal (signo, nto_interrupt_twice);
+ 
+   target_stop ();
+ }
+ 
+ static ptid_t
+ procfs_wait (ptid, ourstatus)
+      ptid_t ptid;
+      struct target_waitstatus *ourstatus;
+ {
+   sigset_t set;
+   siginfo_t info;
+   procfs_status status;
+   static int exit_signo = 0;	/* used to track signals that cause termination */
+ 
+   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ 
+   if (ptid_equal (inferior_ptid, null_ptid))
+     {
+       ourstatus->kind = TARGET_WAITKIND_STOPPED;
+       ourstatus->value.sig = TARGET_SIGNAL_0;
+       exit_signo = 0;
+       return null_ptid;
+     }
+ 
+   sigemptyset (&set);
+   sigaddset (&set, SIGUSR1);
+ 
+   devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
+   while (!(status.flags & _DEBUG_FLAG_ISTOP))
+     {
+       ofunc = (void (*)()) signal (SIGINT, nto_interrupt);
+       sigwaitinfo (&set, &info);
+       signal (SIGINT, ofunc);
+       devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
+     }
+ 
+   if (status.flags & _DEBUG_FLAG_SSTEP)
+     {
+       ourstatus->kind = TARGET_WAITKIND_STOPPED;
+       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+     }
+   /* Was it a breakpoint? */
+   else if (status.flags & _DEBUG_FLAG_TRACE)
+     {
+       ourstatus->kind = TARGET_WAITKIND_STOPPED;
+       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+     }
+   else if (status.flags & _DEBUG_FLAG_ISTOP)
+     {
+       switch (status.why)
+ 	{
+ 	case _DEBUG_WHY_SIGNALLED:
+ 	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ 	  ourstatus->value.sig =
+ 	    target_signal_from_host (status.info.si_signo);
+ 	  exit_signo = 0;
+ 	  break;
+ 	case _DEBUG_WHY_FAULTED:
+ 	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ 	  if (status.info.si_signo == SIGTRAP)
+ 	    {
+ 	      ourstatus->value.sig = 0;
+ 	      exit_signo = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      ourstatus->value.sig =
+ 		target_signal_from_host (status.info.si_signo);
+ 	      exit_signo = ourstatus->value.sig;
+ 	    }
+ 	  break;
+ 
+ 	case _DEBUG_WHY_TERMINATED:
+ 	  {
+ 	    int waitval = 0;
+ 
+ 	    waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG);
+ 	    if (exit_signo)
+ 	      {
+ 		ourstatus->kind = TARGET_WAITKIND_SIGNALLED;	/* abnormal death */
+ 		ourstatus->value.sig = exit_signo;
+ 	      }
+ 	    else
+ 	      {
+ 		ourstatus->kind = TARGET_WAITKIND_EXITED;	/* normal death */
+ 		ourstatus->value.integer = WEXITSTATUS (waitval);
+ 	      }
+ 	    exit_signo = 0;
+ 	    break;
+ 	  }
+ 
+ 	case _DEBUG_WHY_REQUESTED:
+ 	  /* we are assuming a requested stop is due to a SIGINT */
+ 	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ 	  ourstatus->value.sig = TARGET_SIGNAL_INT;
+ 	  exit_signo = 0;
+ 	  break;
+ 	}
+     }
+ 
+   return inferior_ptid;
+ }
+ 
+ /*
+ 
+ LOCAL FUNCTION
+ 
+ 	procfs_fetch_registers -- fetch current registers from inferior
+ 
+ SYNOPSIS
+ 
+ 	void procfs_fetch_registers (int regno)
+ 
+ DESCRIPTION
+ 
+ 	Read the current values of the inferior's registers, both the
+ 	general register set and floating point registers (if supported)
+ 	and update gdb's idea of their current values.
+ 
+ */
+ 
+ static void
+ procfs_fetch_registers (regno)
+      int regno;
+ {
+   union
+   {
+     procfs_greg greg;
+     procfs_fpreg fpreg;
+   }
+   reg;
+   int regsize;
+ 
+   procfs_set_thread (inferior_ptid);
+   if (devctl (ctl_fd, DCMD_PROC_GETGREG, &reg, sizeof (reg), &regsize) == EOK)
+     {
+       nto_supply_gregset (&reg.greg);
+     }
+   if (devctl (ctl_fd, DCMD_PROC_GETFPREG, &reg, sizeof (reg), &regsize) ==
+       EOK)
+     {
+       nto_supply_fpregset (&reg.fpreg);
+     }
+ }
+ 
+ /*
+ 
+ LOCAL FUNCTION
+ 
+ 	procfs_xfer_memory -- copy data to or from inferior memory space
+ 
+ SYNOPSIS
+ 
+ 	int procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ 		int dowrite, struct target_ops target)
+ 
+ DESCRIPTION
+ 
+ 	Copy LEN bytes to/from inferior's memory starting at MEMADDR
+ 	from/to debugger memory starting at MYADDR.  Copy from inferior
+ 	if DOWRITE is zero or to inferior if DOWRITE is nonzero.
+   
+ 	Returns the length copied, which is either the LEN argument or
+ 	zero.  This xfer function does not do partial moves, since procfs_ops
+ 	doesn't allow memory operations to cross below us in the target stack
+ 	anyway.
+ 
+ NOTES
+ 
+ 	The /proc interface makes this an almost trivial task.
+  */
+ 
+ static int
+ procfs_xfer_memory (memaddr, myaddr, len, dowrite, attrib, target)
+      CORE_ADDR memaddr;
+      char *myaddr;
+      int len;
+      int dowrite;
+      struct mem_attrib *attrib;	/* ignored */
+      struct target_ops *target;	/* ignored */
+ {
+   int nbytes = 0;
+ 
+   if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
+     {
+       if (dowrite)
+ 	{
+ 	  nbytes = write (ctl_fd, myaddr, len);
+ 	}
+       else
+ 	{
+ 	  nbytes = read (ctl_fd, myaddr, len);
+ 	}
+       if (nbytes < 0)
+ 	{
+ 	  nbytes = 0;
+ 	}
+     }
+   return (nbytes);
+ }
+ 
+ /* Take a program previously attached to and detaches it.
+    The program resumes execution and will no longer stop
+    on signals, etc.  We'd better not have left any breakpoints
+    in the program or it'll die when it hits one.  For this
+    to work, it may be necessary for the process to have been
+    previously attached.  It *might* work if the program was
+    started via the normal ptrace (PTRACE_TRACEME).  */
+ 
+ static void
+ procfs_detach (args, from_tty)
+      char *args;
+      int from_tty;
+ {
+   int siggnal = 0;
+ 
+   if (from_tty)
+     {
+       char *exec_file = get_exec_file (0);
+       if (exec_file == 0)
+ 	exec_file = "";
+       printf_unfiltered ("Detaching from program: %s %s\n",
+ 			 exec_file, target_pid_to_str (inferior_ptid));
+       gdb_flush (gdb_stdout);
+     }
+   if (args)
+     siggnal = atoi (args);
+ 
+   if (siggnal)
+     SignalKill (QNX_NODE, PIDGET (inferior_ptid), 0, siggnal, 0, 0);
+ 
+   close (ctl_fd);
+   ctl_fd = -1;
+   init_thread_list ();
+   inferior_ptid = null_ptid;
+   attach_flag = 0;
+   unpush_target (&procfs_ops);	/* Pop out of handling an inferior */
+ }
+ 
+ static int
+ procfs_breakpoint (addr, type, size)
+      CORE_ADDR addr;
+      int type;
+      int size;
+ {
+   procfs_break brk;
+ 
+   brk.type = type;
+   brk.addr = addr;
+   brk.size = size;
+   if ((errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)) !=
+       EOK)
+     {
+       return 1;
+     }
+   return 0;
+ }
+ 
+ static int
+ procfs_insert_breakpoint (addr, contents_cache)
+      CORE_ADDR addr;
+      char *contents_cache;
+ {
+   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0);
+ }
+ 
+ static int
+ procfs_remove_breakpoint (addr, contents_cache)
+      CORE_ADDR addr;
+      char *contents_cache;
+ {
+   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1);
+ }
+ 
+ static int
+ procfs_insert_hw_breakpoint (addr, contents_cache)
+      CORE_ADDR addr;
+      char *contents_cache;
+ {
+   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
+ }
+ 
+ static int
+ procfs_remove_hw_breakpoint (addr, contents_cache)
+      CORE_ADDR addr;
+      char *contents_cache;
+ {
+   return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
+ }
+ 
+ static void
+ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+ {
+   int signal_to_pass;
+   procfs_status status;
+ 
+   if (ptid_equal (inferior_ptid, null_ptid))
+     return;
+ 
+   procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
+ 		     ptid);
+ 
+ 
+   run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
+   if (step)
+     run.flags |= _DEBUG_RUN_STEP;
+ 
+   sigemptyset ((sigset_t *) & run.fault);
+   sigaddset ((sigset_t *) & run.fault, FLTBPT);
+   sigaddset ((sigset_t *) & run.fault, FLTTRACE);
+   sigaddset ((sigset_t *) & run.fault, FLTILL);
+   sigaddset ((sigset_t *) & run.fault, FLTPRIV);
+   sigaddset ((sigset_t *) & run.fault, FLTBOUNDS);
+   sigaddset ((sigset_t *) & run.fault, FLTIOVF);
+   sigaddset ((sigset_t *) & run.fault, FLTIZDIV);
+   sigaddset ((sigset_t *) & run.fault, FLTFPE);
+   /* Peter V will be changing this at some point... */
+   sigaddset ((sigset_t *) & run.fault, FLTPAGE);
+ 
+   run.flags |= _DEBUG_RUN_ARM;
+ 
+   sigemptyset (&run.trace);
+   notice_signals ();
+   signal_to_pass = target_signal_to_host (signo);
+ 
+   if (signal_to_pass)
+     {
+       devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
+       signal_to_pass = target_signal_to_host (signo);
+       if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
+ 	{
+ 	  if (signal_to_pass != status.info.si_signo)
+ 	    {
+ 	      SignalKill (QNX_NODE, PIDGET (inferior_ptid), 0, signal_to_pass,
+ 			  0, 0);
+ 	      run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
+ 	    }
+ 	  else
+ 	    {
+ 	      /* let it kill the program without telling us */
+ 	      sigdelset (&run.trace, signal_to_pass);
+ 	    }
+ 	}
+     }
+   else
+     {
+       run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
+     }
+   if ((errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0)) != EOK)
+     {
+       perror ("run error!\n");
+       return;
+     }
+ }
+ 
+ static void
+ procfs_mourn_inferior ()
+ {
+   if (!ptid_equal (inferior_ptid, null_ptid))
+     {
+       SignalKill (QNX_NODE, PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
+       close (ctl_fd);
+     }
+   inferior_ptid = null_ptid;
+   init_thread_list ();
+   unpush_target (&procfs_ops);
+   generic_mourn_inferior ();
+   attach_flag = 0;
+ }
+ 
+ /* This function breaks up an argument string into an argument
+  * vector suitable for passing to execvp().
+  * E.g., on "run a b c d" this routine would get as input
+  * the string "a b c d", and as output it would fill in argv with
+  * the four arguments "a", "b", "c", "d".  The only additional
+  * functionality is simple quoting.  The gdb command:
+  *	run a "b c d" f
+  * will fill in argv with the three args "a", "b c d", "e".  
+  */
+ static void
+ breakup_args (scratch, argv)
+      char *scratch;
+      char **argv;
+ {
+   char *pp, *cp = scratch;
+   char quoting = 0;
+ 
+   for (;;)
+     {
+ 
+       /* Scan past leading separators */
+       quoting = 0;
+       while (*cp == ' ' || *cp == '\t' || *cp == '\n')
+ 	{
+ 	  cp++;
+ 	}
+ 
+       /* Break if at end of string */
+       if (*cp == '\0')
+ 	break;
+ 
+       /* Take an arg */
+       if (*cp == '"')
+ 	{
+ 	  cp++;
+ 	  quoting = strchr (cp, '"') ? 1 : 0;
+ 	}
+ 
+       *argv++ = cp;
+ 
+       /* Scan for next arg separator */
+       pp = cp;
+       if (quoting)
+ 	cp = strchr (pp, '"');
+       if ((cp == NULL) || (!quoting))
+ 	cp = strchr (pp, ' ');
+       if (cp == NULL)
+ 	cp = strchr (pp, '\t');
+       if (cp == NULL)
+ 	cp = strchr (pp, '\n');
+ 
+       /* No separators => end of string => break */
+       if (cp == NULL)
+ 	{
+ 	  pp = cp;
+ 	  break;
+ 	}
+ 
+       /* Replace the separator with a terminator */
+       *cp++ = '\0';
+     }
+ 
+   /* execv requires a null-terminated arg vector */
+   *argv = NULL;
+ 
+ }
+ 
+ static void
+ procfs_create_inferior (exec_file, allargs, env)
+      char *exec_file;
+      char *allargs;
+      char **env;
+ {
+   struct inheritance inherit;
+   pid_t pid;
+   int flags, errn;
+   char **argv, *args;
+   char *in = "", *out = "", *err = "";
+   int fd, fds[3];
+   sigset_t set;
+ 
+   argv =
+     (char **) xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
+ 		       sizeof (*argv));
+   argv[0] = get_exec_file (1);
+   if (!argv[0])
+     {
+       if (exec_file)
+ 	argv[0] = exec_file;
+       else
+ 	return;
+     }
+ 
+   args = strdup (allargs);
+   breakup_args (args, exec_file ? &argv[1] : &argv[0]);
+ 
+   argv = nto_parse_redirection (argv, &in, &out, &err);
+ 
+   fds[0] = STDIN_FILENO;
+   fds[1] = STDOUT_FILENO;
+   fds[2] = STDERR_FILENO;
+ 
+   /* If the user specified I/O via gdb's --tty= arg, use it, but only
+      if the i/o is not also being specified via redirection. */
+   if (inferior_io_terminal)
+     {
+       if (!in[0])
+ 	in = inferior_io_terminal;
+       if (!out[0])
+ 	out = inferior_io_terminal;
+       if (!err[0])
+ 	err = inferior_io_terminal;
+     }
+ 
+   if (in[0])
+     {
+       if ((fd = open (in, O_RDONLY)) == -1)
+ 	{
+ 	  perror (in);
+ 	}
+       else
+ 	fds[0] = fd;
+     }
+   if (out[0])
+     {
+       if ((fd = open (out, O_WRONLY)) == -1)
+ 	{
+ 	  perror (out);
+ 	}
+       else
+ 	fds[1] = fd;
+     }
+   if (err[0])
+     {
+       if ((fd = open (err, O_WRONLY)) == -1)
+ 	{
+ 	  perror (err);
+ 	}
+       else
+ 	fds[2] = fd;
+     }
+ 
+   /* Clear any pending SIGUSR1's but keep the behavior the same. */
+   signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
+ 
+   sigemptyset (&set);
+   sigaddset (&set, SIGUSR1);
+   sigprocmask (SIG_UNBLOCK, &set, NULL);
+ 
+   memset (&inherit, 0, sizeof (inherit));
+ 
+   if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
+     {
+       inherit.nd = QNX_NODE;
+       inherit.flags |= SPAWN_SETND;
+       inherit.flags &= ~SPAWN_EXEC;
+     }
+   inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
+   inherit.pgroup = SPAWN_NEWPGROUP;
+   pid =
+     spawnp (argv[0], 3, fds, &inherit, argv,
+ 	    ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
+   xfree (args);
+ 
+   sigprocmask (SIG_BLOCK, &set, NULL);
+ 
+   if (pid == -1)
+     error ("Error spawning %s: %d (%s)", argv[0], errno, strerror (errno));
+ 
+   if (fds[0] != STDIN_FILENO)
+     close (fds[0]);
+   if (fds[1] != STDOUT_FILENO)
+     close (fds[1]);
+   if (fds[2] != STDERR_FILENO)
+     close (fds[2]);
+ 
+   inferior_ptid = do_attach (pid_to_ptid (pid));
+ 
+   attach_flag = 0;
+   flags = _DEBUG_FLAG_KLC;	/* Kill-on-Last-Close flag */
+   if ((errn =
+        devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0)) != EOK)
+     {
+       /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n", errn, strerror(errn) ); */
+     }
+   push_target (&procfs_ops);
+   target_terminal_init ();
+ 
+ #ifdef SOLIB_CREATE_INFERIOR_HOOK
+   if (exec_bfd != NULL
+       || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
+     SOLIB_CREATE_INFERIOR_HOOK (pid);
+ #endif
+ }
+ 
+ static void
+ procfs_stop ()
+ {
+   devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
+ }
+ 
+ static void
+ procfs_kill_inferior ()
+ {
+   target_mourn_inferior ();
+ }
+ 
+ /* Store register REGNO, or all registers if REGNO == -1, from the contents
+    of REGISTERS.  */
+ 
+ static void
+ procfs_prepare_to_store ()
+ {
+ }
+ 
+ void
+ procfs_store_registers (regno)
+      int regno;
+ {
+   union
+   {
+     procfs_greg greg;
+     procfs_fpreg fpreg;
+   }
+   reg;
+   unsigned first;
+   unsigned last;
+   unsigned end;
+   unsigned off;
+   unsigned len;
+   unsigned char subcmd;
+   char *data;
+ 
+   if (ptid_equal (inferior_ptid, null_ptid))
+     return;
+   procfs_set_thread (inferior_ptid);
+ 
+   if (regno == -1)
+     {
+       first = 0;
+       last = NUM_REGS - 1;
+     }
+   else
+     {
+       first = regno;
+       last = regno;
+     }
+   while (first <= last)
+     {
+       end = nto_cpu_register_area (first, last, &subcmd, &off, &len);
+       switch (subcmd)
+ 	{
+ 	case NTO_REG_GENERAL:
+ 	  if (devctl
+ 	      (ctl_fd, DCMD_PROC_GETGREG, &reg.greg, sizeof (reg.greg),
+ 	       0) != EOK)
+ 	    {
+ 	      printf ("error fetching general registers\n");
+ 	      break;
+ 	    }
+ 	  data = (char *) &reg.greg + off;
+ 	  if (nto_cpu_register_store (0, first, end, data))
+ 	    {
+ 	      devctl (ctl_fd, DCMD_PROC_SETGREG, &reg.greg,
+ 		      sizeof (reg.greg), 0);
+ 	    }
+ 	  break;
+ 	case NTO_REG_FLOAT:
+ 	  if (devctl
+ 	      (ctl_fd, DCMD_PROC_GETFPREG, &reg.fpreg,
+ 	       sizeof (reg.fpreg), 0) != EOK)
+ 	    {
+ 	      /* Do not print a warning.  Not all inferiors 
+ 	         have fpregs.  */
+ 	      break;
+ 	    }
+ 	  data = (char *) &reg.fpreg + off;
+ 	  if (nto_cpu_register_store (0, first, end, data))
+ 	    {
+ 	      devctl (ctl_fd, DCMD_PROC_SETFPREG, &reg.fpreg,
+ 		      sizeof (reg.fpreg), 0);
+ 	    }
+ 	  break;
+ 	case NTO_REG_SYSTEM:
+ 	  break;
+ 	default:
+ 	  break;
+ 	}
+       first = end + 1;
+     }
+ }
+ 
+ static void
+ notice_signals (void)
+ {
+   int signo;
+ 
+   for (signo = 1; signo < NSIG; signo++)
+     {
+       if (signal_stop_state (target_signal_from_host (signo)) == 0 &&
+ 	  signal_print_state (target_signal_from_host (signo)) == 0 &&
+ 	  signal_pass_state (target_signal_from_host (signo)) == 1)
+ 	{
+ 	  sigdelset (&run.trace, signo);
+ 	}
+       else
+ 	{
+ 	  sigaddset (&run.trace, signo);
+ 	}
+     }
+ }
+ 
+ /*
+ 
+ GLOBAL FUNCTION
+ 
+ 	procfs_notice_signals
+ 
+ SYNOPSIS
+ 
+ 	static void procfs_notice_signals (int pid);
+ 
+ DESCRIPTION
+ 
+ 	When the user changes the state of gdb's signal handling via the
+ 	"handle" command, this function gets called to see if any change
+ 	in the /proc interface is required.  It is also called internally
+ 	by other /proc interface functions to initialize the state of
+ 	the traced signal set.
+ 
+ 	One thing it does is that signals for which the state is "nostop",
+ 	"noprint", and "pass", have their trace bits reset in the pr_trace
+ 	field, so that they are no longer traced.  This allows them to be
+ 	delivered directly to the inferior without the debugger ever being
+ 	involved.
+  */
+ 
+ static void
+ procfs_notice_signals (pid)
+      int pid;
+ {
+   sigemptyset (&run.trace);
+   notice_signals ();
+ }
+ 
+ static struct tidinfo *
+ procfs_thread_info (pid_t pid, short tid)
+ {
+ /* NYI */
+   return NULL;
+ }
+ 
+ char *
+ procfs_pid_to_str (ptid_t ptid)
+ {
+   static char buf[1024];
+   int pid, tid, n;
+   struct tidinfo *tip;
+ 
+   pid = ptid_get_pid (ptid);
+   tid = ptid_get_tid (ptid);
+ 
+   n = sprintf (buf, "process %d", pid);
+ 
+ #if 0 /* NYI */
+   tip = procfs_thread_info (pid, tid);
+   if (tip != NULL)
+     sprintf (&buf[n], " (state = 0x%02x)", tip->state);
+ #endif
+ 
+   return buf;
+ }
+ 
+ static void
+ init_procfs_ops ()
+ {
+   procfs_ops.to_shortname = "procfs";
+   procfs_ops.to_longname = "QNX Neutrino procfs child process";
+   procfs_ops.to_doc =
+     "QNX Neutrino procfs child process (started by the \"run\" command).\n\
+ 	target procfs <node>";
+   procfs_ops.to_open = procfs_open;
+   procfs_ops.to_attach = procfs_attach;
+   procfs_ops.to_detach = procfs_detach;
+   procfs_ops.to_resume = procfs_resume;
+   procfs_ops.to_wait = procfs_wait;
+   procfs_ops.to_fetch_registers = procfs_fetch_registers;
+   procfs_ops.to_store_registers = procfs_store_registers;
+   procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
+   procfs_ops.to_xfer_memory = procfs_xfer_memory;
+   procfs_ops.to_files_info = procfs_files_info;
+   procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
+   procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
+   procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
+   procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
+   procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
+   procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint;
+   procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint;
+   procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
+   procfs_ops.to_terminal_init = terminal_init_inferior;
+   procfs_ops.to_terminal_inferior = terminal_inferior;
+   procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+   procfs_ops.to_terminal_ours = terminal_ours;
+   procfs_ops.to_terminal_info = child_terminal_info;
+   procfs_ops.to_kill = procfs_kill_inferior;
+   procfs_ops.to_create_inferior = procfs_create_inferior;
+   procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
+   procfs_ops.to_can_run = procfs_can_run;
+   procfs_ops.to_notice_signals = procfs_notice_signals;
+   procfs_ops.to_thread_alive = procfs_thread_alive;
+   procfs_ops.to_find_new_threads = procfs_find_new_threads;
+   procfs_ops.to_pid_to_str = procfs_pid_to_str;
+   procfs_ops.to_stop = procfs_stop;
+   procfs_ops.to_stratum = process_stratum;
+   procfs_ops.to_has_all_memory = 1;
+   procfs_ops.to_has_memory = 1;
+   procfs_ops.to_has_stack = 1;
+   procfs_ops.to_has_registers = 1;
+   procfs_ops.to_has_execution = 1;
+   procfs_ops.to_magic = OPS_MAGIC;
+ }
+ 
+ #define OSTYPE_NTO 1
+ 
+ void
+ _initialize_procfs ()
+ {
+   sigset_t set;
+ 
+   init_procfs_ops ();
+   add_target (&procfs_ops);
+   nto_ostype = OSTYPE_NTO;
+ 
+   /* We use SIGUSR1 to gain control after we block waiting for a process.
+      We use sigwaitevent to wait. */
+   sigemptyset (&set);
+   sigaddset (&set, SIGUSR1);
+   sigprocmask (SIG_BLOCK, &set, NULL);
+ 
+   /* Set up trace and fault sets, as gdb expects them. */
+   sigemptyset (&run.trace);
+   notice_signals ();
+ 
+   /* Stuff some information */
+   nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
+   nto_cpuinfo_valid = 1;
+ 
+   add_info ("pidlist", procfs_pidlist, "pidlist");
+   add_info ("meminfo", procfs_meminfo, "memory information");
+ }
+ 
+ 
+ static int
+ procfs_hw_watchpoint (int addr, int len, int type)
+ {
+   procfs_break brk;
+   int err;
+ 
+   switch (type)
+     {
+     case 1:			/* Read */
+       brk.type = _DEBUG_BREAK_RD;
+       break;
+     case 2:			/* Read/Write */
+       brk.type = _DEBUG_BREAK_RW;
+       break;
+     default:			/* Modify */
+ /*    	brk.type = _DEBUG_BREAK_RWM; This should work, shouldn't it? I get EINVAL */
+       brk.type = _DEBUG_BREAK_RW;
+     }
+   brk.type |= _DEBUG_BREAK_HW;	/* always ask for HW */
+   brk.addr = addr;
+   brk.size = len;
+ 
+   if ((err = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)) != EOK)
+     {
+       errno = err;
+       perror ("Failed to set hardware watchpoint");
+       return -1;
+     }
+   return 0;
+ }
+ 
+ static int
+ procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
+ {
+   return 1;
+ }
+ 
+ static int
+ procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type)
+ {
+   return procfs_hw_watchpoint (addr, -1, type);
+ }
+ 
+ static int
+ procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type)
+ {
+   return procfs_hw_watchpoint (addr, len, type);
+ }
+ 
+ static int
+ procfs_stopped_by_watchpoint (void)
+ {
+   return 0;
+ }
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/nto-share/debug.h src/gdb/nto-share/debug.h
*** src.orig/gdb/nto-share/debug.h	Wed Dec 31 19:00:00 1969
--- src/gdb/nto-share/debug.h	Wed Feb 26 16:36:02 2003
***************
*** 0 ****
--- 1,465 ----
+ #ifndef _DEBUG_H
+ #define _DEBUG_H
+ 
+ /* __DEBUG_H_INCLUDED is Neutrino's native debug.h header.  We don't want
+    these duplicate definitions if we're compiling natively and have already
+    included it.  */
+ #ifndef __DEBUG_H_INCLUDED
+ #define __DEBUG_H_INCLUDED
+ 
+ #include <time.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+ 
+ #define QNX_NOTE_NAME	"QNX"
+ 
+ enum Elf_nto_note_types
+ {
+   QNT_NULL = 0,
+   QNT_DEBUG_FULLPATH,
+   QNT_DEBUG_RELOC,
+   QNT_STACK,
+   QNT_GENERATOR,
+   QNT_DEFAULT_LIB,
+   QNT_CORE_SYSINFO,
+   QNT_CORE_INFO,
+   QNT_CORE_STATUS,
+   QNT_CORE_GREG,
+   QNT_CORE_FPREG,
+   QNT_NUM
+ };
+ 
+ typedef struct
+ {
+   long bits[2];
+ } nto_sigset_t;
+ 
+ union nto_sigval
+ {
+   int sival_int;
+   void *sival_ptr;
+ };
+ 
+ typedef struct nto_siginfo
+ {
+   int si_signo;
+   int si_code;			/* if SI_NOINFO, only si_signo is valid */
+   void (*si_handler) ();
+   union
+   {
+     int _pad[6];
+     struct
+     {
+       pid_t _pid;
+       union
+       {
+ 	struct
+ 	{
+ 	  union nto_sigval _value;
+ 	  uid_t _uid;
+ 	} _kill;		/* si_code <= 0 SI_FROMUSER */
+ 	struct
+ 	{
+ 	  int _status;		/* CLD_EXITED status, else signo */
+ 	  clock_t _utime;
+ 	  clock_t _stime;
+ 	} _chld;		/* si_signo=SIGCHLD si_code=CLD_* */
+       } _pdata;
+     } _proc;
+     struct
+     {
+       int _fltno;
+       void *_addr;
+       void *_fltip;
+     } _fault;			/* si_signo=SIGSEGV,ILL,FPE,TRAP,BUS */
+   } _data;
+ } nto_siginfo_t;
+ 
+ typedef struct arm_cpu_registers
+ {
+   unsigned gpr[16];
+   unsigned spsr;
+ } ARM_CPU_REGISTERS;
+ 
+ typedef struct arm_fpu_registers
+ {
+   /*
+    * There is no architecturally defined FPU
+    */
+   unsigned __dummy;
+ } ARM_FPU_REGISTERS;
+ 
+ typedef struct arm_alt_registers
+ {
+   union
+   {
+     struct xscale_cp0
+     {
+       unsigned acc0_lo;
+       unsigned acc0_hi;
+     } xscale;
+   } un;
+ } ARM_ALT_REGISTERS;
+ 
+ typedef union
+ {
+   unsigned long long u64;
+   double f;
+ } mipsfloat;
+ 
+ typedef struct mips_cpu_registers
+ {
+   unsigned regs[74];
+   unsigned long long regs_alignment;
+ } MIPS_CPU_REGISTERS;
+ 
+ typedef struct mips_fpu_registers
+ {
+   mipsfloat fpr[32];
+   unsigned fpcr31;
+ } MIPS_FPU_REGISTERS;
+ 
+ typedef struct mips_alt_registers
+ {
+   union
+   {
+     struct mips_tx79
+     {
+       unsigned long long gpr_hi[32];
+       unsigned long long lo1;
+       unsigned long long hi1;
+       unsigned sa;
+     } tx79;
+   } un;
+ } MIPS_ALT_REGISTERS;
+ 
+ #ifdef __BIGREGS__
+ typedef unsigned long long ppcint;
+ #else
+ typedef unsigned ppcint;
+ #endif
+ 
+ typedef union
+ {
+   unsigned long long u64;
+   double f;
+ } ppcfloat;
+ 
+ typedef union
+ {
+   unsigned long long u64[2];
+   unsigned u32[4];
+   unsigned char u8[16];
+   float f32[4];
+ } ppcvmx;
+ 
+ typedef struct ppc_cpu_registers
+ {
+   ppcint gpr[32];
+   ppcint ctr;
+   ppcint lr;
+   ppcint msr;
+   ppcint iar;
+   unsigned cr;
+   unsigned xer;
+   unsigned ear;			/* not present on all chips */
+   unsigned mq;			/* only on the 601 */
+   unsigned vrsave;		/* on Altivec CPU's, SPR256 */
+ } PPC_CPU_REGISTERS;
+ 
+ typedef struct ppc_fpu_registers
+ {
+   ppcfloat fpr[32];
+   unsigned fpscr;
+   unsigned fpscr_val;
+   /* load/store of fpscr is done through fprs, the real value is in [32,63] of a fpr.
+      fpscr is the address for lfd, stfd. fpscr_val is the real value of fpscr */
+ } PPC_FPU_REGISTERS;
+ 
+ typedef struct ppc_vmx_registers
+ {
+   ppcvmx vmxr[32];
+   ppcvmx vscr;
+ } PPC_VMX_REGISTERS;
+ 
+ typedef struct ppc_alt_registers
+ {
+   PPC_VMX_REGISTERS vmx;
+ } PPC_ALT_REGISTERS;
+ 
+ typedef unsigned shint;
+ 
+ typedef unsigned shfloat;
+ 
+ typedef struct sh_cpu_registers
+ {
+   shint gr[16];
+   shint sr;
+   shint pc;
+ /*	shint		dbr; */
+   shint gbr;
+   shint mach;
+   shint macl;
+   shint pr;
+ } SH_CPU_REGISTERS;
+ 
+ typedef struct sh_fpu_registers
+ {
+   shfloat fpr_bank0[16];
+   shfloat fpr_bank1[16];
+   unsigned fpul;
+   unsigned fpscr;
+ } SH_FPU_REGISTERS;
+ 
+ typedef struct sh_alt_registers
+ {
+   /*
+    * There are no architecturally defined alt regs
+    */
+   unsigned __dummy;
+ } SH_ALT_REGISTERS;
+ 
+ typedef struct x86_cpu_registers
+ {
+ #ifdef __SEGMENTS__
+   unsigned gs, fs;
+   unsigned es, ds;
+ #endif
+   unsigned edi, esi, ebp, exx, ebx, edx, ecx, eax;
+   unsigned eip, cs, efl;
+   unsigned esp, ss;
+ } X86_CPU_REGISTERS;
+ 
+ typedef struct fsave_area
+ {
+   unsigned fpu_control_word;
+   unsigned fpu_status_word;
+   unsigned fpu_tag_word;
+   unsigned fpu_ip;
+   unsigned fpu_cs;
+   unsigned fpu_op;
+   unsigned fpu_ds;
+   unsigned char st_regs[80];	/* each register is 10 bytes! */
+ } X86_FSAVE_REGISTERS;
+ 
+ typedef struct fxsave_area
+ {
+   unsigned short fpu_control_word;
+   unsigned short fpu_status_word;
+   unsigned short fpu_tag_word;
+   unsigned short fpu_operand;
+   unsigned fpu_ip;
+   unsigned fpu_cs;
+   unsigned fpu_op;
+   unsigned fpu_ds;
+   unsigned mxcsr;
+   unsigned reserved;
+   unsigned char st_regs[128];
+   unsigned char xmm_regs[128];
+   unsigned char reserved2[224];
+ } X86_FXSAVE_REGISTERS;
+ 
+ typedef union x86_fpu_registers
+ {
+   X86_FSAVE_REGISTERS fsave_area;
+   X86_FXSAVE_REGISTERS fxsave_area;
+   unsigned char data[512];	/* Needs to be this big for the emulator. */
+ } X86_FPU_REGISTERS;
+ 
+ #ifdef __QNX__
+ __BEGIN_DECLS
+ #include <_pack64.h>
+ #endif
+ #define _DEBUG_FLAG_STOPPED			0x00000001	/* Thread is not running */
+ #define DEBUG_FLAG_ISTOP			0x00000002	/* Stopped at point of interest */
+ #define _DEBUG_FLAG_IPINVAL			0x00000010	/* IP is not valid */
+ #define _DEBUG_FLAG_ISSYS			0x00000020	/* System process */
+ #define _DEBUG_FLAG_SSTEP			0x00000040	/* Stopped because of single step */
+ #define _DEBUG_FLAG_CURTID			0x00000080	/* Thread is current thread */
+ #define DEBUG_FLAG_TRACE_EXEC		0x00000100	/* Stopped because of breakpoint */
+ #define _DEBUG_FLAG_TRACE_RD		0x00000200	/* Stopped because of read access */
+ #define _DEBUG_FLAG_TRACE_WR		0x00000400	/* Stopped because of write access */
+ #define _DEBUG_FLAG_TRACE_MODIFY	0x00000800	/* Stopped because of modified memory */
+ #define _DEBUG_FLAG_RLC				0x00010000	/* Run-on-Last-Close flag is set */
+ #define _DEBUG_FLAG_KLC				0x00020000	/* Kill-on-Last-Close flag is set */
+ #define _DEBUG_FLAG_FORK			0x00040000	/* Child inherits flags (Stop on fork/spawn) */
+ #define _DEBUG_FLAG_MASK			0x000f0000	/* Flags that can be changed */
+   enum
+ {
+   _DEBUG_WHY_REQUESTED,
+   _DEBUG_WHY_SIGNALLED,
+   _DEBUG_WHY_FAULTED,
+   _DEBUG_WHY_JOBCONTROL,
+   _DEBUG_WHY_TERMINATED,
+   _DEBUG_WHY_CHILD,
+   _DEBUG_WHY_EXEC
+ };
+ 
+ #define _DEBUG_RUN_CLRSIG			0x00000001	/* Clear pending signal */
+ #define _DEBUG_RUN_CLRFLT			0x00000002	/* Clear pending fault */
+ #define DEBUG_RUN_TRACE			0x00000004	/* Trace mask flags interesting signals */
+ #define DEBUG_RUN_HOLD				0x00000008	/* Hold mask flags interesting signals */
+ #define DEBUG_RUN_FAULT			0x00000010	/* Fault mask flags interesting faults */
+ #define _DEBUG_RUN_VADDR			0x00000020	/* Change ip before running */
+ #define _DEBUG_RUN_STEP				0x00000040	/* Single step only one thread */
+ #define _DEBUG_RUN_STEP_ALL			0x00000080	/* Single step one thread, other threads run */
+ #define _DEBUG_RUN_CURTID			0x00000100	/* Change current thread (target thread) */
+ #define DEBUG_RUN_ARM				0x00000200	/* Deliver event at point of interest */
+ 
+ typedef struct _debug_process_info
+ {
+   pid_t pid;
+   pid_t parent;
+   unsigned flags;
+   unsigned umask;
+   pid_t child;
+   pid_t sibling;
+   pid_t pgrp;
+   pid_t sid;
+   int base_address;
+   int initial_stack;
+   uid_t uid;
+   gid_t gid;
+   uid_t euid;
+   gid_t egid;
+   uid_t suid;
+   gid_t sgid;
+   nto_sigset_t sig_ignore;
+   nto_sigset_t sig_queue;
+   nto_sigset_t sig_pending;
+   unsigned num_chancons;
+   unsigned num_fdcons;
+   unsigned num_threads;
+   unsigned num_timers;
+   unsigned long long reserved[20];
+ } nto_procfs_info;
+ 
+ typedef struct _debug_thread_info
+ {
+   pid_t pid;
+   unsigned tid;
+   unsigned flags;
+   unsigned short why;
+   unsigned short what;
+   int ip;
+   int sp;
+   int stkbase;
+   int tls;
+   unsigned stksize;
+   unsigned tid_flags;
+   unsigned char priority;
+   unsigned char real_priority;
+   unsigned char policy;
+   unsigned char state;
+   short syscall;
+   unsigned short last_cpu;
+   unsigned timeout;
+   int last_chid;
+   nto_sigset_t sig_blocked;
+   nto_sigset_t sig_pending;
+   nto_siginfo_t info;
+   unsigned reserved1;
+   union
+   {
+     struct
+     {
+       unsigned tid;
+     } join;
+     struct
+     {
+       int id;
+       int sync;
+     } sync;
+     struct
+     {
+       unsigned nid;
+       pid_t pid;
+       int coid;
+       int chid;
+       int scoid;
+     } connect;
+     struct
+     {
+       int chid;
+     } channel;
+     struct
+     {
+       pid_t pid;
+       int vaddr;
+       unsigned flags;
+     } waitpage;
+     struct
+     {
+       unsigned size;
+     } stack;
+     unsigned long long filler[4];
+   } blocked;
+   unsigned long long reserved2[8];
+ } nto_procfs_status;
+ 
+ typedef union _debug_gregs
+ {
+   ARM_CPU_REGISTERS arm;
+   MIPS_CPU_REGISTERS mips;
+   PPC_CPU_REGISTERS ppc;
+   SH_CPU_REGISTERS sh;
+   X86_CPU_REGISTERS x86;
+   unsigned long long padding[1024];
+ } nto_gregset_t;
+ 
+ typedef union _debug_fpregs
+ {
+ /*	ARM_FPU_REGISTERS	arm;	*/
+   MIPS_FPU_REGISTERS mips;
+   PPC_FPU_REGISTERS ppc;
+   SH_FPU_REGISTERS sh;
+   X86_FPU_REGISTERS x86;
+   unsigned long long padding[1024];
+ } nto_fpregset_t;
+ 
+ typedef union _debug_altregs
+ {
+   ARM_ALT_REGISTERS arm;
+   MIPS_ALT_REGISTERS mips;
+   PPC_ALT_REGISTERS ppc;
+ /*	SH_ALT_REGISTERS	sh;	*/
+ /*	X86_ALT_REGISTERS	x86;	*/
+   unsigned long long padding[1024];
+ } debug_altreg_t;
+ 
+ /* Keep this consistant with neutrino syspage.h */
+ enum
+ {
+   CPUTYPE_X86,
+   CPUTYPE_PPC,
+   CPUTYPE_MIPS,
+   CPUTYPE_SPARE,
+   CPUTYPE_ARM,
+   CPUTYPE_SH,
+   CPUTYPE_UNKNOWN
+ };
+ 
+ enum
+ {
+   OSTYPE_QNX4,
+   OSTYPE_NTO
+ };
+ 
+ #ifdef __QNX__
+ #include <_packpop.h>
+ 
+ __END_DECLS
+ #endif
+ 
+ #endif /* __DEBUG_H_INCLUDED */
+ 
+ /* these correspond to the DSMSG_* versions in dsmsgs.h */
+ enum
+ {
+   NTO_REG_GENERAL,
+   NTO_REG_FLOAT,
+   NTO_REG_SYSTEM,
+   NTO_REG_ALT
+ };
+ 
+ #endif /* _DEBUG_H */
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/nto-tdep.c src/gdb/nto-tdep.c
*** src.orig/gdb/nto-tdep.c	Wed Dec 31 19:00:00 1969
--- src/gdb/nto-tdep.c	Wed Feb 26 10:38:28 2003
***************
*** 0 ****
--- 1,368 ----
+ /* nto-tdep.c - general QNX Neutrino target functionality */
+ 
+ /* Copyright 2003 Free Software Foundation */
+ 
+ /* This code was donated by QNX Software Systems Ltd. */
+ 
+ #include <sys/stat.h>
+ #include <string.h>
+ #include "nto-tdep.h"
+ #include "top.h"
+ #include "cli/cli-decode.h"
+ #include "cli/cli-cmds.h"
+ #include "inferior.h"
+ #include "gdbarch.h"
+ #include "bfd.h"
+ #include "elf-bfd.h"
+ #include "solib-svr4.h"
+ #include "gdbcore.h"
+ 
+ #ifdef __CYGWIN__
+ #include <sys/cygwin.h>
+ #endif
+ 
+ #ifdef __CYGWIN__
+ static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
+ #elif defined(__sun__) || defined(linux)
+ static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
+ #else
+ static char default_nto_target[] = "";
+ #endif
+ 
+ /* Maintenance debugging flag */
+ int nto_internal_debugging;
+ 
+ /* Filled in cpu info structure and flag to indicate its validity. 
+  * This is initialized in procfs_attach or nto_start_remote depending on
+  * our host/target.  It would only be invalid if we were talking to an
+  * older pdebug which didn't support the cpuinfo message. */
+ unsigned nto_cpuinfo_flags;
+ int nto_cpuinfo_valid;
+ int nto_ostype = -1;
+ 
+ static char *
+ nto_target (void)
+ {
+   char *p = getenv ("QNX_TARGET");
+ 
+ #ifdef __CYGWIN__
+   static char buf[PATH_MAX];
+   if (p)
+     cygwin_conv_to_posix_path (p, buf);
+   else
+     cygwin_conv_to_posix_path (default_nto_target, buf);
+   return buf;
+ #else
+   return p ? p : default_nto_target;
+ #endif
+ }
+ 
+ /* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
+    CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h */
+ int
+ nto_map_arch_to_cputype(const char *arch)
+ {
+   if(!strcmp(arch, "i386") || !strcmp(arch, "x86"))
+     return CPUTYPE_X86;
+   if(!strcmp(arch, "rs6000") || !strcmp(arch, "ppc"))
+     return CPUTYPE_PPC;
+   if(!strcmp(arch, "mips"))
+     return CPUTYPE_MIPS;
+   if(!strcmp(arch, "arm"))
+     return CPUTYPE_ARM;
+   if(!strcmp(arch, "sh"))
+     return CPUTYPE_SH;
+   return CPUTYPE_UNKNOWN;
+ }
+ 
+ int
+ nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
+ {
+   char *buf, arch_path[PATH_MAX], *nto_root, *endian;
+   const char *arch;
+   char *path_fmt = "%s/lib:%s/usr/lib:%s/usr/photon/lib\
+ :%s/usr/photon/dll:%s/lib/dll";
+ 
+   nto_root = nto_target ();
+   if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0)
+     {
+       arch = "x86";
+       endian = "";
+     }
+   else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0)
+     {
+       arch = "ppc";
+       endian = "be";
+     }
+   else
+     {
+       arch = TARGET_ARCHITECTURE->arch_name;
+       endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le";
+     }
+ 
+   sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
+ 
+   buf = alloca (strlen(path_fmt) + strlen(arch_path) * 5 + 1);
+   sprintf (buf, path_fmt, arch_path, arch_path, arch_path, arch_path, arch_path);
+ 
+   return openp(buf, 1, solib, o_flags, 0, temp_pathname);
+ }
+ 
+ void
+ nto_init_solib_search_path (void)
+ {
+   char buf[PATH_MAX * 2], arch_path[PATH_MAX];
+   char *nto_root, *endian;
+   const char *arch;
+   char *solib_search_path, *cmd_name = "solib-search-path";
+   struct cmd_list_element *c;
+ 
+   c = lookup_cmd (&cmd_name, setlist, "", 1, 1);
+ 
+   if (!c || !c->var)
+     return;
+ 
+   solib_search_path = *((char **) c->var);
+ 
+   if (solib_search_path != NULL)
+     return;
+ 
+   nto_root = nto_target ();
+   if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0)
+     {
+       arch = "x86";
+       endian = "";
+     }
+   else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0)
+     {
+       arch = "ppc";
+       endian = "be";
+     }
+   else
+     {
+       arch = TARGET_ARCHITECTURE->arch_name;
+       endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le";
+     }
+ 
+   sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
+ 
+   sprintf (buf, "set solib-absolute-prefix %s", arch_path);
+   execute_command (buf, 0);
+ 
+ #if 0
+   sprintf (buf, "%s/lib:%s/usr/lib:%s/usr/photon/lib\
+ :%s/usr/photon/dll:%s/lib/dll", arch_path, arch_path, arch_path, arch_path, arch_path);
+   /* we already looked up the command...might as well use it */
+   *((char **) c->var) = xstrdup (buf);
+ #endif
+ }
+ 
+ char **
+ nto_parse_redirection (char *pargv[], char **pin, char **pout, char **perr)
+ {
+   char **argv;
+   char *in, *out, *err, *p;
+   int argc, i, n;
+ 
+   for (n = 0; pargv[n]; n++);
+   if (n == 0)
+     return NULL;
+   in = "";
+   out = "";
+   err = "";
+ 
+   argv = xcalloc (n + 1, sizeof argv[0]);
+   argc = n;
+   for (i = 0, n = 0; n < argc; n++)
+     {
+       p = pargv[n];
+       if (*p == '>')
+ 	{
+ 	  p++;
+ 	  if (*p)
+ 	    out = p;
+ 	  else
+ 	    out = pargv[++n];
+ 	}
+       else if (*p == '<')
+ 	{
+ 	  p++;
+ 	  if (*p)
+ 	    in = p;
+ 	  else
+ 	    in = pargv[++n];
+ 	}
+       else if (*p++ == '2' && *p++ == '>')
+ 	{
+ 	  if (*p == '&' && *(p + 1) == '1')
+ 	    err = out;
+ 	  else if (*p)
+ 	    err = p;
+ 	  else
+ 	    err = pargv[++n];
+ 	}
+       else
+ 	argv[i++] = pargv[n];
+     }
+   *pin = in;
+   *pout = out;
+   *perr = err;
+   return argv;
+ }
+ 
+ void
+ nto_source_extra_gdbinit (char *file)
+ {
+   char *homedir, *homeinit;
+   struct stat statbuf;
+ 
+   homedir = getenv ("HOME");
+ 
+   if (homedir && !inhibit_gdbinit)
+     {
+       homeinit = (char *) alloca (strlen (homedir) + strlen (file) + 10);
+       sprintf (homeinit, "%s/%s", homedir, file);
+       if (stat (homeinit, &statbuf) == 0)
+ 	catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
+     }
+ }
+ 
+ /* struct lm_info, LM_ADDR, and nto_truncate_ptr are copied from
+    solib-svr4.c to support nto_relocate_section_addresses
+    which is different from the svr4 version. */
+ 
+ struct lm_info
+ {
+   /* Pointer to copy of link map from inferior.  The type is char *
+      rather than void *, so that we may use byte offsets to find the
+      various fields without the need for a cast.  */
+   char *lm;
+ };
+ 
+ static CORE_ADDR
+ LM_ADDR (struct so_list *so)
+ {
+   struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
+ 
+   return (CORE_ADDR) extract_signed_integer (so->lm_info->lm +
+ 					     lmo->l_addr_offset,
+ 					     lmo->l_addr_size);
+ }
+ 
+ static CORE_ADDR
+ nto_truncate_ptr (CORE_ADDR addr)
+ {
+   if (TARGET_PTR_BIT == sizeof (CORE_ADDR) * 8)
+     /* We don't need to truncate anything, and the bit twiddling below
+        will fail due to overflow problems.  */
+     return addr;
+   else
+     return addr & (((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1);
+ }
+ 
+ Elf_Internal_Phdr *
+ find_load_phdr (bfd *abfd)
+ {
+   Elf_Internal_Phdr *phdr;
+   unsigned int i;
+ 
+   if (!elf_tdata (abfd))
+     return NULL;
+ 
+   phdr = elf_tdata (abfd)->phdr;
+   for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+     {
+       if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
+ 	return phdr;
+     }
+   return NULL;
+ }
+ 
+ void
+ nto_relocate_section_addresses (struct so_list *so, struct section_table *sec)
+ {
+   /* On some platforms, (ie. QNXnto, NetBSD) LM_ADDR is the assigned
+      address, not the offset.
+      The addresses are formed as follows:
+      LM_ADDR is the target address where the shared library file
+      is mapped, so the actual section start address is LM_ADDR plus
+      the section offset within the shared library file.  The end
+      address is that plus the section length.  Note that we pay no
+      attention to the section start address as recorded in the
+      library header.
+    */
+   Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd);
+   unsigned vaddr = phdr ? phdr->p_vaddr : 0;
+ 
+   sec->addr = nto_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr);
+   sec->endaddr = nto_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr);
+ }
+ 
+ static void
+ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
+      char *core_reg_sect;
+      unsigned core_reg_size;
+      int which;
+      CORE_ADDR reg_addr;
+ {
+   nto_gregset_t gregset;
+   nto_fpregset_t fpregset;
+ 
+   nto_init_solib_search_path ();
+ 
+   if (which == 0)
+     {
+       memcpy ((char *) &gregset, core_reg_sect,
+ 	      min (core_reg_size, sizeof (gregset)));
+       nto_supply_gregset (&gregset);
+     }
+   else if (which == 2)
+     {
+       memcpy ((char *) &fpregset, core_reg_sect,
+ 	      min (core_reg_size, sizeof (fpregset)));
+       nto_supply_fpregset (&fpregset);
+     }
+ }
+ 
+ /* Register that we are able to handle ELF file formats using standard
+    procfs "regset" structures.  */
+ 
+ static struct core_fns regset_core_fns = {
+   bfd_target_elf_flavour,	/* core_flavour */
+   default_check_format,		/* check_format */
+   default_core_sniffer,		/* core_sniffer */
+   fetch_core_registers,		/* core_read_registers */
+   NULL				/* next */
+ };
+ 
+ void
+ _initialize_nto_tdep ()
+ {
+   add_show_from_set (add_set_cmd ("nto-debug", class_maintenance, var_zinteger, (char *) &nto_internal_debugging, "Set QNX NTO internal debugging.\n\
+ When non-zero, nto specific debug info is\n\
+ displayed. Different information is displayed\n\
+ for different positive values.", &setdebuglist),
+ 		     &showdebuglist);
+ 
+   /* We use SIG45 for pulses, or something, so nostop, noprint
+      and pass them. */
+   signal_stop_update (target_signal_from_name ("SIG45"), 0);
+   signal_print_update (target_signal_from_name ("SIG45"), 0);
+   signal_pass_update (target_signal_from_name ("SIG45"), 1);
+ 
+   /* by default we don't want to stop on these two, but we do want to pass */
+ #if defined(SIGSELECT)
+   signal_stop_update (SIGSELECT, 0);
+   signal_print_update (SIGSELECT, 0);
+   signal_pass_update (SIGSELECT, 1);
+ #endif
+ 
+ #if defined(SIGPHOTON)
+   signal_stop_update (SIGPHOTON, 0);
+   signal_print_update (SIGPHOTON, 0);
+   signal_pass_update (SIGPHOTON, 1);
+ #endif
+ 
+   /* register core file support */
+   add_core_fns (&regset_core_fns);
+ }
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/nto-tdep.h src/gdb/nto-tdep.h
*** src.orig/gdb/nto-tdep.h	Wed Dec 31 19:00:00 1969
--- src/gdb/nto-tdep.h	Mon Feb 24 17:07:10 2003
***************
*** 0 ****
--- 1,63 ----
+ /* nto-tdep.h - QNX Neutrino target header */
+ 
+ /* Copyright 2003 Free Software Foundation */
+ 
+ /* This code was donated by QNX Software Systems Ltd. */
+ 
+ #ifndef _NTO_TDEP_H
+ #define _NTO_TDEP_H
+ 
+ #include "defs.h"
+ #include "nto-share/debug.h"
+ #include "solist.h"
+ 
+ /* Generic functions in nto-tdep.c */
+ 
+ extern void nto_init_solib_search_path PARAMS ((void));
+ 
+ char **nto_parse_redirection
+ PARAMS ((char *start_argv[], char **in, char **out, char **err));
+ 
+ int proc_iterate_over_mappings PARAMS ((int (*func) (int, CORE_ADDR)));
+ 
+ void nto_source_extra_gdbinit PARAMS ((char *));
+ 
+ void nto_relocate_section_addresses
+ PARAMS ((struct so_list *, struct section_table *));
+ 
+ int nto_map_arch_to_cputype PARAMS((const char *));
+ 
+ int nto_find_and_open_solib PARAMS((char *, unsigned, char **));
+ 
+ /* Functions exported from all Neutrino targets (<target>-nto-tdep.c) */
+ 
+ unsigned nto_get_regset_id PARAMS ((int regno));
+ 
+ void nto_cpu_regset_fetch PARAMS ((int endian, int regset, void *data));
+ 
+ unsigned nto_get_regset_area PARAMS ((unsigned regset, char *subcmd));
+ 
+ unsigned nto_cpu_register_area
+ PARAMS ((unsigned first_regno, unsigned last_regno, unsigned char *subcmd,
+ 	 unsigned *off, unsigned *len));
+ 
+ void nto_cpu_register_fetch
+ PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data));
+ 
+ int nto_cpu_register_store
+ PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data));
+ 
+ void nto_supply_gregset PARAMS ((union _debug_gregs *));
+ 
+ void nto_supply_fpregset PARAMS ((union _debug_fpregs *));
+ 
+ struct link_map_offsets *nto_fetch_link_map_offsets PARAMS ((void));
+ 
+ /* Globals */
+ 
+ extern int nto_internal_debugging;
+ extern unsigned nto_cpuinfo_flags;
+ extern int nto_cpuinfo_valid;
+ extern int nto_ostype;
+ 
+ #endif

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2003-02-26 21:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-26 21:51 [Patch] The rest of the QNX files for native i386 Kris Warkentin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox