/* QNX Neutrino specific low level interface, for the remote server
   for GDB.
   Copyright (C) 2009, 2010, 2011 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 3 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, see <http://www.gnu.org/licenses/>.  */


#include "server.h"
#include "nto-low.h"

#include <limits.h>
#include <fcntl.h>
#include <spawn.h>
#include <sys/procfs.h>
#include <sys/auxv.h>
#include <stdarg.h>
#include <sys/iomgr.h>
#include <sys/neutrino.h>


extern int using_threads;
int using_threads = 1;

static void
nto_trace (const char *fmt, ...)
{
  va_list arg_list;

  if (debug_threads == 0)
    return;
  fprintf (stderr, "nto:");
  va_start (arg_list, fmt);
  vfprintf (stderr, fmt, arg_list);
  va_end (arg_list);
}

#define TRACE nto_trace

/* Structure holding neutrino specific information about
   inferior.  */

struct nto_inferior
{
  char nto_procfs_path[PATH_MAX];
  int ctl_fd;
  pid_t pid;
  int exit_signo; /* For tracking exit status.  */
};

static struct nto_inferior nto_inferior;

static void
init_nto_inferior (struct nto_inferior *nto_inferior)
{
  memset (nto_inferior, 0, sizeof (struct nto_inferior));
  nto_inferior->ctl_fd = -1;
  nto_inferior->pid = -1;
}

static void
do_detach (void)
{
  if (nto_inferior.ctl_fd != -1)
    {
      nto_trace ("Closing fd\n");
      close (nto_inferior.ctl_fd);
      init_nto_inferior (&nto_inferior);
    }
}

/* Set current thread. Return 1 on success, 0 otherwise.  */

static int
nto_set_thread (ptid_t ptid)
{
  int res = 0;

  TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid),
	 ptid_get_lwp (ptid));
  if (nto_inferior.ctl_fd != -1
      && !ptid_equal (ptid, null_ptid)
      && !ptid_equal (ptid, minus_one_ptid))
    {
      pthread_t tid = ptid_get_lwp (ptid);

      if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid,
	  sizeof (tid), 0))
	res = 1;
      else
	TRACE ("%s: Error: failed to set current thread\n", __func__);
    }
  return res;
}

/* This function will determine all alive threads.  Note that we do not list
   dead but unjoined threads even though they are still in the process' thread
   list.  

   NTO_INFERIOR must not be NULL.  */

static void
nto_find_new_threads (struct nto_inferior *nto_inferior)
{
  pthread_t tid;

  TRACE ("%s pid:%d\n", __func__, nto_inferior->pid);

  if (nto_inferior->ctl_fd == -1)
    return;

  for (tid = 1;; ++tid)
    {
      procfs_status status;
      ptid_t ptid;
      int err;

      status.tid = tid;
      err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status,
		    sizeof (status), 0);

      if (err != EOK || status.tid == 0)
	break;

      /* All threads in between are gone.  */
      while (tid != status.tid || status.state == STATE_DEAD)
	{
	  struct thread_info *ti;

	  ptid = ptid_build (nto_inferior->pid, tid, 0);
	  ti = find_thread_ptid (ptid);
	  if (ti != NULL)
	    {
	      TRACE ("Removing thread %d\n", tid);
	      remove_thread (ti);
	    }
	  if (tid == status.tid)
	    break;
	  ++tid;
	}

      if (status.state != STATE_DEAD)
	{
	  TRACE ("Adding thread %d\n", tid);
	  ptid = ptid_build (nto_inferior->pid, tid, 0);
	  if (!find_thread_ptid (ptid))
	    add_thread (ptid, NULL);
	}
    }
}

/* Given pid, open procfs path.  */

static pid_t
do_attach (pid_t pid)
{
  procfs_status status;
  struct sigevent event;

  if (nto_inferior.ctl_fd != -1)
    {
      close (nto_inferior.ctl_fd);
      init_nto_inferior (&nto_inferior);
    }
  xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid);
  nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR);
  if (nto_inferior.ctl_fd == -1)
    {
      TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path);
      init_nto_inferior (&nto_inferior);
      return -1;
    }
  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0)
      != EOK)
    {
      do_detach ();
      return -1;
    }
  nto_inferior.pid = pid;
  /* 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 (nto_inferior.ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);

  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
	      0) == EOK
      && (status.flags & _DEBUG_FLAG_STOPPED))
    {
      ptid_t ptid;

      kill (pid, SIGCONT);
      ptid = ptid_build (status.pid, status.tid, 0);
      the_low_target.arch_setup ();
      add_process (status.pid, 1);
      TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid,
	     ptid_get_lwp (ptid));
      nto_find_new_threads (&nto_inferior);
    }
  else
    {
      do_detach ();
      return -1;
    }

  return pid;
}

/* Read or write LEN bytes from/to inferior's MEMADDR memory address
   into gdbservers's MYADDR buffer.  Return number of bytes actually
   transfered.  */

static int
nto_xfer_memory (off_t memaddr, unsigned char *myaddr, int len,
		 int dowrite)
{
  int nbytes = 0;

  if (lseek (nto_inferior.ctl_fd, memaddr, SEEK_SET) == memaddr)
    {
      if (dowrite)
	nbytes = write (nto_inferior.ctl_fd, myaddr, len);
      else
	nbytes = read (nto_inferior.ctl_fd, myaddr, len);
      if (nbytes < 0)
	nbytes = 0;
    }
  if (nbytes == 0)
    {
      int e = errno;
      TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, strerror (e));
    }
  return nbytes;
}

/* Insert or remove breakpoint or watchpoint at address ADDR.
   TYPE can be one of Neutrino breakpoint types.  SIZE must be 0 for
   inserting the point, -1 for removing it.  

   Return 0 on success, 1 otherwise.  */

static int
nto_breakpoint (CORE_ADDR addr, int type, int size)
{
  procfs_break brk;

  brk.type = type;
  brk.addr = addr;
  brk.size = size;
  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)
      != EOK)
    return 1;
  return 0;
}

/* Read auxiliary vector from inferior's initial stack into gdbserver's
   MYADDR buffer, up to LEN bytes.  

   Return number of bytes read.  */

static int
nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack,
				  unsigned char *myaddr,
				  unsigned int len)
{
  int data_ofs = 0;
  int anint;
  unsigned int len_read = 0;

  /* Skip over argc, argv and envp... Comment from ldd.c:

     The startup frame is set-up so that we have:
     auxv
     NULL
     ...
     envp2
     envp1 <----- void *frame + (argc + 2) * sizeof(char *)
     NULL
     ...
     argv2
     argv1
     argc  <------ void * frame

     On entry to ldd, frame gives the address of argc on the stack.  */
  if (nto_xfer_memory (initial_stack, (unsigned char *)&anint,
		       sizeof (anint), 0) != sizeof (anint))
    return 0;

  /* Size of pointer is assumed to be 4 bytes (32 bit arch. ) */
  data_ofs += (anint + 2) * sizeof (void *); /* + 2 comes from argc itself and
						NULL terminating pointer in
						argv.  */

  /* Now loop over env table:  */
  while (nto_xfer_memory (initial_stack + data_ofs,
			  (unsigned char *)&anint, sizeof (anint), 0)
	 == sizeof (anint))
    {
      data_ofs += sizeof (anint);
      if (anint == 0)
	break;
    }
  initial_stack += data_ofs;

  memset (myaddr, 0, len);
  while (len_read <= len - sizeof (auxv_t))
    {
      auxv_t *auxv = (auxv_t *)myaddr;

      /* Search backwards until we have read AT_PHDR (num. 3),
	 AT_PHENT (num 4), AT_PHNUM (num 5)  */
      if (nto_xfer_memory (initial_stack, (unsigned char *)auxv,
			   sizeof (auxv_t), 0) == sizeof (auxv_t))
	{
	  if (auxv->a_type != AT_NULL)
	    {
	      auxv++;
	      len_read += sizeof (auxv_t);
	    }
	  if (auxv->a_type == AT_PHNUM) /* That's all we need.  */
	    break;
	  initial_stack += sizeof (auxv_t);
	}
      else
	break;
    }
  TRACE ("auxv: len_read: %d\n", len_read);
  return len_read;
}

/* Start inferior specified by PROGRAM passing arguments ALLARGS.  */

static int
nto_create_inferior (char *program, char **allargs)
{
  struct inheritance inherit;
  pid_t pid;
  sigset_t set;

  TRACE ("%s %s\n", __func__, program);
  /* 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));
  inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
  inherit.pgroup = SPAWN_NEWPGROUP;
  pid = spawnp (program, 0, NULL, &inherit, allargs, 0);
  sigprocmask (SIG_BLOCK, &set, NULL);

  if (pid == -1)
    return -1;

  if (do_attach (pid) != pid)
    return -1;

  return pid;
}

/* Attach to process PID.  */

static int
nto_attach (unsigned long pid)
{
  TRACE ("%s %ld\n", __func__, pid);
  if (do_attach (pid) != pid)
    error ("Unable to attach to %ld\n", pid);
  return 0;
}

/* Send signal to process PID.  */

static int
nto_kill (int pid)
{
  TRACE ("%s %d\n", __func__, pid);
  kill (pid, SIGKILL);
  do_detach ();
  return 0;
}

/* Detach from process PID.  */

static int
nto_detach (int pid)
{
  TRACE ("%s %d\n", __func__, pid);
  do_detach ();
  return 0;
}

static void
nto_mourn (struct process_info *process)
{
  remove_process (process);
}

/* Check if the given thread is alive.  

   Return 1 if alive, 0 otherwise.  */

static int
nto_thread_alive (ptid_t ptid)
{
  int res;

  TRACE ("%s pid:%d tid:%d\n", __func__, ptid_get_pid (ptid),
	 ptid_get_lwp (ptid));
  if (SignalKill (0, ptid_get_pid (ptid), ptid_get_lwp (ptid),
		  0, 0, 0) == -1)
    res = 0;
  else
    res = 1;
  TRACE ("%s: %s\n", __func__, res ? "yes" : "no");
  return res;
}

/* Resume inferior's execution.  */

static void
nto_resume (struct thread_resume *resume_info, size_t n)
{
  /* We can only work in all-stop mode.  */
  procfs_status status;
  procfs_run run;
  int err;

  TRACE ("%s\n", __func__);
  /* Workaround for aliasing rules violation. */
  sigset_t *run_fault = (sigset_t *) (void *) &run.fault;

  nto_set_thread (resume_info->thread);

  run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
  if (resume_info->kind == resume_step)
    run.flags |= _DEBUG_RUN_STEP;
  run.flags |= _DEBUG_RUN_ARM;

  sigemptyset (run_fault);
  sigaddset (run_fault, FLTBPT);
  sigaddset (run_fault, FLTTRACE);
  sigaddset (run_fault, FLTILL);
  sigaddset (run_fault, FLTPRIV);
  sigaddset (run_fault, FLTBOUNDS);
  sigaddset (run_fault, FLTIOVF);
  sigaddset (run_fault, FLTIZDIV);
  sigaddset (run_fault, FLTFPE);
  sigaddset (run_fault, FLTPAGE);
  sigaddset (run_fault, FLTSTACK);
  sigaddset (run_fault, FLTACCESS);

  sigemptyset (&run.trace);
  if (resume_info->sig)
    {
      int signal_to_pass;

      devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
	      0);
      signal_to_pass = resume_info->sig;
      if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
	{
	  if (signal_to_pass != status.info.si_signo)
	    {
	      kill (status.pid, signal_to_pass);
	      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;

  sigfillset (&run.trace);

  regcache_invalidate ();

  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
  if (err != EOK)
    TRACE ("Error: %d \"%s\"\n", err, strerror (err));
}

/* Wait for inferior's event.  

   Return ptid of thread that caused the event.  */

static ptid_t
nto_wait (ptid_t ptid,
	  struct target_waitstatus *ourstatus, int target_options)
{
  sigset_t set;
  siginfo_t info;
  procfs_status status;
  const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
			  | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);

  TRACE ("%s\n", __func__);

  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;

  sigemptyset (&set);
  sigaddset (&set, SIGUSR1);

  devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
  while (!(status.flags & _DEBUG_FLAG_ISTOP))
    {
      sigwaitinfo (&set, &info);
      devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
	      0);
    }
  nto_find_new_threads (&nto_inferior);

  if (status.flags & _DEBUG_FLAG_SSTEP)
    {
      TRACE ("SSTEP\n");
      ourstatus->kind = TARGET_WAITKIND_STOPPED;
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
    }
  /* Was it a breakpoint?  */
  else if (status.flags & trace_mask)
    {
      TRACE ("STOPPED\n");
      ourstatus->kind = TARGET_WAITKIND_STOPPED;
      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
    }
  else if (status.flags & _DEBUG_FLAG_ISTOP)
    {
      TRACE ("ISTOP\n");
      switch (status.why)
	{
	case _DEBUG_WHY_SIGNALLED:
	  TRACE ("  SIGNALLED\n");
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  ourstatus->value.sig =
	    target_signal_from_host (status.info.si_signo);
	  nto_inferior.exit_signo = ourstatus->value.sig;
	  break;
	case _DEBUG_WHY_FAULTED:
	  TRACE ("  FAULTED\n");
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  if (status.info.si_signo == SIGTRAP)
	    {
	      ourstatus->value.sig = 0;
	      nto_inferior.exit_signo = 0;
	    }
	  else
	    {
	      ourstatus->value.sig =
		target_signal_from_host (status.info.si_signo);
	      nto_inferior.exit_signo = ourstatus->value.sig;
	    }
	  break;

	case _DEBUG_WHY_TERMINATED:
	  {
	    int waitval = 0;

	    TRACE ("  TERMINATED\n");
	    waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
	    if (nto_inferior.exit_signo)
	      {
		/* Abnormal death.  */
		ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
		ourstatus->value.sig = nto_inferior.exit_signo;
	      }
	    else
	      {
		/* Normal death.  */
		ourstatus->kind = TARGET_WAITKIND_EXITED;
		ourstatus->value.integer = WEXITSTATUS (waitval);
	      }
	    nto_inferior.exit_signo = 0;
	    break;
	  }

	case _DEBUG_WHY_REQUESTED:
	  TRACE ("REQUESTED\n");
	  /* We are assuming a requested stop is due to a SIGINT.  */
	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
	  ourstatus->value.sig = TARGET_SIGNAL_INT;
	  nto_inferior.exit_signo = 0;
	  break;
	}
    }

  return ptid_build (status.pid, status.tid, 0);
}

/* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR).
   If REGNO is -1, fetch all registers, or REGNO register only otherwise.  */

static void
nto_fetch_registers (struct regcache *regcache, int regno)
{
  int regsize;
  procfs_greg greg;
  ptid_t ptid;

  TRACE ("%s (regno=%d)\n", __func__, regno);
  if (regno >= the_low_target.num_regs)
    return;

  if (current_inferior == NULL)
    {
      TRACE ("current_inferior is NULL\n");
      return;
    }
  ptid = thread_to_gdb_id (current_inferior);
  if (!nto_set_thread (ptid))
    return;

  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg),
	      &regsize) == EOK)
    {
      if (regno == -1) /* All registers. */
	{
	  for (regno = 0; regno != the_low_target.num_regs; ++regno)
	    {
	      const unsigned int registeroffset
		= the_low_target.register_offset (regno);
	      supply_register (regcache, regno,
			       ((char *)&greg) + registeroffset);
	    }
	}
      else
	{
	  const unsigned int registeroffset
	    = the_low_target.register_offset (regno);
	  if (registeroffset == -1)
	    return;
	  supply_register (regcache, regno, ((char *)&greg) + registeroffset);
	}
    }
  else
    TRACE ("ERROR reading registers from inferior.\n");
}

/* Store registers for currently selected thread (CURRENT_INFERIOR).  
   We always store all registers, regardless of REGNO.  */

static void
nto_store_registers (struct regcache *regcache, int regno)
{
  procfs_greg greg;
  int err;
  ptid_t ptid;

  TRACE ("%s (regno:%d)\n", __func__, regno);

  if (current_inferior == NULL)
    {
      TRACE ("current_inferior is NULL\n");
      return;
    }
  ptid = thread_to_gdb_id (current_inferior);
  if (!nto_set_thread (ptid))
    return;

  memset (&greg, 0, sizeof (greg));
  for  (regno = 0; regno != the_low_target.num_regs; ++regno)
    {
      const unsigned int regoffset
	= the_low_target.register_offset (regno);
      collect_register (regcache, regno, ((char *)&greg) + regoffset);
    }
  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg),
		0);
  if (err != EOK)
    TRACE ("Error: setting registers.\n");
}

/* Read LEN bytes from inferior's memory address MEMADDR into
   gdbserver's MYADDR buffer.  

   Return 0 on success -1 otherwise.  */

static int
nto_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
  TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);

  if (nto_xfer_memory (memaddr, myaddr, len, 0) != len)
    {
      TRACE ("Failed to read memory\n");
      return -1;
    }

  return 0;
}

/* Write LEN bytes from gdbserver's buffer MYADDR into inferior's
   memory at address MEMADDR.  

   Return 0 on success -1 otherwise.  */

static int
nto_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
  int len_written;

  TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
  if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len,
				      1))
      != len)
    {
      TRACE ("Wanted to write: %d but written: %d\n", len, len_written);
      return -1;
    }

  return 0;
}

/* Stop inferior.  We always stop all threads.  */

static void
nto_request_interrupt (void)
{
  TRACE ("%s\n", __func__);
  nto_set_thread (ptid_build (nto_inferior.pid, 1, 0));
  if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
    TRACE ("Error stopping inferior.\n");
}

/* Read auxiliary vector from inferior's memory into gdbserver's buffer
   MYADDR.  We always read whole auxv.  
   
   Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0
   or -1 on error.  */

static int
nto_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
{
  int err;
  CORE_ADDR initial_stack;
  procfs_info procinfo;

  TRACE ("%s\n", __func__);
  if (offset > 0)
    return 0;

  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo,
		sizeof procinfo, 0);
  if (err != EOK)
    return -1;

  initial_stack = procinfo.initial_stack;

  return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len);
}

/* Insert {break/watch}point at address ADDR.
   TYPE must be in '0'..'4' range.  LEN is not used.  */

static int
nto_insert_point (char type, CORE_ADDR addr, int len)
{
  int wtype = _DEBUG_BREAK_HW; /* Always request HW.  */

  TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
  switch (type)
    {
    case '0': /* software-breakpoint */
      wtype = _DEBUG_BREAK_EXEC;
      break;
    case '1': /* hardware-breakpoint */
      wtype |= _DEBUG_BREAK_EXEC;
      break;
    case '2':  /* write watchpoint */
      wtype |= _DEBUG_BREAK_RW;
      break;
    case '3':  /* read watchpoint */
      wtype |= _DEBUG_BREAK_RD;
      break;
    case '4':  /* access watchpoint */
      wtype |= _DEBUG_BREAK_RW;
      break;
    default:
      return 1; /* Not supported.  */
    }
  return nto_breakpoint (addr, wtype, 0);
}

/* Remove {break/watch}point at address ADDR.
   TYPE must be in '0'..'4' range.  LEN is not used.  */

static int
nto_remove_point (char type, CORE_ADDR addr, int len)
{
  int wtype = _DEBUG_BREAK_HW; /* Always request HW.  */

  TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
  switch (type)
    {
    case '0': /* software-breakpoint */
      wtype = _DEBUG_BREAK_EXEC;
      break;
    case '1': /* hardware-breakpoint */
      wtype |= _DEBUG_BREAK_EXEC;
      break;
    case '2':  /* write watchpoint */
      wtype |= _DEBUG_BREAK_RW;
      break;
    case '3':  /* read watchpoint */
      wtype |= _DEBUG_BREAK_RD;
      break;
    case '4':  /* access watchpoint */
      wtype |= _DEBUG_BREAK_RW;
      break;
    default:
      return 1; /* Not supported.  */
    }
  return nto_breakpoint (addr, wtype, -1);
}

/* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
   a watchpoint.

   Return 1 if stopped by watchpoint, 0 otherwise.  */

static int
nto_stopped_by_watchpoint (void)
{
  int ret = 0;

  TRACE ("%s\n", __func__);
  if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
    {
      ptid_t ptid;

      ptid = thread_to_gdb_id (current_inferior);
      if (nto_set_thread (ptid))
	{
	  const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
				| _DEBUG_FLAG_TRACE_MODIFY;
	  procfs_status status;
	  int err;

	  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
			sizeof (status), 0);
	  if (err == EOK && (status.flags & watchmask))
	    ret = 1;
	}
    }
  TRACE ("%s: %s\n", __func__, ret ? "yes" : "no");
  return ret;
}

/* Get instruction pointer for CURRENT_INFERIOR thread.  

   Return inferior's instruction pointer value, or 0 on error.  */ 

static CORE_ADDR
nto_stopped_data_address (void)
{
  CORE_ADDR ret = (CORE_ADDR)0;

  TRACE ("%s\n", __func__);
  if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
    {
      ptid_t ptid;

      ptid = thread_to_gdb_id (current_inferior);

      if (nto_set_thread (ptid))
	{
	  procfs_status status;

	  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
		      sizeof (status), 0) == EOK)
	    ret = status.ip;
	}
    }
  TRACE ("%s: 0x%08lx\n", __func__, ret);
  return ret;
}

/* We do not currently support non-stop.  */

static int
nto_supports_non_stop (void)
{
  TRACE ("%s\n", __func__);
  return 0;
}



static struct target_ops nto_target_ops = {
  nto_create_inferior,
  nto_attach,
  nto_kill,
  nto_detach,
  nto_mourn,
  NULL, /* nto_join */
  nto_thread_alive,
  nto_resume,
  nto_wait,
  nto_fetch_registers,
  nto_store_registers,
  NULL, /* prepare_to_access_memory */
  NULL, /* done_accessing_memory */
  nto_read_memory,
  nto_write_memory,
  NULL, /* nto_look_up_symbols */
  nto_request_interrupt,
  nto_read_auxv,
  nto_insert_point,
  nto_remove_point,
  nto_stopped_by_watchpoint,
  nto_stopped_data_address,
  NULL, /* nto_read_offsets */
  NULL, /* thread_db_set_tls_address */
  NULL,
  hostio_last_error_from_errno,
  NULL, /* nto_qxfer_osdata */
  NULL, /* xfer_siginfo */
  nto_supports_non_stop,
  NULL, /* async */
  NULL  /* start_non_stop */
};


/* Global function called by server.c.  Initializes QNX Neutrino
   gdbserver.  */

void
initialize_low (void)
{
  sigset_t set;

  TRACE ("%s\n", __func__);
  set_target_ops (&nto_target_ops);
  set_breakpoint_data (the_low_target.breakpoint,
		       the_low_target.breakpoint_len);

  /* 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);
}

