/* QNX Neutrino specific low level interface, for the remote server
   for GDB.
   Copyright (C) 2009, 2010 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);
    }
  snprintf (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,
  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);
}

