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