🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gdb.bug
Article #9956

[will@nirvana.westford.ccur.com: GDB patches for Concurrent/Masscomp machines.]

#9956
From: rms
Date: Wed, 08 Aug 1990 17:47
1427 lines
45829 bytes
Return-Path: <will@nirvana.westford.ccur.com>
To: rms@ai.mit.edu
Cc: will@nirvana.westford.ccur.com
Subject: GDB patches for Concurrent/Masscomp machines.
Date: Tue, 07 Aug 90 13:48:10 EDT
From: will@nirvana.westford.ccur.com

In-Real-Life: Will Athanasiou (x2647)
--------

These patches will allow GDB to work on our machines up to and including our
current OS RTU v5.0.

Should I post these to the gnu.* news groups as well?  What is the most 
appropriate group for GDB stuff?

----- cut here -----

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	masscomp.chang
#	gdb.diffs
#	m-mass.h
#	mass-dep.c
# This archive created Tue Aug  7 13:42:52 EDT 1990
#
PATH=/bin:$PATH; export PATH
#
echo 'bundle: extracting' masscomp.chang \(     144  Characters\)
if test -f masscomp.chang
then
   echo shar: will not overwrite existing file masscomp.chang
else
   sed -n -e 's@^X	@@p' << \BUNDLE_EOF > masscomp.chang
X	Look at:
X	   Masscomp specific files
X	      m-mass.h
X	      mass-dep.c
X	   Changes were made to 
X	      infrun.c   -- marked by #ifdef SOS .. #endif
BUNDLE_EOF
if test      144  -ne "`wc -c <masscomp.chang`"
then
   echo shar: error transmitting masscomp.chang \(should have      144  characters\)
fi
fi
#
echo 'bundle: extracting' gdb.diffs \(    2114  Characters\)
if test -f gdb.diffs
then
   echo shar: will not overwrite existing file gdb.diffs
else
   sed -n -e 's@^X	@@p' << \BUNDLE_EOF > gdb.diffs
X	diff -c5 dist-gdb/config.gdb rel-gdb/config.gdb
X	*** dist-gdb/config.gdb	Tue Jan 30 15:35:46 1990
X	--- rel-gdb/config.gdb	Fri Mar 16 11:46:53 1990
X	***************
X	*** 46,55
X	  		$machine=newsos3
X	  		$os=""
X	  		;;
X	  	esac
X	  	;;
X	  sun2)
X	  	case $os in
X	  	os4|sunos4)
X	  		machine=sun2os4
X	  		os=""
X	
X	--- 46,66 -----
X	  		$machine=newsos3
X	  		$os=""
X	  		;;
X	  	esac
X	  	;;
X	+ mass)
X	+ 	case $os in
X	+ 	sos|SOS|5.0)
X	+ 		machine=massSOS
X	+ 		os=""
X	+ 	;;
X	+ 	*)
X	+ 		machine=mass4.1
X	+ 		os="" ;;
X	+         esac
X	+ 	;;
X	  sun2)
X	  	case $os in
X	  	os4|sunos4)
X	  		machine=sun2os4
X	  		os=""
X	***************
X	*** 245,254
X	  sun2)
X	  	depfile=sun3-dep.c
X	  	pinsnfile=m68k-pinsn.c
X	  	opcodefile=m68k-opcode.h
X	  	;;
X	  sun2os2|sun2-os2)
X	  	depfile=default-dep.c
X	  	paramfile=m-sun2.h
X	  	pinsnfile=m68k-pinsn.c
X	  	opcodefile=m68k-opcode.h
X	
X	--- 256,280 -----
X	  sun2)
X	  	depfile=sun3-dep.c
X	  	pinsnfile=m68k-pinsn.c
X	  	opcodefile=m68k-opcode.h
X	  	;;
X	+ massSOS)
X	+ 	makedefine="-DM_CFLAGS='-DMASSCOMP=700 -DSOS'"
X	+ 	depfile=mass-dep.c
X	+ 	paramfile=m-mass.h
X	+         pinsnfile=m68k-pinsn.c
X	+ 	opcodefile=m68k-opcode.h
X	+         ;;
X	+ mass4.1)
X	+ 	makedefine="-DM_CFLAGS='-DMASSCOMP=700'"
X	+ 	depfile=mass-dep.c
X	+ 	paramfile=m-mass.h
X	+         pinsnfile=m68k-pinsn.c
X	+ 	opcodefile=m68k-opcode.h
X	+ 	;;
X	+ 
X	  sun2os2|sun2-os2)
X	  	depfile=default-dep.c
X	  	paramfile=m-sun2.h
X	  	pinsnfile=m68k-pinsn.c
X	  	opcodefile=m68k-opcode.h
X	diff -c5 dist-gdb/infrun.c rel-gdb/infrun.c
X	*** dist-gdb/infrun.c	Tue Jan 23 18:10:35 1990
X	--- rel-gdb/infrun.c	Fri Mar 16 13:29:49 1990
X	***************
X	*** 543,552
X	  #ifdef NO_SINGLE_STEP
X	  	  one_stepped = 0;
X	  #endif
X	  	  break;
X	  	}
X	        
X	  #ifdef NO_SINGLE_STEP
X	        if (one_stepped)
X	  	single_step (0);	/* This actually cleans up the ss */
X	  #endif /* NO_SINGLE_STEP */
X	
X	--- 543,556 -----
X	  #ifdef NO_SINGLE_STEP
X	  	  one_stepped = 0;
X	  #endif
X	  	  break;
X	  	}
X	+ 
X	+ #ifdef SOS
X	+       get_initial_thread( pid );
X	+ #endif
X	        
X	  #ifdef NO_SINGLE_STEP
X	        if (one_stepped)
X	  	single_step (0);	/* This actually cleans up the ss */
X	  #endif /* NO_SINGLE_STEP */
X	Only in rel-gdb: m-mass.h
X	Only in rel-gdb: mass-dep.c
BUNDLE_EOF
if test     2114  -ne "`wc -c <gdb.diffs`"
then
   echo shar: error transmitting gdb.diffs \(should have     2114  characters\)
fi
fi
#
echo 'bundle: extracting' m-mass.h \(   18408  Characters\)
if test -f m-mass.h
then
   echo shar: will not overwrite existing file m-mass.h
else
   sed -n -e 's@^X	@@p' << \BUNDLE_EOF > m-mass.h
X	/* Parameters for execution on a MASSCOMP machine, for GDB, the GNU debugger.
X	   Copyright (C) 1989 Free Software Foundation, Inc.
X	
X	This file is part of GDB.
X	
X	GDB is free software; you can redistribute it and/or modify
X	it under the terms of the GNU General Public License as published by
X	the Free Software Foundation; either version 1, or (at your option)
X	any later version.
X	
X	GDB is distributed in the hope that it will be useful,
X	but WITHOUT ANY WARRANTY; without even the implied warranty of
X	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X	GNU General Public License for more details.
X	
X	You should have received a copy of the GNU General Public License
X	along with GDB; see the file COPYING.  If not, write to
X	the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
X	
X	/* Define the bit, byte, and word ordering of the machine.  */
X	#define BITS_BIG_ENDIAN
X	#define BYTES_BIG_ENDIAN
X	#define WORDS_BIG_ENDIAN
X	
X	#define HAVE_WAIT_STRUCT
X	
X	/* Watch out for NaNs */
X	
X	#define IEEE_FLOAT
X	
X	/* Tell user about floating point units. */
X	
X	#define FLOAT_INFO \
X	{ \
X	    printf ("68881 coprocessor available.\n"); \
X	}
X	
X	/* Get rid of any system-imposed stack limit if possible.  */
X	
X	#define SET_STACK_LIMIT_HUGE
X	
X	/* Define this if the C compiler puts an underscore at the front
X	   of external names before giving them to the linker.  */
X	
X	#define NAMES_HAVE_UNDERSCORE
X	
X	/* Debugger information will be in DBX format.  */
X	
X	#define READ_DBX_FORMAT
X	
X	/* Doesn't have siginterupt.  */
X	
X	#define NO_SIGINTERRUPT
X	
X	/* Offset from address of function to start of its code.
X	   Zero on most machines.  */
X	
X	#define FUNCTION_START_OFFSET 0
X	
X	/* Advance PC across any function entry prologue instructions
X	   to reach some "real" code.  */
X	
X	#define SKIP_PROLOGUE(pc) \
X	{ register int op = read_memory_integer (pc, 2); \
X	  if (op == 0047126) \
X	    pc += 4;   /* Skip link #word */ \
X	  else if (op == 0044016) \
X	    pc += 6;   /* Skip link #long */ \
X	  else if (op == 0060000) \
X	    pc += 4;   /* Skip bra #word */ \
X	  else if (op == 00600377) \
X	    pc += 6;   /* skip bra #long */ \
X	  else if ((op & 0177400) == 0060000) \
X	    pc += 2;   /* skip bra #char */ \
X	}
X	
X	/* Immediately after a function call, return the saved pc.
X	   Can't go through the frames for this because on some machines
X	   the new frame is not set up until the new function executes
X	   some instructions.  */
X	
X	#define SAVED_PC_AFTER_CALL(frame) \
X	read_memory_integer (read_register (SP_REGNUM), 4)
X	
X	/* Address of end of stack space.  */
X	
X	#define usrstk_300 0x08000000
X	#define usrstk_700 0xC0000000
X	#if MASSCOMP == 300
X	#define STACK_END_ADDR usrstk_300
X	#else
X	#define STACK_END_ADDR usrstk_700
X	#endif
X	
X	/* Stack grows downward.  */
X	
X	#define INNER_THAN <
X	
X	/* Data segment starts at etext rounded up to DATAROUND in {N,Z}MAGIC files */
X	
X	#define DATAROUND	0x1000
X	#define N_DATADDR(hdr)	(hdr.a_magic != OMAGIC ? \
X		(hdr.a_text + DATAROUND) & ~(DATAROUND-1) : hdr.a_text)
X	
X	/* Sequence of bytes for breakpoint instruction.  */
X	
X	#define BREAKPOINT {0x4e, 0x41}
X	
X	/* Amount PC must be decremented by after a breakpoint.
X	   This is often the number of bytes in BREAKPOINT
X	   but not always.  */
X	
X	#define DECR_PC_AFTER_BREAK 2
X	
X	/* Nonzero if instruction at PC is a return instruction.  */
X	/* Allow any of the return instructions, including a trapv and a return
X	   from interupt.  */
X	
X	#define ABOUT_TO_RETURN(pc) ((read_memory_integer (pc, 2) & ~0x3) == 0x4e74)
X	
X	/* Return 1 if P points to an invalid floating point value.  */
X	
X	#define INVALID_FLOAT(p, len) 0   /* Just a first guess; not checked */
X	
X	/* Largest integer type */
X	#define LONGEST long
X	
X	/* Name of the builtin type for the LONGEST type above. */
X	#define BUILTIN_TYPE_LONGEST builtin_type_long
X	
X	/* Say how long (ordinary) registers are.  */
X	
X	#define REGISTER_TYPE long
X	
X	/* Number of machine registers */
X	
X	#define NUM_REGS 29
X	
X	/* Initializer for an array of names of registers.
X	   There should be NUM_REGS strings in this initializer.  */
X	
X	#define REGISTER_NAMES \
X	 {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
X	  "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
X	  "ps", "pc", \
X	  "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
X	  "fpcontrol", "fpstatus", "fpiaddr" }
X	
X	/* Register numbers of various important registers.
X	   Note that some of these values are "real" register numbers,
X	   and correspond to the general registers of the machine,
X	   and some are "phony" register numbers which are too large
X	   to be actual register numbers as far as the user is concerned
X	   but do serve to get the desired values when passed to read_register.  */
X	
X	#define FP_REGNUM 14		/* Contains address of executing stack frame */
X	#define SP_REGNUM 15		/* Contains address of top of stack */
X	#define PS_REGNUM 16		/* Contains processor status */
X	#define PC_REGNUM 17		/* Contains program counter */
X	#define FP0_REGNUM 18		/* Floating point register 0 */
X	#define FPC_REGNUM 26		/* 68881 control register */
X	
X	#ifdef SOS
X	#define REGISTER_ADDR(blockend, regno) ((int) &current_upanel + reg_off[regno])
X	#define FP_REGISTER_ADDR(blockend,regno) ((int) &current_upanel + reg_off[regno])
X	#else
X	#define REGISTER_ADDR(blockend, regno) (blockend + regno * 4 + ((regno <= SP_REGNUM) ? 0 : 4))
X	
X	#define FP_REGISTER_ADDR(blockend, regno) (blockend + ((regno < FPC_REGNUM) ? \
X		(regno - FP0_REGNUM) * 12 : 8 * 12 + (regno - FPC_REGNUM) * 4))
X	#endif
X	
X	/* Total amount of space needed to store our copies of the machine's
X	   register state, the array `registers'.  */
X	
X	#define REGISTER_BYTES (16*4+8*12+2*4+3*4)
X	
X	/* Index within `registers' of the first byte of the space for
X	   register N.  */
X	
X	#define REGISTER_BYTE(N) \
X	 ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
X	  : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
X	  : (N) * 4)
X	
X	/* Number of bytes of storage in the actual machine representation
X	   for register N.  On the 68000, all regs are 4 bytes
X	   except the floating point regs which are 12 bytes.  */
X	
X	#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
X	
X	/* Number of bytes of storage in the program's representation
X	   for register N.  On the 68000, all regs are 4 bytes
X	   except the floating point regs which are 8-byte doubles.  */
X	
X	#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
X	
X	/* Largest value REGISTER_RAW_SIZE can have.  */
X	
X	#define MAX_REGISTER_RAW_SIZE 12
X	
X	/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
X	
X	#define MAX_REGISTER_VIRTUAL_SIZE 8
X	
X	/* Nonzero if register N requires conversion
X	   from raw format to virtual format.  */
X	
X	#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
X	
X	/* Convert data from raw format for register REGNUM
X	   to virtual format for register REGNUM.  */
X	
X	#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
X	{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
X	    convert_from_68881 ((FROM), (TO)); \
X	  else \
X	    bcopy ((FROM), (TO), 4); }
X	
X	/* Convert data from virtual format for register REGNUM
X	   to raw format for register REGNUM.  */
X	
X	#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
X	{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
X	    convert_to_68881 ((FROM), (TO)); \
X	  else \
X	    bcopy ((FROM), (TO), 4); }
X	
X	/* Return the GDB type object for the "standard" data type
X	   of data in register N.  */
X	
X	#define REGISTER_VIRTUAL_TYPE(N) \
X	 (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
X	
X	/* Store the address of the place in which to copy the structure the
X	   subroutine will return.  This is called from call_function. */
X	
X	#define STORE_STRUCT_RETURN(ADDR, SP) \
X	  { write_register (9, (ADDR)); }
X	
X	/* Extract from an array REGBUF containing the (raw) register state
X	   a function return value of type TYPE, and copy that, in virtual format,
X	   into VALBUF.  */
X	
X	#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
X	  bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
X	
X	/* Write into appropriate registers a function return value
X	   of type TYPE, given in virtual format.  */
X	
X	#define STORE_RETURN_VALUE(TYPE,VALBUF) \
X	  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
X	
X	/* Extract from an array REGBUF containing the (raw) register state
X	   the address in which a function should return its structure value,
X	   as a CORE_ADDR (or an expression that can be used as one).  */
X	
X	#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
X	
X	/* Compensate for lack of `vprintf' function.  */ 
X	
X	#define vprintf(format, ap) _doprnt (format, ap, stdout) 
X	
X	/* Do implement the attach and detach commands.  */
X	
X	#define ATTACH_DETACH
X	
X	/* It is safe to look for symsegs, because ld
X	   does not screw up with random garbage at end of file.  */
X	
X	#define READ_GDB_SYMSEGS
X	
X	#define IGNORE_SYMBOL(type)  (type == N_RMASK1 || type == N_RMASK2) /* gdb gets these register masks from the text */
X	
X	/* Describe the pointer in each stack frame to the previous stack frame
X	   (its caller).  */
X	
X	/* FRAME_CHAIN takes a frame's nominal address
X	   and produces the frame's chain-pointer.
X	
X	   FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
X	   and produces the nominal address of the caller frame.
X	
X	   However, if FRAME_CHAIN_VALID returns zero,
X	   it means the given frame is the outermost one and has no caller.
X	   In that case, FRAME_CHAIN_COMBINE is not used.  */
X	
X	/* In the case of MASSCOMP, the frame's nominal address
X	   is the address of a 4-byte word containing the calling frame's address.  */
X	
X	#define FRAME_CHAIN(thisframe)  \
X	  (outside_startup_file ((thisframe)->pc) ? \
X	   read_memory_integer ((thisframe)->frame, 4) :\
X	   0)
X	
X	#define FRAME_CHAIN_VALID(chain, thisframe) \
X	  (chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
X	
X	#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
X	
X	/* Define other aspects of the stack frame.  */
X	
X	/* A macro that tells us whether the function invocation represented
X	   by FI does not have a frame on the stack associated with it.  If it
X	   does not, FRAMELESS is set to 1, else 0.  */
X	#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
X	  FRAMELESS_LOOK_FOR_PROLOGUE(FI, FRAMELESS)
X	
X	#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
X	
X	#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
X	
X	#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
X	
X	/* Set VAL to the number of args passed to frame described by FI.
X	   Can set VAL to -1, meaning no way to tell.  */
X	
X	#define FRAME_NUM_ARGS(val, fi) \
X	{ register CORE_ADDR pc = FRAME_SAVED_PC (fi); \
X	  register int insn = 0177777 & read_memory_integer (pc, 2); \
X	  val = 0; \
X	  if (insn == 0047757 || insn == 0157374)  /* lea W(sp),sp or addaw #W,sp */ \
X	    val = read_memory_integer (pc + 2, 2); \
X	  else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
X		   || (insn & 0170777) == 0050117)  /* addqw */ \
X	    { val = (insn >> 9) & 7; if (val == 0) val = 8; } \
X	  else if (insn == 0157774) /* addal #WW, sp */ \
X	    val = read_memory_integer (pc + 2, 4); \
X	  val >>= 2; }
X	
X	/* Return number of bytes at start of arglist that are not really args.  */
X	
X	#define FRAME_ARGS_SKIP 8
X	
X	/* Put here the code to store, into a struct frame_saved_regs,
X	   the addresses of the saved registers of frame described by FRAME_INFO.
X	   This includes special registers such as pc and fp saved in special
X	   ways in the stack frame.  sp is even more special:
X	   the address we return for it IS the sp for the next frame.  */
X	
X	#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
X	{ register int regnum; \
X	  register int regmask; \
X	  register CORE_ADDR next_addr; \
X	  register CORE_ADDR pc; \
X	  int nextinsn; \
X	  bzero (&frame_saved_regs, sizeof frame_saved_regs); \
X	  if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
X	      && (frame_info)->pc <= (frame_info)->frame) \
X	    { next_addr = (frame_info)->frame; \
X	      pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; } \
X	  else \
X	    { pc = get_pc_function_start ((frame_info)->pc); \
X	      /* Verify we have a link a6 instruction next, \
X		 or a branch followed by a link a6 instruction; \
X		 if not we lose.  If we win, find the address above the saved \
X		 regs using the amount of storage from the link instruction.  */ \
X	retry: \
X	      nextinsn = read_memory_integer (pc, 2); \
X	      if (nextinsn == 044016) \
X		next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; \
X	      else if (nextinsn == 047126) \
X		next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; \
X	      else if ((nextinsn & 0177400) == 060000)	/* bra insn */ \
X		{ int offset; \
X		  offset = nextinsn & 0377; \
X	          pc += 2;				/* advance past bra */ \
X		  if (offset == 0)			/* bra #word */ \
X		    offset = read_memory_integer (pc, 2), pc += 2; \
X		  else if (offset == 0377)		/* bra #long */ \
X		    offset = read_memory_integer (pc, 4), pc += 4; \
X		  pc += offset; \
X		  goto retry; \
X	      } else goto lose; \
X	      /* If have an addal #-n, sp next, adjust next_addr.  */ \
X	      if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
X		next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
X	    } \
X	  /* Now we can have a series of save type instructions.  Most common are
X	     a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
X	  for (;;) \
X	    { \
X	      nextinsn = read_memory_integer (pc, 2) & 0xffff; \
X	      regmask = read_memory_integer (pc + 2, 2); \
X	      /* fmovem.  */ \
X	      if (nextinsn == 0xf227 \
X		  && (regmask & 0xff00) == 0xe000) \
X		{ pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
X		  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
X		    if (regmask & 1) \
X		      (frame_saved_regs).regs[regnum] = (next_addr -= 12); } \
X	      /* movem */ \
X	      else if (nextinsn == 0044327) \
X		{ pc += 4; /* Regmask's low bit is for register 0, the first written */ \
X		  for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
X		    if (regmask & 1) \
X		      (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
X	      else if (nextinsn == 0044347) \
X		{ pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
X		  for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
X		    if (regmask & 1) \
X		      (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
X	      else if ((nextinsn & 0xfff0) == 0x2f00) \
X		{ regnum = nextinsn & 0xf; pc += 2; \
X		  (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
X	      /* fmovemx to index of sp may follow.  */ \
X	      else if (nextinsn == 0xf236 \
X		  && (regmask & 0xff00) == 0xf000) \
X		{ pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
X		  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
X		    if (regmask & 1) \
X		      (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; } \
X	      /* clrw -(sp); movw ccr,-(sp) may follow.  */ \
X	      else if (nextinsn == 041147 \
X		       && regmask == 041347) \
X		{ pc += 4; \
X		  (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); } \
X	      else break; \
X	    } \
X	  lose: ; \
X	  (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8; \
X	  (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame; \
X	  (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4; \
X	}
X	
X	/* Things needed for making the inferior call functions.  */
X	
X	/* Push an empty stack frame, to record the current PC, etc.  */
X	
X	#define PUSH_DUMMY_FRAME \
X	{ register CORE_ADDR sp = read_register (SP_REGNUM); \
X	  register int regnum; \
X	  char raw_buffer[12]; \
X	  sp = push_word (sp, read_register (PC_REGNUM)); \
X	  sp = push_word (sp, read_register (FP_REGNUM)); \
X	  write_register (FP_REGNUM, sp); \
X	  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
X	    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
X	      sp = push_bytes (sp, raw_buffer, 12); } \
X	  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
X	    sp = push_word (sp, read_register (regnum)); \
X	  sp = push_word (sp, read_register (PS_REGNUM)); \
X	  write_register (SP_REGNUM, sp);  }
X	
X	/* Discard from the stack the innermost frame, 
X	   restoring all saved registers.  */
X	
X	#define POP_FRAME \
X	{ register FRAME frame = get_current_frame (); \
X	  register CORE_ADDR fp; \
X	  register int regnum; \
X	  struct frame_saved_regs fsr; \
X	  struct frame_info *fi; \
X	  char raw_buffer[12]; \
X	  fi = get_frame_info (frame); \
X	  fp = fi->frame; \
X	  get_frame_saved_regs (fi, &fsr); \
X	  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
X	    if (fsr.regs[regnum]) \
X	      { read_memory (fsr.regs[regnum], raw_buffer, 12); \
X	        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); } \
X	  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
X	    if (fsr.regs[regnum]) \
X	      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
X	  if (fsr.regs[PS_REGNUM]) \
X	    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
X	  write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
X	  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
X	  write_register (SP_REGNUM, fp + 8); \
X	  flush_cached_frames (); \
X	  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
X						read_pc ())); }
X	
X	/* This sequence of words is the instructions
X	     fmovem 0xff,-(sp)
X	     moveml 0xfffc,-(sp)
X	     clrw -(sp)
X	     movew ccr,-(sp)
X	     /..* The arguments are pushed at this point by GDB;
X		no code is needed in the dummy for this.
X		The CALL_DUMMY_START_OFFSET gives the position of 
X		the following jsr instruction.  *../
X	     jsr @#32323232
X	     addl #69696969,sp
X	     trap #1
X	     nop
X	Note this is 28 bytes.
X	We actually start executing at the jsr, since the pushing of the
X	registers is done by PUSH_DUMMY_FRAME.  If this were real code,
X	the arguments for the function called by the jsr would be pushed
X	between the moveml and the jsr, and we could allow it to execute through.
X	But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
X	and we cannot allow the moveml to push the registers again lest they be
X	taken for the arguments.  */
X	
X	#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e414e71}
X	
X	#define CALL_DUMMY_LENGTH 28
X	
X	#define CALL_DUMMY_START_OFFSET 12
X	
X	/* Insert the specified number of args and function address
X	   into a call sequence of the above form stored at DUMMYNAME.  */
X	
X	#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type) \
X	{ *(int *)((char *) dummyname + 20) = nargs * 4; \
X	  *(int *)((char *) dummyname + 14) = fun; }
X	
X	/*
X	** Missing interface for KDB
X	*/
BUNDLE_EOF
if test    18408  -ne "`wc -c <m-mass.h`"
then
   echo shar: error transmitting m-mass.h \(should have    18408  characters\)
fi
fi
#
echo 'bundle: extracting' mass-dep.c \(   18183  Characters\)
if test -f mass-dep.c
then
   echo shar: will not overwrite existing file mass-dep.c
else
   sed -n -e 's@^X	@@p' << \BUNDLE_EOF > mass-dep.c
X	/* Low level interface to ptrace, for GDB when running under Unix.
X	   Copyright (C) 1989 Free Software Foundation, Inc.
X	
X	This file is part of GDB.
X	
X	GDB is free software; you can redistribute it and/or modify
X	it under the terms of the GNU General Public License as published by
X	the Free Software Foundation; either version 1, or (at your option)
X	any later version.
X	
X	GDB is distributed in the hope that it will be useful,
X	but WITHOUT ANY WARRANTY; without even the implied warranty of
X	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
X	GNU General Public License for more details.
X	
X	You should have received a copy of the GNU General Public License
X	along with GDB; see the file COPYING.  If not, write to
X	the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
X	
X	#include "defs.h"
X	#include "param.h"
X	#include "frame.h"
X	#include "inferior.h"
X	#include <sys/types.h>
X	
X	#include <stdio.h>
X	#include <sys/param.h>
X	#include <sys/dir.h>
X	#include <signal.h>
X	#include <sys/ioctl.h>
X	#include <fcntl.h>
X	#ifdef SOS
X	#  include <sys/reg.h>
X	#endif
X	#include <ptrace.h>
X	
X	#include <a.out.h>
X	#ifndef N_SET_MAGIC
X	#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
X	#endif
X	
X	#include <sys/user.h>
X	#include <sys/stat.h>
X	
X	extern int errno;
X	extern int attach_flag;
X	
X	#ifdef SOS
X	/*
X	** Current_upanel added for SOS compatibility.  main_tid is the 
X	** thread id of the parent (main) thread.
X	*/
X	upanel_t current_upanel;
X	int main_tid;
X	
X	/* 
X	** Register offsets from upanel start.
X	** (hard coded because of bug in masscomp c)
X	*/
X	int reg_off[] = {
X	        /* d0-d7 */
X		24, /*  0 */	 28, /*  1 */	 32, /*  2 */	 36, /*  3 */	 40, /*  4 */
X		44, /*  5 */	 48, /*  6 */	 52, /*  7 */
X	
X	        /* a0-a7,ps,pc */
X		56, /*  8 */	 60, /*  9 */    64, /* 10 */	 68, /* 11 */	 72, /* 12 */	 
X		76, /* 13 */	 80, /* 14 */  	 84, /* 15 */	 88, /* 16 */	 90, /* 17 */
X	
X	        /* fp0-fp7,fpcontrol,fpstatus,fpiaddr */
X		104, /* 18 */	116, /* 19 */	128, /* 20 */	140, /* 21 */
X		152, /* 22 */	164, /* 23 */	176, /* 24 */	188, /* 25 */	200, /* 26 */
X		204, /* 27 */	208, /* 28 */	
X	
X	        /* lightning registers (mabye someday?) */
X		212, /* 37 */	220, /* 38 */	228, /* 39 */
X		236, /* 40 */	244, /* 41 */	252, /* 42 */	260, /* 43 */	268, /* 44 */
X		276, /* 45 */	284, /* 46 */	292, /* 47 */	300, /* 48 */	308, /* 49 */
X		316, /* 50 */	324, /* 51 */	332, /* 52 */	340, /* 53 */	348, /* 54 */
X		356, /* 55 */	364, /* 56 */	372, /* 57 */	380, /* 58 */	388, /* 59 */
X		396, /* 60 */	404, /* 61 */	412, /* 62 */	420, /* 63 */	428, /* 64 */
X		436, /* 65 */	444, /* 66 */	452, /* 67 */	460, /* 68 */	468, /* 69 */
X		470  /* 70 */	
X	};
X	
X	#endif
X	
X	
X	#ifdef SOS
X	/*
X	** This function returns the current thread id.  This could be expanded
X	** to determine the current thread from the currently active task.
X	*/
X	int 
X	current_thread()
X	{
X	   return main_tid;
X	}
X	
X	int
X	get_initial_thread( pid )
X	int pid;
X	{
X	   extern int errno;
X	   tidlist_t tmp;
X	   /*
X	   ** get thread id of main process.
X	   */
X	   errno = 0;
X	   main_tid = 0;
X	
X	   main_tid = ptrace( TIDLIST, pid, &tmp, sizeof( tidlist_t ) );
X	   if ( errno != 0 && main_tid == -1 ) {
X	      return -1;
X	   }
X	   else {
X	      main_tid = tmp.tid;
X	      return 0;
X	   }
X	}
X	#endif /* SOS */
X	
X	/* This function simply calls ptrace with the given arguments.  
X	   It exists so that all calls to ptrace are isolated in this 
X	   machine-dependent file. */
X	int
X	call_ptrace (request, pid, arg3, arg4)
X	     int request, pid, arg3, arg4;
X	{
X	  return ptrace (request, pid, arg3, arg4);
X	}
X	
X	kill_inferior ()
X	{
X	  if (remote_debugging)
X	    return;
X	  if (inferior_pid == 0)
X	    return;
X	  ptrace (PKILL, inferior_pid, 0, 0);
X	  wait (0);
X	  inferior_died ();
X	}
X	
X	/* This is used when GDB is exiting.  It gives less chance of error.*/
X	
X	kill_inferior_fast ()
X	{
X	  if (remote_debugging)
X	    return;
X	  if (inferior_pid == 0)
X	    return;
X	  ptrace (PKILL, inferior_pid, 0, 0);
X	  wait (0);
X	}
X	
X	/* Resume execution of the inferior process.
X	   If STEP is nonzero, single-step it.
X	   If SIGNAL is nonzero, give it that signal.  */
X	
X	void
X	resume (step, signal)
X	     int step;
X	     int signal;
X	{
X	  errno = 0;
X	  if (remote_debugging)
X	    remote_resume (step, signal);
X	  else
X	    {
X	      ptrace (step ? SSTEP : CONT, inferior_pid, 1, signal);
X	      if (errno)
X		perror_with_name ("ptrace");
X	    }
X	}
X	
X	#ifdef ATTACH_DETACH
X	
X	/* Start debugging the process whose number is PID.  */
X	
X	attach (pid)
X	     int pid;
X	{
X	  errno = 0;
X	  ptrace (ATTACH, pid, 0, 0);
X	  if (errno)
X	    perror_with_name ("ptrace");
X	  attach_flag = 1;
X	  return pid;
X	}
X	
X	/* Stop debugging the process whose number is PID
X	   and continue it with signal number SIGNAL.
X	   SIGNAL = 0 means just continue it.  */
X	
X	void
X	detach (signal)
X	     int signal;
X	{
X	  errno = 0;
X	  ptrace (DETACH, inferior_pid, 1, signal);
X	  if (errno)
X	    perror_with_name ("ptrace");
X	  attach_flag = 0;
X	}
X	#endif /* ATTACH_DETACH */
X	
X	void
X	fetch_inferior_registers ()
X	{
X	  extern int errno;
X	  register int regno;
X	  register unsigned int regaddr;
X	  char buf[MAX_REGISTER_RAW_SIZE];
X	  register int i;
X	  extern char registers[];
X	
X	#ifdef SOS
X	  extern upanel_t current_upanel;
X	  int tmp;
X	#else
X	  struct user u;
X	  unsigned int int_offset = (char *) &u.u_ar0 - (char *) &u;
X	  unsigned int fp_offset = (char *) &u.u_fp_881reg0 - (char *) &u;
X	#endif
X	
X	  if (remote_debugging)
X	    remote_fetch_registers (registers);
X	  else
X	  {
X	#ifdef SOS
X	     errno = 0;
X	     tmp = ptrace( UPREAD, inferior_pid, &current_upanel, sizeof( upanel_t ), current_thread() );
X	     if (errno != 0 && tmp == -1) {
X		sprintf (buf, "reading current upanel of thread %d", current_thread());
X		perror_with_name (buf);
X	     }
X	#else      
X	     int_offset = ptrace (UREAD, inferior_pid, int_offset, 0) & 0xfff;
X	     fp_offset  = ptrace (UREAD, inferior_pid, fp_offset - 2, 0) & 0xfff; /*fp_offset is a short */
X	#endif      
X	     for (regno = 0; regno < NUM_REGS; regno++) {
X	#ifdef SOS
X	        regaddr = (int) &current_upanel + reg_off[regno];
X	        supply_register( regno, regaddr );
X	#else
X		if (regno < FP0_REGNUM)
X		   regaddr = REGISTER_ADDR (int_offset, regno);
X		else
X		   regaddr = FP_REGISTER_ADDR (fp_offset, regno);
X	
X		for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) {
X	           errno = 0;
X		   *(int *) &buf[i] = ptrace (UREAD, inferior_pid, regaddr, 0);
X		   if (errno != 0)
X		   {
X		      sprintf (buf, "reading register number %d(%d)", regno, i);
X		      perror_with_name (buf);
X		   }
X		   regaddr += sizeof (int);
X		}
X		supply_register (regno, buf);
X	#endif /* SOS */
X	     }
X	  }
X	}
X	
X	/* Store our register values back into the inferior.
X	   If REGNO is -1, do this for all registers.
X	   Otherwise, REGNO specifies which register (so we can save time).  */
X	
X	store_inferior_registers (regno)
X	int regno;
X	{
X	  register unsigned int regaddr;
X	  char buf[80];
X	  extern char registers[];
X	  register int i;
X	
X	#ifndef SOS
X	  struct user u;
X	  unsigned int int_offset = (char *) &u.u_ar0 - (char *) &u;
X	  unsigned int fp_offset = (char *) &u.u_fp_881reg0 - (char *) &u;
X	#endif
X	
X	  if (remote_debugging)
X	    remote_store_registers (registers);
X	  else {
X	#ifndef SOS
X	     int_offset = ptrace (UREAD, inferior_pid, int_offset, 0) & 0xfff;
X	     fp_offset  = ptrace (UREAD, inferior_pid, fp_offset - 2, 0) & 0xfff; /*fp_offset is a short */
X	#endif /* SOS */
X	     if (regno >= 0) {
X	#ifdef SOS
X	        regaddr = reg_off[regno];
X	#else
X		if (regno < FP0_REGNUM)
X		   regaddr = REGISTER_ADDR (int_offset, regno);
X		else
X		   regaddr = FP_REGISTER_ADDR (fp_offset, regno);
X	#endif
X		for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) {
X		   errno = 0;
X	#ifdef SOS
X		   ptrace (UPWRITE, inferior_pid, regaddr, 
X			  *((int *) &registers[REGISTER_BYTE (regno) + i]), current_thread());
X	#else
X		   ptrace (UWRITE, inferior_pid, regaddr,
X			   *(int *) &registers[REGISTER_BYTE (regno) + i]);
X	#endif /* SOS */
X		   if (errno != 0)
X		   {
X		      sprintf (buf, "writing register number %d(%d)", regno, i);
X		      perror_with_name (buf);
X		   }
X		   regaddr += sizeof(int);
X		}
X	     }
X	     else 
X		for (regno = 0; regno < NUM_REGS; regno++) {
X	#ifdef SOS
X	           regaddr = reg_off[regno];
X	#else
X		   if (regno < FP0_REGNUM)
X		      regaddr = REGISTER_ADDR (int_offset, regno);
X		   else
X		      regaddr = FP_REGISTER_ADDR (fp_offset, regno);
X	#endif
X		   for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int)) {
X		      errno = 0;
X	#ifdef SOS
X		      ptrace (UPWRITE, inferior_pid, regaddr, 
X			      * ((int *) &registers[REGISTER_BYTE (regno) + i]), current_thread());
X	#else
X		      ptrace (UWRITE, inferior_pid, regaddr,
X			      *(int *) &registers[REGISTER_BYTE (regno) + i]);
X	#endif
X		      if (errno != 0) {
X			 sprintf (buf, "writing all regs, number %d(%d)", regno, i);
X			 perror_with_name (buf);
X		      }
X		      regaddr += sizeof(int);
X		   }
X		}
X	  }
X	}
X	
X	/* Virtual addresses of bounds of the two areas of memory in the core file.  */
X	
X	extern CORE_ADDR data_start;
X	extern CORE_ADDR data_end;
X	extern CORE_ADDR stack_start;
X	extern CORE_ADDR stack_end;
X	
X	/* Virtual addresses of bounds of two areas of memory in the exec file.
X	   Note that the data area in the exec file is used only when there is no core file.  */
X	
X	extern CORE_ADDR text_start;
X	extern CORE_ADDR text_end;
X	
X	extern CORE_ADDR exec_data_start;
X	extern CORE_ADDR exec_data_end;
X	
X	/* Address in executable file of start of text area data.  */
X	
X	extern int text_offset;
X	
X	/* Address in executable file of start of data area data.  */
X	
X	extern int exec_data_offset;
X	
X	/* Address in core file of start of data area data.  */
X	
X	extern int data_offset;
X	
X	/* Address in core file of start of stack area data.  */
X	
X	extern int stack_offset;
X	
X	/* Copy LEN bytes from inferior's memory starting at MEMADDR
X	   to debugger memory starting at MYADDR. 
X	   On failure (cannot read from inferior, usually because address is out
X	   of bounds) returns the value of errno. */
X	
X	int
X	read_inferior_memory (memaddr, myaddr, len)
X	     CORE_ADDR memaddr;
X	     char *myaddr;
X	     int len;
X	{
X	  register int i;
X	  /* Round starting address down to longword boundary.  */
X	  register CORE_ADDR addr = memaddr & - sizeof (int);
X	  /* Round ending address up; get number of longwords that makes.  */
X	  register int count
X	    = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
X	  /* Allocate buffer of that many longwords.  */
X	  register int *buffer = (int *) alloca (count * sizeof (int));
X	  extern int errno;
X	
X	  /* Read all the longwords */
X	  for (i = 0; i < count; i++, addr += sizeof (int))
X	    {
X	      errno = 0;
X	      if (remote_debugging)
X		buffer[i] = remote_fetch_word (addr);
X	      else
X		buffer[i] = ptrace (TREAD, inferior_pid, addr, 0);
X	      if (errno)
X		return errno;
X	    }
X	
X	  /* Copy appropriate bytes out of the buffer.  */
X	  bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
X	  return 0;
X	}
X	
X	/* Copy LEN bytes of data from debugger memory at MYADDR
X	   to inferior's memory at MEMADDR.
X	   On failure (cannot write the inferior)
X	   returns the value of errno.  */
X	
X	int
X	write_inferior_memory (memaddr, myaddr, len)
X	     CORE_ADDR memaddr;
X	     char *myaddr;
X	     int len;
X	{
X	  register int i;
X	  /* Round starting address down to longword boundary.  */
X	  register CORE_ADDR addr = memaddr & - sizeof (int);
X	  /* Round ending address up; get number of longwords that makes.  */
X	  register int count
X	    = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
X	  /* Allocate buffer of that many longwords.  */
X	  register int *buffer = (int *) alloca (count * sizeof (int));
X	  extern int errno;
X	
X	  /* Fill start and end extra bytes of buffer with existing memory data.  */
X	
X	  if (remote_debugging)
X	    buffer[0] = remote_fetch_word (addr);
X	  else
X	    buffer[0] = ptrace (TREAD, inferior_pid, addr, 0);
X	
X	  if (count > 1)
X	    {
X	      if (remote_debugging)
X		buffer[count - 1]
X		  = remote_fetch_word (addr + (count - 1) * sizeof (int));
X	      else
X		buffer[count - 1]
X		  = ptrace (TREAD, inferior_pid,
X			    addr + (count - 1) * sizeof (int), 0);
X	    }
X	
X	  /* Copy data to be written over corresponding part of buffer */
X	
X	  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
X	
X	  /* Write the entire buffer.  */
X	
X	  for (i = 0; i < count; i++, addr += sizeof (int))
X	    {
X	      errno = 0;
X	      if (remote_debugging)
X		remote_store_word (addr, buffer[i]);
X	      else
X		ptrace ((addr >= data_start) ? DWRITE : TWRITE,
X			inferior_pid, addr, buffer[i]);
X	      if (errno)
X		return errno;
X	    }
X	
X	  return 0;
X	}
X	
X	/* Work with core dump and executable files, for GDB. 
X	   This code would be in core.c if it weren't machine-dependent. */
X	
X	#ifndef N_TXTADDR
X	#define N_TXTADDR(hdr) 0
X	#endif /* no N_TXTADDR */
X	
X	#ifndef N_DATADDR
X	#define N_DATADDR(hdr) hdr.a_text
X	#endif /* no N_DATADDR */
X	
X	/* Make COFF and non-COFF names for things a little more compatible
X	   to reduce conditionals later.  */
X	
X	#ifdef COFF_FORMAT
X	#define a_magic magic
X	#endif
X	
X	#ifndef COFF_FORMAT
X	#ifndef AOUTHDR
X	#define AOUTHDR struct exec
X	#endif
X	#endif
X	
X	extern char *sys_siglist[];
X	
X	
X	/* Hook for `exec_file_command' command to call.  */
X	
X	extern void (*exec_file_display_hook) ();
X	   
X	/* File names of core file and executable file.  */
X	
X	extern char *corefile;
X	extern char *execfile;
X	
X	/* Descriptors on which core file and executable file are open.
X	   Note that the execchan is closed when an inferior is created
X	   and reopened if the inferior dies or is killed.  */
X	
X	extern int corechan;
X	extern int execchan;
X	
X	/* Last modification time of executable file.
X	   Also used in source.c to compare against mtime of a source file.  */
X	
X	extern int exec_mtime;
X	
X	#ifdef COFF_FORMAT
X	/* various coff data structures */
X	
X	extern FILHDR file_hdr;
X	extern SCNHDR text_hdr;
X	extern SCNHDR data_hdr;
X	
X	#endif /* not COFF_FORMAT */
X	
X	/* a.out header saved in core file.  */
X	  
X	extern AOUTHDR core_aouthdr;
X	
X	/* a.out header of exec file.  */
X	
X	extern AOUTHDR exec_aouthdr;
X	
X	extern void validate_files ();
X	
X	extern int maxstkaddr;		/* machine dependent values */
X	extern short cpu_type;		/* determines machine & cpu type  */
X	extern short fpu_exist;		/* determines presence of Lightning*/
X	extern short fpp_type;		/* determines floating point processor type 
X					/* (ie. Lightning); this is used in 
X					/* conjunction with fpu_exist */
X	
X	core_file_command (filename, from_tty)
X	     char *filename;
X	     int from_tty;
X	{
X	  int val;
X	  extern char registers[];
X	
X	  /* Discard all vestiges of any previous core file
X	     and mark data and stack spaces as empty.  */
X	
X	  if (corefile)
X	    free (corefile);
X	  corefile = 0;
X	
X	  if (corechan >= 0)
X	    close (corechan);
X	  corechan = -1;
X	
X	  data_start = 0;
X	  data_end = 0;
X	  stack_start = STACK_END_ADDR;
X	  stack_end = STACK_END_ADDR;
X	
X	  /* Now, if a new core file was specified, open it and digest it.  */
X	
X	  if (filename)
X	    {
X	      if (have_inferior_p ())
X		error ("To look at a core file, you must kill the inferior with \"kill\".");
X	      corechan = open (filename, O_RDONLY, 0);
X	      if (corechan < 0)
X		perror_with_name (filename);
X	      /* 4.2-style (and perhaps also sysV-style) core dump file.  */
X	      {
X		struct user u;
X	
X		unsigned int int_reg_offset;
X		unsigned int fp_reg_offset;
X	
X		val = myread (corechan, &u, sizeof u);
X		if (val < 0)
X		  perror_with_name ("Not a core file: reading upage");
X		if (val != sizeof u)
X		  error ("Not a core file: could only read %d bytes", val);
X		data_start = exec_data_start;
X	
X		data_end = data_start + NBPG * u.u_dsize;
X		stack_start = stack_end - NBPG * u.u_ssize;
X		data_offset = NBPG * UPAGES;
X		stack_offset = NBPG * (UPAGES + u.u_dsize);
X		int_reg_offset = (int) u.u_ar0 & 0xfff;
X		fp_reg_offset = u.u_fp_881reg0 & 0xfff;
X	
X		/* I don't know where to find this info.
X		   So, for now, mark it as not available.  */
X		N_SET_MAGIC (core_aouthdr, 0);
X	
X		/* Read the register values out of the core file and store
X		   them where `read_register' will find them.  */
X	
X		{
X		  register int regno;
X	
X		  for (regno = 0; regno < NUM_REGS; regno++)
X		    {
X		      char buf[MAX_REGISTER_RAW_SIZE];
X	
X		      if (regno < FP0_REGNUM)
X			val = lseek (corechan, REGISTER_ADDR (int_reg_offset, regno), 0);
X		      else
X			val = lseek (corechan, FP_REGISTER_ADDR (fp_reg_offset, regno), 0);
X		      if (val < 0
X			  || (val = myread (corechan, buf, sizeof buf)) < 0)
X			{
X			  char * buffer = (char *) alloca (strlen (reg_names[regno])
X							   + 30);
X			  strcpy (buffer, "Reading register ");
X			  strcat (buffer, reg_names[regno]);
X							   
X			  perror_with_name (buffer);
X			}
X	
X		      supply_register (regno, buf);
X		    }
X		}
X	      }
X	      if (filename[0] == '/')
X		corefile = savestring (filename, strlen (filename));
X	      else
X		{
X		  corefile = concat (current_directory, "/", filename);
X		}
X	
X	      set_current_frame ( create_new_frame (read_register (FP_REGNUM),
X						    read_pc ()));
X	      select_frame (get_current_frame (), 0);
X	      validate_files ();
X	    }
X	  else if (from_tty)
X	    printf ("No core file now.\n");
X	}
X	
X	exec_file_command (filename, from_tty)
X	     char *filename;
X	     int from_tty;
X	{
X	  int val;
X	
X	  /* Eliminate all traces of old exec file.
X	     Mark text segment as empty.  */
X	
X	  if (execfile)
X	    free (execfile);
X	  execfile = 0;
X	  data_start = 0;
X	  data_end -= exec_data_start;
X	  text_start = 0;
X	  text_end = 0;
X	  exec_data_start = 0;
X	  exec_data_end = 0;
X	  if (execchan >= 0)
X	    close (execchan);
X	  execchan = -1;
X	
X	  /* Now open and digest the file the user requested, if any.  */
X	
X	  if (filename)
X	    {
X	      execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
X				&execfile);
X	      if (execchan < 0)
X		perror_with_name (filename);
X	
X	      {
X		struct stat st_exec;
X	
X	#ifdef HEADER_SEEK_FD
X		HEADER_SEEK_FD (execchan);
X	#endif
X		
X		val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
X	
X		if (val < 0)
X		  perror_with_name (filename);
X	
X	        text_start = N_TXTADDR (exec_aouthdr);
X	        exec_data_start = N_DATADDR (exec_aouthdr);
X	
X		text_offset = N_TXTOFF (exec_aouthdr);
X		exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
X	
X		text_end = text_start + exec_aouthdr.a_text;
X	        exec_data_end = exec_data_start + exec_aouthdr.a_data;
X		data_start = exec_data_start;
X		data_end += exec_data_start;
X	
X		fstat (execchan, &st_exec);
X		exec_mtime = st_exec.st_mtime;
X	      }
X	
X	      validate_files ();
X	    }
X	  else if (from_tty)
X	    printf ("No exec file now.\n");
X	
X	  /* Tell display code (if any) about the changed file name.  */
X	  if (exec_file_display_hook)
X	    (*exec_file_display_hook) (filename);
X	}
BUNDLE_EOF
if test    18183  -ne "`wc -c <mass-dep.c`"
then
   echo shar: error transmitting mass-dep.c \(should have    18183  characters\)
fi
fi
Technical Details
Message-ID: <9008081747.AA01046@sugar-bombs.ai.mit.edu>
Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!AI.MIT.EDU!rms

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f5053,a1dd611f8af67d25,start
X-Google-Attributes: gidf5053,public
X-Google-ArrivalTime: 1990-08-09 04:35:17 PST
Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!AI.MIT.EDU!rms
From: rms@AI.MIT.EDU
Newsgroups: gnu.gdb.bug
Subject: [will@nirvana.westford.ccur.com: GDB patches for Concurrent/Masscomp machines.]
Message-ID: <9008081747.AA01046@sugar-bombs.ai.mit.edu>
Date: 8 Aug 90 17:47:22 GMT
Sender: quinlan@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 1427
Posted: Wed Aug  8 18:47:22 1990