gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdbserver / nto-low.cc
CommitLineData
ac8c974e
AR
1/* QNX Neutrino specific low level interface, for the remote server
2 for GDB.
b811d2c2 3 Copyright (C) 2009-2020 Free Software Foundation, Inc.
ac8c974e
AR
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"
623b6bdf 22#include "gdbthread.h"
ac8c974e 23#include "nto-low.h"
533b0600 24#include "hostio.h"
f9d949fb 25#include "debug.h"
ac8c974e
AR
26
27#include <limits.h>
28#include <fcntl.h>
29#include <spawn.h>
30#include <sys/procfs.h>
31#include <sys/auxv.h>
ac8c974e
AR
32#include <sys/iomgr.h>
33#include <sys/neutrino.h>
34
35
ac8c974e
AR
36int using_threads = 1;
37
3aee8918
PA
38const struct target_desc *nto_tdesc;
39
ac8c974e
AR
40static void
41nto_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
58struct 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
66static struct nto_inferior nto_inferior;
67
68static void
69init_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
76static void
77do_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
89static int
90nto_set_thread (ptid_t ptid)
91{
92 int res = 0;
93
e99b03dc 94 TRACE ("%s pid: %d tid: %ld\n", __func__, ptid.pid (),
e38504b3 95 ptid.lwp ());
ac8c974e 96 if (nto_inferior.ctl_fd != -1
d7e15655
TT
97 && ptid != null_ptid
98 && ptid != minus_one_ptid)
ac8c974e 99 {
e38504b3 100 pthread_t tid = ptid.lwp ();
ac8c974e
AR
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
117static void
118nto_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
fd79271b 145 ptid = ptid_t (nto_inferior->pid, tid, 0);
ac8c974e
AR
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);
fd79271b 160 ptid = ptid_t (nto_inferior->pid, tid, 0);
ac8c974e
AR
161 if (!find_thread_ptid (ptid))
162 add_thread (ptid, NULL);
163 }
164 }
165}
166
167/* Given pid, open procfs path. */
168
169static pid_t
170do_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 }
6cebaf6e 180 xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid);
ac8c974e
AR
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;
3aee8918 208 struct process_info *proc;
ac8c974e
AR
209
210 kill (pid, SIGCONT);
fd79271b 211 ptid = ptid_t (status.pid, status.tid, 0);
ac8c974e 212 the_low_target.arch_setup ();
3aee8918
PA
213 proc = add_process (status.pid, 1);
214 proc->tdesc = nto_tdesc;
ac8c974e 215 TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid,
e38504b3 216 ptid.lwp ());
ac8c974e
AR
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
232static int
233nto_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;
6d91ce9a 250 TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, safe_strerror (e));
ac8c974e
AR
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
261static int
262nto_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
280static int
281nto_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
2090129c
SDJ
350/* Start inferior specified by PROGRAM, using PROGRAM_ARGS as its
351 arguments. */
ac8c974e 352
15295543
TBA
353int
354nto_process_target::create_inferior (const char *program,
355 const std::vector<char *> &program_args)
ac8c974e
AR
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;
2090129c 372 pid = spawnp (program, 0, NULL, &inherit,
ace6b919 373 program_args.data (), 0);
ac8c974e
AR
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
ef03dad8
TBA
387int
388nto_process_target::attach (unsigned long pid)
ac8c974e
AR
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
c6885a57
TBA
398int
399nto_process_target::kill (process_info *proc)
ac8c974e 400{
a780ef4f
PA
401 int pid = proc->pid;
402
ac8c974e
AR
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
9061c9cf
TBA
411int
412nto_process_target::detach (process_info *proc)
ac8c974e 413{
ef2ddb33 414 TRACE ("%s %d\n", __func__, proc->pid);
ac8c974e
AR
415 do_detach ();
416 return 0;
417}
418
8adb37b9
TBA
419void
420nto_process_target::mourn (struct process_info *process)
505106cd
PA
421{
422 remove_process (process);
423}
424
95a49a39
TBA
425void
426nto_process_target::join (int pid)
427{
428 error (_("nto target does not implement the join op"));
429}
430
ac8c974e
AR
431/* Check if the given thread is alive.
432
13d3d99b 433 Return true if alive, false otherwise. */
ac8c974e 434
13d3d99b
TBA
435bool
436nto_process_target::thread_alive (ptid_t ptid)
ac8c974e
AR
437{
438 int res;
439
e99b03dc 440 TRACE ("%s pid:%d tid:%d\n", __func__, ptid.pid (),
e38504b3
TT
441 ptid.lwp ());
442 if (SignalKill (0, ptid.pid (), ptid.lwp (),
ac8c974e
AR
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
0e4d7e35
TBA
453void
454nto_process_target::resume (thread_resume *resume_info, size_t n)
ac8c974e
AR
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)
6d91ce9a 513 TRACE ("Error: %d \"%s\"\n", err, safe_strerror (err));
ac8c974e
AR
514}
515
516/* Wait for inferior's event.
517
518 Return ptid of thread that caused the event. */
519
6532e7e3
TBA
520ptid_t
521nto_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
522 int target_options)
ac8c974e
AR
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;
a493e3e2 550 ourstatus->value.sig = GDB_SIGNAL_TRAP;
ac8c974e
AR
551 }
552 /* Was it a breakpoint? */
553 else if (status.flags & trace_mask)
554 {
555 TRACE ("STOPPED\n");
556 ourstatus->kind = TARGET_WAITKIND_STOPPED;
a493e3e2 557 ourstatus->value.sig = GDB_SIGNAL_TRAP;
ac8c974e
AR
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 =
2ea28649 568 gdb_signal_from_host (status.info.si_signo);
ac8c974e
AR
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 =
2ea28649 582 gdb_signal_from_host (status.info.si_signo);
ac8c974e
AR
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");
e99b03dc 592 waitpid (ptid.pid (), &waitval, WNOHANG);
ac8c974e
AR
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;
a493e3e2 613 ourstatus->value.sig = GDB_SIGNAL_INT;
ac8c974e
AR
614 nto_inferior.exit_signo = 0;
615 break;
616 }
617 }
618
fd79271b 619 return ptid_t (status.pid, status.tid, 0);
ac8c974e
AR
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
a5a4d4cd
TBA
625void
626nto_process_target::fetch_registers (regcache *regcache, int regno)
ac8c974e
AR
627{
628 int regsize;
629 procfs_greg greg;
ac8c974e
AR
630
631 TRACE ("%s (regno=%d)\n", __func__, regno);
632 if (regno >= the_low_target.num_regs)
633 return;
634
0bfdf32f 635 if (current_thread == NULL)
ac8c974e 636 {
0bfdf32f 637 TRACE ("current_thread is NULL\n");
ac8c974e
AR
638 return;
639 }
124aceb4 640 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
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);
493e2a69
MS
653 supply_register (regcache, regno,
654 ((char *)&greg) + registeroffset);
ac8c974e
AR
655 }
656 }
657 else
658 {
659 const unsigned int registeroffset
660 = the_low_target.register_offset (regno);
661 if (registeroffset == -1)
662 return;
442ea881 663 supply_register (regcache, regno, ((char *)&greg) + registeroffset);
ac8c974e
AR
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
a5a4d4cd
TBA
673void
674nto_process_target::store_registers (regcache *regcache, int regno)
ac8c974e
AR
675{
676 procfs_greg greg;
677 int err;
ac8c974e
AR
678
679 TRACE ("%s (regno:%d)\n", __func__, regno);
680
0bfdf32f 681 if (current_thread == NULL)
ac8c974e 682 {
0bfdf32f 683 TRACE ("current_thread is NULL\n");
ac8c974e
AR
684 return;
685 }
124aceb4 686 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
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);
442ea881 695 collect_register (regcache, regno, ((char *)&greg) + regoffset);
ac8c974e
AR
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
e2558df3
TBA
708int
709nto_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
710 int len)
ac8c974e
AR
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
e2558df3
TBA
728int
729nto_process_target::write_memory (CORE_ADDR memaddr,
730 const unsigned char *myaddr, int len)
ac8c974e
AR
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
eb497a2a
TBA
748void
749nto_process_target::request_interrupt ()
ac8c974e
AR
750{
751 TRACE ("%s\n", __func__);
fd79271b 752 nto_set_thread (ptid_t (nto_inferior.pid, 1, 0));
ac8c974e
AR
753 if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
754 TRACE ("Error stopping inferior.\n");
755}
756
eac215cc
TBA
757bool
758nto_process_target::supports_read_auxv ()
759{
760 return true;
761}
762
ac8c974e
AR
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
eac215cc
TBA
769int
770nto_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr,
771 unsigned int len)
ac8c974e
AR
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
a2b2297a
TBA
791bool
792nto_process_target::supports_z_point_type (char z_type)
802e8e6d
PA
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:
a2b2297a 801 return true;
802e8e6d 802 default:
a2b2297a 803 return false;
802e8e6d
PA
804 }
805}
806
807/* Insert {break/watch}point at address ADDR. SIZE is not used. */
ac8c974e 808
7e0bde70
TBA
809int
810nto_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
811 int size, raw_breakpoint *bp)
ac8c974e
AR
812{
813 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
814
774ee6d2 815 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
ac8c974e
AR
816 switch (type)
817 {
802e8e6d 818 case raw_bkpt_type_sw:
ac8c974e
AR
819 wtype = _DEBUG_BREAK_EXEC;
820 break;
802e8e6d 821 case raw_bkpt_type_hw:
ac8c974e
AR
822 wtype |= _DEBUG_BREAK_EXEC;
823 break;
802e8e6d 824 case raw_bkpt_type_write_wp:
ac8c974e
AR
825 wtype |= _DEBUG_BREAK_RW;
826 break;
802e8e6d 827 case raw_bkpt_type_read_wp:
ac8c974e
AR
828 wtype |= _DEBUG_BREAK_RD;
829 break;
802e8e6d 830 case raw_bkpt_type_access_wp:
ac8c974e
AR
831 wtype |= _DEBUG_BREAK_RW;
832 break;
833 default:
834 return 1; /* Not supported. */
835 }
836 return nto_breakpoint (addr, wtype, 0);
837}
838
802e8e6d 839/* Remove {break/watch}point at address ADDR. SIZE is not used. */
ac8c974e 840
7e0bde70
TBA
841int
842nto_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
843 int size, raw_breakpoint *bp)
ac8c974e
AR
844{
845 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
846
774ee6d2 847 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
ac8c974e
AR
848 switch (type)
849 {
802e8e6d 850 case raw_bkpt_type_sw:
ac8c974e
AR
851 wtype = _DEBUG_BREAK_EXEC;
852 break;
802e8e6d 853 case raw_bkpt_type_hw:
ac8c974e
AR
854 wtype |= _DEBUG_BREAK_EXEC;
855 break;
802e8e6d 856 case raw_bkpt_type_write_wp:
ac8c974e
AR
857 wtype |= _DEBUG_BREAK_RW;
858 break;
802e8e6d 859 case raw_bkpt_type_read_wp:
ac8c974e
AR
860 wtype |= _DEBUG_BREAK_RD;
861 break;
802e8e6d 862 case raw_bkpt_type_access_wp:
ac8c974e
AR
863 wtype |= _DEBUG_BREAK_RW;
864 break;
865 default:
866 return 1; /* Not supported. */
867 }
868 return nto_breakpoint (addr, wtype, -1);
869}
870
22aa6223
TBA
871bool
872nto_process_target::supports_hardware_single_step ()
873{
874 return true;
875}
876
ac8c974e
AR
877/* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
878 a watchpoint.
879
6eeb5c55 880 Return true if stopped by watchpoint, false otherwise. */
ac8c974e 881
6eeb5c55
TBA
882bool
883nto_process_target::stopped_by_watchpoint ()
ac8c974e 884{
6eeb5c55 885 bool ret = false;
ac8c974e
AR
886
887 TRACE ("%s\n", __func__);
0bfdf32f 888 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
ac8c974e 889 {
124aceb4 890 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
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))
6eeb5c55 901 ret = true;
ac8c974e
AR
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
6eeb5c55
TBA
912CORE_ADDR
913nto_process_target::stopped_data_address ()
ac8c974e
AR
914{
915 CORE_ADDR ret = (CORE_ADDR)0;
916
917 TRACE ("%s\n", __func__);
0bfdf32f 918 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
ac8c974e 919 {
124aceb4 920 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
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
fb78e89c
AT
935/* Implementation of the target_ops method "sw_breakpoint_from_kind". */
936
d367006f
TBA
937const gdb_byte *
938nto_process_target::sw_breakpoint_from_kind (int kind, int *size)
fb78e89c
AT
939{
940 *size = the_low_target.breakpoint_len;
941 return the_low_target.breakpoint;
942}
ac8c974e 943
5ef9273d
TBA
944/* The QNX Neutrino target ops object. */
945
946static nto_process_target the_nto_target;
ac8c974e 947
ac8c974e
AR
948/* Global function called by server.c. Initializes QNX Neutrino
949 gdbserver. */
950
951void
952initialize_low (void)
953{
954 sigset_t set;
955
956 TRACE ("%s\n", __func__);
52405d85 957 set_target_ops (&the_nto_target);
ac8c974e
AR
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.944735 seconds and 4 git commands to generate.