diff options
-rw-r--r-- | gdbserver/ChangeLog | 8 | ||||
-rwxr-xr-x | gdbserver/configure | 2 | ||||
-rw-r--r-- | gdbserver/configure.ac | 2 | ||||
-rw-r--r-- | gdbserver/configure.srv | 13 | ||||
-rw-r--r-- | gdbserver/lynx-i386-low.cc | 358 | ||||
-rw-r--r-- | gdbserver/lynx-low.cc | 747 | ||||
-rw-r--r-- | gdbserver/lynx-low.h | 102 | ||||
-rw-r--r-- | gdbserver/lynx-ppc-low.cc | 185 |
8 files changed, 8 insertions, 1409 deletions
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index 8df1ca7..c6cc5f1 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,5 +1,13 @@ 2020-06-12 Simon Marchi <simon.marchi@efficios.com> + * configure: Re-generate. + * configure.ac: Remove srv_lynxos test. + * configure.srv: Remove lynxos cases. + * lynx-i386-low.cc, lynx-low.cc, lynx-low.h, lynx-ppc-low.c: + Remove. + +2020-06-12 Simon Marchi <simon.marchi@efficios.com> + * README: Fix a few outdated or incoherent things. 2020-05-27 Hannes Domani <ssbssa@yahoo.de> diff --git a/gdbserver/configure b/gdbserver/configure index 5479823..dc81873 100755 --- a/gdbserver/configure +++ b/gdbserver/configure @@ -10254,8 +10254,6 @@ elif test "${srv_mingw}" = "yes"; then LIBS="$LIBS $WIN32APILIBS" elif test "${srv_qnx}" = "yes"; then LIBS="$LIBS -lsocket" -elif test "${srv_lynxos}" = "yes"; then - LIBS="$LIBS -lnetinet" fi if test "${srv_linux_usrregs}" = "yes"; then diff --git a/gdbserver/configure.ac b/gdbserver/configure.ac index 090a6dc..0b1c81d 100644 --- a/gdbserver/configure.ac +++ b/gdbserver/configure.ac @@ -227,8 +227,6 @@ elif test "${srv_mingw}" = "yes"; then LIBS="$LIBS $WIN32APILIBS" elif test "${srv_qnx}" = "yes"; then LIBS="$LIBS -lsocket" -elif test "${srv_lynxos}" = "yes"; then - LIBS="$LIBS -lnetinet" fi if test "${srv_linux_usrregs}" = "yes"; then diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv index 9a027e4..24a9306 100644 --- a/gdbserver/configure.srv +++ b/gdbserver/configure.srv @@ -117,12 +117,6 @@ case "${gdbserver_host}" in ipa_obj="linux-i386-ipa.o linux-x86-tdesc-ipa.o" ipa_obj="${ipa_obj} arch/i386-ipa.o" ;; - i[34567]86-*-lynxos*) srv_regobj="" - srv_tgtobj="lynx-low.o lynx-i386-low.o fork-child.o" - srv_tgtobj="${srv_tgtobj} nat/fork-inferior.o" - srv_tgtobj="${srv_tgtobj} arch/i386.o" - srv_lynxos=yes - ;; i[34567]86-*-mingw32ce*) srv_regobj="" srv_tgtobj="x86-low.o nat/x86-dregs.o win32-low.o" @@ -274,13 +268,6 @@ case "${gdbserver_host}" in srv_linux_thread_db=yes ipa_obj="${ipa_ppc_linux_regobj} linux-ppc-ipa.o" ;; - powerpc-*-lynxos*) srv_regobj="powerpc-32.o" - srv_tgtobj="lynx-low.o lynx-ppc-low.o" - srv_xmlfiles="rs6000/powerpc-32.xml" - srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml" - srv_xmlfiles="${srv_xmlfiles} rs6000/power-fpu.xml" - srv_lynxos=yes - ;; riscv*-*-linux*) srv_tgtobj="arch/riscv.o nat/riscv-linux-tdesc.o" srv_tgtobj="${srv_tgtobj} linux-riscv-low.o" srv_tgtobj="${srv_tgtobj} ${srv_linux_obj}" diff --git a/gdbserver/lynx-i386-low.cc b/gdbserver/lynx-i386-low.cc deleted file mode 100644 index d00e1a1..0000000 --- a/gdbserver/lynx-i386-low.cc +++ /dev/null @@ -1,358 +0,0 @@ -/* Copyright (C) 2010-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 <http://www.gnu.org/licenses/>. */ - -#include "server.h" -#include "lynx-low.h" -#include <limits.h> -#include <sys/ptrace.h> -#include "gdbsupport/x86-xstate.h" -#include "arch/i386.h" -#include "x86-tdesc.h" - -/* The following two typedefs are defined in a .h file which is not - in the standard include path (/sys/include/family/x86/ucontext.h), - so we just duplicate them here. - - Unfortunately for us, the definition of this structure differs between - LynxOS 5.x and LynxOS 178. Rather than duplicate the code, we use - different definitions depending on the target. */ - -#ifdef VMOS_DEV -#define LYNXOS_178 -#endif - -/* General register context */ -typedef struct usr_econtext { - - uint32_t uec_fault; - uint32_t uec_es; - uint32_t uec_ds; - uint32_t uec_edi; - uint32_t uec_esi; - uint32_t uec_ebp; - uint32_t uec_temp; - uint32_t uec_ebx; - uint32_t uec_edx; - uint32_t uec_ecx; - uint32_t uec_eax; - uint32_t uec_inum; - uint32_t uec_ecode; - uint32_t uec_eip; - uint32_t uec_cs; - uint32_t uec_eflags; - uint32_t uec_esp; - uint32_t uec_ss; - uint32_t uec_fs; - uint32_t uec_gs; -} usr_econtext_t; - -#if defined(LYNXOS_178) - -/* Floating point register context */ -typedef struct usr_fcontext { - uint32_t ufc_control; - uint32_t ufc_status; - uint32_t ufc_tag; - uint8_t *ufc_inst_off; - uint32_t ufc_inst_sel; - uint8_t *ufc_data_off; - uint32_t ufc_data_sel; - struct ufp387_real { - uint16_t umant4; - uint16_t umant3; - uint16_t umant2; - uint16_t umant1; - uint16_t us_and_e; - } ufc_reg[8]; -} usr_fcontext_t; - -#else /* This is LynxOS 5.x. */ - -/* Floating point and SIMD register context */ -typedef struct usr_fcontext { - uint16_t ufc_control; - uint16_t ufc_status; - uint16_t ufc_tag; - uint16_t ufc_opcode; - uint8_t *ufc_inst_off; - uint32_t ufc_inst_sel; - uint8_t *ufc_data_off; - uint32_t ufc_data_sel; - uint32_t usse_mxcsr; - uint32_t usse_mxcsr_mask; - struct ufp387_real { - uint16_t umant4; - uint16_t umant3; - uint16_t umant2; - uint16_t umant1; - uint16_t us_and_e; - uint16_t ureserved_1; - uint16_t ureserved_2; - uint16_t ureserved_3; - } ufc_reg[8]; - struct uxmm_register { - uint16_t uchunk_1; - uint16_t uchunk_2; - uint16_t uchunk_3; - uint16_t uchunk_4; - uint16_t uchunk_5; - uint16_t uchunk_6; - uint16_t uchunk_7; - uint16_t uchunk_8; - } uxmm_reg[8]; - char ureserved[16][14]; -} usr_fcontext_t; - -#endif - -/* The index of various registers inside the regcache. */ - -enum lynx_i386_gdb_regnum -{ - I386_EAX_REGNUM, - I386_ECX_REGNUM, - I386_EDX_REGNUM, - I386_EBX_REGNUM, - I386_ESP_REGNUM, - I386_EBP_REGNUM, - I386_ESI_REGNUM, - I386_EDI_REGNUM, - I386_EIP_REGNUM, - I386_EFLAGS_REGNUM, - I386_CS_REGNUM, - I386_SS_REGNUM, - I386_DS_REGNUM, - I386_ES_REGNUM, - I386_FS_REGNUM, - I386_GS_REGNUM, - I386_ST0_REGNUM, - I386_FCTRL_REGNUM = I386_ST0_REGNUM + 8, - I386_FSTAT_REGNUM, - I386_FTAG_REGNUM, - I386_FISEG_REGNUM, - I386_FIOFF_REGNUM, - I386_FOSEG_REGNUM, - I386_FOOFF_REGNUM, - I386_FOP_REGNUM, - I386_XMM0_REGNUM = 32, - I386_MXCSR_REGNUM = I386_XMM0_REGNUM + 8, - I386_SENTINEL_REGUM -}; - -/* The fill_function for the general-purpose register set. */ - -static void -lynx_i386_fill_gregset (struct regcache *regcache, char *buf) -{ -#define lynx_i386_collect_gp(regnum, fld) \ - collect_register (regcache, regnum, \ - buf + offsetof (usr_econtext_t, uec_##fld)) - - lynx_i386_collect_gp (I386_EAX_REGNUM, eax); - lynx_i386_collect_gp (I386_ECX_REGNUM, ecx); - lynx_i386_collect_gp (I386_EDX_REGNUM, edx); - lynx_i386_collect_gp (I386_EBX_REGNUM, ebx); - lynx_i386_collect_gp (I386_ESP_REGNUM, esp); - lynx_i386_collect_gp (I386_EBP_REGNUM, ebp); - lynx_i386_collect_gp (I386_ESI_REGNUM, esi); - lynx_i386_collect_gp (I386_EDI_REGNUM, edi); - lynx_i386_collect_gp (I386_EIP_REGNUM, eip); - lynx_i386_collect_gp (I386_EFLAGS_REGNUM, eflags); - lynx_i386_collect_gp (I386_CS_REGNUM, cs); - lynx_i386_collect_gp (I386_SS_REGNUM, ss); - lynx_i386_collect_gp (I386_DS_REGNUM, ds); - lynx_i386_collect_gp (I386_ES_REGNUM, es); - lynx_i386_collect_gp (I386_FS_REGNUM, fs); - lynx_i386_collect_gp (I386_GS_REGNUM, gs); -} - -/* The store_function for the general-purpose register set. */ - -static void -lynx_i386_store_gregset (struct regcache *regcache, const char *buf) -{ -#define lynx_i386_supply_gp(regnum, fld) \ - supply_register (regcache, regnum, \ - buf + offsetof (usr_econtext_t, uec_##fld)) - - lynx_i386_supply_gp (I386_EAX_REGNUM, eax); - lynx_i386_supply_gp (I386_ECX_REGNUM, ecx); - lynx_i386_supply_gp (I386_EDX_REGNUM, edx); - lynx_i386_supply_gp (I386_EBX_REGNUM, ebx); - lynx_i386_supply_gp (I386_ESP_REGNUM, esp); - lynx_i386_supply_gp (I386_EBP_REGNUM, ebp); - lynx_i386_supply_gp (I386_ESI_REGNUM, esi); - lynx_i386_supply_gp (I386_EDI_REGNUM, edi); - lynx_i386_supply_gp (I386_EIP_REGNUM, eip); - lynx_i386_supply_gp (I386_EFLAGS_REGNUM, eflags); - lynx_i386_supply_gp (I386_CS_REGNUM, cs); - lynx_i386_supply_gp (I386_SS_REGNUM, ss); - lynx_i386_supply_gp (I386_DS_REGNUM, ds); - lynx_i386_supply_gp (I386_ES_REGNUM, es); - lynx_i386_supply_gp (I386_FS_REGNUM, fs); - lynx_i386_supply_gp (I386_GS_REGNUM, gs); -} - -/* Extract the first 16 bits of register REGNUM in the REGCACHE, - and store these 2 bytes at DEST. - - This is useful to collect certain 16bit registers which are known - by GDBserver as 32bit registers (such as the Control Register - for instance). */ - -static void -collect_16bit_register (struct regcache *regcache, int regnum, char *dest) -{ - gdb_byte word[4]; - - collect_register (regcache, regnum, word); - memcpy (dest, word, 2); -} - -/* The fill_function for the floating-point register set. */ - -static void -lynx_i386_fill_fpregset (struct regcache *regcache, char *buf) -{ - int i; - - /* Collect %st0 .. %st7. */ - for (i = 0; i < 8; i++) - collect_register (regcache, I386_ST0_REGNUM + i, - buf + offsetof (usr_fcontext_t, ufc_reg) - + i * sizeof (struct ufp387_real)); - - /* Collect the other FPU registers. */ - collect_16bit_register (regcache, I386_FCTRL_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_control)); - collect_16bit_register (regcache, I386_FSTAT_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_status)); - collect_16bit_register (regcache, I386_FTAG_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_tag)); - collect_register (regcache, I386_FISEG_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_inst_sel)); - collect_register (regcache, I386_FIOFF_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_inst_off)); - collect_register (regcache, I386_FOSEG_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_data_sel)); - collect_register (regcache, I386_FOOFF_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_data_off)); -#if !defined(LYNXOS_178) - collect_16bit_register (regcache, I386_FOP_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_opcode)); - - /* Collect the XMM registers. */ - for (i = 0; i < 8; i++) - collect_register (regcache, I386_XMM0_REGNUM + i, - buf + offsetof (usr_fcontext_t, uxmm_reg) - + i * sizeof (struct uxmm_register)); - collect_register (regcache, I386_MXCSR_REGNUM, - buf + offsetof (usr_fcontext_t, usse_mxcsr)); -#endif -} - -/* This is the supply counterpart for collect_16bit_register: - It extracts a 2byte value from BUF, and uses that value to - set REGNUM's value in the regcache. - - This is useful to supply the value of certain 16bit registers - which are known by GDBserver as 32bit registers (such as the Control - Register for instance). */ - -static void -supply_16bit_register (struct regcache *regcache, int regnum, const char *buf) -{ - gdb_byte word[4]; - - memcpy (word, buf, 2); - memset (word + 2, 0, 2); - supply_register (regcache, regnum, word); -} - -/* The store_function for the floating-point register set. */ - -static void -lynx_i386_store_fpregset (struct regcache *regcache, const char *buf) -{ - int i; - - /* Store the %st0 .. %st7 registers. */ - for (i = 0; i < 8; i++) - supply_register (regcache, I386_ST0_REGNUM + i, - buf + offsetof (usr_fcontext_t, ufc_reg) - + i * sizeof (struct ufp387_real)); - - /* Store the other FPU registers. */ - supply_16bit_register (regcache, I386_FCTRL_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_control)); - supply_16bit_register (regcache, I386_FSTAT_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_status)); - supply_16bit_register (regcache, I386_FTAG_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_tag)); - supply_register (regcache, I386_FISEG_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_inst_sel)); - supply_register (regcache, I386_FIOFF_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_inst_off)); - supply_register (regcache, I386_FOSEG_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_data_sel)); - supply_register (regcache, I386_FOOFF_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_data_off)); -#if !defined(LYNXOS_178) - supply_16bit_register (regcache, I386_FOP_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_opcode)); - - /* Store the XMM registers. */ - for (i = 0; i < 8; i++) - supply_register (regcache, I386_XMM0_REGNUM + i, - buf + offsetof (usr_fcontext_t, uxmm_reg) - + i * sizeof (struct uxmm_register)); - supply_register (regcache, I386_MXCSR_REGNUM, - buf + offsetof (usr_fcontext_t, usse_mxcsr)); -#endif -} - -/* Implements the lynx_target_ops.arch_setup routine. */ - -static void -lynx_i386_arch_setup (void) -{ - struct target_desc *tdesc - = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); - - init_target_desc (tdesc, i386_expedite_regs); - - lynx_tdesc = tdesc; -} - -/* Description of all the x86-lynx register sets. */ - -struct lynx_regset_info lynx_target_regsets[] = { - /* General Purpose Registers. */ - {PTRACE_GETREGS, PTRACE_SETREGS, sizeof(usr_econtext_t), - lynx_i386_fill_gregset, lynx_i386_store_gregset}, - /* Floating Point Registers. */ - { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof(usr_fcontext_t), - lynx_i386_fill_fpregset, lynx_i386_store_fpregset }, - /* End of list marker. */ - {0, 0, -1, NULL, NULL } -}; - -/* The lynx_target_ops vector for x86-lynx. */ - -struct lynx_target_ops the_low_target = { - lynx_i386_arch_setup, -}; diff --git a/gdbserver/lynx-low.cc b/gdbserver/lynx-low.cc deleted file mode 100644 index a8e4e60..0000000 --- a/gdbserver/lynx-low.cc +++ /dev/null @@ -1,747 +0,0 @@ -/* 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 <http://www.gnu.org/licenses/>. */ - -#include "server.h" -#include "target.h" -#include "lynx-low.h" - -#include <limits.h> -#include <sys/ptrace.h> -#include <sys/piddef.h> /* Provides PIDGET, TIDGET, BUILDPID, etc. */ -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include "gdbsupport/gdb_wait.h" -#include <signal.h> -#include "gdbsupport/filestuff.h" -#include "gdbsupport/common-inferior.h" -#include "nat/fork-inferior.h" - -int using_threads = 1; - -const struct target_desc *lynx_tdesc; - -/* Per-process private data. */ - -struct process_info_private -{ - /* The PTID obtained from the last wait performed on this process. - Initialized to null_ptid until the first wait is performed. */ - ptid_t last_wait_event_ptid; -}; - -/* Print a debug trace on standard output if debug_threads is set. */ - -static void -lynx_debug (char *string, ...) -{ - va_list args; - - if (!debug_threads) - return; - - va_start (args, string); - fprintf (stderr, "DEBUG(lynx): "); - vfprintf (stderr, string, args); - fprintf (stderr, "\n"); - va_end (args); -} - -/* Build a ptid_t given a PID and a LynxOS TID. */ - -static ptid_t -lynx_ptid_t (int pid, long tid) -{ - /* brobecker/2010-06-21: It looks like the LWP field in ptids - should be distinct for each thread (see write_ptid where it - writes the thread ID from the LWP). So instead of storing - the LynxOS tid in the tid field of the ptid, we store it in - the lwp field. */ - return ptid_t (pid, tid, 0); -} - -/* Return the process ID of the given PTID. - - This function has little reason to exist, it's just a wrapper around - ptid_get_pid. But since we have a getter function for the lynxos - ptid, it feels cleaner to have a getter for the pid as well. */ - -static int -lynx_ptid_get_pid (ptid_t ptid) -{ - return ptid.pid (); -} - -/* Return the LynxOS tid of the given PTID. */ - -static long -lynx_ptid_get_tid (ptid_t ptid) -{ - /* See lynx_ptid_t: The LynxOS tid is stored inside the lwp field - of the ptid. */ - return ptid.lwp (); -} - -/* For a given PTID, return the associated PID as known by the LynxOS - ptrace layer. */ - -static int -lynx_ptrace_pid_from_ptid (ptid_t ptid) -{ - return BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); -} - -/* Return a string image of the ptrace REQUEST number. */ - -static char * -ptrace_request_to_str (int request) -{ -#define CASE(X) case X: return #X - switch (request) - { - CASE(PTRACE_TRACEME); - CASE(PTRACE_PEEKTEXT); - CASE(PTRACE_PEEKDATA); - CASE(PTRACE_PEEKUSER); - CASE(PTRACE_POKETEXT); - CASE(PTRACE_POKEDATA); - CASE(PTRACE_POKEUSER); - CASE(PTRACE_CONT); - CASE(PTRACE_KILL); - CASE(PTRACE_SINGLESTEP); - CASE(PTRACE_ATTACH); - CASE(PTRACE_DETACH); - CASE(PTRACE_GETREGS); - CASE(PTRACE_SETREGS); - CASE(PTRACE_GETFPREGS); - CASE(PTRACE_SETFPREGS); - CASE(PTRACE_READDATA); - CASE(PTRACE_WRITEDATA); - CASE(PTRACE_READTEXT); - CASE(PTRACE_WRITETEXT); - CASE(PTRACE_GETFPAREGS); - CASE(PTRACE_SETFPAREGS); - CASE(PTRACE_GETWINDOW); - CASE(PTRACE_SETWINDOW); - CASE(PTRACE_SYSCALL); - CASE(PTRACE_DUMPCORE); - CASE(PTRACE_SETWRBKPT); - CASE(PTRACE_SETACBKPT); - CASE(PTRACE_CLRBKPT); - CASE(PTRACE_GET_UCODE); -#ifdef PT_READ_GPR - CASE(PT_READ_GPR); -#endif -#ifdef PT_WRITE_GPR - CASE(PT_WRITE_GPR); -#endif -#ifdef PT_READ_FPR - CASE(PT_READ_FPR); -#endif -#ifdef PT_WRITE_FPR - CASE(PT_WRITE_FPR); -#endif -#ifdef PT_READ_VPR - CASE(PT_READ_VPR); -#endif -#ifdef PT_WRITE_VPR - CASE(PT_WRITE_VPR); -#endif -#ifdef PTRACE_PEEKUSP - CASE(PTRACE_PEEKUSP); -#endif -#ifdef PTRACE_POKEUSP - CASE(PTRACE_POKEUSP); -#endif - CASE(PTRACE_PEEKTHREAD); - CASE(PTRACE_THREADUSER); - CASE(PTRACE_FPREAD); - CASE(PTRACE_FPWRITE); - CASE(PTRACE_SETSIG); - CASE(PTRACE_CONT_ONE); - CASE(PTRACE_KILL_ONE); - CASE(PTRACE_SINGLESTEP_ONE); - CASE(PTRACE_GETLOADINFO); - CASE(PTRACE_GETTRACESIG); -#ifdef PTRACE_GETTHREADLIST - CASE(PTRACE_GETTHREADLIST); -#endif - } -#undef CASE - - return "<unknown-request>"; -} - -/* A wrapper around ptrace that allows us to print debug traces of - ptrace calls if debug traces are activated. */ - -static int -lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2) -{ - int result; - const int pid = lynx_ptrace_pid_from_ptid (ptid); - int saved_errno; - - if (debug_threads) - fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, " - "data=0x%x, addr2=0x%x)", - ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid), - addr, data, addr2); - result = ptrace (request, pid, addr, data, addr2); - saved_errno = errno; - if (debug_threads) - fprintf (stderr, " -> %d (=0x%x)\n", result, result); - - errno = saved_errno; - return result; -} - -/* Call add_process with the given parameters, and initializes - the process' private data. */ - -static struct process_info * -lynx_add_process (int pid, int attached) -{ - struct process_info *proc; - - proc = add_process (pid, attached); - proc->tdesc = lynx_tdesc; - proc->priv = XCNEW (struct process_info_private); - proc->priv->last_wait_event_ptid = null_ptid; - - return proc; -} - -/* Callback used by fork_inferior to start tracing the inferior. */ - -static void -lynx_ptrace_fun () -{ - int pgrp; - - /* Switch child to its own process group so that signals won't - directly affect GDBserver. */ - pgrp = getpid(); - if (pgrp < 0) - trace_start_error_with_name ("pgrp"); - if (setpgid (0, pgrp) < 0) - trace_start_error_with_name ("setpgid"); - if (ioctl (0, TIOCSPGRP, &pgrp) < 0) - trace_start_error_with_name ("ioctl"); - if (lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0) < 0) - trace_start_error_with_name ("lynx_ptrace"); -} - -/* Implement the create_inferior method of the target_ops vector. */ - -int -lynx_process_target::create_inferior (const char *program, - const std::vector<char *> &program_args) -{ - int pid; - std::string str_program_args = construct_inferior_arguments (program_args); - - lynx_debug ("create_inferior ()"); - - pid = fork_inferior (program, - str_program_args.c_str (), - get_environ ()->envp (), lynx_ptrace_fun, - NULL, NULL, NULL, NULL); - - post_fork_inferior (pid, program); - - lynx_add_process (pid, 0); - /* Do not add the process thread just yet, as we do not know its tid. - We will add it later, during the wait for the STOP event corresponding - to the lynx_ptrace (PTRACE_TRACEME) call above. */ - return pid; -} - -/* Assuming we've just attached to a running inferior whose pid is PID, - add all threads running in that process. */ - -static void -lynx_add_threads_after_attach (int pid) -{ - /* Ugh! There appears to be no way to get the list of threads - in the program we just attached to. So get the list by calling - the "ps" command. This is only needed now, as we will then - keep the thread list up to date thanks to thread creation and - exit notifications. */ - FILE *f; - char buf[256]; - int thread_pid, thread_tid; - - f = popen ("ps atx", "r"); - if (f == NULL) - perror_with_name ("Cannot get thread list"); - - while (fgets (buf, sizeof (buf), f) != NULL) - if ((sscanf (buf, "%d %d", &thread_pid, &thread_tid) == 2 - && thread_pid == pid)) - { - ptid_t thread_ptid = lynx_ptid_t (pid, thread_tid); - - if (!find_thread_ptid (thread_ptid)) - { - lynx_debug ("New thread: (pid = %d, tid = %d)", - pid, thread_tid); - add_thread (thread_ptid, NULL); - } - } - - pclose (f); -} - -/* Implement the attach target_ops method. */ - -int -lynx_process_target::attach (unsigned long pid) -{ - ptid_t ptid = lynx_ptid_t (pid, 0); - - if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0) - error ("Cannot attach to process %lu: %s (%d)\n", pid, - safe_strerror (errno), errno); - - lynx_add_process (pid, 1); - lynx_add_threads_after_attach (pid); - - return 0; -} - -/* Implement the resume target_ops method. */ - -void -lynx_process_target::resume (thread_resume *resume_info, size_t n) -{ - ptid_t ptid = resume_info[0].thread; - const int request - = (resume_info[0].kind == resume_step - ? (n == 1 ? PTRACE_SINGLESTEP_ONE : PTRACE_SINGLESTEP) - : PTRACE_CONT); - const int signal = resume_info[0].sig; - - /* If given a minus_one_ptid, then try using the current_process' - private->last_wait_event_ptid. On most LynxOS versions, - using any of the process' thread works well enough, but - LynxOS 178 is a little more sensitive, and triggers some - unexpected signals (Eg SIG61) when we resume the inferior - using a different thread. */ - if (ptid == minus_one_ptid) - ptid = current_process()->priv->last_wait_event_ptid; - - /* The ptid might still be minus_one_ptid; this can happen between - the moment we create the inferior or attach to a process, and - the moment we resume its execution for the first time. It is - fine to use the current_thread's ptid in those cases. */ - if (ptid == minus_one_ptid) - ptid = ptid_of (current_thread); - - regcache_invalidate_pid (ptid.pid ()); - - errno = 0; - lynx_ptrace (request, ptid, 1, signal, 0); - if (errno) - perror_with_name ("ptrace"); -} - -/* Resume the execution of the given PTID. */ - -static void -lynx_continue (ptid_t ptid) -{ - struct thread_resume resume_info; - - resume_info.thread = ptid; - resume_info.kind = resume_continue; - resume_info.sig = 0; - - lynx_resume (&resume_info, 1); -} - -/* A wrapper around waitpid that handles the various idiosyncrasies - of LynxOS' waitpid. */ - -static int -lynx_waitpid (int pid, int *stat_loc) -{ - int ret = 0; - - while (1) - { - ret = waitpid (pid, stat_loc, WNOHANG); - if (ret < 0) - { - /* An ECHILD error is not indicative of a real problem. - It happens for instance while waiting for the inferior - to stop after attaching to it. */ - if (errno != ECHILD) - perror_with_name ("waitpid (WNOHANG)"); - } - if (ret > 0) - break; - /* No event with WNOHANG. See if there is one with WUNTRACED. */ - ret = waitpid (pid, stat_loc, WNOHANG | WUNTRACED); - if (ret < 0) - { - /* An ECHILD error is not indicative of a real problem. - It happens for instance while waiting for the inferior - to stop after attaching to it. */ - if (errno != ECHILD) - perror_with_name ("waitpid (WNOHANG|WUNTRACED)"); - } - if (ret > 0) - break; - usleep (1000); - } - return ret; -} - -/* Implement the wait target_ops method. */ - -static ptid_t -lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options) -{ - int pid; - int ret; - int wstat; - ptid_t new_ptid; - - if (ptid == minus_one_ptid) - pid = lynx_ptid_get_pid (ptid_of (current_thread)); - else - pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); - -retry: - - ret = lynx_waitpid (pid, &wstat); - new_ptid = lynx_ptid_t (ret, ((union wait *) &wstat)->w_tid); - find_process_pid (ret)->priv->last_wait_event_ptid = new_ptid; - - /* If this is a new thread, then add it now. The reason why we do - this here instead of when handling new-thread events is because - we need to add the thread associated to the "main" thread - even - for non-threaded applications where the new-thread events are not - generated. */ - if (!find_thread_ptid (new_ptid)) - { - lynx_debug ("New thread: (pid = %d, tid = %d)", - lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid)); - add_thread (new_ptid, NULL); - } - - if (WIFSTOPPED (wstat)) - { - status->kind = TARGET_WAITKIND_STOPPED; - status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat)); - lynx_debug ("process stopped with signal: %d", - status->value.integer); - } - else if (WIFEXITED (wstat)) - { - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = WEXITSTATUS (wstat); - lynx_debug ("process exited with code: %d", status->value.integer); - } - else if (WIFSIGNALED (wstat)) - { - status->kind = TARGET_WAITKIND_SIGNALLED; - status->value.integer = gdb_signal_from_host (WTERMSIG (wstat)); - lynx_debug ("process terminated with code: %d", - status->value.integer); - } - else - { - /* Not sure what happened if we get here, or whether we can - in fact get here. But if we do, handle the event the best - we can. */ - status->kind = TARGET_WAITKIND_STOPPED; - status->value.integer = gdb_signal_from_host (0); - lynx_debug ("unknown event ????"); - } - - /* SIGTRAP events are generated for situations other than single-step/ - breakpoint events (Eg. new-thread events). Handle those other types - of events, and resume the execution if necessary. */ - if (status->kind == TARGET_WAITKIND_STOPPED - && status->value.integer == GDB_SIGNAL_TRAP) - { - const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0); - - lynx_debug ("(realsig = %d)", realsig); - switch (realsig) - { - case SIGNEWTHREAD: - /* We just added the new thread above. No need to do anything - further. Just resume the execution again. */ - lynx_continue (new_ptid); - goto retry; - - case SIGTHREADEXIT: - remove_thread (find_thread_ptid (new_ptid)); - lynx_continue (new_ptid); - goto retry; - } - } - - return new_ptid; -} - -/* A wrapper around lynx_wait_1 that also prints debug traces when - such debug traces have been activated. */ - -ptid_t -lynx_process_target::wait (ptid_t ptid, target_waitstatus *status, - int options) -{ - ptid_t new_ptid; - - lynx_debug ("wait (pid = %d, tid = %ld)", - lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid)); - new_ptid = lynx_wait_1 (ptid, status, options); - lynx_debug (" -> (pid=%d, tid=%ld, status->kind = %d)", - lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid), - status->kind); - return new_ptid; -} - -/* Implement the kill target_ops method. */ - -int -lynx_process_target::kill (process_info *process) -{ - ptid_t ptid = lynx_ptid_t (process->pid, 0); - struct target_waitstatus status; - - lynx_ptrace (PTRACE_KILL, ptid, 0, 0, 0); - lynx_wait (ptid, &status, 0); - mourn (process); - return 0; -} - -/* Implement the detach target_ops method. */ - -int -lynx_process_target::detach (process_info *process) -{ - ptid_t ptid = lynx_ptid_t (process->pid, 0); - - lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0); - mourn (process); - return 0; -} - -/* Implement the mourn target_ops method. */ - -void -lynx_process_target::mourn (struct process_info *proc) -{ - for_each_thread (proc->pid, remove_thread); - - /* Free our private data. */ - free (proc->priv); - proc->priv = NULL; - - remove_process (proc); -} - -/* Implement the join target_ops method. */ - -void -lynx_process_target::join (int pid) -{ - /* The PTRACE_DETACH is sufficient to detach from the process. - So no need to do anything extra. */ -} - -/* Implement the thread_alive target_ops method. */ - -bool -lynx_process_target::thread_alive (ptid_t ptid) -{ - /* The list of threads is updated at the end of each wait, so it - should be up to date. No need to re-fetch it. */ - return (find_thread_ptid (ptid) != NULL); -} - -/* Implement the fetch_registers target_ops method. */ - -void -lynx_process_target::fetch_registers (regcache *regcache, int regno) -{ - struct lynx_regset_info *regset = lynx_target_regsets; - ptid_t inferior_ptid = ptid_of (current_thread); - - lynx_debug ("fetch_registers (regno = %d)", regno); - - while (regset->size >= 0) - { - char *buf; - int res; - - buf = xmalloc (regset->size); - res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0); - if (res < 0) - perror ("ptrace"); - regset->store_function (regcache, buf); - free (buf); - regset++; - } -} - -/* Implement the store_registers target_ops method. */ - -void -lynx_process_target::store_registers (regcache *regcache, int regno) -{ - struct lynx_regset_info *regset = lynx_target_regsets; - ptid_t inferior_ptid = ptid_of (current_thread); - - lynx_debug ("store_registers (regno = %d)", regno); - - while (regset->size >= 0) - { - char *buf; - int res; - - buf = xmalloc (regset->size); - res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0); - if (res == 0) - { - /* Then overlay our cached registers on that. */ - regset->fill_function (regcache, buf); - /* Only now do we write the register set. */ - res = lynx_ptrace (regset->set_request, inferior_ptid, (int) buf, - 0, 0); - } - if (res < 0) - perror ("ptrace"); - free (buf); - regset++; - } -} - -/* Implement the read_memory target_ops method. */ - -int -lynx_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr, - int len) -{ - /* On LynxOS, memory reads needs to be performed in chunks the size - of int types, and they should also be aligned accordingly. */ - int buf; - const int xfer_size = sizeof (buf); - CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size; - ptid_t inferior_ptid = ptid_of (current_thread); - - while (addr < memaddr + len) - { - int skip = 0; - int truncate = 0; - - errno = 0; - if (addr < memaddr) - skip = memaddr - addr; - if (addr + xfer_size > memaddr + len) - truncate = addr + xfer_size - memaddr - len; - buf = lynx_ptrace (PTRACE_PEEKTEXT, inferior_ptid, addr, 0, 0); - if (errno) - return errno; - memcpy (myaddr + (addr - memaddr) + skip, (gdb_byte *) &buf + skip, - xfer_size - skip - truncate); - addr += xfer_size; - } - - return 0; -} - -/* Implement the write_memory target_ops method. */ - -int -lynx_process_target::write_memory (CORE_ADDR memaddr, - const unsigned char *myaddr, int len) -{ - /* On LynxOS, memory writes needs to be performed in chunks the size - of int types, and they should also be aligned accordingly. */ - int buf; - const int xfer_size = sizeof (buf); - CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size; - ptid_t inferior_ptid = ptid_of (current_thread); - - while (addr < memaddr + len) - { - int skip = 0; - int truncate = 0; - - if (addr < memaddr) - skip = memaddr - addr; - if (addr + xfer_size > memaddr + len) - truncate = addr + xfer_size - memaddr - len; - if (skip > 0 || truncate > 0) - { - /* We need to read the memory at this address in order to preserve - the data that we are not overwriting. */ - read_memory (addr, (unsigned char *) &buf, xfer_size); - if (errno) - return errno; - } - memcpy ((gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip, - xfer_size - skip - truncate); - errno = 0; - lynx_ptrace (PTRACE_POKETEXT, inferior_ptid, addr, buf, 0); - if (errno) - return errno; - addr += xfer_size; - } - - return 0; -} - -/* Implement the kill_request target_ops method. */ - -void -lynx_process_target::request_interrupt () -{ - ptid_t inferior_ptid = ptid_of (get_first_thread ()); - - kill (lynx_ptid_get_pid (inferior_ptid), SIGINT); -} - -bool -lynx_process_target::supports_hardware_single_step () -{ - return true; -} - -const gdb_byte * -lynx_process_target::sw_breakpoint_from_kind (int kind, int *size) -{ - error (_("Target does not implement the sw_breakpoint_from_kind op")); -} - -/* The LynxOS target ops object. */ - -static lynx_process_target the_lynx_target; - -void -initialize_low (void) -{ - set_target_ops (&the_lynx_target); - the_low_target.arch_setup (); -} - diff --git a/gdbserver/lynx-low.h b/gdbserver/lynx-low.h deleted file mode 100644 index fa975a2..0000000 --- a/gdbserver/lynx-low.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (C) 2010-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 <http://www.gnu.org/licenses/>. */ - -#ifndef GDBSERVER_LYNX_LOW_H -#define GDBSERVER_LYNX_LOW_H - -struct regcache; -struct target_desc; - -/* Some information relative to a given register set. */ - -struct lynx_regset_info -{ - /* The ptrace request needed to get/set registers of this set. */ - int get_request, set_request; - /* The size of the register set. */ - int size; - /* Fill the buffer BUF from the contents of the given REGCACHE. */ - void (*fill_function) (struct regcache *regcache, char *buf); - /* Store the register value in BUF in the given REGCACHE. */ - void (*store_function) (struct regcache *regcache, const char *buf); -}; - -/* A list of regsets for the target being debugged, terminated by an entry - where the size is negative. - - This list should be created by the target-specific code. */ - -extern struct lynx_regset_info lynx_target_regsets[]; - -/* The target-specific operations for LynxOS support. */ - -struct lynx_target_ops -{ - /* Architecture-specific setup. */ - void (*arch_setup) (void); -}; - -extern struct lynx_target_ops the_low_target; - -/* Target ops definitions for a LynxOS target. */ - -class lynx_process_target : public process_stratum_target -{ -public: - - int create_inferior (const char *program, - const std::vector<char *> &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_hardware_single_step () 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 *lynx_tdesc; - -#endif /* GDBSERVER_LYNX_LOW_H */ diff --git a/gdbserver/lynx-ppc-low.cc b/gdbserver/lynx-ppc-low.cc deleted file mode 100644 index f93fc1d..0000000 --- a/gdbserver/lynx-ppc-low.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* 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 <http://www.gnu.org/licenses/>. */ - -#include "server.h" -#include "lynx-low.h" -#include <limits.h> -#include <sys/ptrace.h> - -/* The following two typedefs are defined in a .h file which is not - in the standard include path (/sys/include/family/ppc/ucontext.h), - so we just duplicate them here. */ - -/* General register context */ -typedef struct usr_econtext_s -{ - uint32_t uec_iregs[32]; - uint32_t uec_inum; - uint32_t uec_srr0; - uint32_t uec_srr1; - uint32_t uec_lr; - uint32_t uec_ctr; - uint32_t uec_cr; - uint32_t uec_xer; - uint32_t uec_dar; - uint32_t uec_mq; - uint32_t uec_msr; - uint32_t uec_sregs[16]; - uint32_t uec_ss_count; - uint32_t uec_ss_addr1; - uint32_t uec_ss_addr2; - uint32_t uec_ss_code1; - uint32_t uec_ss_code2; -} usr_econtext_t; - -/* Floating point register context */ -typedef struct usr_fcontext_s -{ - uint64_t ufc_freg[32]; - uint32_t ufc_fpscr[2]; -} usr_fcontext_t; - -/* Index of for various registers inside the regcache. */ -#define R0_REGNUM 0 -#define F0_REGNUM 32 -#define PC_REGNUM 64 -#define MSR_REGNUM 65 -#define CR_REGNUM 66 -#define LR_REGNUM 67 -#define CTR_REGNUM 68 -#define XER_REGNUM 69 -#define FPSCR_REGNUM 70 - -/* Defined in auto-generated file powerpc-32.c. */ -extern void init_registers_powerpc_32 (void); -extern const struct target_desc *tdesc_powerpc_32; - -/* The fill_function for the general-purpose register set. */ - -static void -lynx_ppc_fill_gregset (struct regcache *regcache, char *buf) -{ - int i; - - /* r0 - r31 */ - for (i = 0; i < 32; i++) - collect_register (regcache, R0_REGNUM + i, - buf + offsetof (usr_econtext_t, uec_iregs[i])); - - /* The other registers provided in the GP register context. */ - collect_register (regcache, PC_REGNUM, - buf + offsetof (usr_econtext_t, uec_srr0)); - collect_register (regcache, MSR_REGNUM, - buf + offsetof (usr_econtext_t, uec_srr1)); - collect_register (regcache, CR_REGNUM, - buf + offsetof (usr_econtext_t, uec_cr)); - collect_register (regcache, LR_REGNUM, - buf + offsetof (usr_econtext_t, uec_lr)); - collect_register (regcache, CTR_REGNUM, - buf + offsetof (usr_econtext_t, uec_ctr)); - collect_register (regcache, XER_REGNUM, - buf + offsetof (usr_econtext_t, uec_xer)); -} - -/* The store_function for the general-purpose register set. */ - -static void -lynx_ppc_store_gregset (struct regcache *regcache, const char *buf) -{ - int i; - - /* r0 - r31 */ - for (i = 0; i < 32; i++) - supply_register (regcache, R0_REGNUM + i, - buf + offsetof (usr_econtext_t, uec_iregs[i])); - - /* The other registers provided in the GP register context. */ - supply_register (regcache, PC_REGNUM, - buf + offsetof (usr_econtext_t, uec_srr0)); - supply_register (regcache, MSR_REGNUM, - buf + offsetof (usr_econtext_t, uec_srr1)); - supply_register (regcache, CR_REGNUM, - buf + offsetof (usr_econtext_t, uec_cr)); - supply_register (regcache, LR_REGNUM, - buf + offsetof (usr_econtext_t, uec_lr)); - supply_register (regcache, CTR_REGNUM, - buf + offsetof (usr_econtext_t, uec_ctr)); - supply_register (regcache, XER_REGNUM, - buf + offsetof (usr_econtext_t, uec_xer)); -} - -/* The fill_function for the floating-point register set. */ - -static void -lynx_ppc_fill_fpregset (struct regcache *regcache, char *buf) -{ - int i; - - /* f0 - f31 */ - for (i = 0; i < 32; i++) - collect_register (regcache, F0_REGNUM + i, - buf + offsetof (usr_fcontext_t, ufc_freg[i])); - - /* fpscr */ - collect_register (regcache, FPSCR_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_fpscr)); -} - -/* The store_function for the floating-point register set. */ - -static void -lynx_ppc_store_fpregset (struct regcache *regcache, const char *buf) -{ - int i; - - /* f0 - f31 */ - for (i = 0; i < 32; i++) - supply_register (regcache, F0_REGNUM + i, - buf + offsetof (usr_fcontext_t, ufc_freg[i])); - - /* fpscr */ - supply_register (regcache, FPSCR_REGNUM, - buf + offsetof (usr_fcontext_t, ufc_fpscr)); -} - -/* Implements the lynx_target_ops.arch_setup routine. */ - -static void -lynx_ppc_arch_setup (void) -{ - init_registers_powerpc_32 (); - lynx_tdesc = tdesc_powerpc_32; -} - -/* Description of all the powerpc-lynx register sets. */ - -struct lynx_regset_info lynx_target_regsets[] = { - /* General Purpose Registers. */ - {PTRACE_GETREGS, PTRACE_SETREGS, sizeof(usr_econtext_t), - lynx_ppc_fill_gregset, lynx_ppc_store_gregset}, - /* Floating Point Registers. */ - { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof(usr_fcontext_t), - lynx_ppc_fill_fpregset, lynx_ppc_store_fpregset }, - /* End of list marker. */ - {0, 0, -1, NULL, NULL } -}; - -/* The lynx_target_ops vector for powerpc-lynxos. */ - -struct lynx_target_ops the_low_target = { - lynx_ppc_arch_setup, -}; |