1/* QNX Neutrino specific low level interface, for the remote server
2   for GDB.
3   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
4
5   This file is part of GDB.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20
21#include "server.h"
22#include "nto-low.h"
23
24#include <limits.h>
25#include <fcntl.h>
26#include <spawn.h>
27#include <sys/procfs.h>
28#include <sys/auxv.h>
29#include <stdarg.h>
30#include <sys/iomgr.h>
31#include <sys/neutrino.h>
32
33
34extern int using_threads;
35int using_threads = 1;
36
37static void
38nto_trace (const char *fmt, ...)
39{
40  va_list arg_list;
41
42  if (debug_threads == 0)
43    return;
44  fprintf (stderr, "nto:");
45  va_start (arg_list, fmt);
46  vfprintf (stderr, fmt, arg_list);
47  va_end (arg_list);
48}
49
50#define TRACE nto_trace
51
52/* Structure holding neutrino specific information about
53   inferior.  */
54
55struct nto_inferior
56{
57  char nto_procfs_path[PATH_MAX];
58  int ctl_fd;
59  pid_t pid;
60  int exit_signo; /* For tracking exit status.  */
61};
62
63static struct nto_inferior nto_inferior;
64
65static void
66init_nto_inferior (struct nto_inferior *nto_inferior)
67{
68  memset (nto_inferior, 0, sizeof (struct nto_inferior));
69  nto_inferior->ctl_fd = -1;
70  nto_inferior->pid = -1;
71}
72
73static void
74do_detach (void)
75{
76  if (nto_inferior.ctl_fd != -1)
77    {
78      nto_trace ("Closing fd\n");
79      close (nto_inferior.ctl_fd);
80      init_nto_inferior (&nto_inferior);
81    }
82}
83
84/* Set current thread. Return 1 on success, 0 otherwise.  */
85
86static int
87nto_set_thread (ptid_t ptid)
88{
89  int res = 0;
90
91  TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid),
92	 ptid_get_lwp (ptid));
93  if (nto_inferior.ctl_fd != -1
94      && !ptid_equal (ptid, null_ptid)
95      && !ptid_equal (ptid, minus_one_ptid))
96    {
97      pthread_t tid = ptid_get_lwp (ptid);
98
99      if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid,
100	  sizeof (tid), 0))
101	res = 1;
102      else
103	TRACE ("%s: Error: failed to set current thread\n", __func__);
104    }
105  return res;
106}
107
108/* This function will determine all alive threads.  Note that we do not list
109   dead but unjoined threads even though they are still in the process' thread
110   list.
111
112   NTO_INFERIOR must not be NULL.  */
113
114static void
115nto_find_new_threads (struct nto_inferior *nto_inferior)
116{
117  pthread_t tid;
118
119  TRACE ("%s pid:%d\n", __func__, nto_inferior->pid);
120
121  if (nto_inferior->ctl_fd == -1)
122    return;
123
124  for (tid = 1;; ++tid)
125    {
126      procfs_status status;
127      ptid_t ptid;
128      int err;
129
130      status.tid = tid;
131      err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status,
132		    sizeof (status), 0);
133
134      if (err != EOK || status.tid == 0)
135	break;
136
137      /* All threads in between are gone.  */
138      while (tid != status.tid || status.state == STATE_DEAD)
139	{
140	  struct thread_info *ti;
141
142	  ptid = ptid_build (nto_inferior->pid, tid, 0);
143	  ti = find_thread_ptid (ptid);
144	  if (ti != NULL)
145	    {
146	      TRACE ("Removing thread %d\n", tid);
147	      remove_thread (ti);
148	    }
149	  if (tid == status.tid)
150	    break;
151	  ++tid;
152	}
153
154      if (status.state != STATE_DEAD)
155	{
156	  TRACE ("Adding thread %d\n", tid);
157	  ptid = ptid_build (nto_inferior->pid, tid, 0);
158	  if (!find_thread_ptid (ptid))
159	    add_thread (ptid, NULL);
160	}
161    }
162}
163
164/* Given pid, open procfs path.  */
165
166static pid_t
167do_attach (pid_t pid)
168{
169  procfs_status status;
170  struct sigevent event;
171
172  if (nto_inferior.ctl_fd != -1)
173    {
174      close (nto_inferior.ctl_fd);
175      init_nto_inferior (&nto_inferior);
176    }
177  xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid);
178  nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR);
179  if (nto_inferior.ctl_fd == -1)
180    {
181      TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path);
182      init_nto_inferior (&nto_inferior);
183      return -1;
184    }
185  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0)
186      != EOK)
187    {
188      do_detach ();
189      return -1;
190    }
191  nto_inferior.pid = pid;
192  /* Define a sigevent for process stopped notification.  */
193  event.sigev_notify = SIGEV_SIGNAL_THREAD;
194  event.sigev_signo = SIGUSR1;
195  event.sigev_code = 0;
196  event.sigev_value.sival_ptr = NULL;
197  event.sigev_priority = -1;
198  devctl (nto_inferior.ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
199
200  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
201	      0) == EOK
202      && (status.flags & _DEBUG_FLAG_STOPPED))
203    {
204      ptid_t ptid;
205
206      kill (pid, SIGCONT);
207      ptid = ptid_build (status.pid, status.tid, 0);
208      the_low_target.arch_setup ();
209      add_process (status.pid, 1);
210      TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid,
211	     ptid_get_lwp (ptid));
212      nto_find_new_threads (&nto_inferior);
213    }
214  else
215    {
216      do_detach ();
217      return -1;
218    }
219
220  return pid;
221}
222
223/* Read or write LEN bytes from/to inferior's MEMADDR memory address
224   into gdbservers's MYADDR buffer.  Return number of bytes actually
225   transfered.  */
226
227static int
228nto_xfer_memory (off_t memaddr, unsigned char *myaddr, int len,
229		 int dowrite)
230{
231  int nbytes = 0;
232
233  if (lseek (nto_inferior.ctl_fd, memaddr, SEEK_SET) == memaddr)
234    {
235      if (dowrite)
236	nbytes = write (nto_inferior.ctl_fd, myaddr, len);
237      else
238	nbytes = read (nto_inferior.ctl_fd, myaddr, len);
239      if (nbytes < 0)
240	nbytes = 0;
241    }
242  if (nbytes == 0)
243    {
244      int e = errno;
245      TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, strerror (e));
246    }
247  return nbytes;
248}
249
250/* Insert or remove breakpoint or watchpoint at address ADDR.
251   TYPE can be one of Neutrino breakpoint types.  SIZE must be 0 for
252   inserting the point, -1 for removing it.
253
254   Return 0 on success, 1 otherwise.  */
255
256static int
257nto_breakpoint (CORE_ADDR addr, int type, int size)
258{
259  procfs_break brk;
260
261  brk.type = type;
262  brk.addr = addr;
263  brk.size = size;
264  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)
265      != EOK)
266    return 1;
267  return 0;
268}
269
270/* Read auxiliary vector from inferior's initial stack into gdbserver's
271   MYADDR buffer, up to LEN bytes.
272
273   Return number of bytes read.  */
274
275static int
276nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack,
277				  unsigned char *myaddr,
278				  unsigned int len)
279{
280  int data_ofs = 0;
281  int anint;
282  unsigned int len_read = 0;
283
284  /* Skip over argc, argv and envp... Comment from ldd.c:
285
286     The startup frame is set-up so that we have:
287     auxv
288     NULL
289     ...
290     envp2
291     envp1 <----- void *frame + (argc + 2) * sizeof(char *)
292     NULL
293     ...
294     argv2
295     argv1
296     argc  <------ void * frame
297
298     On entry to ldd, frame gives the address of argc on the stack.  */
299  if (nto_xfer_memory (initial_stack, (unsigned char *)&anint,
300		       sizeof (anint), 0) != sizeof (anint))
301    return 0;
302
303  /* Size of pointer is assumed to be 4 bytes (32 bit arch. ) */
304  data_ofs += (anint + 2) * sizeof (void *); /* + 2 comes from argc itself and
305						NULL terminating pointer in
306						argv.  */
307
308  /* Now loop over env table:  */
309  while (nto_xfer_memory (initial_stack + data_ofs,
310			  (unsigned char *)&anint, sizeof (anint), 0)
311	 == sizeof (anint))
312    {
313      data_ofs += sizeof (anint);
314      if (anint == 0)
315	break;
316    }
317  initial_stack += data_ofs;
318
319  memset (myaddr, 0, len);
320  while (len_read <= len - sizeof (auxv_t))
321    {
322      auxv_t *auxv = (auxv_t *)myaddr;
323
324      /* Search backwards until we have read AT_PHDR (num. 3),
325	 AT_PHENT (num 4), AT_PHNUM (num 5)  */
326      if (nto_xfer_memory (initial_stack, (unsigned char *)auxv,
327			   sizeof (auxv_t), 0) == sizeof (auxv_t))
328	{
329	  if (auxv->a_type != AT_NULL)
330	    {
331	      auxv++;
332	      len_read += sizeof (auxv_t);
333	    }
334	  if (auxv->a_type == AT_PHNUM) /* That's all we need.  */
335	    break;
336	  initial_stack += sizeof (auxv_t);
337	}
338      else
339	break;
340    }
341  TRACE ("auxv: len_read: %d\n", len_read);
342  return len_read;
343}
344
345/* Start inferior specified by PROGRAM passing arguments ALLARGS.  */
346
347static int
348nto_create_inferior (char *program, char **allargs)
349{
350  struct inheritance inherit;
351  pid_t pid;
352  sigset_t set;
353
354  TRACE ("%s %s\n", __func__, program);
355  /* Clear any pending SIGUSR1's but keep the behavior the same.  */
356  signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
357
358  sigemptyset (&set);
359  sigaddset (&set, SIGUSR1);
360  sigprocmask (SIG_UNBLOCK, &set, NULL);
361
362  memset (&inherit, 0, sizeof (inherit));
363  inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
364  inherit.pgroup = SPAWN_NEWPGROUP;
365  pid = spawnp (program, 0, NULL, &inherit, allargs, 0);
366  sigprocmask (SIG_BLOCK, &set, NULL);
367
368  if (pid == -1)
369    return -1;
370
371  if (do_attach (pid) != pid)
372    return -1;
373
374  return pid;
375}
376
377/* Attach to process PID.  */
378
379static int
380nto_attach (unsigned long pid)
381{
382  TRACE ("%s %ld\n", __func__, pid);
383  if (do_attach (pid) != pid)
384    error ("Unable to attach to %ld\n", pid);
385  return 0;
386}
387
388/* Send signal to process PID.  */
389
390static int
391nto_kill (int pid)
392{
393  TRACE ("%s %d\n", __func__, pid);
394  kill (pid, SIGKILL);
395  do_detach ();
396  return 0;
397}
398
399/* Detach from process PID.  */
400
401static int
402nto_detach (int pid)
403{
404  TRACE ("%s %d\n", __func__, pid);
405  do_detach ();
406  return 0;
407}
408
409static void
410nto_mourn (struct process_info *process)
411{
412  remove_process (process);
413}
414
415/* Check if the given thread is alive.
416
417   Return 1 if alive, 0 otherwise.  */
418
419static int
420nto_thread_alive (ptid_t ptid)
421{
422  int res;
423
424  TRACE ("%s pid:%d tid:%d\n", __func__, ptid_get_pid (ptid),
425	 ptid_get_lwp (ptid));
426  if (SignalKill (0, ptid_get_pid (ptid), ptid_get_lwp (ptid),
427		  0, 0, 0) == -1)
428    res = 0;
429  else
430    res = 1;
431  TRACE ("%s: %s\n", __func__, res ? "yes" : "no");
432  return res;
433}
434
435/* Resume inferior's execution.  */
436
437static void
438nto_resume (struct thread_resume *resume_info, size_t n)
439{
440  /* We can only work in all-stop mode.  */
441  procfs_status status;
442  procfs_run run;
443  int err;
444
445  TRACE ("%s\n", __func__);
446  /* Workaround for aliasing rules violation. */
447  sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
448
449  nto_set_thread (resume_info->thread);
450
451  run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
452  if (resume_info->kind == resume_step)
453    run.flags |= _DEBUG_RUN_STEP;
454  run.flags |= _DEBUG_RUN_ARM;
455
456  sigemptyset (run_fault);
457  sigaddset (run_fault, FLTBPT);
458  sigaddset (run_fault, FLTTRACE);
459  sigaddset (run_fault, FLTILL);
460  sigaddset (run_fault, FLTPRIV);
461  sigaddset (run_fault, FLTBOUNDS);
462  sigaddset (run_fault, FLTIOVF);
463  sigaddset (run_fault, FLTIZDIV);
464  sigaddset (run_fault, FLTFPE);
465  sigaddset (run_fault, FLTPAGE);
466  sigaddset (run_fault, FLTSTACK);
467  sigaddset (run_fault, FLTACCESS);
468
469  sigemptyset (&run.trace);
470  if (resume_info->sig)
471    {
472      int signal_to_pass;
473
474      devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
475	      0);
476      signal_to_pass = resume_info->sig;
477      if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
478	{
479	  if (signal_to_pass != status.info.si_signo)
480	    {
481	      kill (status.pid, signal_to_pass);
482	      run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
483	    }
484	  else		/* Let it kill the program without telling us.  */
485	    sigdelset (&run.trace, signal_to_pass);
486	}
487    }
488  else
489    run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
490
491  sigfillset (&run.trace);
492
493  regcache_invalidate ();
494
495  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
496  if (err != EOK)
497    TRACE ("Error: %d \"%s\"\n", err, strerror (err));
498}
499
500/* Wait for inferior's event.
501
502   Return ptid of thread that caused the event.  */
503
504static ptid_t
505nto_wait (ptid_t ptid,
506	  struct target_waitstatus *ourstatus, int target_options)
507{
508  sigset_t set;
509  siginfo_t info;
510  procfs_status status;
511  const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
512			  | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);
513
514  TRACE ("%s\n", __func__);
515
516  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
517
518  sigemptyset (&set);
519  sigaddset (&set, SIGUSR1);
520
521  devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
522  while (!(status.flags & _DEBUG_FLAG_ISTOP))
523    {
524      sigwaitinfo (&set, &info);
525      devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
526	      0);
527    }
528  nto_find_new_threads (&nto_inferior);
529
530  if (status.flags & _DEBUG_FLAG_SSTEP)
531    {
532      TRACE ("SSTEP\n");
533      ourstatus->kind = TARGET_WAITKIND_STOPPED;
534      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
535    }
536  /* Was it a breakpoint?  */
537  else if (status.flags & trace_mask)
538    {
539      TRACE ("STOPPED\n");
540      ourstatus->kind = TARGET_WAITKIND_STOPPED;
541      ourstatus->value.sig = TARGET_SIGNAL_TRAP;
542    }
543  else if (status.flags & _DEBUG_FLAG_ISTOP)
544    {
545      TRACE ("ISTOP\n");
546      switch (status.why)
547	{
548	case _DEBUG_WHY_SIGNALLED:
549	  TRACE ("  SIGNALLED\n");
550	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
551	  ourstatus->value.sig =
552	    target_signal_from_host (status.info.si_signo);
553	  nto_inferior.exit_signo = ourstatus->value.sig;
554	  break;
555	case _DEBUG_WHY_FAULTED:
556	  TRACE ("  FAULTED\n");
557	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
558	  if (status.info.si_signo == SIGTRAP)
559	    {
560	      ourstatus->value.sig = 0;
561	      nto_inferior.exit_signo = 0;
562	    }
563	  else
564	    {
565	      ourstatus->value.sig =
566		target_signal_from_host (status.info.si_signo);
567	      nto_inferior.exit_signo = ourstatus->value.sig;
568	    }
569	  break;
570
571	case _DEBUG_WHY_TERMINATED:
572	  {
573	    int waitval = 0;
574
575	    TRACE ("  TERMINATED\n");
576	    waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
577	    if (nto_inferior.exit_signo)
578	      {
579		/* Abnormal death.  */
580		ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
581		ourstatus->value.sig = nto_inferior.exit_signo;
582	      }
583	    else
584	      {
585		/* Normal death.  */
586		ourstatus->kind = TARGET_WAITKIND_EXITED;
587		ourstatus->value.integer = WEXITSTATUS (waitval);
588	      }
589	    nto_inferior.exit_signo = 0;
590	    break;
591	  }
592
593	case _DEBUG_WHY_REQUESTED:
594	  TRACE ("REQUESTED\n");
595	  /* We are assuming a requested stop is due to a SIGINT.  */
596	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
597	  ourstatus->value.sig = TARGET_SIGNAL_INT;
598	  nto_inferior.exit_signo = 0;
599	  break;
600	}
601    }
602
603  return ptid_build (status.pid, status.tid, 0);
604}
605
606/* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR).
607   If REGNO is -1, fetch all registers, or REGNO register only otherwise.  */
608
609static void
610nto_fetch_registers (struct regcache *regcache, int regno)
611{
612  int regsize;
613  procfs_greg greg;
614  ptid_t ptid;
615
616  TRACE ("%s (regno=%d)\n", __func__, regno);
617  if (regno >= the_low_target.num_regs)
618    return;
619
620  if (current_inferior == NULL)
621    {
622      TRACE ("current_inferior is NULL\n");
623      return;
624    }
625  ptid = thread_to_gdb_id (current_inferior);
626  if (!nto_set_thread (ptid))
627    return;
628
629  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg),
630	      &regsize) == EOK)
631    {
632      if (regno == -1) /* All registers. */
633	{
634	  for (regno = 0; regno != the_low_target.num_regs; ++regno)
635	    {
636	      const unsigned int registeroffset
637		= the_low_target.register_offset (regno);
638	      supply_register (regcache, regno,
639			       ((char *)&greg) + registeroffset);
640	    }
641	}
642      else
643	{
644	  const unsigned int registeroffset
645	    = the_low_target.register_offset (regno);
646	  if (registeroffset == -1)
647	    return;
648	  supply_register (regcache, regno, ((char *)&greg) + registeroffset);
649	}
650    }
651  else
652    TRACE ("ERROR reading registers from inferior.\n");
653}
654
655/* Store registers for currently selected thread (CURRENT_INFERIOR).
656   We always store all registers, regardless of REGNO.  */
657
658static void
659nto_store_registers (struct regcache *regcache, int regno)
660{
661  procfs_greg greg;
662  int err;
663  ptid_t ptid;
664
665  TRACE ("%s (regno:%d)\n", __func__, regno);
666
667  if (current_inferior == NULL)
668    {
669      TRACE ("current_inferior is NULL\n");
670      return;
671    }
672  ptid = thread_to_gdb_id (current_inferior);
673  if (!nto_set_thread (ptid))
674    return;
675
676  memset (&greg, 0, sizeof (greg));
677  for  (regno = 0; regno != the_low_target.num_regs; ++regno)
678    {
679      const unsigned int regoffset
680	= the_low_target.register_offset (regno);
681      collect_register (regcache, regno, ((char *)&greg) + regoffset);
682    }
683  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg),
684		0);
685  if (err != EOK)
686    TRACE ("Error: setting registers.\n");
687}
688
689/* Read LEN bytes from inferior's memory address MEMADDR into
690   gdbserver's MYADDR buffer.
691
692   Return 0 on success -1 otherwise.  */
693
694static int
695nto_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
696{
697  TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);
698
699  if (nto_xfer_memory (memaddr, myaddr, len, 0) != len)
700    {
701      TRACE ("Failed to read memory\n");
702      return -1;
703    }
704
705  return 0;
706}
707
708/* Write LEN bytes from gdbserver's buffer MYADDR into inferior's
709   memory at address MEMADDR.
710
711   Return 0 on success -1 otherwise.  */
712
713static int
714nto_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
715{
716  int len_written;
717
718  TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
719  if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len,
720				      1))
721      != len)
722    {
723      TRACE ("Wanted to write: %d but written: %d\n", len, len_written);
724      return -1;
725    }
726
727  return 0;
728}
729
730/* Stop inferior.  We always stop all threads.  */
731
732static void
733nto_request_interrupt (void)
734{
735  TRACE ("%s\n", __func__);
736  nto_set_thread (ptid_build (nto_inferior.pid, 1, 0));
737  if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
738    TRACE ("Error stopping inferior.\n");
739}
740
741/* Read auxiliary vector from inferior's memory into gdbserver's buffer
742   MYADDR.  We always read whole auxv.
743
744   Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0
745   or -1 on error.  */
746
747static int
748nto_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
749{
750  int err;
751  CORE_ADDR initial_stack;
752  procfs_info procinfo;
753
754  TRACE ("%s\n", __func__);
755  if (offset > 0)
756    return 0;
757
758  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo,
759		sizeof procinfo, 0);
760  if (err != EOK)
761    return -1;
762
763  initial_stack = procinfo.initial_stack;
764
765  return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len);
766}
767
768/* Insert {break/watch}point at address ADDR.
769   TYPE must be in '0'..'4' range.  LEN is not used.  */
770
771static int
772nto_insert_point (char type, CORE_ADDR addr, int len)
773{
774  int wtype = _DEBUG_BREAK_HW; /* Always request HW.  */
775
776  TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
777  switch (type)
778    {
779    case '0': /* software-breakpoint */
780      wtype = _DEBUG_BREAK_EXEC;
781      break;
782    case '1': /* hardware-breakpoint */
783      wtype |= _DEBUG_BREAK_EXEC;
784      break;
785    case '2':  /* write watchpoint */
786      wtype |= _DEBUG_BREAK_RW;
787      break;
788    case '3':  /* read watchpoint */
789      wtype |= _DEBUG_BREAK_RD;
790      break;
791    case '4':  /* access watchpoint */
792      wtype |= _DEBUG_BREAK_RW;
793      break;
794    default:
795      return 1; /* Not supported.  */
796    }
797  return nto_breakpoint (addr, wtype, 0);
798}
799
800/* Remove {break/watch}point at address ADDR.
801   TYPE must be in '0'..'4' range.  LEN is not used.  */
802
803static int
804nto_remove_point (char type, CORE_ADDR addr, int len)
805{
806  int wtype = _DEBUG_BREAK_HW; /* Always request HW.  */
807
808  TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
809  switch (type)
810    {
811    case '0': /* software-breakpoint */
812      wtype = _DEBUG_BREAK_EXEC;
813      break;
814    case '1': /* hardware-breakpoint */
815      wtype |= _DEBUG_BREAK_EXEC;
816      break;
817    case '2':  /* write watchpoint */
818      wtype |= _DEBUG_BREAK_RW;
819      break;
820    case '3':  /* read watchpoint */
821      wtype |= _DEBUG_BREAK_RD;
822      break;
823    case '4':  /* access watchpoint */
824      wtype |= _DEBUG_BREAK_RW;
825      break;
826    default:
827      return 1; /* Not supported.  */
828    }
829  return nto_breakpoint (addr, wtype, -1);
830}
831
832/* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
833   a watchpoint.
834
835   Return 1 if stopped by watchpoint, 0 otherwise.  */
836
837static int
838nto_stopped_by_watchpoint (void)
839{
840  int ret = 0;
841
842  TRACE ("%s\n", __func__);
843  if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
844    {
845      ptid_t ptid;
846
847      ptid = thread_to_gdb_id (current_inferior);
848      if (nto_set_thread (ptid))
849	{
850	  const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
851				| _DEBUG_FLAG_TRACE_MODIFY;
852	  procfs_status status;
853	  int err;
854
855	  err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
856			sizeof (status), 0);
857	  if (err == EOK && (status.flags & watchmask))
858	    ret = 1;
859	}
860    }
861  TRACE ("%s: %s\n", __func__, ret ? "yes" : "no");
862  return ret;
863}
864
865/* Get instruction pointer for CURRENT_INFERIOR thread.
866
867   Return inferior's instruction pointer value, or 0 on error.  */
868
869static CORE_ADDR
870nto_stopped_data_address (void)
871{
872  CORE_ADDR ret = (CORE_ADDR)0;
873
874  TRACE ("%s\n", __func__);
875  if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
876    {
877      ptid_t ptid;
878
879      ptid = thread_to_gdb_id (current_inferior);
880
881      if (nto_set_thread (ptid))
882	{
883	  procfs_status status;
884
885	  if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
886		      sizeof (status), 0) == EOK)
887	    ret = status.ip;
888	}
889    }
890  TRACE ("%s: 0x%08lx\n", __func__, ret);
891  return ret;
892}
893
894/* We do not currently support non-stop.  */
895
896static int
897nto_supports_non_stop (void)
898{
899  TRACE ("%s\n", __func__);
900  return 0;
901}
902
903
904
905static struct target_ops nto_target_ops = {
906  nto_create_inferior,
907  nto_attach,
908  nto_kill,
909  nto_detach,
910  nto_mourn,
911  NULL, /* nto_join */
912  nto_thread_alive,
913  nto_resume,
914  nto_wait,
915  nto_fetch_registers,
916  nto_store_registers,
917  NULL, /* prepare_to_access_memory */
918  NULL, /* done_accessing_memory */
919  nto_read_memory,
920  nto_write_memory,
921  NULL, /* nto_look_up_symbols */
922  nto_request_interrupt,
923  nto_read_auxv,
924  nto_insert_point,
925  nto_remove_point,
926  nto_stopped_by_watchpoint,
927  nto_stopped_data_address,
928  NULL, /* nto_read_offsets */
929  NULL, /* thread_db_set_tls_address */
930  NULL,
931  hostio_last_error_from_errno,
932  NULL, /* nto_qxfer_osdata */
933  NULL, /* xfer_siginfo */
934  nto_supports_non_stop,
935  NULL, /* async */
936  NULL  /* start_non_stop */
937};
938
939
940/* Global function called by server.c.  Initializes QNX Neutrino
941   gdbserver.  */
942
943void
944initialize_low (void)
945{
946  sigset_t set;
947
948  TRACE ("%s\n", __func__);
949  set_target_ops (&nto_target_ops);
950  set_breakpoint_data (the_low_target.breakpoint,
951		       the_low_target.breakpoint_len);
952
953  /* We use SIGUSR1 to gain control after we block waiting for a process.
954     We use sigwaitevent to wait.  */
955  sigemptyset (&set);
956  sigaddset (&set, SIGUSR1);
957  sigprocmask (SIG_BLOCK, &set, NULL);
958}
959
960