OSDN Git Service

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