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