1 /* QNX Neutrino specific low level interface, for the remote server
3 Copyright (C) 2009-2018 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "gdbthread.h"
29 #include <sys/procfs.h>
31 #include <sys/iomgr.h>
32 #include <sys/neutrino.h>
35 extern int using_threads;
36 int using_threads = 1;
38 const struct target_desc *nto_tdesc;
41 nto_trace (const char *fmt, ...)
45 if (debug_threads == 0)
47 fprintf (stderr, "nto:");
48 va_start (arg_list, fmt);
49 vfprintf (stderr, fmt, arg_list);
53 #define TRACE nto_trace
55 /* Structure holding neutrino specific information about
60 char nto_procfs_path[PATH_MAX];
63 int exit_signo; /* For tracking exit status. */
66 static struct nto_inferior nto_inferior;
69 init_nto_inferior (struct nto_inferior *nto_inferior)
71 memset (nto_inferior, 0, sizeof (struct nto_inferior));
72 nto_inferior->ctl_fd = -1;
73 nto_inferior->pid = -1;
79 if (nto_inferior.ctl_fd != -1)
81 nto_trace ("Closing fd\n");
82 close (nto_inferior.ctl_fd);
83 init_nto_inferior (&nto_inferior);
87 /* Set current thread. Return 1 on success, 0 otherwise. */
90 nto_set_thread (ptid_t ptid)
94 TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid),
96 if (nto_inferior.ctl_fd != -1
97 && !ptid_equal (ptid, null_ptid)
98 && !ptid_equal (ptid, minus_one_ptid))
100 pthread_t tid = ptid_get_lwp (ptid);
102 if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid,
106 TRACE ("%s: Error: failed to set current thread\n", __func__);
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
115 NTO_INFERIOR must not be NULL. */
118 nto_find_new_threads (struct nto_inferior *nto_inferior)
122 TRACE ("%s pid:%d\n", __func__, nto_inferior->pid);
124 if (nto_inferior->ctl_fd == -1)
127 for (tid = 1;; ++tid)
129 procfs_status status;
134 err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status,
137 if (err != EOK || status.tid == 0)
140 /* All threads in between are gone. */
141 while (tid != status.tid || status.state == STATE_DEAD)
143 struct thread_info *ti;
145 ptid = ptid_build (nto_inferior->pid, tid, 0);
146 ti = find_thread_ptid (ptid);
149 TRACE ("Removing thread %d\n", tid);
152 if (tid == status.tid)
157 if (status.state != STATE_DEAD)
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);
167 /* Given pid, open procfs path. */
170 do_attach (pid_t pid)
172 procfs_status status;
173 struct sigevent event;
175 if (nto_inferior.ctl_fd != -1)
177 close (nto_inferior.ctl_fd);
178 init_nto_inferior (&nto_inferior);
180 xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid);
181 nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR);
182 if (nto_inferior.ctl_fd == -1)
184 TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path);
185 init_nto_inferior (&nto_inferior);
188 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0)
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);
203 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
205 && (status.flags & _DEBUG_FLAG_STOPPED))
208 struct process_info *proc;
211 ptid = ptid_build (status.pid, status.tid, 0);
212 the_low_target.arch_setup ();
213 proc = add_process (status.pid, 1);
214 proc->tdesc = nto_tdesc;
215 TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid,
216 ptid_get_lwp (ptid));
217 nto_find_new_threads (&nto_inferior);
228 /* Read or write LEN bytes from/to inferior's MEMADDR memory address
229 into gdbservers's MYADDR buffer. Return number of bytes actually
233 nto_xfer_memory (off_t memaddr, unsigned char *myaddr, int len,
238 if (lseek (nto_inferior.ctl_fd, memaddr, SEEK_SET) == memaddr)
241 nbytes = write (nto_inferior.ctl_fd, myaddr, len);
243 nbytes = read (nto_inferior.ctl_fd, myaddr, len);
250 TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, strerror (e));
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.
259 Return 0 on success, 1 otherwise. */
262 nto_breakpoint (CORE_ADDR addr, int type, int size)
269 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)
275 /* Read auxiliary vector from inferior's initial stack into gdbserver's
276 MYADDR buffer, up to LEN bytes.
278 Return number of bytes read. */
281 nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack,
282 unsigned char *myaddr,
287 unsigned int len_read = 0;
289 /* Skip over argc, argv and envp... Comment from ldd.c:
291 The startup frame is set-up so that we have:
296 envp1 <----- void *frame + (argc + 2) * sizeof(char *)
301 argc <------ void * frame
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))
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
313 /* Now loop over env table: */
314 while (nto_xfer_memory (initial_stack + data_ofs,
315 (unsigned char *)&anint, sizeof (anint), 0)
318 data_ofs += sizeof (anint);
322 initial_stack += data_ofs;
324 memset (myaddr, 0, len);
325 while (len_read <= len - sizeof (auxv_t))
327 auxv_t *auxv = (auxv_t *)myaddr;
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))
334 if (auxv->a_type != AT_NULL)
337 len_read += sizeof (auxv_t);
339 if (auxv->a_type == AT_PHNUM) /* That's all we need. */
341 initial_stack += sizeof (auxv_t);
346 TRACE ("auxv: len_read: %d\n", len_read);
350 /* Start inferior specified by PROGRAM, using PROGRAM_ARGS as its
354 nto_create_inferior (const char *program,
355 const std::vector<char *> &program_args)
357 struct inheritance inherit;
360 std::string str_program_args = stringify_argv (program_args);
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));
367 sigaddset (&set, SIGUSR1);
368 sigprocmask (SIG_UNBLOCK, &set, NULL);
370 memset (&inherit, 0, sizeof (inherit));
371 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
372 inherit.pgroup = SPAWN_NEWPGROUP;
373 pid = spawnp (program, 0, NULL, &inherit,
374 (char *) str_program_args.c_str (), 0);
375 sigprocmask (SIG_BLOCK, &set, NULL);
380 if (do_attach (pid) != pid)
386 /* Attach to process PID. */
389 nto_attach (unsigned long pid)
391 TRACE ("%s %ld\n", __func__, pid);
392 if (do_attach (pid) != pid)
393 error ("Unable to attach to %ld\n", pid);
397 /* Send signal to process PID. */
402 TRACE ("%s %d\n", __func__, pid);
408 /* Detach from process PID. */
413 TRACE ("%s %d\n", __func__, pid);
419 nto_mourn (struct process_info *process)
421 remove_process (process);
424 /* Check if the given thread is alive.
426 Return 1 if alive, 0 otherwise. */
429 nto_thread_alive (ptid_t ptid)
433 TRACE ("%s pid:%d tid:%d\n", __func__, ptid_get_pid (ptid),
434 ptid_get_lwp (ptid));
435 if (SignalKill (0, ptid_get_pid (ptid), ptid_get_lwp (ptid),
440 TRACE ("%s: %s\n", __func__, res ? "yes" : "no");
444 /* Resume inferior's execution. */
447 nto_resume (struct thread_resume *resume_info, size_t n)
449 /* We can only work in all-stop mode. */
450 procfs_status status;
454 TRACE ("%s\n", __func__);
455 /* Workaround for aliasing rules violation. */
456 sigset_t *run_fault = (sigset_t *) (void *) &run.fault;
458 nto_set_thread (resume_info->thread);
460 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
461 if (resume_info->kind == resume_step)
462 run.flags |= _DEBUG_RUN_STEP;
463 run.flags |= _DEBUG_RUN_ARM;
465 sigemptyset (run_fault);
466 sigaddset (run_fault, FLTBPT);
467 sigaddset (run_fault, FLTTRACE);
468 sigaddset (run_fault, FLTILL);
469 sigaddset (run_fault, FLTPRIV);
470 sigaddset (run_fault, FLTBOUNDS);
471 sigaddset (run_fault, FLTIOVF);
472 sigaddset (run_fault, FLTIZDIV);
473 sigaddset (run_fault, FLTFPE);
474 sigaddset (run_fault, FLTPAGE);
475 sigaddset (run_fault, FLTSTACK);
476 sigaddset (run_fault, FLTACCESS);
478 sigemptyset (&run.trace);
479 if (resume_info->sig)
483 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
485 signal_to_pass = resume_info->sig;
486 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
488 if (signal_to_pass != status.info.si_signo)
490 kill (status.pid, signal_to_pass);
491 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
493 else /* Let it kill the program without telling us. */
494 sigdelset (&run.trace, signal_to_pass);
498 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
500 sigfillset (&run.trace);
502 regcache_invalidate ();
504 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0);
506 TRACE ("Error: %d \"%s\"\n", err, strerror (err));
509 /* Wait for inferior's event.
511 Return ptid of thread that caused the event. */
514 nto_wait (ptid_t ptid,
515 struct target_waitstatus *ourstatus, int target_options)
519 procfs_status status;
520 const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
521 | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);
523 TRACE ("%s\n", __func__);
525 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
528 sigaddset (&set, SIGUSR1);
530 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
531 while (!(status.flags & _DEBUG_FLAG_ISTOP))
533 sigwaitinfo (&set, &info);
534 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status),
537 nto_find_new_threads (&nto_inferior);
539 if (status.flags & _DEBUG_FLAG_SSTEP)
542 ourstatus->kind = TARGET_WAITKIND_STOPPED;
543 ourstatus->value.sig = GDB_SIGNAL_TRAP;
545 /* Was it a breakpoint? */
546 else if (status.flags & trace_mask)
549 ourstatus->kind = TARGET_WAITKIND_STOPPED;
550 ourstatus->value.sig = GDB_SIGNAL_TRAP;
552 else if (status.flags & _DEBUG_FLAG_ISTOP)
557 case _DEBUG_WHY_SIGNALLED:
558 TRACE (" SIGNALLED\n");
559 ourstatus->kind = TARGET_WAITKIND_STOPPED;
560 ourstatus->value.sig =
561 gdb_signal_from_host (status.info.si_signo);
562 nto_inferior.exit_signo = ourstatus->value.sig;
564 case _DEBUG_WHY_FAULTED:
565 TRACE (" FAULTED\n");
566 ourstatus->kind = TARGET_WAITKIND_STOPPED;
567 if (status.info.si_signo == SIGTRAP)
569 ourstatus->value.sig = 0;
570 nto_inferior.exit_signo = 0;
574 ourstatus->value.sig =
575 gdb_signal_from_host (status.info.si_signo);
576 nto_inferior.exit_signo = ourstatus->value.sig;
580 case _DEBUG_WHY_TERMINATED:
584 TRACE (" TERMINATED\n");
585 waitpid (ptid_get_pid (ptid), &waitval, WNOHANG);
586 if (nto_inferior.exit_signo)
588 /* Abnormal death. */
589 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
590 ourstatus->value.sig = nto_inferior.exit_signo;
595 ourstatus->kind = TARGET_WAITKIND_EXITED;
596 ourstatus->value.integer = WEXITSTATUS (waitval);
598 nto_inferior.exit_signo = 0;
602 case _DEBUG_WHY_REQUESTED:
603 TRACE ("REQUESTED\n");
604 /* We are assuming a requested stop is due to a SIGINT. */
605 ourstatus->kind = TARGET_WAITKIND_STOPPED;
606 ourstatus->value.sig = GDB_SIGNAL_INT;
607 nto_inferior.exit_signo = 0;
612 return ptid_build (status.pid, status.tid, 0);
615 /* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR).
616 If REGNO is -1, fetch all registers, or REGNO register only otherwise. */
619 nto_fetch_registers (struct regcache *regcache, int regno)
624 TRACE ("%s (regno=%d)\n", __func__, regno);
625 if (regno >= the_low_target.num_regs)
628 if (current_thread == NULL)
630 TRACE ("current_thread is NULL\n");
633 ptid_t ptid = ptid_of (current_thread);
634 if (!nto_set_thread (ptid))
637 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg),
640 if (regno == -1) /* All registers. */
642 for (regno = 0; regno != the_low_target.num_regs; ++regno)
644 const unsigned int registeroffset
645 = the_low_target.register_offset (regno);
646 supply_register (regcache, regno,
647 ((char *)&greg) + registeroffset);
652 const unsigned int registeroffset
653 = the_low_target.register_offset (regno);
654 if (registeroffset == -1)
656 supply_register (regcache, regno, ((char *)&greg) + registeroffset);
660 TRACE ("ERROR reading registers from inferior.\n");
663 /* Store registers for currently selected thread (CURRENT_INFERIOR).
664 We always store all registers, regardless of REGNO. */
667 nto_store_registers (struct regcache *regcache, int regno)
672 TRACE ("%s (regno:%d)\n", __func__, regno);
674 if (current_thread == NULL)
676 TRACE ("current_thread is NULL\n");
679 ptid_t ptid = ptid_of (current_thread);
680 if (!nto_set_thread (ptid))
683 memset (&greg, 0, sizeof (greg));
684 for (regno = 0; regno != the_low_target.num_regs; ++regno)
686 const unsigned int regoffset
687 = the_low_target.register_offset (regno);
688 collect_register (regcache, regno, ((char *)&greg) + regoffset);
690 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg),
693 TRACE ("Error: setting registers.\n");
696 /* Read LEN bytes from inferior's memory address MEMADDR into
697 gdbserver's MYADDR buffer.
699 Return 0 on success -1 otherwise. */
702 nto_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
704 TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);
706 if (nto_xfer_memory (memaddr, myaddr, len, 0) != len)
708 TRACE ("Failed to read memory\n");
715 /* Write LEN bytes from gdbserver's buffer MYADDR into inferior's
716 memory at address MEMADDR.
718 Return 0 on success -1 otherwise. */
721 nto_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
725 TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
726 if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len,
730 TRACE ("Wanted to write: %d but written: %d\n", len, len_written);
737 /* Stop inferior. We always stop all threads. */
740 nto_request_interrupt (void)
742 TRACE ("%s\n", __func__);
743 nto_set_thread (ptid_build (nto_inferior.pid, 1, 0));
744 if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0))
745 TRACE ("Error stopping inferior.\n");
748 /* Read auxiliary vector from inferior's memory into gdbserver's buffer
749 MYADDR. We always read whole auxv.
751 Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0
755 nto_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
758 CORE_ADDR initial_stack;
759 procfs_info procinfo;
761 TRACE ("%s\n", __func__);
765 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo,
770 initial_stack = procinfo.initial_stack;
772 return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len);
776 nto_supports_z_point_type (char z_type)
782 case Z_PACKET_WRITE_WP:
783 case Z_PACKET_READ_WP:
784 case Z_PACKET_ACCESS_WP:
791 /* Insert {break/watch}point at address ADDR. SIZE is not used. */
794 nto_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
795 int size, struct raw_breakpoint *bp)
797 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
799 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
802 case raw_bkpt_type_sw:
803 wtype = _DEBUG_BREAK_EXEC;
805 case raw_bkpt_type_hw:
806 wtype |= _DEBUG_BREAK_EXEC;
808 case raw_bkpt_type_write_wp:
809 wtype |= _DEBUG_BREAK_RW;
811 case raw_bkpt_type_read_wp:
812 wtype |= _DEBUG_BREAK_RD;
814 case raw_bkpt_type_access_wp:
815 wtype |= _DEBUG_BREAK_RW;
818 return 1; /* Not supported. */
820 return nto_breakpoint (addr, wtype, 0);
823 /* Remove {break/watch}point at address ADDR. SIZE is not used. */
826 nto_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
827 int size, struct raw_breakpoint *bp)
829 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */
831 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size);
834 case raw_bkpt_type_sw:
835 wtype = _DEBUG_BREAK_EXEC;
837 case raw_bkpt_type_hw:
838 wtype |= _DEBUG_BREAK_EXEC;
840 case raw_bkpt_type_write_wp:
841 wtype |= _DEBUG_BREAK_RW;
843 case raw_bkpt_type_read_wp:
844 wtype |= _DEBUG_BREAK_RD;
846 case raw_bkpt_type_access_wp:
847 wtype |= _DEBUG_BREAK_RW;
850 return 1; /* Not supported. */
852 return nto_breakpoint (addr, wtype, -1);
855 /* Check if the reason of stop for current thread (CURRENT_INFERIOR) is
858 Return 1 if stopped by watchpoint, 0 otherwise. */
861 nto_stopped_by_watchpoint (void)
865 TRACE ("%s\n", __func__);
866 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
868 ptid_t ptid = ptid_of (current_thread);
869 if (nto_set_thread (ptid))
871 const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
872 | _DEBUG_FLAG_TRACE_MODIFY;
873 procfs_status status;
876 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
878 if (err == EOK && (status.flags & watchmask))
882 TRACE ("%s: %s\n", __func__, ret ? "yes" : "no");
886 /* Get instruction pointer for CURRENT_INFERIOR thread.
888 Return inferior's instruction pointer value, or 0 on error. */
891 nto_stopped_data_address (void)
893 CORE_ADDR ret = (CORE_ADDR)0;
895 TRACE ("%s\n", __func__);
896 if (nto_inferior.ctl_fd != -1 && current_thread != NULL)
898 ptid_t ptid = ptid_of (current_thread);
900 if (nto_set_thread (ptid))
902 procfs_status status;
904 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status,
905 sizeof (status), 0) == EOK)
909 TRACE ("%s: 0x%08lx\n", __func__, ret);
913 /* We do not currently support non-stop. */
916 nto_supports_non_stop (void)
918 TRACE ("%s\n", __func__);
922 /* Implementation of the target_ops method "sw_breakpoint_from_kind". */
924 static const gdb_byte *
925 nto_sw_breakpoint_from_kind (int kind, int *size)
927 *size = the_low_target.breakpoint_len;
928 return the_low_target.breakpoint;
932 static struct target_ops nto_target_ops = {
934 NULL, /* post_create_inferior */
945 NULL, /* prepare_to_access_memory */
946 NULL, /* done_accessing_memory */
949 NULL, /* nto_look_up_symbols */
950 nto_request_interrupt,
952 nto_supports_z_point_type,
955 NULL, /* stopped_by_sw_breakpoint */
956 NULL, /* supports_stopped_by_sw_breakpoint */
957 NULL, /* stopped_by_hw_breakpoint */
958 NULL, /* supports_stopped_by_hw_breakpoint */
959 target_can_do_hardware_single_step,
960 nto_stopped_by_watchpoint,
961 nto_stopped_data_address,
962 NULL, /* nto_read_offsets */
963 NULL, /* thread_db_set_tls_address */
965 hostio_last_error_from_errno,
966 NULL, /* nto_qxfer_osdata */
967 NULL, /* xfer_siginfo */
968 nto_supports_non_stop,
970 NULL, /* start_non_stop */
971 NULL, /* supports_multi_process */
972 NULL, /* supports_fork_events */
973 NULL, /* supports_vfork_events */
974 NULL, /* supports_exec_events */
975 NULL, /* handle_new_gdb_connection */
976 NULL, /* handle_monitor_command */
977 NULL, /* core_of_thread */
978 NULL, /* read_loadmap */
979 NULL, /* process_qsupported */
980 NULL, /* supports_tracepoints */
983 NULL, /* thread_stopped */
984 NULL, /* get_tib_address */
985 NULL, /* pause_all */
986 NULL, /* unpause_all */
987 NULL, /* stabilize_threads */
988 NULL, /* install_fast_tracepoint_jump_pad */
990 NULL, /* supports_disable_randomization */
991 NULL, /* get_min_fast_tracepoint_insn_len */
992 NULL, /* qxfer_libraries_svr4 */
993 NULL, /* support_agent */
994 NULL, /* support_btrace */
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,
1009 /* Global function called by server.c. Initializes QNX Neutrino
1013 initialize_low (void)
1017 TRACE ("%s\n", __func__);
1018 set_target_ops (&nto_target_ops);
1020 /* We use SIGUSR1 to gain control after we block waiting for a process.
1021 We use sigwaitevent to wait. */
1023 sigaddset (&set, SIGUSR1);
1024 sigprocmask (SIG_BLOCK, &set, NULL);