* infptrace.c: Split out define of PT_KILL; Sequent defines PT_KILL

but not the others.
	* symm-tdep.c: Remove exec_file_command.
	[_SEQUENT_] (ptx_coff_regno_to_gdb, register_addr): New functions.
	A few miscellaneous cleanups.
	* symm-nat.c: Renamed from symm-xdep.c.
	* All symmetry dependent files: Many changes.
This commit is contained in:
Jim Kingdon 1993-07-19 05:00:13 +00:00
parent bea80b013d
commit 56eec3c737
11 changed files with 605 additions and 831 deletions

View File

@ -1,5 +1,12 @@
Sun Jul 18 15:22:45 1993 Jim Kingdon (kingdon@rtl.cygnus.com)
* infptrace.c: Split out define of PT_KILL; Sequent defines PT_KILL
but not the others.
* symm-tdep.c: Remove exec_file_command.
[_SEQUENT_] (ptx_coff_regno_to_gdb, register_addr): New functions.
A few miscellaneous cleanups.
* symm-nat.c: Renamed from symm-xdep.c.
* mips-tdep.c (mips_skip_prologue): New argument lenient.
Use read_memory_nobpt.
(is_delayed, mips_in_lenient_prologue): New functions.

View File

@ -809,7 +809,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
remote-udi.c remote-vx.c remote-z8k.c rs6000-nat.c rs6000-pinsn.c \
rs6000-tdep.c ser-go32.c ser-tcp.c sh-tdep.c solib.c sparc-nat.c \
sparc-pinsn.c sparc-tdep.c sun3-nat.c sun386-nat.c symm-tdep.c \
symm-xdep.c tahoe-pinsn.c ultra3-nat.c ultra3-xdep.c umax-xdep.c \
symm-nat.c tahoe-pinsn.c ultra3-nat.c ultra3-xdep.c umax-xdep.c \
vax-pinsn.c vx-share/xdr_ld.c vx-share/xdr_ptrace.c vx-share/xdr_rdb.c \
xcoffexec.c xcoffread.c xcoffsolib.c z8k-tdep.c
@ -1255,7 +1255,7 @@ symfile.o: symfile.c $(breakpoint_h) complaints.h $(defs_h) \
language.h objfiles.h symfile.h $(symtab_h) target.h
symm-tdep.o: symm-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
symm-xdep.o: symm-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
symm-nat.o: symm-nat.c $(defs_h) $(gdbcore_h) $(inferior_h)
symmisc.o: symmisc.c $(bfd_h) $(breakpoint_h) $(command_h) $(defs_h) \
$(expression_h) $(gdbtypes_h) language.h objfiles.h symfile.h \

View File

@ -1,3 +1,3 @@
# Host: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387.
XDEPFILES= infptrace.o inftarg.o fork-child.o symm-xdep.o
XDEPFILES= infptrace.o inftarg.o fork-child.o symm-nat.o
XM_FILE= xm-symmetry.h

View File

@ -1,3 +1,3 @@
# Target: Sequent Symmetry running Dynix 3.0, with Weitek 1167 or i387.
TDEPFILES= symm-tdep.o i386-pinsn.o
TDEPFILES= symm-tdep.o i386-pinsn.o i387-tdep.o
TM_FILE= tm-symmetry.h

View File

@ -225,7 +225,7 @@ i386_skip_prologue PARAMS ((int));
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell. */
#define FRAME_NUM_ARGS(numargs, fi) (numargs) = i386_frame_num_args(fi)
#define FRAME_NUM_ARGS(numargs, fi) (numargs) = -1
#ifdef __STDC__ /* Forward decl's for prototypes */
struct frame_info;

View File

@ -1,7 +1,7 @@
/* Target machine definitions for GDB on a Sequent Symmetry under dynix 3.0,
with Weitek 1167 and i387 support.
Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
Symmetry version by Jay Vosburgh (uunet!sequent!fubar).
Symmetry version by Jay Vosburgh (fubar@sequent.com).
This file is part of GDB.
@ -21,46 +21,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* I don't know if this will work for cross-debugging, even if you do get
a copy of the right include file. */
#ifdef _SEQUENT_
/* ptx */
#include <sys/reg.h>
#else
/* dynix */
#include <machine/reg.h>
#endif
#define TARGET_BYTE_ORDER LITTLE_ENDIAN
#ifdef _SEQUENT_
/* ptx, not dynix */
#define SDB_REG_TO_REGNUM(value) ptx_coff_regno_to_gdb(value)
extern int ptx_coff_regno_to_gdb();
#endif /* _SEQUENT_ */
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 0
/* Advance PC across any function entry prologue instructions
to reach some "real" code. From m-i386.h */
#define SKIP_PROLOGUE(frompc) {(frompc) = i386_skip_prologue((frompc));}
extern int
i386_skip_prologue PARAMS ((int));
/* Immediately after a function call, return the saved pc.
Can't always go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
read_memory_integer(read_register(SP_REGNUM), 4)
/* I don't know the real values for these. */
#define TARGET_UPAGES UPAGES
#define TARGET_NBPG NBPG
/* Address of end of stack space. */
#define STACK_END_ADDR (0x40000000 - (TARGET_UPAGES * TARGET_NBPG))
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0xcc}
#define START_INFERIOR_TRAPS_EXPECTED 2
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
@ -68,17 +43,15 @@ i386_skip_prologue PARAMS ((int));
#define DECR_PC_AFTER_BREAK 0
#include "i386/tm-i386v.h"
/* Nonzero if instruction at PC is a return instruction. */
/* For Symmetry, this is really the 'leave' instruction, which */
/* is right before the ret */
#undef
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc9)
/* Return 1 if P points to an invalid floating point value.
*/
#define INVALID_FLOAT(p, len) (0)
#if 0
--- this code can't be used unless we know we are running native,
since it uses host specific ptrace calls.
@ -88,11 +61,8 @@ i386_skip_prologue PARAMS ((int));
#define FLOAT_INFO { i386_float_info(); }
#endif
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#undef NUM_REGS
#define NUM_REGS 49
/* Initializer for an array of names of registers.
@ -104,6 +74,7 @@ i386_skip_prologue PARAMS ((int));
Also note that the st(0)...st(7) 387 registers are represented as
st0...st7. */
#undef REGISTER_NAMES
#define REGISTER_NAMES { "eax", "edx", "ecx", "st0", "st1", \
"ebx", "esi", "edi", "st2", "st3", \
"st4", "st5", "st6", "st7", "esp", \
@ -122,20 +93,146 @@ i386_skip_prologue PARAMS ((int));
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define EAX_REGNUM 0
#define EDX_REGNUM 1
#define ECX_REGNUM 2
#define ST0_REGNUM 3
#define ST1_REGNUM 4
#define EBX_REGNUM 5
#define ESI_REGNUM 6
#define EDI_REGNUM 7
#define ST2_REGNUM 8
#define ST3_REGNUM 9
#define ST4_REGNUM 10
#define ST5_REGNUM 11
#define ST6_REGNUM 12
#define ST7_REGNUM 13
#define FP1_REGNUM 18 /* first 1167 register */
/* Get %fp2 - %fp31 by addition, since they are contiguous */
#undef SP_REGNUM
#define SP_REGNUM 14 /* Contains address of top of stack */
#undef FP_REGNUM
#define FP_REGNUM 15 /* Contains address of executing stack frame */
#undef PC_REGNUM
#define PC_REGNUM 16 /* Contains program counter */
#undef PS_REGNUM
#define PS_REGNUM 17 /* Contains processor status */
#ifndef _SEQUENT_
/* dynix, not ptx. For ptx, see register_addr in symm-tdep.c */
/* The magic numbers below are offsets into u_ar0 in the user struct.
* They live in <machine/reg.h>. Gdb calls this macro with blockend
* holding u.u_ar0 - KERNEL_U_ADDR. Only the registers listed are
* saved in the u area (along with a few others that aren't useful
* here. See <machine/reg.h>).
*/
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ struct user foo; /* needed for finding fpu regs */ \
switch (regno) { \
case 0: \
addr = blockend + EAX * sizeof(int); break; \
case 1: \
addr = blockend + EDX * sizeof(int); break; \
case 2: \
addr = blockend + ECX * sizeof(int); break; \
case 3: /* st(0) */ \
addr = blockend - \
((int)&foo.u_fpusave.fpu_stack[0][0] - (int)&foo); \
break; \
case 4: /* st(1) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[1][0] - (int)&foo); \
break; \
case 5: \
addr = blockend + EBX * sizeof(int); break; \
case 6: \
addr = blockend + ESI * sizeof(int); break; \
case 7: \
addr = blockend + EDI * sizeof(int); break; \
case 8: /* st(2) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[2][0] - (int)&foo); \
break; \
case 9: /* st(3) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[3][0] - (int)&foo); \
break; \
case 10: /* st(4) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[4][0] - (int)&foo); \
break; \
case 11: /* st(5) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[5][0] - (int)&foo); \
break; \
case 12: /* st(6) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[6][0] - (int)&foo); \
break; \
case 13: /* st(7) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[7][0] - (int)&foo); \
break; \
case 14: \
addr = blockend + ESP * sizeof(int); break; \
case 15: \
addr = blockend + EBP * sizeof(int); break; \
case 16: \
addr = blockend + EIP * sizeof(int); break; \
case 17: \
addr = blockend + FLAGS * sizeof(int); break; \
case 18: /* fp1 */ \
case 19: /* fp2 */ \
case 20: /* fp3 */ \
case 21: /* fp4 */ \
case 22: /* fp5 */ \
case 23: /* fp6 */ \
case 24: /* fp7 */ \
case 25: /* fp8 */ \
case 26: /* fp9 */ \
case 27: /* fp10 */ \
case 28: /* fp11 */ \
case 29: /* fp12 */ \
case 30: /* fp13 */ \
case 31: /* fp14 */ \
case 32: /* fp15 */ \
case 33: /* fp16 */ \
case 34: /* fp17 */ \
case 35: /* fp18 */ \
case 36: /* fp19 */ \
case 37: /* fp20 */ \
case 38: /* fp21 */ \
case 39: /* fp22 */ \
case 40: /* fp23 */ \
case 41: /* fp24 */ \
case 42: /* fp25 */ \
case 43: /* fp26 */ \
case 44: /* fp27 */ \
case 45: /* fp28 */ \
case 46: /* fp29 */ \
case 47: /* fp30 */ \
case 48: /* fp31 */ \
addr = blockend - \
((int) &foo.u_fpasave.fpa_regs[(regno)-18] - (int)&foo); \
} \
}
#endif /* _SEQUENT_ */
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
/* 10 i386 registers, 8 i387 registers, and 31 Weitek 1167 registers */
#undef REGISTER_BYTES
#define REGISTER_BYTES ((10 * 4) + (8 * 10) + (31 * 4))
/* Index within `registers' of the first byte of the space for
register N. */
#undef REGISTER_BYTE
#define REGISTER_BYTE(N) \
((N < 3) ? (N * 4) : \
(N < 5) ? (((N - 2) * 10) + 2) : \
@ -148,6 +245,7 @@ i386_skip_prologue PARAMS ((int));
* which are 80 bits each.
*/
#undef REGISTER_RAW_SIZE
#define REGISTER_RAW_SIZE(N) \
((N < 3) ? 4 : \
(N < 5) ? 10 : \
@ -155,22 +253,15 @@ i386_skip_prologue PARAMS ((int));
(N < 14) ? 10 : \
4)
/* Number of bytes of storage in the program's representation
for register N. On the vax, all regs are 4 bytes. */
#define REGISTER_VIRTUAL_SIZE(N) 4
/* Largest value REGISTER_RAW_SIZE can have. */
#undef MAX_REGISTER_RAW_SIZE
#define MAX_REGISTER_RAW_SIZE 10
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 4
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#undef REGISTER_CONVERTIBLE
#define REGISTER_CONVERTIBLE(N) \
((N < 3) ? 0 : \
(N < 5) ? 1 : \
@ -181,6 +272,7 @@ i386_skip_prologue PARAMS ((int));
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#undef REGISTER_CONVERT_TO_VIRTUAL
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
((REGNUM < 3) ? bcopy ((FROM), (TO), 4) : \
(REGNUM < 5) ? i387_to_double((FROM), (TO)) : \
@ -194,6 +286,7 @@ i387_to_double PARAMS ((char *, char *));
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#undef REGISTER_CONVERT_TO_RAW
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
((REGNUM < 3) ? bcopy ((FROM), (TO), 4) : \
(REGNUM < 5) ? double_to_i387((FROM), (TO)) : \
@ -207,6 +300,7 @@ double_to_i387 PARAMS ((char *, char *));
/* Return the GDB type object for the "standard" data type
of data in register N. */
#undef REGISTER_VIRTUAL_TYPE
#define REGISTER_VIRTUAL_TYPE(N) \
((N < 3) ? builtin_type_int : \
(N < 5) ? builtin_type_double : \
@ -214,10 +308,13 @@ double_to_i387 PARAMS ((char *, char *));
(N < 14) ? builtin_type_double : \
builtin_type_int)
/* from m-i386.h */
/* from m-i386.h (now known as tm-i386v.h). */
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
subroutine will return. This is called from call_function. FIXME:
Why is it writing register 0? Is the symmetry different from tm-i386v.h,
or is it some sort of artifact? FIXME. */
#undef STORE_STRUCT_RETURN
#define STORE_STRUCT_RETURN(ADDR, SP) \
{ (SP) -= sizeof (ADDR); \
write_memory ((SP), &(ADDR), sizeof (ADDR)); \
@ -227,111 +324,13 @@ double_to_i387 PARAMS ((char *, char *));
a function return value of type TYPE, and copy that, in virtual format,
into VALBUF. */
#undef EXTRACT_RETURN_VALUE
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
symmetry_extract_return_value(TYPE, REGBUF, VALBUF)
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
/* Extract from an array REGBUF containing the (raw) register state
the address in which a function should return its structure value,
as a CORE_ADDR (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller. */
/* On Symmetry, %ebp points to caller's %ebp, and the return address
is right on top of that. */
#define FRAME_CHAIN(thisframe) \
(!inside_entry_file ((thisframe)->pc) ? \
read_memory_integer((thisframe)->frame, 4) :\
0)
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0)
/* Define other aspects of the stack frame. */
/* A macro that tells us whether the function invocation represented
by FI does not have a frame on the stack associated with it. If it
does not, FRAMELESS is set to 1, else 0. */
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
(FRAMELESS) = frameless_look_for_prologue(FI)
#define FRAME_SAVED_PC(fi) (read_memory_integer((fi)->frame + 4, 4))
#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell.
The weirdness in the "addl $imm8" case is due to gcc sometimes
issuing "addl $-int" after function call returns; this would
produce ridiculously huge arg counts. */
#define FRAME_NUM_ARGS(numargs, fi) \
{ \
int op = read_memory_integer(FRAME_SAVED_PC((fi)), 4); \
int narg; \
if ((op & 0xff) == 0x59) /* 0x59 'popl %ecx' */ \
{ \
numargs = 1; \
} \
else if ((op & 0xffff) == 0xc483) /* 0xc483 'addl $imm8' */ \
{ \
narg = ((op >> 16) & 0xff); \
numargs = (narg >= 128) ? -1 : narg / 4; \
} \
else if ((op & 0xffff) == 0xc481) /* 0xc481 'addl $imm32' */ \
{ \
narg = read_memory_integer(FRAME_SAVED_PC((fi))+2,4); \
numargs = (narg < 0) ? -1 : narg / 4; \
} \
else \
{ \
numargs = -1; \
} \
}
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
This includes special registers such as pc and fp saved in special
ways in the stack frame. sp is even more special:
the address we return for it IS the sp for the next frame. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); }
#ifdef __STDC__ /* Forward decl's for prototypes */
struct frame_info;
struct frame_saved_regs;
#endif
extern void
i386_frame_find_saved_regs PARAMS ((struct frame_info *,
struct frame_saved_regs *));
/* Things needed for making the inferior call functions. */
/* Things needed for making the inferior call functions. FIXME: Merge
this with the main 386 stuff. */
#define PUSH_DUMMY_FRAME \
{ CORE_ADDR sp = read_register (SP_REGNUM); \

View File

@ -1,6 +1,6 @@
/* Definitions to make GDB run on a Sequent Symmetry under dynix 3.0,
with Weitek 1167 and i387 support.
Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
/* Definitions to make GDB run on a Sequent Symmetry under
dynix 3.1 and ptx 1.3, with Weitek 1167 and i387 support.
Copyright 1986, 1987, 1989, 1992, 1993 Free Software Foundation, Inc.
This file is part of GDB.
@ -18,13 +18,26 @@ 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. */
/* Symmetry version by Jay Vosburgh (uunet!sequent!fubar) */
/* Symmetry version by Jay Vosburgh (fubar@sequent.com) */
/* This machine doesn't have the siginterrupt call. */
#define NO_SIGINTERRUPT
#define HAVE_WAIT_STRUCT
#ifdef _SEQUENT_
/* ptx */
#define HAVE_TERMIO
#define USG
#else
/* dynix */
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
#endif
/* XPT_DEBUG doesn't work yet under Dynix 3.0.12, but UNDEBUG does... */
/* #define PTRACE_ATTACH XPT_DEBUG
#define PTRACE_DETACH XPT_UNDEBUG
@ -32,116 +45,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
/* 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 (0x80000000 - (UPAGES * NBPG))
/* The magic numbers below are offsets into u_ar0 in the user struct.
They live in <machine/reg.h>. Gdb calls this macro with blockend
holding u.u_ar0 - KERNEL_U_ADDR. Only the registers listed are
saved in the u area (along with a few others that aren't useful
here. See <machine/reg.h>). */
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ struct user foo; /* needed for finding fpu regs */ \
switch (regno) { \
case 0: \
addr = blockend + EAX * sizeof(int); break; \
case 1: \
addr = blockend + EDX * sizeof(int); break; \
case 2: \
addr = blockend + ECX * sizeof(int); break; \
case 3: /* st(0) */ \
addr = blockend - \
((int)&foo.u_fpusave.fpu_stack[0][0] - (int)&foo); \
break; \
case 4: /* st(1) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[1][0] - (int)&foo); \
break; \
case 5: \
addr = blockend + EBX * sizeof(int); break; \
case 6: \
addr = blockend + ESI * sizeof(int); break; \
case 7: \
addr = blockend + EDI * sizeof(int); break; \
case 8: /* st(2) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[2][0] - (int)&foo); \
break; \
case 9: /* st(3) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[3][0] - (int)&foo); \
break; \
case 10: /* st(4) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[4][0] - (int)&foo); \
break; \
case 11: /* st(5) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[5][0] - (int)&foo); \
break; \
case 12: /* st(6) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[6][0] - (int)&foo); \
break; \
case 13: /* st(7) */ \
addr = blockend - \
((int) &foo.u_fpusave.fpu_stack[7][0] - (int)&foo); \
break; \
case 14: \
addr = blockend + ESP * sizeof(int); break; \
case 15: \
addr = blockend + EBP * sizeof(int); break; \
case 16: \
addr = blockend + EIP * sizeof(int); break; \
case 17: \
addr = blockend + FLAGS * sizeof(int); break; \
case 18: /* fp1 */ \
case 19: /* fp2 */ \
case 20: /* fp3 */ \
case 21: /* fp4 */ \
case 22: /* fp5 */ \
case 23: /* fp6 */ \
case 24: /* fp7 */ \
case 25: /* fp8 */ \
case 26: /* fp9 */ \
case 27: /* fp10 */ \
case 28: /* fp11 */ \
case 29: /* fp12 */ \
case 30: /* fp13 */ \
case 31: /* fp14 */ \
case 32: /* fp15 */ \
case 33: /* fp16 */ \
case 34: /* fp17 */ \
case 35: /* fp18 */ \
case 36: /* fp19 */ \
case 37: /* fp20 */ \
case 38: /* fp21 */ \
case 39: /* fp22 */ \
case 40: /* fp23 */ \
case 41: /* fp24 */ \
case 42: /* fp25 */ \
case 43: /* fp26 */ \
case 44: /* fp27 */ \
case 45: /* fp28 */ \
case 46: /* fp29 */ \
case 47: /* fp30 */ \
case 48: /* fp31 */ \
addr = blockend - \
((int) &foo.u_fpasave.fpa_regs[(regno)-18] - (int)&foo); \
} \
}
/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
#define FETCH_INFERIOR_REGISTERS
/* We must fetch all the regs before storing, since we store all at once. */
#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)

View File

@ -35,7 +35,8 @@ hppa*-hp-bsd*) gdb_host=hppabsd ;;
hppa*-hp-hpux*) gdb_host=hppahpux ;;
i[34]86-ncr-*) gdb_host=ncr3000 ;;
i[34]86-sequent-*) gdb_host=symmetry ;;
i[34]86-sequent-bsd*) gdb_host=symmetry ;; #dynix
i[34]86-sequent-sysv*) gdb_host=ptx ;;
i[34]86-*-aix*) gdb_host=i386aix ;;
i[34]86-*-bsd*) gdb_host=i386bsd ;;

308
gdb/symm-nat.c Normal file
View File

@ -0,0 +1,308 @@
/* Sequent Symmetry host interface, for GDB when running under Unix.
Copyright 1986, 1987, 1989, 1991, 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. */
/* FIXME, some 387-specific items of use taken from i387-tdep.c -- ought to be
merged back in. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "symtab.h"
#include <signal.h>
#include <sys/param.h>
#include <sys/user.h>
#include <sys/dir.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include "gdbcore.h"
#include <fcntl.h>
#include <sgtty.h>
#define TERMINAL struct sgttyb
#include "gdbcore.h"
void
store_inferior_registers(regno)
int regno;
{
struct pt_regset regs;
int reg_tmp, i;
extern char registers[];
regs.pr_eax = *(int *)&registers[REGISTER_BYTE(0)];
regs.pr_ebx = *(int *)&registers[REGISTER_BYTE(5)];
regs.pr_ecx = *(int *)&registers[REGISTER_BYTE(2)];
regs.pr_edx = *(int *)&registers[REGISTER_BYTE(1)];
regs.pr_esi = *(int *)&registers[REGISTER_BYTE(6)];
regs.pr_edi = *(int *)&registers[REGISTER_BYTE(7)];
regs.pr_esp = *(int *)&registers[REGISTER_BYTE(14)];
regs.pr_ebp = *(int *)&registers[REGISTER_BYTE(15)];
regs.pr_eip = *(int *)&registers[REGISTER_BYTE(16)];
regs.pr_flags = *(int *)&registers[REGISTER_BYTE(17)];
for (i = 0; i < 31; i++)
{
regs.pr_fpa.fpa_regs[i] =
*(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)];
}
PTRACE_WRITE_REGS (inferior_pid, (PTRACE_ARG3_TYPE) &regs);
}
void
fetch_inferior_registers (regno)
int regno;
{
int i;
struct pt_regset regs;
extern char registers[];
registers_fetched ();
PTRACE_READ_REGS (inferior_pid, (PTRACE_ARG3_TYPE) &regs);
*(int *)&registers[REGISTER_BYTE(EAX_REGNUM)] = regs.pr_eax;
*(int *)&registers[REGISTER_BYTE(EBX_REGNUM)] = regs.pr_ebx;
*(int *)&registers[REGISTER_BYTE(ECX_REGNUM)] = regs.pr_ecx;
*(int *)&registers[REGISTER_BYTE(EDX_REGNUM)] = regs.pr_edx;
*(int *)&registers[REGISTER_BYTE(ESI_REGNUM)] = regs.pr_esi;
*(int *)&registers[REGISTER_BYTE(EDI_REGNUM)] = regs.pr_edi;
*(int *)&registers[REGISTER_BYTE(EBP_REGNUM)] = regs.pr_ebp;
*(int *)&registers[REGISTER_BYTE(ESP_REGNUM)] = regs.pr_esp;
*(int *)&registers[REGISTER_BYTE(EIP_REGNUM)] = regs.pr_eip;
*(int *)&registers[REGISTER_BYTE(EFLAGS_REGNUM)] = regs.pr_flags;
for (i = 0; i < FPA_NREGS; i++)
{
*(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)] =
regs.pr_fpa.fpa_regs[i];
}
memcpy (&registers[REGISTER_BYTE(ST0_REGNUM)], regs.pr_fpu.fpu_stack[0], 10);
memcpy (&registers[REGISTER_BYTE(ST1_REGNUM)], regs.pr_fpu.fpu_stack[1], 10);
memcpy (&registers[REGISTER_BYTE(ST2_REGNUM)], regs.pr_fpu.fpu_stack[2], 10);
memcpy (&registers[REGISTER_BYTE(ST3_REGNUM)], regs.pr_fpu.fpu_stack[3], 10);
memcpy (&registers[REGISTER_BYTE(ST4_REGNUM)], regs.pr_fpu.fpu_stack[4], 10);
memcpy (&registers[REGISTER_BYTE(ST5_REGNUM)], regs.pr_fpu.fpu_stack[5], 10);
memcpy (&registers[REGISTER_BYTE(ST6_REGNUM)], regs.pr_fpu.fpu_stack[6], 10);
memcpy (&registers[REGISTER_BYTE(ST7_REGNUM)], regs.pr_fpu.fpu_stack[7], 10);
}
/* FIXME: This should be merged with i387-tdep.c as well. */
static
print_fpu_status(ep)
struct pt_regset ep;
{
int i;
int bothstatus;
int top;
int fpreg;
unsigned char *p;
printf("80387:");
if (ep.pr_fpu.fpu_ip == 0) {
printf(" not in use.\n");
return;
} else {
printf("\n");
}
if (ep.pr_fpu.fpu_status != 0) {
print_387_status_word (ep.pr_fpu.fpu_status);
}
print_387_control_word (ep.pr_fpu.fpu_control);
printf ("last exception: ");
printf ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4);
printf ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip);
printf ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel);
top = (ep.pr_fpu.fpu_status >> 11) & 7;
printf ("regno tag msb lsb value\n");
for (fpreg = 7; fpreg >= 0; fpreg--)
{
double val;
printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3)
{
case 0: printf ("valid "); break;
case 1: printf ("zero "); break;
case 2: printf ("trap "); break;
case 3: printf ("empty "); break;
}
for (i = 9; i >= 0; i--)
printf ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]);
i387_to_double (ep.pr_fpu.fpu_stack[fpreg], (char *)&val);
printf (" %g\n", val);
}
if (ep.pr_fpu.fpu_rsvd1)
warning ("rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1);
if (ep.pr_fpu.fpu_rsvd2)
warning ("rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2);
if (ep.pr_fpu.fpu_rsvd3)
warning ("rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3);
if (ep.pr_fpu.fpu_rsvd5)
warning ("rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5);
}
print_1167_control_word(pcr)
unsigned int pcr;
{
int pcr_tmp;
pcr_tmp = pcr & FPA_PCR_MODE;
printf("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12);
switch (pcr_tmp & 12) {
case 0:
printf("RN (Nearest Value)");
break;
case 1:
printf("RZ (Zero)");
break;
case 2:
printf("RP (Positive Infinity)");
break;
case 3:
printf("RM (Negative Infinity)");
break;
}
printf("; IRND= %d ", pcr_tmp & 2);
if (0 == pcr_tmp & 2) {
printf("(same as RND)\n");
} else {
printf("(toward zero)\n");
}
pcr_tmp = pcr & FPA_PCR_EM;
printf("\tEM= %#x", pcr_tmp);
if (pcr_tmp & FPA_PCR_EM_DM) printf(" DM");
if (pcr_tmp & FPA_PCR_EM_UOM) printf(" UOM");
if (pcr_tmp & FPA_PCR_EM_PM) printf(" PM");
if (pcr_tmp & FPA_PCR_EM_UM) printf(" UM");
if (pcr_tmp & FPA_PCR_EM_OM) printf(" OM");
if (pcr_tmp & FPA_PCR_EM_ZM) printf(" ZM");
if (pcr_tmp & FPA_PCR_EM_IM) printf(" IM");
printf("\n");
pcr_tmp = FPA_PCR_CC;
printf("\tCC= %#x", pcr_tmp);
if (pcr_tmp & FPA_PCR_20MHZ) printf(" 20MHZ");
if (pcr_tmp & FPA_PCR_CC_Z) printf(" Z");
if (pcr_tmp & FPA_PCR_CC_C2) printf(" C2");
if (pcr_tmp & FPA_PCR_CC_C1) printf(" C1");
switch (pcr_tmp) {
case FPA_PCR_CC_Z:
printf(" (Equal)");
break;
case FPA_PCR_CC_C1:
printf(" (Less than)");
break;
case 0:
printf(" (Greater than)");
break;
case FPA_PCR_CC_Z | FPA_PCR_CC_C1 | FPA_PCR_CC_C2:
printf(" (Unordered)");
break;
default:
printf(" (Undefined)");
break;
}
printf("\n");
pcr_tmp = pcr & FPA_PCR_AE;
printf("\tAE= %#x", pcr_tmp);
if (pcr_tmp & FPA_PCR_AE_DE) printf(" DE");
if (pcr_tmp & FPA_PCR_AE_UOE) printf(" UOE");
if (pcr_tmp & FPA_PCR_AE_PE) printf(" PE");
if (pcr_tmp & FPA_PCR_AE_UE) printf(" UE");
if (pcr_tmp & FPA_PCR_AE_OE) printf(" OE");
if (pcr_tmp & FPA_PCR_AE_ZE) printf(" ZE");
if (pcr_tmp & FPA_PCR_AE_EE) printf(" EE");
if (pcr_tmp & FPA_PCR_AE_IE) printf(" IE");
printf("\n");
}
print_1167_regs(regs)
long regs[FPA_NREGS];
{
int i;
union {
double d;
long l[2];
} xd;
union {
float f;
long l;
} xf;
for (i = 0; i < FPA_NREGS; i++) {
xf.l = regs[i];
printf("%%fp%d: raw= %#x, single= %f", i+1, regs[i], xf.f);
if (!(i & 1)) {
printf("\n");
} else {
xd.l[1] = regs[i];
xd.l[0] = regs[i+1];
printf(", double= %f\n", xd.d);
}
}
}
print_fpa_status(ep)
struct pt_regset ep;
{
printf("WTL 1167:");
if (ep.pr_fpa.fpa_pcr !=0) {
printf("\n");
print_1167_control_word(ep.pr_fpa.fpa_pcr);
print_1167_regs(ep.pr_fpa.fpa_regs);
} else {
printf(" not in use.\n");
}
}
i386_float_info ()
{
char ubuf[UPAGES*NBPG];
struct pt_regset regset;
if (have_inferior_p())
{
PTRACE_READ_REGS (inferior_pid, (PTRACE_ARG3_TYPE) &regset);
}
else
{
int corechan = bfd_cache_lookup (core_bfd);
if (lseek (corechan, 0, 0) < 0)
{
perror ("seek on core file");
}
if (myread (corechan, ubuf, UPAGES*NBPG) < 0)
{
perror ("read on core file");
}
/* only interested in the floating point registers */
regset.pr_fpu = ((struct user *) ubuf)->u_fpusave;
regset.pr_fpa = ((struct user *) ubuf)->u_fpasave;
}
print_fpu_status(regset);
print_fpa_status(regset);
}

View File

@ -39,105 +39,6 @@ static i386_follow_jump ();
#include <sgtty.h>
#define TERMINAL struct sgttyb
exec_file_command (filename, from_tty)
char *filename;
int from_tty;
{
int val;
/* Eliminate all traces of old exec file.
Mark text segment as empty. */
if (execfile)
free (execfile);
execfile = 0;
data_start = 0;
data_end -= exec_data_start;
text_start = 0;
text_end = 0;
exec_data_start = 0;
exec_data_end = 0;
if (execchan >= 0)
close (execchan);
execchan = -1;
/* Now open and digest the file the user requested, if any. */
if (filename)
{
filename = tilde_expand (filename);
make_cleanup (free, filename);
execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
&execfile);
if (execchan < 0)
perror_with_name (filename);
#ifdef COFF_FORMAT
{
int aout_hdrsize;
int num_sections;
if (read_file_hdr (execchan, &file_hdr) < 0)
error ("\"%s\": not in executable format.", execfile);
aout_hdrsize = file_hdr.f_opthdr;
num_sections = file_hdr.f_nscns;
if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
error ("\"%s\": can't read optional aouthdr", execfile);
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
aout_hdrsize) < 0)
error ("\"%s\": can't read text section header", execfile);
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
aout_hdrsize) < 0)
error ("\"%s\": can't read data section header", execfile);
text_start = exec_aouthdr.text_start;
text_end = text_start + exec_aouthdr.tsize;
text_offset = text_hdr.s_scnptr;
exec_data_start = exec_aouthdr.data_start;
exec_data_end = exec_data_start + exec_aouthdr.dsize;
exec_data_offset = data_hdr.s_scnptr;
data_start = exec_data_start;
data_end += exec_data_start;
exec_mtime = file_hdr.f_timdat;
}
#else /* not COFF_FORMAT */
{
struct stat st_exec;
val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
if (val < 0)
perror_with_name (filename);
text_start = N_ADDRADJ(exec_aouthdr);
exec_data_start = round(exec_aouthdr.a_text, NBPG*CLSIZE);
text_offset = N_TXTOFF (exec_aouthdr);
exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
text_end = exec_aouthdr.a_text;
exec_data_end = exec_data_start + exec_aouthdr.a_data;
data_start = exec_data_start;
data_end = data_start + exec_aouthdr.a_data;
exec_data_offset = N_TXTOFF(exec_aouthdr);
fstat (execchan, &st_exec);
exec_mtime = st_exec.st_mtime;
}
#endif /* not COFF_FORMAT */
validate_files ();
}
else if (from_tty)
printf ("No exec file now.\n");
/* Tell display code (if any) about the changed file name. */
if (exec_file_display_hook)
(*exec_file_display_hook) (filename);
}
/* rounds 'one' up to divide evenly by 'two' */
int
@ -229,7 +130,7 @@ i386_frame_find_saved_regs (fip, fsrp)
CORE_ADDR adr;
int i;
bzero (fsrp, sizeof *fsrp);
memset (fsrp, 0, sizeof *fsrp);
/* if frame is the end of a dummy, compute where the
* beginning would be
@ -301,9 +202,9 @@ i386_get_frame_setup (pc)
static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 };
pos = codestream_tell ();
codestream_read (buf, 4);
if (bcmp (buf, proto1, 3) == 0)
if (memcmp (buf, proto1, 3) == 0)
pos += 3;
else if (bcmp (buf, proto2, 4) == 0)
else if (memcmp (buf, proto2, 4) == 0)
pos += 4;
codestream_seek (pos);
@ -434,6 +335,7 @@ i386_skip_prologue (pc)
return (codestream_tell ());
}
void
symmetry_extract_return_value(type, regbuf, valbuf)
struct type *type;
char *regbuf;
@ -456,11 +358,13 @@ symmetry_extract_return_value(type, regbuf, valbuf)
xd.l[0] = *((int *)&regbuf[REGISTER_BYTE(20)]);
switch (TYPE_LENGTH(type)) {
case 4:
/* FIXME: broken for cross-debugging. */
f = (float) xd.d;
bcopy(&f, valbuf, TYPE_LENGTH(type));
memcpy (valbuf, &f, TYPE_LENGTH(type));
break;
case 8:
bcopy(&xd.d, valbuf, TYPE_LENGTH(type));
/* FIXME: broken for cross-debugging. */
memcpy (valbuf, &xd.d, TYPE_LENGTH(type));
break;
default:
error("Unknown floating point size");
@ -473,17 +377,113 @@ symmetry_extract_return_value(type, regbuf, valbuf)
switch (TYPE_LENGTH(type)) {
case 4: /* float */
f = (float) xd.d;
bcopy(&f, valbuf, 4);
/* FIXME: broken for cross-debugging. */
memcpy (valbuf, &f, 4);
break;
case 8: /* double */
bcopy(&xd.d, valbuf, 8);
/* FIXME: broken for cross-debugging. */
memcpy (valbuf, &xd.d, 8);
break;
default:
error("Unknown floating point size");
break;
}
}
} else {
bcopy (regbuf, valbuf, TYPE_LENGTH (type));
} else {
memcpy (valbuf, regbuf, TYPE_LENGTH (type));
}
}
#ifdef _SEQUENT_ /* ptx, not dynix */
/*
* Convert compiler register number to gdb internal
* register number. The PTX C compiler only really
* puts things in %edi, %esi and %ebx, but it can't hurt
* to be complete here.
*/
int
ptx_coff_regno_to_gdb(regno)
int regno;
{
return I386_REGNO_TO_SYMMETRY(regno);
}
/* For ptx, the value in blockend will be meaningless. This function
merely returns the proper offset given the register number. This
is much easier, because under ptx, the upage is set up with the
user struct on "top", and the registers "beneath" it (and thus defines
TRAD_CORE_USER_OFFSET in bfd). */
/* The following table is for ptx 1.3. In theory it should not change with
the OS version, but if it does we should (if possible) figure out a way
to accept both the old and the new formats. */
static unsigned int reg_offsets[NUM_REGS] = {
/*
* u.u_ar0 = 0xfffff8d0
* VA_UBLOCK = 0xffffe000
* VA_UAREA = 0xfffff8e8
* struct user at ublock offset 0x18e8
* registers at ublock offset 0x18d0
*/
0x18d0, /* eax */
0x18c8, /* eax */
0x18cc, /* eax */
0x1be0, /* st0 */
0x1bea, /* st1 */
0x18c4, /* ebx */
0x18b8, /* esi */
0x18b4, /* edi */
0x1bf4, /* st2 */
0x1bfe, /* st3 */
0x1c08, /* st4 */
0x1c12, /* st5 */
0x1c1c, /* st6 */
0x1c26, /* st7 */
0x18e0, /* esp */
0x18bc, /* ebp */
0x18d4, /* eip */
0x18dc, /* flags */
0x1c38, /* fp1 */
0x1c3c, /* fp2 */
0x1c40, /* fp3 */
0x1c44, /* fp4 */
0x1c48, /* fp5 */
0x1c4c, /* fp6 */
0x1c50, /* fp7 */
0x1c54, /* fp8 */
0x1c58, /* fp9 */
0x1c5c, /* fp10 */
0x1c60, /* fp11 */
0x1c64, /* fp12 */
0x1c68, /* fp13 */
0x1c6c, /* fp14 */
0x1c70, /* fp15 */
0x1c74, /* fp16 */
0x1c78, /* fp17 */
0x1c7c, /* fp18 */
0x1c80, /* fp19 */
0x1c84, /* fp20 */
0x1c88, /* fp21 */
0x1c8c, /* fp22 */
0x1c90, /* fp23 */
0x1c94, /* fp24 */
0x1c98, /* fp25 */
0x1c9c, /* fp26 */
0x1ca0, /* fp27 */
0x1ca4, /* fp28 */
0x1ca8, /* fp29 */
0x1cac, /* fp30 */
0x1cb0, /* fp31 */
};
unsigned int
register_addr (regno, blockend)
int regno, blockend;
{
if ((regno < 0) || (regno >= NUM_REGS)) {
error("Invalid register number %d.", regno);
}
return reg_offsets[regno];
}
#endif /* _SEQUENT_ */

View File

@ -1,444 +0,0 @@
/* Sequent Symmetry host interface, for GDB when running under Unix.
Copyright 1986, 1987, 1989, 1991, 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. */
/* FIXME, some 387-specific items of use taken from i387-tdep.c -- ought to be
merged back in. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "symtab.h"
#include <signal.h>
#include <sys/param.h>
#include <sys/user.h>
#include <sys/dir.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include "gdbcore.h"
#include <fcntl.h>
#include <sgtty.h>
#define TERMINAL struct sgttyb
#include "gdbcore.h"
void
store_inferior_registers(regno)
int regno;
{
struct pt_regset regs;
int reg_tmp, i;
extern char registers[];
#if 0
/* PREPARE_TO_STORE deals with this. */
if (-1 == regno)
{
#endif
regs.pr_eax = *(int *)&registers[REGISTER_BYTE(0)];
regs.pr_ebx = *(int *)&registers[REGISTER_BYTE(5)];
regs.pr_ecx = *(int *)&registers[REGISTER_BYTE(2)];
regs.pr_edx = *(int *)&registers[REGISTER_BYTE(1)];
regs.pr_esi = *(int *)&registers[REGISTER_BYTE(6)];
regs.pr_edi = *(int *)&registers[REGISTER_BYTE(7)];
regs.pr_esp = *(int *)&registers[REGISTER_BYTE(14)];
regs.pr_ebp = *(int *)&registers[REGISTER_BYTE(15)];
regs.pr_eip = *(int *)&registers[REGISTER_BYTE(16)];
regs.pr_flags = *(int *)&registers[REGISTER_BYTE(17)];
for (i = 0; i < 31; i++) {
regs.pr_fpa.fpa_regs[i] =
*(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)];
}
#if 0
}
else
{
reg_tmp = *(int *)&registers[REGISTER_BYTE(regno)];
ptrace(XPT_RREGS, inferior_pid, (PTRACE_ARG3_TYPE) &regs, 0);
switch (regno)
{
case 0:
regs.pr_eax = *(int *)&registers[REGISTER_BYTE(0)];
break;
case 5:
regs.pr_ebx = *(int *)&registers[REGISTER_BYTE(5)];
break;
case 2:
regs.pr_ecx = *(int *)&registers[REGISTER_BYTE(2)];
break;
case 1:
regs.pr_edx = *(int *)&registers[REGISTER_BYTE(1)];
break;
case 6:
regs.pr_esi = *(int *)&registers[REGISTER_BYTE(6)];
break;
case 7:
regs.pr_edi = *(int *)&registers[REGISTER_BYTE(7)];
break;
case 15:
regs.pr_ebp = *(int *)&registers[REGISTER_BYTE(15)];
break;
case 14:
regs.pr_esp = *(int *)&registers[REGISTER_BYTE(14)];
break;
case 16:
regs.pr_eip = *(int *)&registers[REGISTER_BYTE(16)];
break;
case 17:
regs.pr_flags = *(int *)&registers[REGISTER_BYTE(17)];
break;
}
}
#endif /* 0 */
ptrace(XPT_WREGS, inferior_pid, (PTRACE_ARG3_TYPE) &regs, 0);
}
void
fetch_inferior_registers (regno)
int regno;
{
int i;
struct pt_regset regs;
extern char registers[];
registers_fetched ();
ptrace(XPT_RREGS, inferior_pid, (PTRACE_ARG3_TYPE) &regs, 0);
*(int *)&registers[REGISTER_BYTE(0)] = regs.pr_eax;
*(int *)&registers[REGISTER_BYTE(5)] = regs.pr_ebx;
*(int *)&registers[REGISTER_BYTE(2)] = regs.pr_ecx;
*(int *)&registers[REGISTER_BYTE(1)] = regs.pr_edx;
*(int *)&registers[REGISTER_BYTE(6)] = regs.pr_esi;
*(int *)&registers[REGISTER_BYTE(7)] = regs.pr_edi;
*(int *)&registers[REGISTER_BYTE(15)] = regs.pr_ebp;
*(int *)&registers[REGISTER_BYTE(14)] = regs.pr_esp;
*(int *)&registers[REGISTER_BYTE(16)] = regs.pr_eip;
*(int *)&registers[REGISTER_BYTE(17)] = regs.pr_flags;
for (i = 0; i < FPA_NREGS; i++) {
*(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)] = regs.pr_fpa.fpa_regs[i];
}
bcopy(regs.pr_fpu.fpu_stack[0], &registers[REGISTER_BYTE(3)], 10);
bcopy(regs.pr_fpu.fpu_stack[1], &registers[REGISTER_BYTE(4)], 10);
bcopy(regs.pr_fpu.fpu_stack[2], &registers[REGISTER_BYTE(8)], 10);
bcopy(regs.pr_fpu.fpu_stack[3], &registers[REGISTER_BYTE(9)], 10);
bcopy(regs.pr_fpu.fpu_stack[4], &registers[REGISTER_BYTE(10)], 10);
bcopy(regs.pr_fpu.fpu_stack[5], &registers[REGISTER_BYTE(11)], 10);
bcopy(regs.pr_fpu.fpu_stack[6], &registers[REGISTER_BYTE(12)], 10);
bcopy(regs.pr_fpu.fpu_stack[7], &registers[REGISTER_BYTE(13)], 10);
}
/* Work with core dump and executable files, for GDB.
This code would be in core.c if it weren't machine-dependent. */
void
core_file_command (filename, from_tty)
char *filename;
int from_tty;
{
int val;
extern char registers[];
/* Discard all vestiges of any previous core file
and mark data and stack spaces as empty. */
if (corefile)
free (corefile);
corefile = 0;
if (corechan >= 0)
close (corechan);
corechan = -1;
data_start = 0;
data_end = 0;
stack_start = STACK_END_ADDR;
stack_end = STACK_END_ADDR;
/* Now, if a new core file was specified, open it and digest it. */
if (filename)
{
filename = tilde_expand (filename);
make_cleanup (free, filename);
if (have_inferior_p ())
error ("To look at a core file, you must kill the program with \"kill\".");
corechan = open (filename, O_RDONLY, 0);
if (corechan < 0)
perror_with_name (filename);
/* 4.2-style (and perhaps also sysV-style) core dump file. */
{
struct user u;
int reg_offset;
val = myread (corechan, &u, sizeof u);
if (val < 0)
perror_with_name (filename);
data_start = exec_data_start;
data_end = data_start + NBPG * (u.u_dsize - u.u_tsize);
stack_start = stack_end - NBPG * u.u_ssize;
data_offset = NBPG * UPAGES;
stack_offset = ctob(UPAGES + u.u_dsize - u.u_tsize);
reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
printf("u.u_tsize= %#x, u.u_dsize= %#x, u.u_ssize= %#x, stack_off= %#x\n",
u.u_tsize, u.u_dsize, u.u_ssize, stack_offset);
core_aouthdr.a_magic = 0;
/* Read the register values out of the core file and store
them where `read_register' will find them. */
{
register int regno;
for (regno = 0; regno < NUM_REGS; regno++)
{
char buf[MAX_REGISTER_RAW_SIZE];
val = lseek (corechan, register_addr (regno, reg_offset), 0);
if (val < 0)
perror_with_name (filename);
val = myread (corechan, buf, sizeof buf);
if (val < 0)
perror_with_name (filename);
supply_register (regno, buf);
}
}
}
if (filename[0] == '/')
corefile = savestring (filename, strlen (filename));
else
{
corefile = concat (current_directory, "/", filename, NULL);
}
set_current_frame(create_new_frame(read_register(FP_REGNUM),
read_pc()));
/* set_current_frame (read_register (FP_REGNUM));*/
select_frame (get_current_frame (), 0);
validate_files ();
}
else if (from_tty)
printf ("No core file now.\n");
}
/* FIXME: This should be merged with i387-tdep.c as well. */
static
print_fpu_status(ep)
struct pt_regset ep;
{
int i;
int bothstatus;
int top;
int fpreg;
unsigned char *p;
printf("80387:");
if (ep.pr_fpu.fpu_ip == 0) {
printf(" not in use.\n");
return;
} else {
printf("\n");
}
if (ep.pr_fpu.fpu_status != 0) {
print_387_status_word (ep.pr_fpu.fpu_status);
}
print_387_control_word (ep.pr_fpu.fpu_control);
printf ("last exception: ");
printf ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4);
printf ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip);
printf ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel);
top = (ep.pr_fpu.fpu_status >> 11) & 7;
printf ("regno tag msb lsb value\n");
for (fpreg = 7; fpreg >= 0; fpreg--)
{
double val;
printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3)
{
case 0: printf ("valid "); break;
case 1: printf ("zero "); break;
case 2: printf ("trap "); break;
case 3: printf ("empty "); break;
}
for (i = 9; i >= 0; i--)
printf ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]);
i387_to_double (ep.pr_fpu.fpu_stack[fpreg], (char *)&val);
printf (" %g\n", val);
}
if (ep.pr_fpu.fpu_rsvd1)
warning ("rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1);
if (ep.pr_fpu.fpu_rsvd2)
warning ("rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2);
if (ep.pr_fpu.fpu_rsvd3)
warning ("rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3);
if (ep.pr_fpu.fpu_rsvd5)
warning ("rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5);
}
print_1167_control_word(pcr)
unsigned int pcr;
{
int pcr_tmp;
pcr_tmp = pcr & FPA_PCR_MODE;
printf("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12);
switch (pcr_tmp & 12) {
case 0:
printf("RN (Nearest Value)");
break;
case 1:
printf("RZ (Zero)");
break;
case 2:
printf("RP (Positive Infinity)");
break;
case 3:
printf("RM (Negative Infinity)");
break;
}
printf("; IRND= %d ", pcr_tmp & 2);
if (0 == pcr_tmp & 2) {
printf("(same as RND)\n");
} else {
printf("(toward zero)\n");
}
pcr_tmp = pcr & FPA_PCR_EM;
printf("\tEM= %#x", pcr_tmp);
if (pcr_tmp & FPA_PCR_EM_DM) printf(" DM");
if (pcr_tmp & FPA_PCR_EM_UOM) printf(" UOM");
if (pcr_tmp & FPA_PCR_EM_PM) printf(" PM");
if (pcr_tmp & FPA_PCR_EM_UM) printf(" UM");
if (pcr_tmp & FPA_PCR_EM_OM) printf(" OM");
if (pcr_tmp & FPA_PCR_EM_ZM) printf(" ZM");
if (pcr_tmp & FPA_PCR_EM_IM) printf(" IM");
printf("\n");
pcr_tmp = FPA_PCR_CC;
printf("\tCC= %#x", pcr_tmp);
if (pcr_tmp & FPA_PCR_20MHZ) printf(" 20MHZ");
if (pcr_tmp & FPA_PCR_CC_Z) printf(" Z");
if (pcr_tmp & FPA_PCR_CC_C2) printf(" C2");
if (pcr_tmp & FPA_PCR_CC_C1) printf(" C1");
switch (pcr_tmp) {
case FPA_PCR_CC_Z:
printf(" (Equal)");
break;
case FPA_PCR_CC_C1:
printf(" (Less than)");
break;
case 0:
printf(" (Greater than)");
break;
case FPA_PCR_CC_Z | FPA_PCR_CC_C1 | FPA_PCR_CC_C2:
printf(" (Unordered)");
break;
default:
printf(" (Undefined)");
break;
}
printf("\n");
pcr_tmp = pcr & FPA_PCR_AE;
printf("\tAE= %#x", pcr_tmp);
if (pcr_tmp & FPA_PCR_AE_DE) printf(" DE");
if (pcr_tmp & FPA_PCR_AE_UOE) printf(" UOE");
if (pcr_tmp & FPA_PCR_AE_PE) printf(" PE");
if (pcr_tmp & FPA_PCR_AE_UE) printf(" UE");
if (pcr_tmp & FPA_PCR_AE_OE) printf(" OE");
if (pcr_tmp & FPA_PCR_AE_ZE) printf(" ZE");
if (pcr_tmp & FPA_PCR_AE_EE) printf(" EE");
if (pcr_tmp & FPA_PCR_AE_IE) printf(" IE");
printf("\n");
}
print_1167_regs(regs)
long regs[FPA_NREGS];
{
int i;
union {
double d;
long l[2];
} xd;
union {
float f;
long l;
} xf;
for (i = 0; i < FPA_NREGS; i++) {
xf.l = regs[i];
printf("%%fp%d: raw= %#x, single= %f", i+1, regs[i], xf.f);
if (!(i & 1)) {
printf("\n");
} else {
xd.l[1] = regs[i];
xd.l[0] = regs[i+1];
printf(", double= %f\n", xd.d);
}
}
}
print_fpa_status(ep)
struct pt_regset ep;
{
printf("WTL 1167:");
if (ep.pr_fpa.fpa_pcr !=0) {
printf("\n");
print_1167_control_word(ep.pr_fpa.fpa_pcr);
print_1167_regs(ep.pr_fpa.fpa_regs);
} else {
printf(" not in use.\n");
}
}
i386_float_info ()
{
char ubuf[UPAGES*NBPG];
struct pt_regset regset;
extern int corechan;
if (have_inferior_p()) {
call_ptrace(XPT_RREGS, inferior_pid, (PTRACE_ARG3_TYPE) &regset, 0);
} else {
if (lseek (corechan, 0, 0) < 0) {
perror ("seek on core file");
}
if (myread (corechan, ubuf, UPAGES*NBPG) < 0) {
perror ("read on core file");
}
/* only interested in the floating point registers */
regset.pr_fpu = ((struct user *) ubuf)->u_fpusave;
regset.pr_fpa = ((struct user *) ubuf)->u_fpasave;
}
print_fpu_status(regset);
print_fpa_status(regset);
}