gdbserver: turn target ops 'multifs_{open, readlink, unlink}' into methods
[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;
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
ef03dad8
TBA
388int
389nto_process_target::attach (unsigned long pid)
ac8c974e
AR
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
c6885a57
TBA
399int
400nto_process_target::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
9061c9cf
TBA
412int
413nto_process_target::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
8adb37b9
TBA
420void
421nto_process_target::mourn (struct process_info *process)
505106cd
PA
422{
423 remove_process (process);
424}
425
95a49a39
TBA
426void
427nto_process_target::join (int pid)
428{
429 error (_("nto target does not implement the join op"));
430}
431
ac8c974e
AR
432/* Check if the given thread is alive.
433
13d3d99b 434 Return true if alive, false otherwise. */
ac8c974e 435
13d3d99b
TBA
436bool
437nto_process_target::thread_alive (ptid_t ptid)
ac8c974e
AR
438{
439 int res;
440
e99b03dc 441 TRACE ("%s pid:%d tid:%d\n", __func__, ptid.pid (),
e38504b3
TT
442 ptid.lwp ());
443 if (SignalKill (0, ptid.pid (), ptid.lwp (),
ac8c974e
AR
444 0, 0, 0) == -1)
445 res = 0;
446 else
447 res = 1;
448 TRACE ("%s: %s\n", __func__, res ? "yes" : "no");
449 return res;
450}
451
452/* Resume inferior's execution. */
453
0e4d7e35
TBA
454void
455nto_process_target::resume (thread_resume *resume_info, size_t n)
ac8c974e
AR
456{
457 /* We can only work in all-stop mode. */
458 procfs_status status;
459 procfs_run run;
460 int err;
461
462 TRACE ("%s\n", __func__);
463 /* Workaround for aliasing rules violation. */
464 sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
465
466 nto_set_thread (resume_info->thread);
467
468 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
469 if (resume_info->kind == resume_step)
470 run.flags |= _DEBUG_RUN_STEP;
471 run.flags |= _DEBUG_RUN_ARM;
472
473 sigemptyset (run_fault);
474 sigaddset (run_fault, FLTBPT);
475 sigaddset (run_fault, FLTTRACE);
476 sigaddset (run_fault, FLTILL);
477 sigaddset (run_fault, FLTPRIV);
478 sigaddset (run_fault, FLTBOUNDS);
479 sigaddset (run_fault, FLTIOVF);
480 sigaddset (run_fault, FLTIZDIV);
481 sigaddset (run_fault, FLTFPE);
482 sigaddset (run_fault, FLTPAGE);
483 sigaddset (run_fault, FLTSTACK);
484 sigaddset (run_fault, FLTACCESS);
485
486 sigemptyset (&run.trace);
487 if (resume_info->sig)
488 {
489 int signal_to_pass;
490
491 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
492 0);
493 signal_to_pass = resume_info->sig;
494 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
495 {
496 if (signal_to_pass != status.info.si_signo)
497 {
498 kill (status.pid, signal_to_pass);
499 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
500 }
501 else /* Let it kill the program without telling us. */
502 sigdelset (&run.trace, signal_to_pass);
503 }
504 }
505 else
506 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
507
508 sigfillset (&run.trace);
509
510 regcache_invalidate ();
511
512 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
513 if (err != EOK)
6d91ce9a 514 TRACE ("Error: %d \"%s\"\n", err, safe_strerror (err));
ac8c974e
AR
515}
516
517/* Wait for inferior's event.
518
519 Return ptid of thread that caused the event. */
520
6532e7e3
TBA
521ptid_t
522nto_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
523 int target_options)
ac8c974e
AR
524{
525 sigset_t set;
526 siginfo_t info;
527 procfs_status status;
528 const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
529 | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);
530
531 TRACE ("%s\n", __func__);
532
533 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
534
535 sigemptyset (&set);
536 sigaddset (&set, SIGUSR1);
537
538 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
539 while (!(status.flags & _DEBUG_FLAG_ISTOP))
540 {
541 sigwaitinfo (&set, &info);
542 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
543 0);
544 }
545 nto_find_new_threads (&nto_inferior);
546
547 if (status.flags & _DEBUG_FLAG_SSTEP)
548 {
549 TRACE ("SSTEP\n");
550 ourstatus->kind = TARGET_WAITKIND_STOPPED;
a493e3e2 551 ourstatus->value.sig = GDB_SIGNAL_TRAP;
ac8c974e
AR
552 }
553 /* Was it a breakpoint? */
554 else if (status.flags & trace_mask)
555 {
556 TRACE ("STOPPED\n");
557 ourstatus->kind = TARGET_WAITKIND_STOPPED;
a493e3e2 558 ourstatus->value.sig = GDB_SIGNAL_TRAP;
ac8c974e
AR
559 }
560 else if (status.flags & _DEBUG_FLAG_ISTOP)
561 {
562 TRACE ("ISTOP\n");
563 switch (status.why)
564 {
565 case _DEBUG_WHY_SIGNALLED:
566 TRACE (" SIGNALLED\n");
567 ourstatus->kind = TARGET_WAITKIND_STOPPED;
568 ourstatus->value.sig =
2ea28649 569 gdb_signal_from_host (status.info.si_signo);
ac8c974e
AR
570 nto_inferior.exit_signo = ourstatus->value.sig;
571 break;
572 case _DEBUG_WHY_FAULTED:
573 TRACE (" FAULTED\n");
574 ourstatus->kind = TARGET_WAITKIND_STOPPED;
575 if (status.info.si_signo == SIGTRAP)
576 {
577 ourstatus->value.sig = 0;
578 nto_inferior.exit_signo = 0;
579 }
580 else
581 {
582 ourstatus->value.sig =
2ea28649 583 gdb_signal_from_host (status.info.si_signo);
ac8c974e
AR
584 nto_inferior.exit_signo = ourstatus->value.sig;
585 }
586 break;
587
588 case _DEBUG_WHY_TERMINATED:
589 {
590 int waitval = 0;
591
592 TRACE (" TERMINATED\n");
e99b03dc 593 waitpid (ptid.pid (), &waitval, WNOHANG);
ac8c974e
AR
594 if (nto_inferior.exit_signo)
595 {
596 /* Abnormal death. */
597 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
598 ourstatus->value.sig = nto_inferior.exit_signo;
599 }
600 else
601 {
602 /* Normal death. */
603 ourstatus->kind = TARGET_WAITKIND_EXITED;
604 ourstatus->value.integer = WEXITSTATUS (waitval);
605 }
606 nto_inferior.exit_signo = 0;
607 break;
608 }
609
610 case _DEBUG_WHY_REQUESTED:
611 TRACE ("REQUESTED\n");
612 /* We are assuming a requested stop is due to a SIGINT. */
613 ourstatus->kind = TARGET_WAITKIND_STOPPED;
a493e3e2 614 ourstatus->value.sig = GDB_SIGNAL_INT;
ac8c974e
AR
615 nto_inferior.exit_signo = 0;
616 break;
617 }
618 }
619
fd79271b 620 return ptid_t (status.pid, status.tid, 0);
ac8c974e
AR
621}
622
623/* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR).
624 If REGNO is -1, fetch all registers, or REGNO register only otherwise. */
625
a5a4d4cd
TBA
626void
627nto_process_target::fetch_registers (regcache *regcache, int regno)
ac8c974e
AR
628{
629 int regsize;
630 procfs_greg greg;
ac8c974e
AR
631
632 TRACE ("%s (regno=%d)\n", __func__, regno);
633 if (regno >= the_low_target.num_regs)
634 return;
635
0bfdf32f 636 if (current_thread == NULL)
ac8c974e 637 {
0bfdf32f 638 TRACE ("current_thread is NULL\n");
ac8c974e
AR
639 return;
640 }
124aceb4 641 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
642 if (!nto_set_thread (ptid))
643 return;
644
645 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg),
646 &regsize) == EOK)
647 {
648 if (regno == -1) /* All registers. */
649 {
650 for (regno = 0; regno != the_low_target.num_regs; ++regno)
651 {
652 const unsigned int registeroffset
653 = the_low_target.register_offset (regno);
493e2a69
MS
654 supply_register (regcache, regno,
655 ((char *)&greg) + registeroffset);
ac8c974e
AR
656 }
657 }
658 else
659 {
660 const unsigned int registeroffset
661 = the_low_target.register_offset (regno);
662 if (registeroffset == -1)
663 return;
442ea881 664 supply_register (regcache, regno, ((char *)&greg) + registeroffset);
ac8c974e
AR
665 }
666 }
667 else
668 TRACE ("ERROR reading registers from inferior.\n");
669}
670
671/* Store registers for currently selected thread (CURRENT_INFERIOR).
672 We always store all registers, regardless of REGNO. */
673
a5a4d4cd
TBA
674void
675nto_process_target::store_registers (regcache *regcache, int regno)
ac8c974e
AR
676{
677 procfs_greg greg;
678 int err;
ac8c974e
AR
679
680 TRACE ("%s (regno:%d)\n", __func__, regno);
681
0bfdf32f 682 if (current_thread == NULL)
ac8c974e 683 {
0bfdf32f 684 TRACE ("current_thread is NULL\n");
ac8c974e
AR
685 return;
686 }
124aceb4 687 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
688 if (!nto_set_thread (ptid))
689 return;
690
691 memset (&greg, 0, sizeof (greg));
692 for (regno = 0; regno != the_low_target.num_regs; ++regno)
693 {
694 const unsigned int regoffset
695 = the_low_target.register_offset (regno);
442ea881 696 collect_register (regcache, regno, ((char *)&greg) + regoffset);
ac8c974e
AR
697 }
698 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg),
699 0);
700 if (err != EOK)
701 TRACE ("Error: setting registers.\n");
702}
703
704/* Read LEN bytes from inferior's memory address MEMADDR into
705 gdbserver's MYADDR buffer.
706
707 Return 0 on success -1 otherwise. */
708
e2558df3
TBA
709int
710nto_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
711 int len)
ac8c974e
AR
712{
713 TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);
714
715 if (nto_xfer_memory (memaddr, myaddr, len, 0) != len)
716 {
717 TRACE ("Failed to read memory\n");
718 return -1;
719 }
720
721 return 0;
722}
723
724/* Write LEN bytes from gdbserver's buffer MYADDR into inferior's
725 memory at address MEMADDR.
726
727 Return 0 on success -1 otherwise. */
728
e2558df3
TBA
729int
730nto_process_target::write_memory (CORE_ADDR memaddr,
731 const unsigned char *myaddr, int len)
ac8c974e
AR
732{
733 int len_written;
734
735 TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
736 if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len,
737 1))
738 != len)
739 {
740 TRACE ("Wanted to write: %d but written: %d\n", len, len_written);
741 return -1;
742 }
743
744 return 0;
745}
746
747/* Stop inferior. We always stop all threads. */
748
eb497a2a
TBA
749void
750nto_process_target::request_interrupt ()
ac8c974e
AR
751{
752 TRACE ("%s\n", __func__);
fd79271b 753 nto_set_thread (ptid_t (nto_inferior.pid, 1, 0));
ac8c974e
AR
754 if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
755 TRACE ("Error stopping inferior.\n");
756}
757
eac215cc
TBA
758bool
759nto_process_target::supports_read_auxv ()
760{
761 return true;
762}
763
ac8c974e
AR
764/* Read auxiliary vector from inferior's memory into gdbserver's buffer
765 MYADDR. We always read whole auxv.
766
767 Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0
768 or -1 on error. */
769
eac215cc
TBA
770int
771nto_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr,
772 unsigned int len)
ac8c974e
AR
773{
774 int err;
775 CORE_ADDR initial_stack;
776 procfs_info procinfo;
777
778 TRACE ("%s\n", __func__);
779 if (offset > 0)
780 return 0;
781
782 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo,
783 sizeof procinfo, 0);
784 if (err != EOK)
785 return -1;
786
787 initial_stack = procinfo.initial_stack;
788
789 return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len);
790}
791
a2b2297a
TBA
792bool
793nto_process_target::supports_z_point_type (char z_type)
802e8e6d
PA
794{
795 switch (z_type)
796 {
797 case Z_PACKET_SW_BP:
798 case Z_PACKET_HW_BP:
799 case Z_PACKET_WRITE_WP:
800 case Z_PACKET_READ_WP:
801 case Z_PACKET_ACCESS_WP:
a2b2297a 802 return true;
802e8e6d 803 default:
a2b2297a 804 return false;
802e8e6d
PA
805 }
806}
807
808/* Insert {break/watch}point at address ADDR. SIZE is not used. */
ac8c974e 809
7e0bde70
TBA
810int
811nto_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
812 int size, raw_breakpoint *bp)
ac8c974e
AR
813{
814 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
815
774ee6d2 816 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
ac8c974e
AR
817 switch (type)
818 {
802e8e6d 819 case raw_bkpt_type_sw:
ac8c974e
AR
820 wtype = _DEBUG_BREAK_EXEC;
821 break;
802e8e6d 822 case raw_bkpt_type_hw:
ac8c974e
AR
823 wtype |= _DEBUG_BREAK_EXEC;
824 break;
802e8e6d 825 case raw_bkpt_type_write_wp:
ac8c974e
AR
826 wtype |= _DEBUG_BREAK_RW;
827 break;
802e8e6d 828 case raw_bkpt_type_read_wp:
ac8c974e
AR
829 wtype |= _DEBUG_BREAK_RD;
830 break;
802e8e6d 831 case raw_bkpt_type_access_wp:
ac8c974e
AR
832 wtype |= _DEBUG_BREAK_RW;
833 break;
834 default:
835 return 1; /* Not supported. */
836 }
837 return nto_breakpoint (addr, wtype, 0);
838}
839
802e8e6d 840/* Remove {break/watch}point at address ADDR. SIZE is not used. */
ac8c974e 841
7e0bde70
TBA
842int
843nto_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
844 int size, raw_breakpoint *bp)
ac8c974e
AR
845{
846 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
847
774ee6d2 848 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
ac8c974e
AR
849 switch (type)
850 {
802e8e6d 851 case raw_bkpt_type_sw:
ac8c974e
AR
852 wtype = _DEBUG_BREAK_EXEC;
853 break;
802e8e6d 854 case raw_bkpt_type_hw:
ac8c974e
AR
855 wtype |= _DEBUG_BREAK_EXEC;
856 break;
802e8e6d 857 case raw_bkpt_type_write_wp:
ac8c974e
AR
858 wtype |= _DEBUG_BREAK_RW;
859 break;
802e8e6d 860 case raw_bkpt_type_read_wp:
ac8c974e
AR
861 wtype |= _DEBUG_BREAK_RD;
862 break;
802e8e6d 863 case raw_bkpt_type_access_wp:
ac8c974e
AR
864 wtype |= _DEBUG_BREAK_RW;
865 break;
866 default:
867 return 1; /* Not supported. */
868 }
869 return nto_breakpoint (addr, wtype, -1);
870}
871
22aa6223
TBA
872bool
873nto_process_target::supports_hardware_single_step ()
874{
875 return true;
876}
877
ac8c974e
AR
878/* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
879 a watchpoint.
880
6eeb5c55 881 Return true if stopped by watchpoint, false otherwise. */
ac8c974e 882
6eeb5c55
TBA
883bool
884nto_process_target::stopped_by_watchpoint ()
ac8c974e 885{
6eeb5c55 886 bool ret = false;
ac8c974e
AR
887
888 TRACE ("%s\n", __func__);
0bfdf32f 889 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
ac8c974e 890 {
124aceb4 891 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
892 if (nto_set_thread (ptid))
893 {
894 const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
895 | _DEBUG_FLAG_TRACE_MODIFY;
896 procfs_status status;
897 int err;
898
899 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
900 sizeof (status), 0);
901 if (err == EOK && (status.flags & watchmask))
6eeb5c55 902 ret = true;
ac8c974e
AR
903 }
904 }
905 TRACE ("%s: %s\n", __func__, ret ? "yes" : "no");
906 return ret;
907}
908
909/* Get instruction pointer for CURRENT_INFERIOR thread.
910
911 Return inferior's instruction pointer value, or 0 on error. */
912
6eeb5c55
TBA
913CORE_ADDR
914nto_process_target::stopped_data_address ()
ac8c974e
AR
915{
916 CORE_ADDR ret = (CORE_ADDR)0;
917
918 TRACE ("%s\n", __func__);
0bfdf32f 919 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
ac8c974e 920 {
124aceb4 921 ptid_t ptid = ptid_of (current_thread);
ac8c974e
AR
922
923 if (nto_set_thread (ptid))
924 {
925 procfs_status status;
926
927 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
928 sizeof (status), 0) == EOK)
929 ret = status.ip;
930 }
931 }
932 TRACE ("%s: 0x%08lx\n", __func__, ret);
933 return ret;
934}
935
fb78e89c
AT
936/* Implementation of the target_ops method "sw_breakpoint_from_kind". */
937
938static const gdb_byte *
939nto_sw_breakpoint_from_kind (int kind, int *size)
940{
941 *size = the_low_target.breakpoint_len;
942 return the_low_target.breakpoint;
943}
ac8c974e 944
5ef9273d
TBA
945/* The QNX Neutrino target ops object. */
946
947static nto_process_target the_nto_target;
ac8c974e 948
5b6d1e4f 949static process_stratum_target nto_target_ops = {
fb78e89c
AT
950 NULL, /* breakpoint_kind_from_pc */
951 nto_sw_breakpoint_from_kind,
5ef9273d
TBA
952 NULL, /* thread_name */
953 NULL, /* breakpoint_kind_from_current_state */
954 NULL, /* supports_software_single_step */
955 NULL, /* supports_catch_syscall */
956 NULL, /* get_ipa_tdesc_idx */
957 NULL, /* thread_handle */
958 &the_nto_target,
ac8c974e
AR
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);
ac8c974e
AR
972
973 /* We use SIGUSR1 to gain control after we block waiting for a process.
974 We use sigwaitevent to wait. */
975 sigemptyset (&set);
976 sigaddset (&set, SIGUSR1);
977 sigprocmask (SIG_BLOCK, &set, NULL);
978}
979
This page took 1.041193 seconds and 4 git commands to generate.