From 613f149a90d6fc32a5a6ff47e0325f762cb07424 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 12 Jun 2020 16:06:41 -0400 Subject: [PATCH] gdbserver: remove support for Neutrino This port has been unmaintained for years, remove it. gdbserver/ChangeLog: * configure: Re-generate. * configure.ac: Remove srv_qnx test. * configure.srv: Remove nto case. * nto-low.cc, nto-low.h, nto-x86-low.cc: Remove. * remote-utils.c: Remove __QNX__-guarded code. Change-Id: I8a1ad9c740a69352da1f6993778dbf951eebb22f --- gdbserver/ChangeLog | 8 + gdbserver/configure | 2 - gdbserver/configure.ac | 2 - gdbserver/configure.srv | 4 - gdbserver/nto-low.cc | 965 -------------------------------------- gdbserver/nto-low.h | 109 ----- gdbserver/nto-x86-low.cc | 109 ----- gdbserver/remote-utils.cc | 33 -- 8 files changed, 8 insertions(+), 1224 deletions(-) delete mode 100644 gdbserver/nto-low.cc delete mode 100644 gdbserver/nto-low.h delete mode 100644 gdbserver/nto-x86-low.cc diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index c6cc5f1b12..07cf443354 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,11 @@ +2020-06-12 Simon Marchi + + * configure: Re-generate. + * configure.ac: Remove srv_qnx test. + * configure.srv: Remove nto case. + * nto-low.cc, nto-low.h, nto-x86-low.cc: Remove. + * remote-utils.c: Remove __QNX__-guarded code. + 2020-06-12 Simon Marchi * configure: Re-generate. diff --git a/gdbserver/configure b/gdbserver/configure index dc818736b0..0f77ac6cb8 100755 --- a/gdbserver/configure +++ b/gdbserver/configure @@ -10252,8 +10252,6 @@ if test "${srv_mingwce}" = "yes"; then elif test "${srv_mingw}" = "yes"; then # WIN32APILIBS is set by GDB_AC_COMMON. LIBS="$LIBS $WIN32APILIBS" -elif test "${srv_qnx}" = "yes"; then - LIBS="$LIBS -lsocket" fi if test "${srv_linux_usrregs}" = "yes"; then diff --git a/gdbserver/configure.ac b/gdbserver/configure.ac index 0b1c81d6af..10f2f4c0cb 100644 --- a/gdbserver/configure.ac +++ b/gdbserver/configure.ac @@ -225,8 +225,6 @@ if test "${srv_mingwce}" = "yes"; then elif test "${srv_mingw}" = "yes"; then # WIN32APILIBS is set by GDB_AC_COMMON. LIBS="$LIBS $WIN32APILIBS" -elif test "${srv_qnx}" = "yes"; then - LIBS="$LIBS -lsocket" fi if test "${srv_linux_usrregs}" = "yes"; then diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 24a9306240..0a3bf32dd1 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -136,10 +136,6 @@ case "${gdbserver_host}" in srv_tgtobj="${srv_tgtobj} arch/i386.o" srv_mingw=yes ;; - i[34567]86-*-nto*) srv_regobj="" - srv_tgtobj="nto-low.o nto-x86-low.o arch/i386.o" - srv_qnx="yes" - ;; ia64-*-linux*) srv_regobj=reg-ia64.o srv_tgtobj="$srv_linux_obj linux-ia64-low.o" srv_linux_usrregs=yes diff --git a/gdbserver/nto-low.cc b/gdbserver/nto-low.cc deleted file mode 100644 index a88ad02f64..0000000000 --- a/gdbserver/nto-low.cc +++ /dev/null @@ -1,965 +0,0 @@ -/* QNX Neutrino specific low level interface, for the remote server - for GDB. - Copyright (C) 2009-2020 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - - -#include "server.h" -#include "gdbthread.h" -#include "nto-low.h" -#include "hostio.h" -#include "debug.h" - -#include -#include -#include -#include -#include -#include -#include - - -int using_threads = 1; - -const struct target_desc *nto_tdesc; - -static void -nto_trace (const char *fmt, ...) -{ - va_list arg_list; - - if (debug_threads == 0) - return; - fprintf (stderr, "nto:"); - va_start (arg_list, fmt); - vfprintf (stderr, fmt, arg_list); - va_end (arg_list); -} - -#define TRACE nto_trace - -/* Structure holding neutrino specific information about - inferior. */ - -struct nto_inferior -{ - char nto_procfs_path[PATH_MAX]; - int ctl_fd; - pid_t pid; - int exit_signo; /* For tracking exit status. */ -}; - -static struct nto_inferior nto_inferior; - -static void -init_nto_inferior (struct nto_inferior *nto_inferior) -{ - memset (nto_inferior, 0, sizeof (struct nto_inferior)); - nto_inferior->ctl_fd = -1; - nto_inferior->pid = -1; -} - -static void -do_detach (void) -{ - if (nto_inferior.ctl_fd != -1) - { - nto_trace ("Closing fd\n"); - close (nto_inferior.ctl_fd); - init_nto_inferior (&nto_inferior); - } -} - -/* Set current thread. Return 1 on success, 0 otherwise. */ - -static int -nto_set_thread (ptid_t ptid) -{ - int res = 0; - - TRACE ("%s pid: %d tid: %ld\n", __func__, ptid.pid (), - ptid.lwp ()); - if (nto_inferior.ctl_fd != -1 - && ptid != null_ptid - && ptid != minus_one_ptid) - { - pthread_t tid = ptid.lwp (); - - if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid, - sizeof (tid), 0)) - res = 1; - else - TRACE ("%s: Error: failed to set current thread\n", __func__); - } - return res; -} - -/* This function will determine all alive threads. Note that we do not list - dead but unjoined threads even though they are still in the process' thread - list. - - NTO_INFERIOR must not be NULL. */ - -static void -nto_find_new_threads (struct nto_inferior *nto_inferior) -{ - pthread_t tid; - - TRACE ("%s pid:%d\n", __func__, nto_inferior->pid); - - if (nto_inferior->ctl_fd == -1) - return; - - for (tid = 1;; ++tid) - { - procfs_status status; - ptid_t ptid; - int err; - - status.tid = tid; - err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status, - sizeof (status), 0); - - if (err != EOK || status.tid == 0) - break; - - /* All threads in between are gone. */ - while (tid != status.tid || status.state == STATE_DEAD) - { - struct thread_info *ti; - - ptid = ptid_t (nto_inferior->pid, tid, 0); - ti = find_thread_ptid (ptid); - if (ti != NULL) - { - TRACE ("Removing thread %d\n", tid); - remove_thread (ti); - } - if (tid == status.tid) - break; - ++tid; - } - - if (status.state != STATE_DEAD) - { - TRACE ("Adding thread %d\n", tid); - ptid = ptid_t (nto_inferior->pid, tid, 0); - if (!find_thread_ptid (ptid)) - add_thread (ptid, NULL); - } - } -} - -/* Given pid, open procfs path. */ - -static pid_t -do_attach (pid_t pid) -{ - procfs_status status; - struct sigevent event; - - if (nto_inferior.ctl_fd != -1) - { - close (nto_inferior.ctl_fd); - init_nto_inferior (&nto_inferior); - } - xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid); - nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR); - if (nto_inferior.ctl_fd == -1) - { - TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path); - init_nto_inferior (&nto_inferior); - return -1; - } - if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) - != EOK) - { - do_detach (); - return -1; - } - nto_inferior.pid = pid; - /* Define a sigevent for process stopped notification. */ - event.sigev_notify = SIGEV_SIGNAL_THREAD; - event.sigev_signo = SIGUSR1; - event.sigev_code = 0; - event.sigev_value.sival_ptr = NULL; - event.sigev_priority = -1; - devctl (nto_inferior.ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0); - - if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), - 0) == EOK - && (status.flags & _DEBUG_FLAG_STOPPED)) - { - ptid_t ptid; - struct process_info *proc; - - kill (pid, SIGCONT); - ptid = ptid_t (status.pid, status.tid, 0); - the_low_target.arch_setup (); - proc = add_process (status.pid, 1); - proc->tdesc = nto_tdesc; - TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid, - ptid.lwp ()); - nto_find_new_threads (&nto_inferior); - } - else - { - do_detach (); - return -1; - } - - return pid; -} - -/* Read or write LEN bytes from/to inferior's MEMADDR memory address - into gdbservers's MYADDR buffer. Return number of bytes actually - transfered. */ - -static int -nto_xfer_memory (off_t memaddr, unsigned char *myaddr, int len, - int dowrite) -{ - int nbytes = 0; - - if (lseek (nto_inferior.ctl_fd, memaddr, SEEK_SET) == memaddr) - { - if (dowrite) - nbytes = write (nto_inferior.ctl_fd, myaddr, len); - else - nbytes = read (nto_inferior.ctl_fd, myaddr, len); - if (nbytes < 0) - nbytes = 0; - } - if (nbytes == 0) - { - int e = errno; - TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, safe_strerror (e)); - } - return nbytes; -} - -/* Insert or remove breakpoint or watchpoint at address ADDR. - TYPE can be one of Neutrino breakpoint types. SIZE must be 0 for - inserting the point, -1 for removing it. - - Return 0 on success, 1 otherwise. */ - -static int -nto_breakpoint (CORE_ADDR addr, int type, int size) -{ - procfs_break brk; - - brk.type = type; - brk.addr = addr; - brk.size = size; - if (devctl (nto_inferior.ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0) - != EOK) - return 1; - return 0; -} - -/* Read auxiliary vector from inferior's initial stack into gdbserver's - MYADDR buffer, up to LEN bytes. - - Return number of bytes read. */ - -static int -nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, - unsigned char *myaddr, - unsigned int len) -{ - int data_ofs = 0; - int anint; - unsigned int len_read = 0; - - /* Skip over argc, argv and envp... Comment from ldd.c: - - The startup frame is set-up so that we have: - auxv - NULL - ... - envp2 - envp1 <----- void *frame + (argc + 2) * sizeof(char *) - NULL - ... - argv2 - argv1 - argc <------ void * frame - - On entry to ldd, frame gives the address of argc on the stack. */ - if (nto_xfer_memory (initial_stack, (unsigned char *)&anint, - sizeof (anint), 0) != sizeof (anint)) - return 0; - - /* Size of pointer is assumed to be 4 bytes (32 bit arch. ) */ - data_ofs += (anint + 2) * sizeof (void *); /* + 2 comes from argc itself and - NULL terminating pointer in - argv. */ - - /* Now loop over env table: */ - while (nto_xfer_memory (initial_stack + data_ofs, - (unsigned char *)&anint, sizeof (anint), 0) - == sizeof (anint)) - { - data_ofs += sizeof (anint); - if (anint == 0) - break; - } - initial_stack += data_ofs; - - memset (myaddr, 0, len); - while (len_read <= len - sizeof (auxv_t)) - { - auxv_t *auxv = (auxv_t *)myaddr; - - /* Search backwards until we have read AT_PHDR (num. 3), - AT_PHENT (num 4), AT_PHNUM (num 5) */ - if (nto_xfer_memory (initial_stack, (unsigned char *)auxv, - sizeof (auxv_t), 0) == sizeof (auxv_t)) - { - if (auxv->a_type != AT_NULL) - { - auxv++; - len_read += sizeof (auxv_t); - } - if (auxv->a_type == AT_PHNUM) /* That's all we need. */ - break; - initial_stack += sizeof (auxv_t); - } - else - break; - } - TRACE ("auxv: len_read: %d\n", len_read); - return len_read; -} - -/* Start inferior specified by PROGRAM, using PROGRAM_ARGS as its - arguments. */ - -int -nto_process_target::create_inferior (const char *program, - const std::vector &program_args) -{ - struct inheritance inherit; - pid_t pid; - sigset_t set; - - TRACE ("%s %s\n", __func__, program); - /* Clear any pending SIGUSR1's but keep the behavior the same. */ - signal (SIGUSR1, signal (SIGUSR1, SIG_IGN)); - - sigemptyset (&set); - sigaddset (&set, SIGUSR1); - sigprocmask (SIG_UNBLOCK, &set, NULL); - - memset (&inherit, 0, sizeof (inherit)); - inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD; - inherit.pgroup = SPAWN_NEWPGROUP; - pid = spawnp (program, 0, NULL, &inherit, - program_args.data (), 0); - sigprocmask (SIG_BLOCK, &set, NULL); - - if (pid == -1) - return -1; - - if (do_attach (pid) != pid) - return -1; - - return pid; -} - -/* Attach to process PID. */ - -int -nto_process_target::attach (unsigned long pid) -{ - TRACE ("%s %ld\n", __func__, pid); - if (do_attach (pid) != pid) - error ("Unable to attach to %ld\n", pid); - return 0; -} - -/* Send signal to process PID. */ - -int -nto_process_target::kill (process_info *proc) -{ - int pid = proc->pid; - - TRACE ("%s %d\n", __func__, pid); - kill (pid, SIGKILL); - do_detach (); - return 0; -} - -/* Detach from process PID. */ - -int -nto_process_target::detach (process_info *proc) -{ - TRACE ("%s %d\n", __func__, proc->pid); - do_detach (); - return 0; -} - -void -nto_process_target::mourn (struct process_info *process) -{ - remove_process (process); -} - -void -nto_process_target::join (int pid) -{ - error (_("nto target does not implement the join op")); -} - -/* Check if the given thread is alive. - - Return true if alive, false otherwise. */ - -bool -nto_process_target::thread_alive (ptid_t ptid) -{ - int res; - - TRACE ("%s pid:%d tid:%d\n", __func__, ptid.pid (), - ptid.lwp ()); - if (SignalKill (0, ptid.pid (), ptid.lwp (), - 0, 0, 0) == -1) - res = 0; - else - res = 1; - TRACE ("%s: %s\n", __func__, res ? "yes" : "no"); - return res; -} - -/* Resume inferior's execution. */ - -void -nto_process_target::resume (thread_resume *resume_info, size_t n) -{ - /* We can only work in all-stop mode. */ - procfs_status status; - procfs_run run; - int err; - - TRACE ("%s\n", __func__); - /* Workaround for aliasing rules violation. */ - sigset_t *run_fault = (sigset_t *) (void *) &run.fault; - - nto_set_thread (resume_info->thread); - - run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE; - if (resume_info->kind == resume_step) - run.flags |= _DEBUG_RUN_STEP; - run.flags |= _DEBUG_RUN_ARM; - - sigemptyset (run_fault); - sigaddset (run_fault, FLTBPT); - sigaddset (run_fault, FLTTRACE); - sigaddset (run_fault, FLTILL); - sigaddset (run_fault, FLTPRIV); - sigaddset (run_fault, FLTBOUNDS); - sigaddset (run_fault, FLTIOVF); - sigaddset (run_fault, FLTIZDIV); - sigaddset (run_fault, FLTFPE); - sigaddset (run_fault, FLTPAGE); - sigaddset (run_fault, FLTSTACK); - sigaddset (run_fault, FLTACCESS); - - sigemptyset (&run.trace); - if (resume_info->sig) - { - int signal_to_pass; - - devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), - 0); - signal_to_pass = resume_info->sig; - if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)) - { - if (signal_to_pass != status.info.si_signo) - { - kill (status.pid, signal_to_pass); - run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG; - } - else /* Let it kill the program without telling us. */ - sigdelset (&run.trace, signal_to_pass); - } - } - else - run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT; - - sigfillset (&run.trace); - - regcache_invalidate (); - - err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0); - if (err != EOK) - TRACE ("Error: %d \"%s\"\n", err, safe_strerror (err)); -} - -/* Wait for inferior's event. - - Return ptid of thread that caused the event. */ - -ptid_t -nto_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, - int target_options) -{ - sigset_t set; - siginfo_t info; - procfs_status status; - const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD - | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY); - - TRACE ("%s\n", __func__); - - ourstatus->kind = TARGET_WAITKIND_SPURIOUS; - - sigemptyset (&set); - sigaddset (&set, SIGUSR1); - - devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); - while (!(status.flags & _DEBUG_FLAG_ISTOP)) - { - sigwaitinfo (&set, &info); - devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), - 0); - } - nto_find_new_threads (&nto_inferior); - - if (status.flags & _DEBUG_FLAG_SSTEP) - { - TRACE ("SSTEP\n"); - ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = GDB_SIGNAL_TRAP; - } - /* Was it a breakpoint? */ - else if (status.flags & trace_mask) - { - TRACE ("STOPPED\n"); - ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = GDB_SIGNAL_TRAP; - } - else if (status.flags & _DEBUG_FLAG_ISTOP) - { - TRACE ("ISTOP\n"); - switch (status.why) - { - case _DEBUG_WHY_SIGNALLED: - TRACE (" SIGNALLED\n"); - ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = - gdb_signal_from_host (status.info.si_signo); - nto_inferior.exit_signo = ourstatus->value.sig; - break; - case _DEBUG_WHY_FAULTED: - TRACE (" FAULTED\n"); - ourstatus->kind = TARGET_WAITKIND_STOPPED; - if (status.info.si_signo == SIGTRAP) - { - ourstatus->value.sig = 0; - nto_inferior.exit_signo = 0; - } - else - { - ourstatus->value.sig = - gdb_signal_from_host (status.info.si_signo); - nto_inferior.exit_signo = ourstatus->value.sig; - } - break; - - case _DEBUG_WHY_TERMINATED: - { - int waitval = 0; - - TRACE (" TERMINATED\n"); - waitpid (ptid.pid (), &waitval, WNOHANG); - if (nto_inferior.exit_signo) - { - /* Abnormal death. */ - ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = nto_inferior.exit_signo; - } - else - { - /* Normal death. */ - ourstatus->kind = TARGET_WAITKIND_EXITED; - ourstatus->value.integer = WEXITSTATUS (waitval); - } - nto_inferior.exit_signo = 0; - break; - } - - case _DEBUG_WHY_REQUESTED: - TRACE ("REQUESTED\n"); - /* We are assuming a requested stop is due to a SIGINT. */ - ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = GDB_SIGNAL_INT; - nto_inferior.exit_signo = 0; - break; - } - } - - return ptid_t (status.pid, status.tid, 0); -} - -/* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR). - If REGNO is -1, fetch all registers, or REGNO register only otherwise. */ - -void -nto_process_target::fetch_registers (regcache *regcache, int regno) -{ - int regsize; - procfs_greg greg; - - TRACE ("%s (regno=%d)\n", __func__, regno); - if (regno >= the_low_target.num_regs) - return; - - if (current_thread == NULL) - { - TRACE ("current_thread is NULL\n"); - return; - } - ptid_t ptid = ptid_of (current_thread); - if (!nto_set_thread (ptid)) - return; - - if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg), - ®size) == EOK) - { - if (regno == -1) /* All registers. */ - { - for (regno = 0; regno != the_low_target.num_regs; ++regno) - { - const unsigned int registeroffset - = the_low_target.register_offset (regno); - supply_register (regcache, regno, - ((char *)&greg) + registeroffset); - } - } - else - { - const unsigned int registeroffset - = the_low_target.register_offset (regno); - if (registeroffset == -1) - return; - supply_register (regcache, regno, ((char *)&greg) + registeroffset); - } - } - else - TRACE ("ERROR reading registers from inferior.\n"); -} - -/* Store registers for currently selected thread (CURRENT_INFERIOR). - We always store all registers, regardless of REGNO. */ - -void -nto_process_target::store_registers (regcache *regcache, int regno) -{ - procfs_greg greg; - int err; - - TRACE ("%s (regno:%d)\n", __func__, regno); - - if (current_thread == NULL) - { - TRACE ("current_thread is NULL\n"); - return; - } - ptid_t ptid = ptid_of (current_thread); - if (!nto_set_thread (ptid)) - return; - - memset (&greg, 0, sizeof (greg)); - for (regno = 0; regno != the_low_target.num_regs; ++regno) - { - const unsigned int regoffset - = the_low_target.register_offset (regno); - collect_register (regcache, regno, ((char *)&greg) + regoffset); - } - err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg), - 0); - if (err != EOK) - TRACE ("Error: setting registers.\n"); -} - -/* Read LEN bytes from inferior's memory address MEMADDR into - gdbserver's MYADDR buffer. - - Return 0 on success -1 otherwise. */ - -int -nto_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr, - int len) -{ - TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len); - - if (nto_xfer_memory (memaddr, myaddr, len, 0) != len) - { - TRACE ("Failed to read memory\n"); - return -1; - } - - return 0; -} - -/* Write LEN bytes from gdbserver's buffer MYADDR into inferior's - memory at address MEMADDR. - - Return 0 on success -1 otherwise. */ - -int -nto_process_target::write_memory (CORE_ADDR memaddr, - const unsigned char *myaddr, int len) -{ - int len_written; - - TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len); - if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len, - 1)) - != len) - { - TRACE ("Wanted to write: %d but written: %d\n", len, len_written); - return -1; - } - - return 0; -} - -/* Stop inferior. We always stop all threads. */ - -void -nto_process_target::request_interrupt () -{ - TRACE ("%s\n", __func__); - nto_set_thread (ptid_t (nto_inferior.pid, 1, 0)); - if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0)) - TRACE ("Error stopping inferior.\n"); -} - -bool -nto_process_target::supports_read_auxv () -{ - return true; -} - -/* Read auxiliary vector from inferior's memory into gdbserver's buffer - MYADDR. We always read whole auxv. - - Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0 - or -1 on error. */ - -int -nto_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr, - unsigned int len) -{ - int err; - CORE_ADDR initial_stack; - procfs_info procinfo; - - TRACE ("%s\n", __func__); - if (offset > 0) - return 0; - - err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo, - sizeof procinfo, 0); - if (err != EOK) - return -1; - - initial_stack = procinfo.initial_stack; - - return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len); -} - -bool -nto_process_target::supports_z_point_type (char z_type) -{ - switch (z_type) - { - case Z_PACKET_SW_BP: - case Z_PACKET_HW_BP: - case Z_PACKET_WRITE_WP: - case Z_PACKET_READ_WP: - case Z_PACKET_ACCESS_WP: - return true; - default: - return false; - } -} - -/* Insert {break/watch}point at address ADDR. SIZE is not used. */ - -int -nto_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr, - int size, raw_breakpoint *bp) -{ - int wtype = _DEBUG_BREAK_HW; /* Always request HW. */ - - TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size); - switch (type) - { - case raw_bkpt_type_sw: - wtype = _DEBUG_BREAK_EXEC; - break; - case raw_bkpt_type_hw: - wtype |= _DEBUG_BREAK_EXEC; - break; - case raw_bkpt_type_write_wp: - wtype |= _DEBUG_BREAK_RW; - break; - case raw_bkpt_type_read_wp: - wtype |= _DEBUG_BREAK_RD; - break; - case raw_bkpt_type_access_wp: - wtype |= _DEBUG_BREAK_RW; - break; - default: - return 1; /* Not supported. */ - } - return nto_breakpoint (addr, wtype, 0); -} - -/* Remove {break/watch}point at address ADDR. SIZE is not used. */ - -int -nto_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr, - int size, raw_breakpoint *bp) -{ - int wtype = _DEBUG_BREAK_HW; /* Always request HW. */ - - TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, size); - switch (type) - { - case raw_bkpt_type_sw: - wtype = _DEBUG_BREAK_EXEC; - break; - case raw_bkpt_type_hw: - wtype |= _DEBUG_BREAK_EXEC; - break; - case raw_bkpt_type_write_wp: - wtype |= _DEBUG_BREAK_RW; - break; - case raw_bkpt_type_read_wp: - wtype |= _DEBUG_BREAK_RD; - break; - case raw_bkpt_type_access_wp: - wtype |= _DEBUG_BREAK_RW; - break; - default: - return 1; /* Not supported. */ - } - return nto_breakpoint (addr, wtype, -1); -} - -bool -nto_process_target::supports_hardware_single_step () -{ - return true; -} - -/* Check if the reason of stop for current thread (CURRENT_INFERIOR) is - a watchpoint. - - Return true if stopped by watchpoint, false otherwise. */ - -bool -nto_process_target::stopped_by_watchpoint () -{ - bool ret = false; - - TRACE ("%s\n", __func__); - if (nto_inferior.ctl_fd != -1 && current_thread != NULL) - { - ptid_t ptid = ptid_of (current_thread); - if (nto_set_thread (ptid)) - { - const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR - | _DEBUG_FLAG_TRACE_MODIFY; - procfs_status status; - int err; - - err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, - sizeof (status), 0); - if (err == EOK && (status.flags & watchmask)) - ret = true; - } - } - TRACE ("%s: %s\n", __func__, ret ? "yes" : "no"); - return ret; -} - -/* Get instruction pointer for CURRENT_INFERIOR thread. - - Return inferior's instruction pointer value, or 0 on error. */ - -CORE_ADDR -nto_process_target::stopped_data_address () -{ - CORE_ADDR ret = (CORE_ADDR)0; - - TRACE ("%s\n", __func__); - if (nto_inferior.ctl_fd != -1 && current_thread != NULL) - { - ptid_t ptid = ptid_of (current_thread); - - if (nto_set_thread (ptid)) - { - procfs_status status; - - if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, - sizeof (status), 0) == EOK) - ret = status.ip; - } - } - TRACE ("%s: 0x%08lx\n", __func__, ret); - return ret; -} - -/* Implementation of the target_ops method "sw_breakpoint_from_kind". */ - -const gdb_byte * -nto_process_target::sw_breakpoint_from_kind (int kind, int *size) -{ - *size = the_low_target.breakpoint_len; - return the_low_target.breakpoint; -} - -/* The QNX Neutrino target ops object. */ - -static nto_process_target the_nto_target; - -/* Global function called by server.c. Initializes QNX Neutrino - gdbserver. */ - -void -initialize_low (void) -{ - sigset_t set; - - TRACE ("%s\n", __func__); - set_target_ops (&the_nto_target); - - /* We use SIGUSR1 to gain control after we block waiting for a process. - We use sigwaitevent to wait. */ - sigemptyset (&set); - sigaddset (&set, SIGUSR1); - sigprocmask (SIG_BLOCK, &set, NULL); -} - diff --git a/gdbserver/nto-low.h b/gdbserver/nto-low.h deleted file mode 100644 index e26dcab331..0000000000 --- a/gdbserver/nto-low.h +++ /dev/null @@ -1,109 +0,0 @@ -/* Internal interfaces for the QNX Neutrino specific target code for gdbserver. - Copyright (C) 2009-2020 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef GDBSERVER_NTO_LOW_H -#define GDBSERVER_NTO_LOW_H - -struct target_desc; - -enum regset_type -{ - NTO_REG_GENERAL, - NTO_REG_FLOAT, - NTO_REG_SYSTEM, - NTO_REG_ALT, - NTO_REG_END -}; - -struct nto_target_ops -{ - /* Architecture specific setup. */ - void (*arch_setup) (void); - int num_regs; - int (*register_offset) (int gdbregno); - const unsigned char *breakpoint; - int breakpoint_len; -}; - -extern struct nto_target_ops the_low_target; - -/* Target ops definitions for a QNX Neutrino target. */ - -class nto_process_target : public process_stratum_target -{ -public: - - int create_inferior (const char *program, - const std::vector &program_args) override; - - int attach (unsigned long pid) override; - - int kill (process_info *proc) override; - - int detach (process_info *proc) override; - - void mourn (process_info *proc) override; - - void join (int pid) override; - - bool thread_alive (ptid_t pid) override; - - void resume (thread_resume *resume_info, size_t n) override; - - ptid_t wait (ptid_t ptid, target_waitstatus *status, - int options) override; - - void fetch_registers (regcache *regcache, int regno) override; - - void store_registers (regcache *regcache, int regno) override; - - int read_memory (CORE_ADDR memaddr, unsigned char *myaddr, - int len) override; - - int write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, - int len) override; - - void request_interrupt () override; - - bool supports_read_auxv () override; - - int read_auxv (CORE_ADDR offset, unsigned char *myaddr, - unsigned int len) override; - - bool supports_z_point_type (char z_type) override; - - int insert_point (enum raw_bkpt_type type, CORE_ADDR addr, - int size, raw_breakpoint *bp) override; - - int remove_point (enum raw_bkpt_type type, CORE_ADDR addr, - int size, raw_breakpoint *bp) override; - - bool supports_hardware_single_step () override; - - bool stopped_by_watchpoint () override; - - CORE_ADDR stopped_data_address () override; - - const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override; -}; - -/* The inferior's target description. This is a global because the - LynxOS ports support neither bi-arch nor multi-process. */ -extern const struct target_desc *nto_tdesc; - -#endif /* GDBSERVER_NTO_LOW_H */ diff --git a/gdbserver/nto-x86-low.cc b/gdbserver/nto-x86-low.cc deleted file mode 100644 index efee957362..0000000000 --- a/gdbserver/nto-x86-low.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* QNX Neutrino specific low level interface, for the remote server - for GDB. - Copyright (C) 2009-2020 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include "server.h" -#include "nto-low.h" -#include "regdef.h" -#include "regcache.h" - -#include -#include "gdbsupport/x86-xstate.h" -#include "arch/i386.h" -#include "x86-tdesc.h" - -const unsigned char x86_breakpoint[] = { 0xCC }; -#define x86_breakpoint_len 1 - -/* Returns offset in appropriate Neutrino's context structure. - Defined in x86/context.h. - GDBREGNO is index into regs_i386 array. It is autogenerated and - hopefully doesn't change. */ -static int -nto_x86_register_offset (int gdbregno) -{ - if (gdbregno >= 0 && gdbregno < 16) - { - X86_CPU_REGISTERS *dummy = (void*)0; - /* GPRs */ - switch (gdbregno) - { - case 0: - return (int)&(dummy->eax); - case 1: - return (int)&(dummy->ecx); - case 2: - return (int)&(dummy->edx); - case 3: - return (int)&(dummy->ebx); - case 4: - return (int)&(dummy->esp); - case 5: - return (int)&(dummy->ebp); - case 6: - return (int)&(dummy->esi); - case 7: - return (int)&(dummy->edi); - case 8: - return (int)&(dummy->eip); - case 9: - return (int)&(dummy->efl); - case 10: - return (int)&(dummy->cs); - case 11: - return (int)&(dummy->ss); -#ifdef __SEGMENTS__ - case 12: - return (int)&(dummy->ds); - case 13: - return (int)&(dummy->es); - case 14: - return (int)&(dummy->fs); - case 15: - return (int)&(dummy->gs); -#endif - default: - return -1; - } - } - return -1; -} - -static void -nto_x86_arch_setup (void) -{ - the_low_target.num_regs = 16; - struct target_desc *tdesc - = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); - - init_target_desc (tdesc, i386_expedite_regs); - - nto_tdesc = tdesc; -} - -struct nto_target_ops the_low_target = -{ - nto_x86_arch_setup, - 0, /* num_regs */ - nto_x86_register_offset, - x86_breakpoint, - x86_breakpoint_len -}; - - - diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc index 67c560d1c8..c26668dc0f 100644 --- a/gdbserver/remote-utils.cc +++ b/gdbserver/remote-utils.cc @@ -68,10 +68,6 @@ #include #endif -#if __QNX__ -#include -#endif /* __QNX__ */ - #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif @@ -804,28 +800,6 @@ block_unblock_async_io (int block) #endif } -#ifdef __QNX__ -static void -nto_comctrl (int enable) -{ - struct sigevent event; - - if (enable) - { - event.sigev_notify = SIGEV_SIGNAL_THREAD; - event.sigev_signo = SIGIO; - event.sigev_code = 0; - event.sigev_value.sival_ptr = NULL; - event.sigev_priority = -1; - ionotify (remote_desc, _NOTIFY_ACTION_POLLARM, _NOTIFY_COND_INPUT, - &event); - } - else - ionotify (remote_desc, _NOTIFY_ACTION_POLL, _NOTIFY_COND_INPUT, NULL); -} -#endif /* __QNX__ */ - - /* Current state of asynchronous I/O. */ static int async_io_enabled; @@ -839,9 +813,6 @@ enable_async_io (void) block_unblock_async_io (0); async_io_enabled = 1; -#ifdef __QNX__ - nto_comctrl (1); -#endif /* __QNX__ */ } /* Disable asynchronous I/O. */ @@ -854,10 +825,6 @@ disable_async_io (void) block_unblock_async_io (1); async_io_enabled = 0; -#ifdef __QNX__ - nto_comctrl (0); -#endif /* __QNX__ */ - } void