OSDN Git Service

Update copyright year in most headers.
[pf3gnuchains/pf3gnuchains3x.git] / gdb / gdbserver / nto-low.c
1 /* QNX Neutrino specific low level interface, for the remote server
2    for GDB.
3    Copyright (C) 2009, 2010 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
34 extern int using_threads;
35 int using_threads = 1;
36
37 static void
38 nto_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
55 struct 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
63 static struct nto_inferior nto_inferior;
64
65 static void
66 init_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
73 static void
74 do_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
86 static int
87 nto_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
114 static void
115 nto_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
166 static pid_t
167 do_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   snprintf (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
227 static int
228 nto_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
256 static int
257 nto_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
275 static int
276 nto_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
347 static int
348 nto_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
379 static int
380 nto_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
390 static int
391 nto_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
401 static int
402 nto_detach (int pid)
403 {
404   TRACE ("%s %d\n", __func__, pid);
405   do_detach ();
406   return 0;
407 }
408
409 /* Check if the given thread is alive.  
410
411    Return 1 if alive, 0 otherwise.  */
412
413 static int
414 nto_thread_alive (ptid_t ptid)
415 {
416   int res;
417
418   TRACE ("%s pid:%d tid:%d\n", __func__, ptid_get_pid (ptid),
419          ptid_get_lwp (ptid));
420   if (SignalKill (0, ptid_get_pid (ptid), ptid_get_lwp (ptid),
421                   0, 0, 0) == -1)
422     res = 0;
423   else
424     res = 1;
425   TRACE ("%s: %s\n", __func__, res ? "yes" : "no");
426   return res;
427 }
428
429 /* Resume inferior's execution.  */
430
431 static void
432 nto_resume (struct thread_resume *resume_info, size_t n)
433 {
434   /* We can only work in all-stop mode.  */
435   procfs_status status;
436   procfs_run run;
437   int err;
438
439   TRACE ("%s\n", __func__);
440   /* Workaround for aliasing rules violation. */
441   sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
442
443   nto_set_thread (resume_info->thread);
444
445   run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
446   if (resume_info->kind == resume_step)
447     run.flags |= _DEBUG_RUN_STEP;
448   run.flags |= _DEBUG_RUN_ARM;
449
450   sigemptyset (run_fault);
451   sigaddset (run_fault, FLTBPT);
452   sigaddset (run_fault, FLTTRACE);
453   sigaddset (run_fault, FLTILL);
454   sigaddset (run_fault, FLTPRIV);
455   sigaddset (run_fault, FLTBOUNDS);
456   sigaddset (run_fault, FLTIOVF);
457   sigaddset (run_fault, FLTIZDIV);
458   sigaddset (run_fault, FLTFPE);
459   sigaddset (run_fault, FLTPAGE);
460   sigaddset (run_fault, FLTSTACK);
461   sigaddset (run_fault, FLTACCESS);
462
463   sigemptyset (&run.trace);
464   if (resume_info->sig)
465     {
466       int signal_to_pass;
467
468       devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
469               0);
470       signal_to_pass = resume_info->sig;
471       if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
472         {
473           if (signal_to_pass != status.info.si_signo)
474             {
475               kill (status.pid, signal_to_pass);
476               run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
477             }
478           else          /* Let it kill the program without telling us.  */
479             sigdelset (&run.trace, signal_to_pass);
480         }
481     }
482   else
483     run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
484
485   sigfillset (&run.trace);
486
487   regcache_invalidate ();
488
489   err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
490   if (err != EOK)
491     TRACE ("Error: %d \"%s\"\n", err, strerror (err));
492 }
493
494 /* Wait for inferior's event.  
495
496    Return ptid of thread that caused the event.  */
497
498 static ptid_t
499 nto_wait (ptid_t ptid,
500           struct target_waitstatus *ourstatus, int target_options)
501 {
502   sigset_t set;
503   siginfo_t info;
504   procfs_status status;
505   const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
506                           | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);
507
508   TRACE ("%s\n", __func__);
509
510   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
511
512   sigemptyset (&set);
513   sigaddset (&set, SIGUSR1);
514
515   devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
516   while (!(status.flags & _DEBUG_FLAG_ISTOP))
517     {
518       sigwaitinfo (&set, &info);
519       devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
520               0);
521     }
522   nto_find_new_threads (&nto_inferior);
523
524   if (status.flags & _DEBUG_FLAG_SSTEP)
525     {
526       TRACE ("SSTEP\n");
527       ourstatus->kind = TARGET_WAITKIND_STOPPED;
528       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
529     }
530   /* Was it a breakpoint?  */
531   else if (status.flags & trace_mask)
532     {
533       TRACE ("STOPPED\n");
534       ourstatus->kind = TARGET_WAITKIND_STOPPED;
535       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
536     }
537   else if (status.flags & _DEBUG_FLAG_ISTOP)
538     {
539       TRACE ("ISTOP\n");
540       switch (status.why)
541         {
542         case _DEBUG_WHY_SIGNALLED:
543           TRACE ("  SIGNALLED\n");
544           ourstatus->kind = TARGET_WAITKIND_STOPPED;
545           ourstatus->value.sig =
546             target_signal_from_host (status.info.si_signo);
547           nto_inferior.exit_signo = ourstatus->value.sig;
548           break;
549         case _DEBUG_WHY_FAULTED:
550           TRACE ("  FAULTED\n");
551           ourstatus->kind = TARGET_WAITKIND_STOPPED;
552           if (status.info.si_signo == SIGTRAP)
553             {
554               ourstatus->value.sig = 0;
555               nto_inferior.exit_signo = 0;
556             }
557           else
558             {
559               ourstatus->value.sig =
560                 target_signal_from_host (status.info.si_signo);
561               nto_inferior.exit_signo = ourstatus->value.sig;
562             }
563           break;
564
565         case _DEBUG_WHY_TERMINATED:
566           {
567             int waitval = 0;
568
569             TRACE ("  TERMINATED\n");
570             waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
571             if (nto_inferior.exit_signo)
572               {
573                 /* Abnormal death.  */
574                 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
575                 ourstatus->value.sig = nto_inferior.exit_signo;
576               }
577             else
578               {
579                 /* Normal death.  */
580                 ourstatus->kind = TARGET_WAITKIND_EXITED;
581                 ourstatus->value.integer = WEXITSTATUS (waitval);
582               }
583             nto_inferior.exit_signo = 0;
584             break;
585           }
586
587         case _DEBUG_WHY_REQUESTED:
588           TRACE ("REQUESTED\n");
589           /* We are assuming a requested stop is due to a SIGINT.  */
590           ourstatus->kind = TARGET_WAITKIND_STOPPED;
591           ourstatus->value.sig = TARGET_SIGNAL_INT;
592           nto_inferior.exit_signo = 0;
593           break;
594         }
595     }
596
597   return ptid_build (status.pid, status.tid, 0);
598 }
599
600 /* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR).
601    If REGNO is -1, fetch all registers, or REGNO register only otherwise.  */
602
603 static void
604 nto_fetch_registers (int regno)
605 {
606   int regsize;
607   procfs_greg greg;
608   ptid_t ptid;
609
610   TRACE ("%s (regno=%d)\n", __func__, regno);
611   if (regno >= the_low_target.num_regs)
612     return;
613
614   if (current_inferior == NULL)
615     {
616       TRACE ("current_inferior is NULL\n");
617       return;
618     }
619   ptid = thread_to_gdb_id (current_inferior);
620   if (!nto_set_thread (ptid))
621     return;
622
623   if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg),
624               &regsize) == EOK)
625     {
626       if (regno == -1) /* All registers. */
627         {
628           for (regno = 0; regno != the_low_target.num_regs; ++regno)
629             {
630               const unsigned int registeroffset
631                 = the_low_target.register_offset (regno);
632               supply_register (regno, ((char *)&greg) + registeroffset);
633             }
634         }
635       else
636         {
637           const unsigned int registeroffset
638             = the_low_target.register_offset (regno);
639           if (registeroffset == -1)
640             return;
641           supply_register (regno, ((char *)&greg) + registeroffset);
642         }
643     }
644   else
645     TRACE ("ERROR reading registers from inferior.\n");
646 }
647
648 /* Store registers for currently selected thread (CURRENT_INFERIOR).  
649    We always store all registers, regardless of REGNO.  */
650
651 static void
652 nto_store_registers (int regno)
653 {
654   procfs_greg greg;
655   int err;
656   ptid_t ptid;
657
658   TRACE ("%s (regno:%d)\n", __func__, regno);
659
660   if (current_inferior == NULL)
661     {
662       TRACE ("current_inferior is NULL\n");
663       return;
664     }
665   ptid = thread_to_gdb_id (current_inferior);
666   if (!nto_set_thread (ptid))
667     return;
668
669   memset (&greg, 0, sizeof (greg));
670   for  (regno = 0; regno != the_low_target.num_regs; ++regno)
671     {
672       const unsigned int regoffset
673         = the_low_target.register_offset (regno);
674       collect_register (regno, ((char *)&greg) + regoffset);
675     }
676   err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg),
677                 0);
678   if (err != EOK)
679     TRACE ("Error: setting registers.\n");
680 }
681
682 /* Read LEN bytes from inferior's memory address MEMADDR into
683    gdbserver's MYADDR buffer.  
684
685    Return 0 on success -1 otherwise.  */
686
687 static int
688 nto_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
689 {
690   TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);
691
692   if (nto_xfer_memory (memaddr, myaddr, len, 0) != len)
693     {
694       TRACE ("Failed to read memory\n");
695       return -1;
696     }
697
698   return 0;
699 }
700
701 /* Write LEN bytes from gdbserver's buffer MYADDR into inferior's
702    memory at address MEMADDR.  
703
704    Return 0 on success -1 otherwise.  */
705
706 static int
707 nto_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
708 {
709   int len_written;
710
711   TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
712   if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len,
713                                       1))
714       != len)
715     {
716       TRACE ("Wanted to write: %d but written: %d\n", len, len_written);
717       return -1;
718     }
719
720   return 0;
721 }
722
723 /* Stop inferior.  We always stop all threads.  */
724
725 static void
726 nto_request_interrupt (void)
727 {
728   TRACE ("%s\n", __func__);
729   nto_set_thread (ptid_build (nto_inferior.pid, 1, 0));
730   if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
731     TRACE ("Error stopping inferior.\n");
732 }
733
734 /* Read auxiliary vector from inferior's memory into gdbserver's buffer
735    MYADDR.  We always read whole auxv.  
736    
737    Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0
738    or -1 on error.  */
739
740 static int
741 nto_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
742 {
743   int err;
744   CORE_ADDR initial_stack;
745   procfs_info procinfo;
746
747   TRACE ("%s\n", __func__);
748   if (offset > 0)
749     return 0;
750
751   err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo,
752                 sizeof procinfo, 0);
753   if (err != EOK)
754     return -1;
755
756   initial_stack = procinfo.initial_stack;
757
758   return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len);
759 }
760
761 /* Insert {break/watch}point at address ADDR.
762    TYPE must be in '0'..'4' range.  LEN is not used.  */
763
764 static int
765 nto_insert_point (char type, CORE_ADDR addr, int len)
766 {
767   int wtype = _DEBUG_BREAK_HW; /* Always request HW.  */
768
769   TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
770   switch (type)
771     {
772     case '0': /* software-breakpoint */
773       wtype = _DEBUG_BREAK_EXEC;
774       break;
775     case '1': /* hardware-breakpoint */
776       wtype |= _DEBUG_BREAK_EXEC;
777       break;
778     case '2':  /* write watchpoint */
779       wtype |= _DEBUG_BREAK_RW;
780       break;
781     case '3':  /* read watchpoint */
782       wtype |= _DEBUG_BREAK_RD;
783       break;
784     case '4':  /* access watchpoint */
785       wtype |= _DEBUG_BREAK_RW;
786       break;
787     default:
788       return 1; /* Not supported.  */
789     }
790   return nto_breakpoint (addr, wtype, 0);
791 }
792
793 /* Remove {break/watch}point at address ADDR.
794    TYPE must be in '0'..'4' range.  LEN is not used.  */
795
796 static int
797 nto_remove_point (char type, CORE_ADDR addr, int len)
798 {
799   int wtype = _DEBUG_BREAK_HW; /* Always request HW.  */
800
801   TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
802   switch (type)
803     {
804     case '0': /* software-breakpoint */
805       wtype = _DEBUG_BREAK_EXEC;
806       break;
807     case '1': /* hardware-breakpoint */
808       wtype |= _DEBUG_BREAK_EXEC;
809       break;
810     case '2':  /* write watchpoint */
811       wtype |= _DEBUG_BREAK_RW;
812       break;
813     case '3':  /* read watchpoint */
814       wtype |= _DEBUG_BREAK_RD;
815       break;
816     case '4':  /* access watchpoint */
817       wtype |= _DEBUG_BREAK_RW;
818       break;
819     default:
820       return 1; /* Not supported.  */
821     }
822   return nto_breakpoint (addr, wtype, -1);
823 }
824
825 /* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
826    a watchpoint.
827
828    Return 1 if stopped by watchpoint, 0 otherwise.  */
829
830 static int
831 nto_stopped_by_watchpoint (void)
832 {
833   int ret = 0;
834
835   TRACE ("%s\n", __func__);
836   if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
837     {
838       ptid_t ptid;
839
840       ptid = thread_to_gdb_id (current_inferior);
841       if (nto_set_thread (ptid))
842         {
843           const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
844                                 | _DEBUG_FLAG_TRACE_MODIFY;
845           procfs_status status;
846           int err;
847
848           err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
849                         sizeof (status), 0);
850           if (err == EOK && (status.flags & watchmask))
851             ret = 1;
852         }
853     }
854   TRACE ("%s: %s\n", __func__, ret ? "yes" : "no");
855   return ret;
856 }
857
858 /* Get instruction pointer for CURRENT_INFERIOR thread.  
859
860    Return inferior's instruction pointer value, or 0 on error.  */ 
861
862 static CORE_ADDR
863 nto_stopped_data_address (void)
864 {
865   CORE_ADDR ret = (CORE_ADDR)0;
866
867   TRACE ("%s\n", __func__);
868   if (nto_inferior.ctl_fd != -1 && current_inferior != NULL)
869     {
870       ptid_t ptid;
871
872       ptid = thread_to_gdb_id (current_inferior);
873
874       if (nto_set_thread (ptid))
875         {
876           procfs_status status;
877
878           if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
879                       sizeof (status), 0) == EOK)
880             ret = status.ip;
881         }
882     }
883   TRACE ("%s: 0x%08lx\n", __func__, ret);
884   return ret;
885 }
886
887 /* We do not currently support non-stop.  */
888
889 static int
890 nto_supports_non_stop (void)
891 {
892   TRACE ("%s\n", __func__);
893   return 0;
894 }
895
896
897
898 static struct target_ops nto_target_ops = {
899   nto_create_inferior,
900   nto_attach,
901   nto_kill,
902   nto_detach,
903   NULL, /* nto_join */
904   nto_thread_alive,
905   nto_resume,
906   nto_wait,
907   nto_fetch_registers,
908   nto_store_registers,
909   nto_read_memory,
910   nto_write_memory,
911   NULL, /* nto_look_up_symbols */
912   nto_request_interrupt,
913   nto_read_auxv,
914   nto_insert_point,
915   nto_remove_point,
916   nto_stopped_by_watchpoint,
917   nto_stopped_data_address,
918   NULL, /* nto_read_offsets */
919   NULL, /* thread_db_set_tls_address */
920   NULL,
921   hostio_last_error_from_errno,
922   NULL, /* nto_qxfer_osdata */
923   NULL, /* xfer_siginfo */
924   nto_supports_non_stop,
925   NULL, /* async */
926   NULL  /* start_non_stop */
927 };
928
929
930 /* Global function called by server.c.  Initializes QNX Neutrino
931    gdbserver.  */
932
933 void
934 initialize_low (void)
935 {
936   sigset_t set;
937
938   TRACE ("%s\n", __func__);
939   set_target_ops (&nto_target_ops);
940   set_breakpoint_data (the_low_target.breakpoint,
941                        the_low_target.breakpoint_len);
942
943   /* We use SIGUSR1 to gain control after we block waiting for a process.
944      We use sigwaitevent to wait.  */
945   sigemptyset (&set);
946   sigaddset (&set, SIGUSR1);
947   sigprocmask (SIG_BLOCK, &set, NULL);
948 }
949