mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 20:49:43 +00:00
* 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:
parent
bea80b013d
commit
56eec3c737
@ -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.
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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); \
|
||||
|
@ -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)
|
||||
|
@ -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
308
gdb/symm-nat.c
Normal 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 *)®isters[REGISTER_BYTE(0)];
|
||||
regs.pr_ebx = *(int *)®isters[REGISTER_BYTE(5)];
|
||||
regs.pr_ecx = *(int *)®isters[REGISTER_BYTE(2)];
|
||||
regs.pr_edx = *(int *)®isters[REGISTER_BYTE(1)];
|
||||
regs.pr_esi = *(int *)®isters[REGISTER_BYTE(6)];
|
||||
regs.pr_edi = *(int *)®isters[REGISTER_BYTE(7)];
|
||||
regs.pr_esp = *(int *)®isters[REGISTER_BYTE(14)];
|
||||
regs.pr_ebp = *(int *)®isters[REGISTER_BYTE(15)];
|
||||
regs.pr_eip = *(int *)®isters[REGISTER_BYTE(16)];
|
||||
regs.pr_flags = *(int *)®isters[REGISTER_BYTE(17)];
|
||||
for (i = 0; i < 31; i++)
|
||||
{
|
||||
regs.pr_fpa.fpa_regs[i] =
|
||||
*(int *)®isters[REGISTER_BYTE(FP1_REGNUM+i)];
|
||||
}
|
||||
PTRACE_WRITE_REGS (inferior_pid, (PTRACE_ARG3_TYPE) ®s);
|
||||
}
|
||||
|
||||
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) ®s);
|
||||
*(int *)®isters[REGISTER_BYTE(EAX_REGNUM)] = regs.pr_eax;
|
||||
*(int *)®isters[REGISTER_BYTE(EBX_REGNUM)] = regs.pr_ebx;
|
||||
*(int *)®isters[REGISTER_BYTE(ECX_REGNUM)] = regs.pr_ecx;
|
||||
*(int *)®isters[REGISTER_BYTE(EDX_REGNUM)] = regs.pr_edx;
|
||||
*(int *)®isters[REGISTER_BYTE(ESI_REGNUM)] = regs.pr_esi;
|
||||
*(int *)®isters[REGISTER_BYTE(EDI_REGNUM)] = regs.pr_edi;
|
||||
*(int *)®isters[REGISTER_BYTE(EBP_REGNUM)] = regs.pr_ebp;
|
||||
*(int *)®isters[REGISTER_BYTE(ESP_REGNUM)] = regs.pr_esp;
|
||||
*(int *)®isters[REGISTER_BYTE(EIP_REGNUM)] = regs.pr_eip;
|
||||
*(int *)®isters[REGISTER_BYTE(EFLAGS_REGNUM)] = regs.pr_flags;
|
||||
for (i = 0; i < FPA_NREGS; i++)
|
||||
{
|
||||
*(int *)®isters[REGISTER_BYTE(FP1_REGNUM+i)] =
|
||||
regs.pr_fpa.fpa_regs[i];
|
||||
}
|
||||
memcpy (®isters[REGISTER_BYTE(ST0_REGNUM)], regs.pr_fpu.fpu_stack[0], 10);
|
||||
memcpy (®isters[REGISTER_BYTE(ST1_REGNUM)], regs.pr_fpu.fpu_stack[1], 10);
|
||||
memcpy (®isters[REGISTER_BYTE(ST2_REGNUM)], regs.pr_fpu.fpu_stack[2], 10);
|
||||
memcpy (®isters[REGISTER_BYTE(ST3_REGNUM)], regs.pr_fpu.fpu_stack[3], 10);
|
||||
memcpy (®isters[REGISTER_BYTE(ST4_REGNUM)], regs.pr_fpu.fpu_stack[4], 10);
|
||||
memcpy (®isters[REGISTER_BYTE(ST5_REGNUM)], regs.pr_fpu.fpu_stack[5], 10);
|
||||
memcpy (®isters[REGISTER_BYTE(ST6_REGNUM)], regs.pr_fpu.fpu_stack[6], 10);
|
||||
memcpy (®isters[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) ®set);
|
||||
}
|
||||
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);
|
||||
}
|
216
gdb/symm-tdep.c
216
gdb/symm-tdep.c
@ -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 *)®buf[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_ */
|
||||
|
444
gdb/symm-xdep.c
444
gdb/symm-xdep.c
@ -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 *)®isters[REGISTER_BYTE(0)];
|
||||
regs.pr_ebx = *(int *)®isters[REGISTER_BYTE(5)];
|
||||
regs.pr_ecx = *(int *)®isters[REGISTER_BYTE(2)];
|
||||
regs.pr_edx = *(int *)®isters[REGISTER_BYTE(1)];
|
||||
regs.pr_esi = *(int *)®isters[REGISTER_BYTE(6)];
|
||||
regs.pr_edi = *(int *)®isters[REGISTER_BYTE(7)];
|
||||
regs.pr_esp = *(int *)®isters[REGISTER_BYTE(14)];
|
||||
regs.pr_ebp = *(int *)®isters[REGISTER_BYTE(15)];
|
||||
regs.pr_eip = *(int *)®isters[REGISTER_BYTE(16)];
|
||||
regs.pr_flags = *(int *)®isters[REGISTER_BYTE(17)];
|
||||
for (i = 0; i < 31; i++) {
|
||||
regs.pr_fpa.fpa_regs[i] =
|
||||
*(int *)®isters[REGISTER_BYTE(FP1_REGNUM+i)];
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_tmp = *(int *)®isters[REGISTER_BYTE(regno)];
|
||||
ptrace(XPT_RREGS, inferior_pid, (PTRACE_ARG3_TYPE) ®s, 0);
|
||||
switch (regno)
|
||||
{
|
||||
case 0:
|
||||
regs.pr_eax = *(int *)®isters[REGISTER_BYTE(0)];
|
||||
break;
|
||||
case 5:
|
||||
regs.pr_ebx = *(int *)®isters[REGISTER_BYTE(5)];
|
||||
break;
|
||||
case 2:
|
||||
regs.pr_ecx = *(int *)®isters[REGISTER_BYTE(2)];
|
||||
break;
|
||||
case 1:
|
||||
regs.pr_edx = *(int *)®isters[REGISTER_BYTE(1)];
|
||||
break;
|
||||
case 6:
|
||||
regs.pr_esi = *(int *)®isters[REGISTER_BYTE(6)];
|
||||
break;
|
||||
case 7:
|
||||
regs.pr_edi = *(int *)®isters[REGISTER_BYTE(7)];
|
||||
break;
|
||||
case 15:
|
||||
regs.pr_ebp = *(int *)®isters[REGISTER_BYTE(15)];
|
||||
break;
|
||||
case 14:
|
||||
regs.pr_esp = *(int *)®isters[REGISTER_BYTE(14)];
|
||||
break;
|
||||
case 16:
|
||||
regs.pr_eip = *(int *)®isters[REGISTER_BYTE(16)];
|
||||
break;
|
||||
case 17:
|
||||
regs.pr_flags = *(int *)®isters[REGISTER_BYTE(17)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
ptrace(XPT_WREGS, inferior_pid, (PTRACE_ARG3_TYPE) ®s, 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) ®s, 0);
|
||||
*(int *)®isters[REGISTER_BYTE(0)] = regs.pr_eax;
|
||||
*(int *)®isters[REGISTER_BYTE(5)] = regs.pr_ebx;
|
||||
*(int *)®isters[REGISTER_BYTE(2)] = regs.pr_ecx;
|
||||
*(int *)®isters[REGISTER_BYTE(1)] = regs.pr_edx;
|
||||
*(int *)®isters[REGISTER_BYTE(6)] = regs.pr_esi;
|
||||
*(int *)®isters[REGISTER_BYTE(7)] = regs.pr_edi;
|
||||
*(int *)®isters[REGISTER_BYTE(15)] = regs.pr_ebp;
|
||||
*(int *)®isters[REGISTER_BYTE(14)] = regs.pr_esp;
|
||||
*(int *)®isters[REGISTER_BYTE(16)] = regs.pr_eip;
|
||||
*(int *)®isters[REGISTER_BYTE(17)] = regs.pr_flags;
|
||||
for (i = 0; i < FPA_NREGS; i++) {
|
||||
*(int *)®isters[REGISTER_BYTE(FP1_REGNUM+i)] = regs.pr_fpa.fpa_regs[i];
|
||||
}
|
||||
bcopy(regs.pr_fpu.fpu_stack[0], ®isters[REGISTER_BYTE(3)], 10);
|
||||
bcopy(regs.pr_fpu.fpu_stack[1], ®isters[REGISTER_BYTE(4)], 10);
|
||||
bcopy(regs.pr_fpu.fpu_stack[2], ®isters[REGISTER_BYTE(8)], 10);
|
||||
bcopy(regs.pr_fpu.fpu_stack[3], ®isters[REGISTER_BYTE(9)], 10);
|
||||
bcopy(regs.pr_fpu.fpu_stack[4], ®isters[REGISTER_BYTE(10)], 10);
|
||||
bcopy(regs.pr_fpu.fpu_stack[5], ®isters[REGISTER_BYTE(11)], 10);
|
||||
bcopy(regs.pr_fpu.fpu_stack[6], ®isters[REGISTER_BYTE(12)], 10);
|
||||
bcopy(regs.pr_fpu.fpu_stack[7], ®isters[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) ®set, 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user