From: Stan Shebs Date: Sat, 30 Oct 1993 00:16:25 +0000 (+0000) Subject: More LynxOS support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9bebe5008136deb7bed1667f637bb47b0fc1580b;p=binutils-gdb.git More LynxOS support --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9f0e5f9750f..1788c7f959f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +Fri Oct 29 16:30:36 1993 Stan Shebs (shebs@rtl.cygnus.com) + + LynxOS support: + * configure.in: Change *-*-lynx* to *-*-lynxos*, add + sparc-*-lynxos*. + * Makefile.in (ALLDEPFILES): Add m68kly-nat.c, sparcly-nat.c. + Rename i386lynx-nat.[co] to i386ly-nat.[co]. + (ALLCONFIG): Add config/{m68k,sparc}/{m68k,sparc}lynx.m[ht]. + (m68kly-nat.o, sparcly-nat.o): Add rules. + * i386ly-tdep.c: Cosmetics. + * i386lynx-nat.c: Removed. + * i386ly-nat.c: New file, was i386lynx-nat.c. + * m68kly-nat.c: New file. + * sparcly-nat.c: New file. + * config/xm-lynx.h: New file, cpu-independent host info. + * config/i386/i386lynx.mh: Changes for consistency. + * config/i386/i386lynx.mt: Ditto. + * config/i386/tm-i386lynx.h: Ditto. + * config/i386/nm-i386lynx.h: Ditto. + * config/i386/xm-i386lynx.h: Include config/xm-lynx.h. + * config/m68k/m68klynx.mh, config/m68k/m68klynx.mt, + config/m68k/tm-m68klynx.h, config/m68k/nm-m68klynx.h, + config/m68k/xm-m68klynx.h: New files, M68K LynxOS support. + * config/sparc/sparclynx.mh, config/sparc/sparclynx.mt, + config/sparc/tm-sparclynx.h, config/sparc/nm-sparclynx.h, + config/sparc/xm-sparclynx.h: New files, Sparc LynxOS support. + Fri Oct 29 08:11:29 1993 Jim Kingdon (kingdon@lioth.cygnus.com) * defs.h, findvar.c (extract_floating, store_floating): New functions. diff --git a/gdb/config/i386/i386lynx.mh b/gdb/config/i386/i386lynx.mh index 51b70baa9ca..b979292bf9e 100644 --- a/gdb/config/i386/i386lynx.mh +++ b/gdb/config/i386/i386lynx.mh @@ -1,8 +1,8 @@ -# Host: Intel 386 running Lynx -XDEPFILES= -NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i386lynx-nat.o +# Host: Intel 386 running LynxOS XM_FILE= xm-i386lynx.h +XDEPFILES= NAT_FILE= nm-i386lynx.h +NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o i386ly-nat.o REGEX=regex.o REGEX1=regex.o GDBSERVER_LIBS= -lbsd diff --git a/gdb/config/i386/i386lynx.mt b/gdb/config/i386/i386lynx.mt index 224c12a43c9..56e0cdfc090 100644 --- a/gdb/config/i386/i386lynx.mt +++ b/gdb/config/i386/i386lynx.mt @@ -1,3 +1,3 @@ -# Target: Intel 386 running Lynx +# Target: Intel 386 running LynxOS TDEPFILES= exec.o coff-solib.o i386-tdep.o i386-pinsn.o i386ly-tdep.o TM_FILE= tm-i386lynx.h diff --git a/gdb/config/i386/nm-i386lynx.h b/gdb/config/i386/nm-i386lynx.h index e67ec1dc9cb..b4635016596 100644 --- a/gdb/config/i386/nm-i386lynx.h +++ b/gdb/config/i386/nm-i386lynx.h @@ -1,5 +1,5 @@ -/* Native-dependent definitions for Intel 386 running Lynx, for GDB. - Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc. +/* Native-dependent definitions for Intel 386 running LynxOS. + Copyright 1993 Free Software Foundation, Inc. This file is part of GDB. @@ -31,8 +31,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "thread.h" -/* This is the amount to subtract from u.u_ar0 - to get the offset in the core file of the register values. */ +/* This is the amount to subtract from u.u_ar0 to get the offset in + the core file of the register values. */ #define KERNEL_U_ADDR USRSTACK @@ -54,7 +54,8 @@ i386_register_u_addr PARAMS ((int, int)); #define WIFTID(x) (((union wait *)&x)->w_tid) #define CHILD_WAIT -extern int child_wait PARAMS ((int *status)); + +extern int child_wait PARAMS ((int pid, int *status)); /* Lynx needs a special definition of this so that we can print out the pid and thread number seperatly. */ diff --git a/gdb/config/i386/tm-i386lynx.h b/gdb/config/i386/tm-i386lynx.h index 1385c9629cc..8faf9ebe8ff 100644 --- a/gdb/config/i386/tm-i386lynx.h +++ b/gdb/config/i386/tm-i386lynx.h @@ -1,5 +1,5 @@ -/* Macro definitions for i386 running under BSD Unix. - Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. +/* Macro definitions for Intel 386 running under LynxOS. + Copyright 1993 Free Software Foundation, Inc. This file is part of GDB. diff --git a/gdb/config/i386/xm-i386lynx.h b/gdb/config/i386/xm-i386lynx.h index f0c1198049d..3c6881b1736 100644 --- a/gdb/config/i386/xm-i386lynx.h +++ b/gdb/config/i386/xm-i386lynx.h @@ -1,5 +1,5 @@ -/* Host-dependent definitions for Intel 386 running Lynx, for GDB. - Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc. +/* Host-dependent definitions for Intel 386 running LynxOS. + Copyright 1993 Free Software Foundation, Inc. This file is part of GDB. @@ -19,15 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define HOST_BYTE_ORDER LITTLE_ENDIAN -#include /* for INT_MIN, to avoid "INT_MIN - redefined" warnings from defs.h */ +/* Get generic LynxOS host definitions. */ -/* psignal() is in . */ - -#define PSIGNAL_IN_SIGNAL_H - -/* Get rid of any system-imposed stack limit if possible. */ - -#define SET_STACK_LIMIT_HUGE - -#define MEM_FNS_DECLARED +#include "xm-lynx.h" diff --git a/gdb/config/m68k/m68klynx.mh b/gdb/config/m68k/m68klynx.mh new file mode 100644 index 00000000000..4d80b0b38c1 --- /dev/null +++ b/gdb/config/m68k/m68klynx.mh @@ -0,0 +1,9 @@ +# Host: Motorola 680x0 running LynxOS +XM_FILE= xm-m68klynx.h +XDEPFILES= +NAT_FILE= nm-m68klynx.h +NATDEPFILES= exec.o infptrace.o inftarg.o fork-child.o corelow.o m68kly-nat.o +REGEX=regex.o +REGEX1=regex.o +GDBSERVER_LIBS= -lbsd +GDBSERVER_DEPFILES= low-lynx.o diff --git a/gdb/config/m68k/m68klynx.mt b/gdb/config/m68k/m68klynx.mt new file mode 100644 index 00000000000..4ac81b6e36e --- /dev/null +++ b/gdb/config/m68k/m68klynx.mt @@ -0,0 +1,4 @@ +# Target: Motorola 680x0 running LynxOS +TDEPFILES= exec.o coff-solib.o m68k-tdep.o m68k-pinsn.o +# m68kly-tdep.o +TM_FILE= tm-m68klynx.h diff --git a/gdb/config/m68k/nm-m68klynx.h b/gdb/config/m68k/nm-m68klynx.h new file mode 100644 index 00000000000..351e02bc1f9 --- /dev/null +++ b/gdb/config/m68k/nm-m68klynx.h @@ -0,0 +1,65 @@ +/* Native-dependent definitions for Motorola 680x0 running LynxOS. + Copyright 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef NM_M68KLYNX_H +#define NM_M68KLYNX_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "thread.h" + +/* This is the amount to subtract from u.u_ar0 to get the offset in + the core file of the register values. */ + +#define KERNEL_U_ADDR USRSTACK + +#undef FLOAT_INFO /* No float info yet */ + +#define PTRACE_ARG3_TYPE char* + +/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ + +#define FETCH_INFERIOR_REGISTERS + +/* Thread ID of stopped thread. */ + +#define WIFTID(x) (((union wait *)&x)->w_tid) + +#define CHILD_WAIT + +extern int child_wait PARAMS ((int pid, int *status)); + +#if 0 /* need a sparclynx-nat.c to define this */ +/* Lynx needs a special definition of this so that we can + print out the pid and thread number seperatly. */ + +#undef target_pid_to_str +#define target_pid_to_str(PID) m68klynx_pid_to_str (PID) + +extern char *m68klynx_pid_to_str PARAMS ((int pid)); +#endif + +#endif /* NM_M68KLYNX_H */ diff --git a/gdb/config/m68k/tm-m68klynx.h b/gdb/config/m68k/tm-m68klynx.h new file mode 100644 index 00000000000..4fc71a53274 --- /dev/null +++ b/gdb/config/m68k/tm-m68klynx.h @@ -0,0 +1,31 @@ +/* Macro definitions for Motorola 680x0 running under LynxOS. + Copyright 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef TM_M68KLYNX_H +#define TM_M68KLYNX_H + +/* Use the generic 68k definitions. */ + +#include "m68k/tm-m68k.h" + +/* Include COFF shared library support. */ + +#include "coff-solib.h" + +#endif /* TM_M68KLYNX_H */ diff --git a/gdb/config/m68k/xm-m68klynx.h b/gdb/config/m68k/xm-m68klynx.h new file mode 100644 index 00000000000..a72a1d6686d --- /dev/null +++ b/gdb/config/m68k/xm-m68klynx.h @@ -0,0 +1,24 @@ +/* Host-dependent definitions for Motorola 680x0 running LynxOS, for GDB. + Copyright 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define HOST_BYTE_ORDER BIG_ENDIAN + +/* Get generic LynxOS host definitions. */ + +#include "xm-lynx.h" diff --git a/gdb/config/sparc/nm-sparclynx.h b/gdb/config/sparc/nm-sparclynx.h new file mode 100644 index 00000000000..05a3197021d --- /dev/null +++ b/gdb/config/sparc/nm-sparclynx.h @@ -0,0 +1,64 @@ +/* Native-dependent definitions for Sparc running LynxOS. + Copyright 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef NM_SPARCLYNX_H +#define NM_SPARCLYNX_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "thread.h" + +/* This is the amount to subtract from u.u_ar0 to get the offset in + the core file of the register values. */ + +#define KERNEL_U_ADDR USRSTACK + +#undef FLOAT_INFO /* No float info yet */ + +#define PTRACE_ARG3_TYPE char* + +/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */ +#define FETCH_INFERIOR_REGISTERS + +/* Thread ID of stopped thread. */ + +#define WIFTID(x) (((union wait *)&x)->w_tid) + +#define CHILD_WAIT + +extern int child_wait PARAMS ((int pid, int *status)); + +#if 0 /* need sparcly-nat.c to define this */ +/* Lynx needs a special definition of this so that we can + print out the pid and thread number seperatly. */ + +#undef target_pid_to_str +#define target_pid_to_str(PID) sparclynx_pid_to_str (PID) + +extern char *sparclynx_pid_to_str PARAMS ((int pid)); +#endif + +#endif /* NM_SPARCLYNX_H */ diff --git a/gdb/config/sparc/sparclynx.mh b/gdb/config/sparc/sparclynx.mh new file mode 100644 index 00000000000..cc0d5bae046 --- /dev/null +++ b/gdb/config/sparc/sparclynx.mh @@ -0,0 +1,9 @@ +# Host: Sparc running LynxOS +XM_FILE= xm-sparclynx.h +XDEPFILES= +NAT_FILE= nm-sparclynx.h +NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparcly-nat.o +REGEX=regex.o +REGEX1=regex.o +GDBSERVER_LIBS= -lbsd +GDBSERVER_DEPFILES= low-lynx.o diff --git a/gdb/config/sparc/sparclynx.mt b/gdb/config/sparc/sparclynx.mt new file mode 100644 index 00000000000..948eb11dcb8 --- /dev/null +++ b/gdb/config/sparc/sparclynx.mt @@ -0,0 +1,3 @@ +# Target: Sparc running LynxOS +TDEPFILES= exec.o coff-solib.o sparc-tdep.o sparc-pinsn.o +TM_FILE= tm-sparclynx.h diff --git a/gdb/config/sparc/tm-sparclynx.h b/gdb/config/sparc/tm-sparclynx.h new file mode 100644 index 00000000000..d62c189f50f --- /dev/null +++ b/gdb/config/sparc/tm-sparclynx.h @@ -0,0 +1,31 @@ +/* Macro definitions for Sparc running under LynxOS. + Copyright 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef TM_SPARCLYNX_H +#define TM_SPARCLYNX_H + +/* Use generic Sparc definitions. */ + +#include "sparc/tm-sparc.h" + +/* Include COFF shared library support. */ + +#include "coff-solib.h" + +#endif /* TM_SPARCLYNX_H */ diff --git a/gdb/config/sparc/xm-sparclynx.h b/gdb/config/sparc/xm-sparclynx.h new file mode 100644 index 00000000000..d2374ae534c --- /dev/null +++ b/gdb/config/sparc/xm-sparclynx.h @@ -0,0 +1,24 @@ +/* Host-dependent definitions for Sparc running LynxOS, for GDB. + Copyright 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define HOST_BYTE_ORDER BIG_ENDIAN + +/* Get generic LynxOS host definitions. */ + +#include "xm-lynx.h" diff --git a/gdb/config/xm-lynx.h b/gdb/config/xm-lynx.h new file mode 100644 index 00000000000..ed5e7ef7315 --- /dev/null +++ b/gdb/config/xm-lynx.h @@ -0,0 +1,32 @@ +/* Host-dependent definitions for any CPU running LynxOS. + Copyright 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* for INT_MIN, to avoid "INT_MIN redefined" warnings from defs.h */ + +#include + +/* psignal() is in . */ + +#define PSIGNAL_IN_SIGNAL_H + +/* Get rid of any system-imposed stack limit if possible. */ + +#define SET_STACK_LIMIT_HUGE + +#define MEM_FNS_DECLARED diff --git a/gdb/configure.in b/gdb/configure.in index 2766bb793ec..b57eb199d0e 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -44,7 +44,7 @@ i[34]86-*-bsd*) gdb_host=i386bsd ;; i[34]86-*-netbsd*) gdb_host=i386bsd ;; i[34]86-*-go32*) gdb_host=go32 ;; i[34]86-*-linux*) gdb_host=linux ;; -i[34]86-*-lynx*) gdb_host=i386lynx ;; +i[34]86-*-lynxos*) gdb_host=i386lynx ;; # Obsolete I suspect # i[34]86-*-mach) gdb_host=i386mach ;; i[34]86-*-mach*) gdb_host=i386m3 ;; @@ -71,6 +71,7 @@ m68*-cbm-sysv4*) gdb_host=amix ;; m68*-hp-bsd*) gdb_host=hp300bsd ;; m68*-hp-hpux*) gdb_host=hp300hpux ;; m68*-isi-*) gdb_host=isi ;; +m68*-*-lynxos*) gdb_host=m68klynx ;; m68*-motorola-*) gdb_host=delta68 ;; m68*-sony-*) gdb_host=news ;; m68*-sun-sunos3*) gdb_host=sun3os3 ;; @@ -106,6 +107,7 @@ romp-*-*) gdb_host=rtbsd ;; rs6000-*-*) gdb_host=rs6000 ;; +sparc-*-lynxos*) gdb_host=sparclynx ;; sparc-*-solaris2*) gdb_host=sun4sol2 ;; sparc-*-sunos4*) gdb_host=sun4os4 ;; sparc-*-*) gdb_host=sun4os4 ;; @@ -192,7 +194,7 @@ i[34]86-*-aix*) gdb_target=i386aix ;; i[34]86-*-bsd*) gdb_target=i386bsd ;; i[34]86-*-netbsd*) gdb_target=i386bsd ;; i[34]86-*-go32*) gdb_target=i386aout ;; -i[34]86-*-lynx*) gdb_target=i386lynx +i[34]86-*-lynxos*) gdb_target=i386lynx configdirs="${configdirs} gdbserver" ;; i[34]86-*-solaris*) gdb_target=i386sol2 ;; @@ -238,6 +240,9 @@ m68*-monitor-*) gdb_target=monitor ;; m68*-*-aout*) gdb_target=m68k-em ;; m68*-*-coff*) gdb_target=m68k-em ;; m68*-*-elf*) gdb_target=m68k-em ;; +m68*-*-lynxos*) gdb_target=m68klynx + configdirs="${configdirs} gdbserver" + ;; m68*-*-os68k*) gdb_target=os68k ;; m68*-*-sunos3*) gdb_target=sun3os3 ;; m68*-*-sunos4*) gdb_target=sun3os4 ;; @@ -274,6 +279,9 @@ rs6000-*-*) gdb_target=rs6000 ;; sparc-*-aout*) gdb_target=sparc-em ;; sparc-*-coff*) gdb_target=sparc-em ;; sparc-*-elf*) gdb_target=sparc-em ;; +sparc-*-lynxos*) gdb_target=sparclynx + configdirs="${configdirs} gdbserver" + ;; sparc-*-solaris2*) gdb_target=sun4sol2 ;; sparc-*-sunos4*) gdb_target=sun4os4 ;; sparc-*-vxworks*) gdb_target=vxsparc ;; diff --git a/gdb/i386ly-nat.c b/gdb/i386ly-nat.c new file mode 100644 index 00000000000..5e3bcde263c --- /dev/null +++ b/gdb/i386ly-nat.c @@ -0,0 +1,282 @@ +/* Native-dependent code for Intel 386 running LynxOS. + Copyright 1988, 1989, 1991, 1992, 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "frame.h" +#include "inferior.h" +#include "target.h" + +#include +#include "/usr/include/sys/wait.h" + +/* these values indicate the offset of the named register in the econtext + structure */ + +#define EAX 10 +#define ECX 9 +#define EDX 8 +#define EBX 7 +#define ESP 16 +#define EBP 5 +#define ESI 4 +#define EDI 3 +#define EIP 13 +#define EFL 15 +#define CS 14 +#define SS 17 +#define DS 2 +#define ES 1 + +/* Currently these are not being used. So set them to 0 */ + +#define FS 0 +#define GS 0 + +/* this table must line up with REGISTER_NAMES in m-i386.h */ +static unsigned int regmap[] = +{ + EAX, ECX, EDX, EBX, + ESP, EBP, ESI, EDI, + EIP, EFL, CS, SS, + DS, ES, FS, GS, +}; + +/* Return the address in the core dump or inferior of register REGNO. + BLOCKEND is the address of the econtext structure */ + +static unsigned int +register_addr (regno, blockend) + int regno, blockend; +{ + if (regno < 0 || regno >= NUM_REGS) + error ("Invalid register number %d.", regno); + + return (blockend + regmap[regno] * sizeof (long)); +} + +/* Fetch one register. */ + +static void +fetch_register (regno, offset, bpid) + int regno, bpid; + unsigned int offset; +{ + unsigned int regaddr; + char buf[MAX_REGISTER_RAW_SIZE]; + char mess[128]; /* For messages */ + int i; + + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + errno = 0; + *(int *) &buf[i] = ptrace (PTRACE_PEEKTHREAD, bpid, + (PTRACE_ARG3_TYPE) regaddr, 0); + regaddr += sizeof (int); + if (errno != 0) + { + sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno); + perror_with_name (mess); + } + } + supply_register (regno, buf); +} + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + +static void +store_register (regno, offset, bpid) + int regno, bpid; + unsigned int offset; +{ + unsigned int regaddr; + char mess[128]; + extern char registers[]; + int i; + + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) + { + errno = 0; + ptrace (PTRACE_POKEUSER, bpid, (PTRACE_ARG3_TYPE) regaddr, + *(int *) ®isters[REGISTER_BYTE (regno) + i]); + if (errno != 0) + { + sprintf (mess, "writing register number %d(%d)", regno, i); + perror_with_name (mess); + } + regaddr += sizeof(int); + } +} + +/* return an offset for use with register_addr() */ + +static unsigned int +fetch_offset (pid) + int pid; +{ + struct st_entry s; + unsigned int specpage_off, offset = (char *) &s.ecp - (char *) &s; + + errno = 0; + specpage_off = ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, 0); + if (errno != 0) + perror_with_name ("ptrace"); + errno = 0; + offset = ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) offset, 0) + - specpage_off; + if (errno != 0) + perror_with_name ("ptrace"); + return offset; +} + +/* Fetch all registers, or just one, from the child process. */ + +void +fetch_inferior_registers (regno) + int regno; +{ + unsigned int offset = fetch_offset (inferior_pid); + + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + fetch_register (regno, offset, inferior_pid); + } + else + fetch_register (regno, offset, inferior_pid); +} + +/* Store all registers, or just one, to the child process. */ + +void +store_inferior_registers (regno) + int regno; +{ + unsigned int offset = fetch_offset (inferior_pid); + + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + store_register (regno, offset, inferior_pid); + } + else + store_register (regno, offset, inferior_pid); +} + +/* Wait for child to do something. Return pid of child, or -1 in case + of error; store status through argument pointer STATUS. */ + +int +child_wait (pid, status) + int pid; + int *status; +{ + int save_errno; + int thread; + + while (1) + { + int sig; + + if (attach_flag) + set_sigint_trap(); /* Causes SIGINT to be passed on to the + attached process. */ + pid = wait (status); + save_errno = errno; + + if (attach_flag) + clear_sigint_trap(); + + if (pid == -1) + { + if (save_errno == EINTR) + continue; + fprintf (stderr, "Child process unexpectedly missing: %s.\n", + safe_strerror (save_errno)); + *status = 42; /* Claim it exited with signal 42 */ + return -1; + } + + if (pid != PIDGET (inferior_pid)) /* Some other process?!? */ + continue; + +/* thread = WIFTID (*status);*/ + thread = *status >> 16; + + /* Initial thread value can only be acquired via wait, so we have to + resort to this hack. */ + + if (TIDGET (inferior_pid) == 0) + { + inferior_pid = BUILDPID (inferior_pid, thread); + add_thread (inferior_pid); + } + + pid = BUILDPID (pid, thread); + + return pid; + } +} + +/* Convert a Lynx process ID to a string. Returns the string in a static + buffer. */ + +char * +i386lynx_pid_to_str (pid) + int pid; +{ + static char buf[40]; + + sprintf (buf, "process %d thread %d", PIDGET (pid), TIDGET (pid)); + + return buf; +} + +/* Extract the register values out of the core file and store + them where `read_register' will find them. + + CORE_REG_SECT points to the register values themselves, read into memory. + CORE_REG_SIZE is the size of that area. + WHICH says which set of registers we are handling (0 = int, 2 = float + on machines where they are discontiguous). + REG_ADDR is the offset from u.u_ar0 to the register values relative to + core_reg_sect. This is used with old-fashioned core files to + locate the registers in a large upage-plus-stack ".reg" section. + Original upage address X is at location core_reg_sect+x+reg_addr. + */ + +void +fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) + char *core_reg_sect; + unsigned core_reg_size; + int which; + unsigned reg_addr; +{ + struct st_entry s; + unsigned int regno, addr; + + for (regno = 0; regno < NUM_REGS; regno++) + { + addr = register_addr (regno, (char *) &s.ec - (char *) &s); + supply_register (regno, core_reg_sect + addr); + } +} diff --git a/gdb/i386ly-tdep.c b/gdb/i386ly-tdep.c index 87b0ac17f82..3f87816947e 100644 --- a/gdb/i386ly-tdep.c +++ b/gdb/i386ly-tdep.c @@ -1,6 +1,5 @@ -/* Target-dependent code for Lynx running on i386's, for GDB. - Copyright 1988, 1989, 1991, 1992, 1993 - Free Software Foundation, Inc. +/* Target-dependent code for Intel 386 running LynxOS. + Copyright 1993 Free Software Foundation, Inc. This file is part of GDB. diff --git a/gdb/i386lynx-nat.c b/gdb/i386lynx-nat.c deleted file mode 100644 index 4153a47f8a6..00000000000 --- a/gdb/i386lynx-nat.c +++ /dev/null @@ -1,283 +0,0 @@ -/* Native-dependent code for Lynx running on i386's, for GDB. - Copyright 1988, 1989, 1991, 1992, 1993 - 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 2 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, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "target.h" - -#include -#include "/usr/include/sys/wait.h" - -/* these values indicate the offset of the named register in the econtext - structure */ - -#define EAX 10 -#define ECX 9 -#define EDX 8 -#define EBX 7 -#define ESP 16 -#define EBP 5 -#define ESI 4 -#define EDI 3 -#define EIP 13 -#define EFL 15 -#define CS 14 -#define SS 17 -#define DS 2 -#define ES 1 - -/* Currently these are not being used. So set them to 0 */ - -#define FS 0 -#define GS 0 - -/* this table must line up with REGISTER_NAMES in m-i386.h */ -static unsigned int regmap[] = -{ - EAX, ECX, EDX, EBX, - ESP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS, -}; - -/* Return the address in the core dump or inferior of register REGNO. - BLOCKEND is the address of the econtext structure */ - -static unsigned int -register_addr (regno, blockend) - int regno, blockend; -{ - if (regno < 0 || regno >= NUM_REGS) - error ("Invalid register number %d.", regno); - - return (blockend + regmap[regno] * sizeof (long)); -} - -/* Fetch one register. */ - -static void -fetch_register (regno, offset, bpid) - int regno, bpid; - unsigned int offset; -{ - unsigned int regaddr; - char buf[MAX_REGISTER_RAW_SIZE]; - char mess[128]; /* For messages */ - int i; - - regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - errno = 0; - *(int *) &buf[i] = ptrace (PTRACE_PEEKTHREAD, bpid, - (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (int); - if (errno != 0) - { - sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno); - perror_with_name (mess); - } - } - supply_register (regno, buf); -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -static void -store_register (regno, offset, bpid) - int regno, bpid; - unsigned int offset; -{ - unsigned int regaddr; - char mess[128]; - extern char registers[]; - int i; - - regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) - { - errno = 0; - ptrace (PTRACE_POKEUSER, bpid, (PTRACE_ARG3_TYPE) regaddr, - *(int *) ®isters[REGISTER_BYTE (regno) + i]); - if (errno != 0) - { - sprintf (mess, "writing register number %d(%d)", regno, i); - perror_with_name (mess); - } - regaddr += sizeof(int); - } -} - -/* return an offset for use with register_addr() */ - -static unsigned int -fetch_offset (pid) - int pid; -{ - struct st_entry s; - unsigned int specpage_off, offset = (char *) &s.ecp - (char *) &s; - - errno = 0; - specpage_off = ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, 0); - if (errno != 0) - perror_with_name ("ptrace"); - errno = 0; - offset = ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) offset, 0) - - specpage_off; - if (errno != 0) - perror_with_name ("ptrace"); - return offset; -} - -/* Fetch all registers, or just one, from the child process. */ - -void -fetch_inferior_registers (regno) - int regno; -{ - unsigned int offset = fetch_offset (inferior_pid); - - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - fetch_register (regno, offset, inferior_pid); - } - else - fetch_register (regno, offset, inferior_pid); -} - -/* Store all registers, or just one, to the child process. */ - -void -store_inferior_registers (regno) - int regno; -{ - unsigned int offset = fetch_offset (inferior_pid); - - if (regno == -1) - { - for (regno = 0; regno < NUM_REGS; regno++) - store_register (regno, offset, inferior_pid); - } - else - store_register (regno, offset, inferior_pid); -} - -/* Wait for child to do something. Return pid of child, or -1 in case - of error; store status through argument pointer STATUS. */ - -int -child_wait (pid, status) - int pid; - int *status; -{ - int save_errno; - int thread; - - while (1) - { - int sig; - - if (attach_flag) - set_sigint_trap(); /* Causes SIGINT to be passed on to the - attached process. */ - pid = wait (status); - save_errno = errno; - - if (attach_flag) - clear_sigint_trap(); - - if (pid == -1) - { - if (save_errno == EINTR) - continue; - fprintf (stderr, "Child process unexpectedly missing: %s.\n", - safe_strerror (save_errno)); - *status = 42; /* Claim it exited with signal 42 */ - return -1; - } - - if (pid != PIDGET (inferior_pid)) /* Some other process?!? */ - continue; - -/* thread = WIFTID (*status);*/ - thread = *status >> 16; - - /* Initial thread value can only be acquired via wait, so we have to - resort to this hack. */ - - if (TIDGET (inferior_pid) == 0) - { - inferior_pid = BUILDPID (inferior_pid, thread); - add_thread (inferior_pid); - } - - pid = BUILDPID (pid, thread); - - return pid; - } -} - -/* Convert a Lynx process ID to a string. Returns the string in a static - buffer. */ - -char * -i386lynx_pid_to_str (pid) - int pid; -{ - static char buf[40]; - - sprintf (buf, "process %d thread %d", PIDGET (pid), TIDGET (pid)); - - return buf; -} - -/* Extract the register values out of the core file and store - them where `read_register' will find them. - - CORE_REG_SECT points to the register values themselves, read into memory. - CORE_REG_SIZE is the size of that area. - WHICH says which set of registers we are handling (0 = int, 2 = float - on machines where they are discontiguous). - REG_ADDR is the offset from u.u_ar0 to the register values relative to - core_reg_sect. This is used with old-fashioned core files to - locate the registers in a large upage-plus-stack ".reg" section. - Original upage address X is at location core_reg_sect+x+reg_addr. - */ - -void -fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) - char *core_reg_sect; - unsigned core_reg_size; - int which; - unsigned reg_addr; -{ - struct st_entry s; - unsigned int regno, addr; - - for (regno = 0; regno < NUM_REGS; regno++) - { - addr = register_addr (regno, (char *) &s.ec - (char *) &s); - supply_register (regno, core_reg_sect + addr); - } -} diff --git a/gdb/m68kly-nat.c b/gdb/m68kly-nat.c new file mode 100644 index 00000000000..057855e706f --- /dev/null +++ b/gdb/m68kly-nat.c @@ -0,0 +1,277 @@ +/* Native-dependent code for Motorola 680x0 running LynxOS. + Copyright 1986, 1987, 1989, 1991, 1993 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "frame.h" +#include "inferior.h" +#include "gdbcore.h" +#include "target.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Return the address in the core dump or inferior of register REGNO. + BLOCKEND is the address of the end of the user structure. */ + +static unsigned int +core_register_addr (regno, blockend) + unsigned int regno, blockend; +{ + struct st_entry s; + unsigned int offset; + + if (regno >= 0 && regno <= FP_REGNUM) + offset = (char *) &s.ec.regs[regno] - (char *) &s; + else if (regno == SP_REGNUM) + offset = (char *) &s.stackp - (char *) &s; + else if (regno == PS_REGNUM) + offset = (char *) &s.ec.status - (char *) &s; + else if (regno == PC_REGNUM) + offset = (char *) &s.ec.pc - (char *) &s; + else if (regno >= FP0_REGNUM && regno <= (FPC_REGNUM - 1)) + offset = (char *) &s.ec.fregs[(regno - FP0_REGNUM) * 3] - (char *) &s; + else if (regno >= FPC_REGNUM && regno <= FPI_REGNUM) + offset = (char *) &s.ec.fcregs[regno - FPC_REGNUM] - (char *) &s; + + return blockend + offset; +} + +unsigned int +register_addr (regno, blockend) + int regno, blockend; +{ + struct st_entry s; + unsigned int offset; + + if (regno >= 0 && regno <= FP_REGNUM) + offset = (char *) &s.ec.regs[regno] - (char *) &s.ec; + else if (regno == SP_REGNUM) + offset = (char *) &s.stackp - (char *) &s; + else if (regno == PS_REGNUM) + offset = (char *) &s.ec.status - (char *) &s.ec; + else if (regno == PC_REGNUM) + offset = (char *) &s.ec.pc - (char *) &s.ec; + else if (regno >= FP0_REGNUM && regno <= (FPC_REGNUM - 1)) + offset = (char *) &s.ec.fregs[(regno - FP0_REGNUM) * 3] - (char *) &s.ec; + else if (regno >= FPC_REGNUM && regno <= FPI_REGNUM) + offset = (char *) &s.ec.fcregs[regno - FPC_REGNUM] - (char *) &s.ec; + + return blockend + offset; +} + +#ifdef FETCH_INFERIOR_REGISTERS + +/* Fetch one register. */ + +static void +fetch_register (regno, offset, bpid) + int regno, bpid; + unsigned int offset; +{ + char buf[MAX_REGISTER_RAW_SIZE], mess[128]; + unsigned int regaddr, i, ptrace_request; + + ptrace_request = regno != SP_REGNUM ? PTRACE_PEEKDATA : PTRACE_PEEKUSP; + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + errno = 0; + *(int *) &buf[i] = ptrace (ptrace_request, bpid, + (PTRACE_ARG3_TYPE) regaddr, 0); + if (errno != 0) + { + sprintf (mess, "reading register %s (#%d)", reg_names[regno], regno); + perror_with_name (mess); + } + regaddr += sizeof (int); + } + supply_register (regno, buf); +} + +static void +store_register (regno, offset, bpid) + int regno, bpid; + unsigned int offset; +{ + unsigned int i, regaddr, ptrace_request; + char mess[128]; + + ptrace_request = regno != SP_REGNUM ? PTRACE_POKEUSER : PTRACE_POKEUSP; + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + errno = 0; + ptrace (ptrace_request, bpid, (PTRACE_ARG3_TYPE) regaddr, + *(int *) ®isters[REGISTER_BYTE (regno) + i]); + if (errno != 0) + { + sprintf (mess, "writing register %s (#%d)", reg_names[regno], regno); + perror_with_name (mess); + } + regaddr += sizeof (int); + } +} + +static unsigned int +fetch_offset (pid, write) + int pid, write; +{ + struct st_entry s; + unsigned int specpage_off, offset = (char *) &s.ecp - (char *) &s; + + if (write) + { + errno = 0; + specpage_off = ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0, 0); + if (errno != 0) + perror_with_name ("ptrace"); + errno = 0; + offset = ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) offset, 0) + - specpage_off; + if (errno != 0) + perror_with_name ("ptrace"); + } + else + { + errno = 0; + offset = ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) offset, 0); + if (errno != 0) + perror_with_name ("ptrace"); + } + return offset; +} + +void +fetch_inferior_registers (regno) + int regno; +{ + unsigned int offset = fetch_offset (inferior_pid, 0); + + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + fetch_register (regno, offset, inferior_pid); + } + else + fetch_register (regno, offset, inferior_pid); +} + +void +store_inferior_registers (regno) + int regno; +{ + unsigned int offset = fetch_offset (inferior_pid, 1); + + if (regno == -1) + { + for (regno = 0; regno < NUM_REGS; regno++) + store_register (regno, offset, inferior_pid); + } + else + store_register (regno, offset, inferior_pid); +} + +void +fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) + char *core_reg_sect; + unsigned core_reg_size; + int which; + unsigned int reg_addr; /* Unused in this version */ +{ + unsigned int regno; + + for (regno = 0; regno < NUM_REGS; regno++) + { + unsigned int addr; + + addr = core_register_addr (regno, (unsigned) 0); + supply_register (regno, core_reg_sect + addr); + } +} +#endif /* FETCH_INFERIOR_REGISTERS */ + +/* Wait for child to do something. Return pid of child, or -1 in case + of error; store status through argument pointer STATUS. */ + +int +child_wait (pid, status) + int pid; + int *status; +{ + int save_errno; + int thread; + + while (1) + { + int sig; + + if (attach_flag) + set_sigint_trap(); /* Causes SIGINT to be passed on to the + attached process. */ + pid = wait (status); + save_errno = errno; + + if (attach_flag) + clear_sigint_trap(); + + if (pid == -1) + { + if (save_errno == EINTR) + continue; + fprintf (stderr, "Child process unexpectedly missing: %s.\n", + safe_strerror (save_errno)); + *status = 42; /* Claim it exited with signal 42 */ + return -1; + } + + if (pid != PIDGET (inferior_pid)) /* Some other process?!? */ + continue; + +/* thread = WIFTID (*status);*/ + thread = *status >> 16; + + /* Initial thread value can only be acquired via wait, so we have to + resort to this hack. */ + + if (TIDGET (inferior_pid) == 0) + { + inferior_pid = BUILDPID (inferior_pid, thread); + add_thread (inferior_pid); + } + + pid = BUILDPID (pid, thread); + + return pid; + } +} diff --git a/gdb/sparcly-nat.c b/gdb/sparcly-nat.c new file mode 100644 index 00000000000..193fa1e695a --- /dev/null +++ b/gdb/sparcly-nat.c @@ -0,0 +1,363 @@ +/* Native-dependent code for Sparc running LynxOS. + Copyright (C) 1989, 1992, 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 2 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, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "target.h" + +#include +#include +#include +#if 0 +#include +#endif + +/* We don't store all registers immediately when requested, since they + get sent over in large chunks anyway. Instead, we accumulate most + of the changes and send them over once. "deferred_stores" keeps + track of which sets of registers we have locally-changed copies of, + so we only need send the groups that have changed. */ + +#define INT_REGS 1 +#define STACK_REGS 2 +#define FP_REGS 4 + +/* Fetch one or more registers from the inferior. REGNO == -1 to get + them all. We actually fetch more than requested, when convenient, + marking them as valid so we won't fetch them again. */ + +void +fetch_inferior_registers (regno) + int regno; +{ +#if 0 + struct regs inferior_registers; + struct fp_status inferior_fp_registers; + int i; + + /* We should never be called with deferred stores, because a prerequisite + for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */ + if (deferred_stores) abort(); + + DO_DEFERRED_STORES; + + /* Global and Out regs are fetched directly, as well as the control + registers. If we're getting one of the in or local regs, + and the stack pointer has not yet been fetched, + we have to do that first, since they're found in memory relative + to the stack pointer. */ + if (regno < O7_REGNUM /* including -1 */ + || regno >= Y_REGNUM + || (!register_valid[SP_REGNUM] && regno < I7_REGNUM)) + { + if (0 != ptrace (PTRACE_GETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_registers, 0)) + perror("ptrace_getregs"); + + registers[REGISTER_BYTE (0)] = 0; + memcpy (®isters[REGISTER_BYTE (1)], &inferior_registers.r_g1, + 15 * REGISTER_RAW_SIZE (G0_REGNUM)); + *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; + *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; + *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc; + *(int *)®isters[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; + + for (i = G0_REGNUM; i <= O7_REGNUM; i++) + register_valid[i] = 1; + register_valid[Y_REGNUM] = 1; + register_valid[PS_REGNUM] = 1; + register_valid[PC_REGNUM] = 1; + register_valid[NPC_REGNUM] = 1; + /* If we don't set these valid, read_register_bytes() rereads + all the regs every time it is called! FIXME. */ + register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */ + register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */ + register_valid[FPS_REGNUM] = 1; /* Not true yet, FIXME */ + register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */ + } + + /* Floating point registers */ + if (regno == -1 || (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)) + { + if (0 != ptrace (PTRACE_GETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_fp_registers, + 0)) + perror("ptrace_getfpregs"); + memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, + sizeof inferior_fp_registers.fpu_fr); + /* memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], + &inferior_fp_registers.Fpu_fsr, + sizeof (FPU_FSR_TYPE)); FIXME??? -- gnu@cyg */ + for (i = FP0_REGNUM; i <= FP0_REGNUM+31; i++) + register_valid[i] = 1; + register_valid[FPS_REGNUM] = 1; + } + + /* These regs are saved on the stack by the kernel. Only read them + all (16 ptrace calls!) if we really need them. */ + if (regno == -1) + { + target_xfer_memory (*(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)], + ®isters[REGISTER_BYTE (L0_REGNUM)], + 16*REGISTER_RAW_SIZE (L0_REGNUM), 0); + for (i = L0_REGNUM; i <= I7_REGNUM; i++) + register_valid[i] = 1; + } + else if (regno >= L0_REGNUM && regno <= I7_REGNUM) + { + CORE_ADDR sp = *(CORE_ADDR*)®isters[REGISTER_BYTE (SP_REGNUM)]; + i = REGISTER_BYTE (regno); + if (register_valid[regno]) + printf("register %d valid and read\n", regno); + target_xfer_memory (sp + i - REGISTER_BYTE (L0_REGNUM), + ®isters[i], REGISTER_RAW_SIZE (regno), 0); + register_valid[regno] = 1; + } +#endif +} + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + +void +store_inferior_registers (regno) + int regno; +{ +#if 0 + struct regs inferior_registers; + struct fp_status inferior_fp_registers; + int wanna_store = INT_REGS + STACK_REGS + FP_REGS; + + /* First decide which pieces of machine-state we need to modify. + Default for regno == -1 case is all pieces. */ + if (regno >= 0) + if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32) + { + wanna_store = FP_REGS; + } + else + { + if (regno == SP_REGNUM) + wanna_store = INT_REGS + STACK_REGS; + else if (regno < L0_REGNUM || regno > I7_REGNUM) + wanna_store = INT_REGS; + else + wanna_store = STACK_REGS; + } + + /* See if we're forcing the stores to happen now, or deferring. */ + if (regno == -2) + { + wanna_store = deferred_stores; + deferred_stores = 0; + } + else + { + if (wanna_store == STACK_REGS) + { + /* Fall through and just store one stack reg. If we deferred + it, we'd have to store them all, or remember more info. */ + } + else + { + deferred_stores |= wanna_store; + return; + } + } + + if (wanna_store & STACK_REGS) + { + CORE_ADDR sp = *(CORE_ADDR *)®isters[REGISTER_BYTE (SP_REGNUM)]; + + if (regno < 0 || regno == SP_REGNUM) + { + if (!register_valid[L0_REGNUM+5]) abort(); + target_xfer_memory (sp, + ®isters[REGISTER_BYTE (L0_REGNUM)], + 16*REGISTER_RAW_SIZE (L0_REGNUM), 1); + } + else + { + if (!register_valid[regno]) abort(); + target_xfer_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM), + ®isters[REGISTER_BYTE (regno)], + REGISTER_RAW_SIZE (regno), 1); + } + + } + + if (wanna_store & INT_REGS) + { + if (!register_valid[G1_REGNUM]) abort(); + + memcpy (&inferior_registers.r_g1, ®isters[REGISTER_BYTE (G1_REGNUM)], + 15 * REGISTER_RAW_SIZE (G1_REGNUM)); + + inferior_registers.r_ps = + *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; + inferior_registers.r_pc = + *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; + inferior_registers.r_npc = + *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)]; + inferior_registers.r_y = + *(int *)®isters[REGISTER_BYTE (Y_REGNUM)]; + + if (0 != ptrace (PTRACE_SETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_registers, 0)) + perror("ptrace_setregs"); + } + + if (wanna_store & FP_REGS) + { + if (!register_valid[FP0_REGNUM+9]) abort(); + /* Initialize inferior_fp_registers members that gdb doesn't set + by reading them from the inferior. */ + if (0 != + ptrace (PTRACE_GETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0)) + perror("ptrace_getfpregs"); + memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], + sizeof inferior_fp_registers.fpu_fr); + +/* memcpy (&inferior_fp_registers.Fpu_fsr, + ®isters[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE)); +****/ + if (0 != + ptrace (PTRACE_SETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0)) + perror("ptrace_setfpregs"); + } +#endif +} + + +void +fetch_core_registers (core_reg_sect, core_reg_size, which, ignore) + char *core_reg_sect; + unsigned core_reg_size; + int which; + unsigned int ignore; /* reg addr, unused in this version */ +{ +#if 0 + if (which == 0) { + + /* Integer registers */ + +#define gregs ((struct regs *)core_reg_sect) + /* G0 *always* holds 0. */ + *(int *)®isters[REGISTER_BYTE (0)] = 0; + + /* The globals and output registers. */ + memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, + 15 * REGISTER_RAW_SIZE (G1_REGNUM)); + *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps; + *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc; + *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc; + *(int *)®isters[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y; + + /* My best guess at where to get the locals and input + registers is exactly where they usually are, right above + the stack pointer. If the core dump was caused by a bus error + from blowing away the stack pointer (as is possible) then this + won't work, but it's worth the try. */ + { + int sp; + + sp = *(int *)®isters[REGISTER_BYTE (SP_REGNUM)]; + if (0 != target_read_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], + 16 * REGISTER_RAW_SIZE (L0_REGNUM))) + { + /* fprintf so user can still use gdb */ + fprintf (stderr, + "Couldn't read input and local registers from core file\n"); + } + } + } else if (which == 2) { + + /* Floating point registers */ + +#define fpuregs ((struct fpu *) core_reg_sect) + if (core_reg_size >= sizeof (struct fpu)) + { + memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs, + sizeof (fpuregs->fpu_regs)); + memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr, + sizeof (FPU_FSR_TYPE)); + } + else + fprintf (stderr, "Couldn't read float regs from core file\n"); + } +#endif +} + +/* Wait for child to do something. Return pid of child, or -1 in case + of error; store status through argument pointer STATUS. */ + +int +child_wait (pid, status) + int pid; + int *status; +{ + int save_errno; + int thread; + + while (1) + { + int sig; + + if (attach_flag) + set_sigint_trap(); /* Causes SIGINT to be passed on to the + attached process. */ + pid = wait (status); + save_errno = errno; + + if (attach_flag) + clear_sigint_trap(); + + if (pid == -1) + { + if (save_errno == EINTR) + continue; + fprintf (stderr, "Child process unexpectedly missing: %s.\n", + safe_strerror (save_errno)); + *status = 42; /* Claim it exited with signal 42 */ + return -1; + } + + if (pid != PIDGET (inferior_pid)) /* Some other process?!? */ + continue; + +/* thread = WIFTID (*status);*/ + thread = *status >> 16; + + /* Initial thread value can only be acquired via wait, so we have to + resort to this hack. */ + + if (TIDGET (inferior_pid) == 0) + { + inferior_pid = BUILDPID (inferior_pid, thread); + add_thread (inferior_pid); + } + + pid = BUILDPID (pid, thread); + + return pid; + } +}