/* QNX Neutrino specific low level interface, for the remote server
   for GDB.
   Copyright (C) 2009-2012 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 "gdbthread.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 = GDB_SIGNAL_TRAP;
    }
  /* Was it a breakpoint?  */
  else if (status.flags & trace_mask)
    {
      TRACE ("STOPPED\n");
      ourstatus->kind = TARGET_WAITKIND_STOPPED;
      ourstatus->value.sig = GDB_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 =
	    gdb_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 =
		gdb_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 = GDB_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);
}

