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