Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / gdbserver / nto-low.c
CommitLineData
ac8c974e
AR
1/* QNX Neutrino specific low level interface, for the remote server
2 for GDB.
32d0add0 3 Copyright (C) 2009-2015 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"
ac8c974e
AR
25
26#include <limits.h>
27#include <fcntl.h>
28#include <spawn.h>
29#include <sys/procfs.h>
30#include <sys/auxv.h>
ac8c974e
AR
31#include <sys/iomgr.h>
32#include <sys/neutrino.h>
33
34
35extern int using_threads;
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
94 TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid),
95 ptid_get_lwp (ptid));
96 if (nto_inferior.ctl_fd != -1
97 && !ptid_equal (ptid, null_ptid)
98 && !ptid_equal (ptid, minus_one_ptid))
99 {
100 pthread_t tid = ptid_get_lwp (ptid);
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
145 ptid = ptid_build (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_build (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
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);
211 ptid = ptid_build (status.pid, status.tid, 0);
212 the_low_target.arch_setup ();
3aee8918
PA
213 proc = add_process (status.pid, 1);
214 proc->tdesc = nto_tdesc;
ac8c974e
AR
215 TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid,
216 ptid_get_lwp (ptid));
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;
250 TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, 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
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
350/* Start inferior specified by PROGRAM passing arguments ALLARGS. */
351
352static int
353nto_create_inferior (char *program, char **allargs)
354{
355 struct inheritance inherit;
356 pid_t pid;
357 sigset_t set;
358
359 TRACE ("%s %s\n", __func__, program);
360 /* Clear any pending SIGUSR1's but keep the behavior the same. */
361 signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
362
363 sigemptyset (&set);
364 sigaddset (&set, SIGUSR1);
365 sigprocmask (SIG_UNBLOCK, &set, NULL);
366
367 memset (&inherit, 0, sizeof (inherit));
368 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
369 inherit.pgroup = SPAWN_NEWPGROUP;
370 pid = spawnp (program, 0, NULL, &inherit, allargs, 0);
371 sigprocmask (SIG_BLOCK, &set, NULL);
372
373 if (pid == -1)
374 return -1;
375
376 if (do_attach (pid) != pid)
377 return -1;
378
379 return pid;
380}
381
382/* Attach to process PID. */
383
384static int
385nto_attach (unsigned long pid)
386{
387 TRACE ("%s %ld\n", __func__, pid);
388 if (do_attach (pid) != pid)
389 error ("Unable to attach to %ld\n", pid);
390 return 0;
391}
392
393/* Send signal to process PID. */
394
395static int
396nto_kill (int pid)
397{
398 TRACE ("%s %d\n", __func__, pid);
399 kill (pid, SIGKILL);
400 do_detach ();
401 return 0;
402}
403
404/* Detach from process PID. */
405
406static int
407nto_detach (int pid)
408{
409 TRACE ("%s %d\n", __func__, pid);
410 do_detach ();
411 return 0;
412}
413
505106cd
PA
414static void
415nto_mourn (struct process_info *process)
416{
417 remove_process (process);
418}
419
ac8c974e
AR
420/* Check if the given thread is alive.
421
422 Return 1 if alive, 0 otherwise. */
423
424static int
425nto_thread_alive (ptid_t ptid)
426{
427 int res;
428
429 TRACE ("%s pid:%d tid:%d\n", __func__, ptid_get_pid (ptid),
430 ptid_get_lwp (ptid));
431 if (SignalKill (0, ptid_get_pid (ptid), ptid_get_lwp (ptid),
432 0, 0, 0) == -1)
433 res = 0;
434 else
435 res = 1;
436 TRACE ("%s: %s\n", __func__, res ? "yes" : "no");
437 return res;
438}
439
440/* Resume inferior's execution. */
441
442static void
443nto_resume (struct thread_resume *resume_info, size_t n)
444{
445 /* We can only work in all-stop mode. */
446 procfs_status status;
447 procfs_run run;
448 int err;
449
450 TRACE ("%s\n", __func__);
451 /* Workaround for aliasing rules violation. */
452 sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
453
454 nto_set_thread (resume_info->thread);
455
456 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
457 if (resume_info->kind == resume_step)
458 run.flags |= _DEBUG_RUN_STEP;
459 run.flags |= _DEBUG_RUN_ARM;
460
461 sigemptyset (run_fault);
462 sigaddset (run_fault, FLTBPT);
463 sigaddset (run_fault, FLTTRACE);
464 sigaddset (run_fault, FLTILL);
465 sigaddset (run_fault, FLTPRIV);
466 sigaddset (run_fault, FLTBOUNDS);
467 sigaddset (run_fault, FLTIOVF);
468 sigaddset (run_fault, FLTIZDIV);
469 sigaddset (run_fault, FLTFPE);
470 sigaddset (run_fault, FLTPAGE);
471 sigaddset (run_fault, FLTSTACK);
472 sigaddset (run_fault, FLTACCESS);
473
474 sigemptyset (&run.trace);
475 if (resume_info->sig)
476 {
477 int signal_to_pass;
478
479 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
480 0);
481 signal_to_pass = resume_info->sig;
482 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
483 {
484 if (signal_to_pass != status.info.si_signo)
485 {
486 kill (status.pid, signal_to_pass);
487 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
488 }
489 else /* Let it kill the program without telling us. */
490 sigdelset (&run.trace, signal_to_pass);
491 }
492 }
493 else
494 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
495
496 sigfillset (&run.trace);
497
498 regcache_invalidate ();
499
500 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
501 if (err != EOK)
502 TRACE ("Error: %d \"%s\"\n", err, strerror (err));
503}
504
505/* Wait for inferior's event.
506
507 Return ptid of thread that caused the event. */
508
509static ptid_t
510nto_wait (ptid_t ptid,
511 struct target_waitstatus *ourstatus, int target_options)
512{
513 sigset_t set;
514 siginfo_t info;
515 procfs_status status;
516 const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
517 | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);
518
519 TRACE ("%s\n", __func__);
520
521 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
522
523 sigemptyset (&set);
524 sigaddset (&set, SIGUSR1);
525
526 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
527 while (!(status.flags & _DEBUG_FLAG_ISTOP))
528 {
529 sigwaitinfo (&set, &info);
530 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
531 0);
532 }
533 nto_find_new_threads (&nto_inferior);
534
535 if (status.flags & _DEBUG_FLAG_SSTEP)
536 {
537 TRACE ("SSTEP\n");
538 ourstatus->kind = TARGET_WAITKIND_STOPPED;
a493e3e2 539 ourstatus->value.sig = GDB_SIGNAL_TRAP;
ac8c974e
AR
540 }
541 /* Was it a breakpoint? */
542 else if (status.flags & trace_mask)
543 {
544 TRACE ("STOPPED\n");
545 ourstatus->kind = TARGET_WAITKIND_STOPPED;
a493e3e2 546 ourstatus->value.sig = GDB_SIGNAL_TRAP;
ac8c974e
AR
547 }
548 else if (status.flags & _DEBUG_FLAG_ISTOP)
549 {
550 TRACE ("ISTOP\n");
551 switch (status.why)
552 {
553 case _DEBUG_WHY_SIGNALLED:
554 TRACE (" SIGNALLED\n");
555 ourstatus->kind = TARGET_WAITKIND_STOPPED;
556 ourstatus->value.sig =
2ea28649 557 gdb_signal_from_host (status.info.si_signo);
ac8c974e
AR
558 nto_inferior.exit_signo = ourstatus->value.sig;
559 break;
560 case _DEBUG_WHY_FAULTED:
561 TRACE (" FAULTED\n");
562 ourstatus->kind = TARGET_WAITKIND_STOPPED;
563 if (status.info.si_signo == SIGTRAP)
564 {
565 ourstatus->value.sig = 0;
566 nto_inferior.exit_signo = 0;
567 }
568 else
569 {
570 ourstatus->value.sig =
2ea28649 571 gdb_signal_from_host (status.info.si_signo);
ac8c974e
AR
572 nto_inferior.exit_signo = ourstatus->value.sig;
573 }
574 break;
575
576 case _DEBUG_WHY_TERMINATED:
577 {
578 int waitval = 0;
579
580 TRACE (" TERMINATED\n");
581 waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
582 if (nto_inferior.exit_signo)
583 {
584 /* Abnormal death. */
585 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
586 ourstatus->value.sig = nto_inferior.exit_signo;
587 }
588 else
589 {
590 /* Normal death. */
591 ourstatus->kind = TARGET_WAITKIND_EXITED;
592 ourstatus->value.integer = WEXITSTATUS (waitval);
593 }
594 nto_inferior.exit_signo = 0;
595 break;
596 }
597
598 case _DEBUG_WHY_REQUESTED:
599 TRACE ("REQUESTED\n");
600 /* We are assuming a requested stop is due to a SIGINT. */
601 ourstatus->kind = TARGET_WAITKIND_STOPPED;
a493e3e2 602 ourstatus->value.sig = GDB_SIGNAL_INT;
ac8c974e
AR
603 nto_inferior.exit_signo = 0;
604 break;
605 }
606 }
607
608 return ptid_build (status.pid, status.tid, 0);
609}
610
611/* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR).
612 If REGNO is -1, fetch all registers, or REGNO register only otherwise. */
613
614static void
442ea881 615nto_fetch_registers (struct regcache *regcache, int regno)
ac8c974e
AR
616{
617 int regsize;
618 procfs_greg greg;
619 ptid_t ptid;
620
621 TRACE ("%s (regno=%d)\n", __func__, regno);
622 if (regno >= the_low_target.num_regs)
623 return;
624
0bfdf32f 625 if (current_thread == NULL)
ac8c974e 626 {
0bfdf32f 627 TRACE ("current_thread is NULL\n");
ac8c974e
AR
628 return;
629 }
0bfdf32f 630 ptid = thread_to_gdb_id (current_thread);
ac8c974e
AR
631 if (!nto_set_thread (ptid))
632 return;
633
634 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg),
635 &regsize) == EOK)
636 {
637 if (regno == -1) /* All registers. */
638 {
639 for (regno = 0; regno != the_low_target.num_regs; ++regno)
640 {
641 const unsigned int registeroffset
642 = the_low_target.register_offset (regno);
493e2a69
MS
643 supply_register (regcache, regno,
644 ((char *)&greg) + registeroffset);
ac8c974e
AR
645 }
646 }
647 else
648 {
649 const unsigned int registeroffset
650 = the_low_target.register_offset (regno);
651 if (registeroffset == -1)
652 return;
442ea881 653 supply_register (regcache, regno, ((char *)&greg) + registeroffset);
ac8c974e
AR
654 }
655 }
656 else
657 TRACE ("ERROR reading registers from inferior.\n");
658}
659
660/* Store registers for currently selected thread (CURRENT_INFERIOR).
661 We always store all registers, regardless of REGNO. */
662
663static void
442ea881 664nto_store_registers (struct regcache *regcache, int regno)
ac8c974e
AR
665{
666 procfs_greg greg;
667 int err;
668 ptid_t ptid;
669
670 TRACE ("%s (regno:%d)\n", __func__, regno);
671
0bfdf32f 672 if (current_thread == NULL)
ac8c974e 673 {
0bfdf32f 674 TRACE ("current_thread is NULL\n");
ac8c974e
AR
675 return;
676 }
0bfdf32f 677 ptid = thread_to_gdb_id (current_thread);
ac8c974e
AR
678 if (!nto_set_thread (ptid))
679 return;
680
681 memset (&greg, 0, sizeof (greg));
682 for (regno = 0; regno != the_low_target.num_regs; ++regno)
683 {
684 const unsigned int regoffset
685 = the_low_target.register_offset (regno);
442ea881 686 collect_register (regcache, regno, ((char *)&greg) + regoffset);
ac8c974e
AR
687 }
688 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg),
689 0);
690 if (err != EOK)
691 TRACE ("Error: setting registers.\n");
692}
693
694/* Read LEN bytes from inferior's memory address MEMADDR into
695 gdbserver's MYADDR buffer.
696
697 Return 0 on success -1 otherwise. */
698
699static int
700nto_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
701{
702 TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);
703
704 if (nto_xfer_memory (memaddr, myaddr, len, 0) != len)
705 {
706 TRACE ("Failed to read memory\n");
707 return -1;
708 }
709
710 return 0;
711}
712
713/* Write LEN bytes from gdbserver's buffer MYADDR into inferior's
714 memory at address MEMADDR.
715
716 Return 0 on success -1 otherwise. */
717
718static int
719nto_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
720{
721 int len_written;
722
723 TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
724 if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len,
725 1))
726 != len)
727 {
728 TRACE ("Wanted to write: %d but written: %d\n", len, len_written);
729 return -1;
730 }
731
732 return 0;
733}
734
735/* Stop inferior. We always stop all threads. */
736
737static void
738nto_request_interrupt (void)
739{
740 TRACE ("%s\n", __func__);
741 nto_set_thread (ptid_build (nto_inferior.pid, 1, 0));
742 if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
743 TRACE ("Error stopping inferior.\n");
744}
745
746/* Read auxiliary vector from inferior's memory into gdbserver's buffer
747 MYADDR. We always read whole auxv.
748
749 Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0
750 or -1 on error. */
751
752static int
753nto_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
754{
755 int err;
756 CORE_ADDR initial_stack;
757 procfs_info procinfo;
758
759 TRACE ("%s\n", __func__);
760 if (offset > 0)
761 return 0;
762
763 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo,
764 sizeof procinfo, 0);
765 if (err != EOK)
766 return -1;
767
768 initial_stack = procinfo.initial_stack;
769
770 return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len);
771}
772
802e8e6d
PA
773static int
774nto_supports_z_point_type (char z_type)
775{
776 switch (z_type)
777 {
778 case Z_PACKET_SW_BP:
779 case Z_PACKET_HW_BP:
780 case Z_PACKET_WRITE_WP:
781 case Z_PACKET_READ_WP:
782 case Z_PACKET_ACCESS_WP:
783 return 1;
784 default:
785 return 0;
786 }
787}
788
789/* Insert {break/watch}point at address ADDR. SIZE is not used. */
ac8c974e
AR
790
791static int
802e8e6d
PA
792nto_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
793 int size, struct raw_breakpoint *bp)
ac8c974e
AR
794{
795 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
796
797 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
798 switch (type)
799 {
802e8e6d 800 case raw_bkpt_type_sw:
ac8c974e
AR
801 wtype = _DEBUG_BREAK_EXEC;
802 break;
802e8e6d 803 case raw_bkpt_type_hw:
ac8c974e
AR
804 wtype |= _DEBUG_BREAK_EXEC;
805 break;
802e8e6d 806 case raw_bkpt_type_write_wp:
ac8c974e
AR
807 wtype |= _DEBUG_BREAK_RW;
808 break;
802e8e6d 809 case raw_bkpt_type_read_wp:
ac8c974e
AR
810 wtype |= _DEBUG_BREAK_RD;
811 break;
802e8e6d 812 case raw_bkpt_type_access_wp:
ac8c974e
AR
813 wtype |= _DEBUG_BREAK_RW;
814 break;
815 default:
816 return 1; /* Not supported. */
817 }
818 return nto_breakpoint (addr, wtype, 0);
819}
820
802e8e6d 821/* Remove {break/watch}point at address ADDR. SIZE is not used. */
ac8c974e
AR
822
823static int
802e8e6d
PA
824nto_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
825 int size, struct raw_breakpoint *bp)
ac8c974e
AR
826{
827 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
828
829 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len);
830 switch (type)
831 {
802e8e6d 832 case raw_bkpt_type_sw:
ac8c974e
AR
833 wtype = _DEBUG_BREAK_EXEC;
834 break;
802e8e6d 835 case raw_bkpt_type_hw:
ac8c974e
AR
836 wtype |= _DEBUG_BREAK_EXEC;
837 break;
802e8e6d 838 case raw_bkpt_type_write_wp:
ac8c974e
AR
839 wtype |= _DEBUG_BREAK_RW;
840 break;
802e8e6d 841 case raw_bkpt_type_read_wp:
ac8c974e
AR
842 wtype |= _DEBUG_BREAK_RD;
843 break;
802e8e6d 844 case raw_bkpt_type_access_wp:
ac8c974e
AR
845 wtype |= _DEBUG_BREAK_RW;
846 break;
847 default:
848 return 1; /* Not supported. */
849 }
850 return nto_breakpoint (addr, wtype, -1);
851}
852
853/* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
854 a watchpoint.
855
856 Return 1 if stopped by watchpoint, 0 otherwise. */
857
858static int
859nto_stopped_by_watchpoint (void)
860{
861 int ret = 0;
862
863 TRACE ("%s\n", __func__);
0bfdf32f 864 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
ac8c974e
AR
865 {
866 ptid_t ptid;
867
0bfdf32f 868 ptid = thread_to_gdb_id (current_thread);
ac8c974e
AR
869 if (nto_set_thread (ptid))
870 {
871 const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
872 | _DEBUG_FLAG_TRACE_MODIFY;
873 procfs_status status;
874 int err;
875
876 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
877 sizeof (status), 0);
878 if (err == EOK && (status.flags & watchmask))
879 ret = 1;
880 }
881 }
882 TRACE ("%s: %s\n", __func__, ret ? "yes" : "no");
883 return ret;
884}
885
886/* Get instruction pointer for CURRENT_INFERIOR thread.
887
888 Return inferior's instruction pointer value, or 0 on error. */
889
890static CORE_ADDR
891nto_stopped_data_address (void)
892{
893 CORE_ADDR ret = (CORE_ADDR)0;
894
895 TRACE ("%s\n", __func__);
0bfdf32f 896 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
ac8c974e
AR
897 {
898 ptid_t ptid;
899
0bfdf32f 900 ptid = thread_to_gdb_id (current_thread);
ac8c974e
AR
901
902 if (nto_set_thread (ptid))
903 {
904 procfs_status status;
905
906 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
907 sizeof (status), 0) == EOK)
908 ret = status.ip;
909 }
910 }
911 TRACE ("%s: 0x%08lx\n", __func__, ret);
912 return ret;
913}
914
915/* We do not currently support non-stop. */
916
917static int
918nto_supports_non_stop (void)
919{
920 TRACE ("%s\n", __func__);
921 return 0;
922}
923
924
925
926static struct target_ops nto_target_ops = {
927 nto_create_inferior,
928 nto_attach,
929 nto_kill,
930 nto_detach,
505106cd 931 nto_mourn,
ac8c974e
AR
932 NULL, /* nto_join */
933 nto_thread_alive,
934 nto_resume,
935 nto_wait,
936 nto_fetch_registers,
937 nto_store_registers,
90d74c30 938 NULL, /* prepare_to_access_memory */
0146f85b 939 NULL, /* done_accessing_memory */
ac8c974e
AR
940 nto_read_memory,
941 nto_write_memory,
942 NULL, /* nto_look_up_symbols */
943 nto_request_interrupt,
944 nto_read_auxv,
802e8e6d 945 nto_supports_z_point_type,
ac8c974e
AR
946 nto_insert_point,
947 nto_remove_point,
948 nto_stopped_by_watchpoint,
949 nto_stopped_data_address,
950 NULL, /* nto_read_offsets */
951 NULL, /* thread_db_set_tls_address */
952 NULL,
953 hostio_last_error_from_errno,
954 NULL, /* nto_qxfer_osdata */
955 NULL, /* xfer_siginfo */
956 nto_supports_non_stop,
957 NULL, /* async */
958 NULL /* start_non_stop */
959};
960
961
962/* Global function called by server.c. Initializes QNX Neutrino
963 gdbserver. */
964
965void
966initialize_low (void)
967{
968 sigset_t set;
969
970 TRACE ("%s\n", __func__);
971 set_target_ops (&nto_target_ops);
972 set_breakpoint_data (the_low_target.breakpoint,
973 the_low_target.breakpoint_len);
974
975 /* We use SIGUSR1 to gain control after we block waiting for a process.
976 We use sigwaitevent to wait. */
977 sigemptyset (&set);
978 sigaddset (&set, SIGUSR1);
979 sigprocmask (SIG_BLOCK, &set, NULL);
980}
981
This page took 0.586042 seconds and 4 git commands to generate.