🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gdb.bug
Article #10190

Patches for gdb3.5 on the GOULD NP1

#10190
From: Mark Davies
Date: Sun, 04 Mar 1990 00:07
825 lines
30346 bytes
    Here are my patches to get gdb version 3.5 working on a GOULD NP1 running 
UTX/32 3.1u01. I hope they are in the right format, this is the first time
I ever done anything like this so please bear with me. Any problems please
let me know.
		Thanks,
			Mark

OK here are the details.

Remaining Problems I know about.
The step and next commands seem very slow when compared with the lattest
version of dbx we have.
gdb (and dbx) sometimes get the values of doubles and structures containing 
doubles wrong. This is due to the compiler generating incorrect symbols, the 
address of the variable is normally 4 out.

Here are the changes I have made.

Changes to general files.
config.gdb
	added makedefine and depfile to npl entry.

createtags
	Use $NF instead of $11 in getting filename of symbolic link.

dbxread.c
read_dbx_symtab : added GOULD NP1 nobase symbols N_NBSTS and N_NBLCS.

		  #ifdef'ed out for the NP1 the end_psymtab() on a N_TEXT
                  symbol with a namestring of *.o or -l* . On the NP1 this
                  symbol contains a very low value for n_value which causes
                  the created psymtab to have a textlow > texthigh which
                  causes problems latter. What n_value actually is in this
                  case I don't know. 

process_one_symbol : N_LBRAC and N_RBRAC symbols on the GOULD_NP1 give absolute
		     addresses the code as was expects address relative to
                     last_source_start_addr.
		     Defined BLOCK_ADDRESS_ABSOLUTE in m-npl.h and #ifdef'ed
                     code so if defined last_source_start_addr is not added.

value.c
using_struct_return : GOULD NP1 c compiler returns small structures (size <= 8)
                      in resgisters. Defined REGISTER_STRUCT_RETURN_SIZE to the
		      max size of a structure returned in registers in m-npl.h
                      and #ifdef'ed code so if defined does an extra check.


Changes to GOULD NP1 specific files
gld-pinsn.c
findframe : moved declaration of framechain right side of #if
 
gould-dep.c
write_inferior_memory: Use ptrace 5 above text_end.
store_inferior_registers: FP_REGNUM read only so don't try to write to it.

m-npl.h
Total rewrite of stuff required to make the inferior call functions.
Fixed stuff for getting return value from inferior function call.
IGNORE_SYMBOL: also ignore 0xa4 (I don't know what it is, its a sdb symbol
               according to stab.h).
Removed END_OF_TEXT_DEFAULT
Corrections to STRING_TABLE_OFFSET and FRAME_LOCALS_ADDRESS.
BREAKPOINT: padded out to make size of machine word. Use to give problems
            if hit breakpoint on returning from a function call.
SP_REGNUM and FP_REGNUM swaped as b2 is suppose to be the stack pointer.
FRAME_FIND_SAVED_REGS: also get SP_REGNUM even though its not a saved reg.
Definition of vprintf changed to _doprnt

npl-opcode.h
fixed typing error in lil definition

Heres the patch file

*** config.gdb.orig	Fri Feb  9 21:42:16 1990
--- config.gdb	Sun Feb 25 14:41:14 1990
***************
*** 237,243 ****
--- 237,245 ----
  	depfile=news-dep.c
  	;;
  npl)
+ 	makedefine="-Ugould"
  	pinsnfile=gld-pinsn.c
+ 	depfile=gould-dep.c
  	;;
  pn)
  	pinsnfile=gld-pinsn.c
*** createtags.orig	Mon Jul 10 23:49:03 1989
--- createtags	Sun Feb 25 14:41:15 1990
***************
*** 6,12 ****
  #
  filelist=""
  if test "`find main.c -type l -print `" != "" ; then
! 	prefix=`ls -l main.c | awk '{print $11}' | sed 's;main.c$;;'`
  else
  	prefix=""
  fi
--- 6,12 ----
  #
  filelist=""
  if test "`find main.c -type l -print `" != "" ; then
! 	prefix=`ls -l main.c | awk '{print $NF}' | sed 's;main.c$;;'`
  else
  	prefix=""
  fi
***************
*** 25,34 ****
  	else
  		frmatfile=${prefix}dbxread.c
  	fi
! 	hfile=$prefix`ls -l param.h | awk '{print $11}'`
! 	dfile=$prefix`ls -l dep.c | awk '{print $11}'`
! 	ofile=$prefix`ls -l opcode.h | awk '{print $11}'`
! 	pfile=$prefix`ls -l pinsn.c | awk '{print $11}'`
  	etags $hfile $dfile $ofile $pfile $frmatfile $filelist
  else
  	etags $filelist
--- 25,34 ----
  	else
  		frmatfile=${prefix}dbxread.c
  	fi
! 	hfile=$prefix`ls -l param.h | awk '{print $NF}'`
! 	dfile=$prefix`ls -l dep.c | awk '{print $NF}'`
! 	ofile=$prefix`ls -l opcode.h | awk '{print $NF}'`
! 	pfile=$prefix`ls -l pinsn.c | awk '{print $NF}'`
  	etags $hfile $dfile $ofile $pfile $frmatfile $filelist
  else
  	etags $filelist
*** dbxread.c.orig	Fri Feb  9 21:42:24 1990
--- dbxread.c	Sun Feb 25 15:11:45 1990
***************
*** 2139,2144 ****
--- 2139,2145 ----
  		}
  	      if (past_first_source_file && pst)
  		{
+ #ifndef GOULD_NP1
  		  end_psymtab (pst, psymtab_include_list, includes_used,
  			       symnum * sizeof (struct nlist), bufp->n_value,
  			       dependency_list, dependencies_used,
***************
*** 2146,2151 ****
--- 2147,2155 ----
  		  pst = (struct partial_symtab *) 0;
  		  includes_used = 0;
  		  dependencies_used = 0;
+ #else
+ 		  ;
+ #endif   /* GOULD_NP1 */
  		}
  	      else
  		past_first_source_file = 1;
***************
*** 2417,2422 ****
--- 2421,2431 ----
  	case N_STSYM:		/* Data seg var -- static  */
  	case N_LCSYM:		/* BSS      "  */
  
+ #ifdef N_NBSTS
+   	case N_NBSTS:           /* Gould nobase */
+ 	case N_NBLCS:           /* symbols      */
+ #endif 
+ 
  	/* Following may probably be ignored; I'll leave them here
  	   for now (until I do Pascal and Modula 2 extensions).  */
  
***************
*** 3322,3329 ****
--- 3331,3343 ----
  	    new->start_addr = value;
  	  /* Make a block for the local symbols within.  */
  	  finish_block (0, &local_symbols, new->old_blocks,
+ #ifndef BLOCK_ADDRESS_ABSOLUTE
  			new->start_addr + last_source_start_addr,
  			value + last_source_start_addr);
+ #else
+ 			new->start_addr,
+ 			value);
+ #endif   /* BLOCK_ADDRESS_ABSOLUTE */
  	}
        else
  	{
*** values.c.orig	Sun Sep 10 04:39:19 1989
--- values.c	Sun Feb 25 14:41:20 1990
***************
*** 974,980 ****
      {
        struct block *b = block_for_pc (funcaddr);
  
!       if (!(BLOCK_GCC_COMPILED (b) && TYPE_LENGTH (value_type) < 8))
  	return 1;
      }
  
--- 974,985 ----
      {
        struct block *b = block_for_pc (funcaddr);
  
!       if (!(BLOCK_GCC_COMPILED (b) && TYPE_LENGTH (value_type) <= 8)
! #ifdef REGISTER_STRUCT_RETURN_SIZE
! 	  && !(!BLOCK_GCC_COMPILED(b) &&
! 	       TYPE_LENGTH(value_type) <= REGISTER_STRUCT_RETURN_SIZE)
! #endif
! 	  )
  	return 1;
      }
  
*** gld-pinsn.c.orig	Wed Jul  5 20:46:00 1989
--- gld-pinsn.c	Sun Feb 25 14:41:18 1990
***************
*** 224,232 ****
      FRAME thisframe;
  {
      register FRAME_ADDR pointer;
  #if 0    
      struct frame_info *frame;
-     FRAME_ADDR framechain();
  
      /* Setup toplevel frame structure */
      frame->pc = read_pc();
--- 224,232 ----
      FRAME thisframe;
  {
      register FRAME_ADDR pointer;
+     FRAME_ADDR framechain();
  #if 0    
      struct frame_info *frame;
  
      /* Setup toplevel frame structure */
      frame->pc = read_pc();
*** gould-dep.c.orig	Fri Feb  9 21:42:36 1990
--- gould-dep.c	Sun Feb 25 14:41:18 1990
***************
*** 140,145 ****
--- 140,146 ----
      }
    else for (regno = 0; regno < NUM_REGS; regno++)
      {
+       if(regno == FP_REGNUM) continue;
        regaddr = register_addr (regno, offset);
        errno = 0;
        ptrace (6, inferior_pid, regaddr, read_register (regno));
***************
*** 215,221 ****
    /* Allocate buffer of that many longwords.  */
    register int *buffer = (int *) alloca (count * sizeof (int));
    extern int errno;
! 
    /* Fill start and end extra bytes of buffer with existing memory data.  */
  
    if (remote_debugging)
--- 216,223 ----
    /* Allocate buffer of that many longwords.  */
    register int *buffer = (int *) alloca (count * sizeof (int));
    extern int errno;
!   extern CORE_ADDR text_end;
!   
    /* Fill start and end extra bytes of buffer with existing memory data.  */
  
    if (remote_debugging)
***************
*** 246,252 ****
        if (remote_debugging)
  	remote_store_word (addr, buffer[i]);
        else
! 	ptrace (4, inferior_pid, addr, buffer[i]);
        if (errno)
  	return errno;
      }
--- 248,257 ----
        if (remote_debugging)
  	remote_store_word (addr, buffer[i]);
        else
! 	if(addr < text_end)
! 	  ptrace (4, inferior_pid, addr, buffer[i]);
! 	else
! 	  ptrace (5, inferior_pid, addr, buffer[i]);
        if (errno)
  	return errno;
      }
*** m-npl.h.orig	Sat Aug  5 08:00:22 1989
--- m-npl.h	Sun Feb 25 16:26:00 1990
***************
*** 23,29 ****
  #define WORDS_BIG_ENDIAN
  
  /* This code appears in libraries on Gould machines.  Ignore it. */
! #define IGNORE_SYMBOL(type) (type == N_ENTRY)
  
  /* We don't want the extra gnu symbols on the machine;
     they will interfere with the shared segment symbols.  */
--- 23,30 ----
  #define WORDS_BIG_ENDIAN
  
  /* This code appears in libraries on Gould machines.  Ignore it. */
! /* MJD - 0xa4 added - mentioned in stab.h but only in sdb symbol list! */
! #define IGNORE_SYMBOL(type) (type == N_ENTRY || type == 0xa4)
  
  /* We don't want the extra gnu symbols on the machine;
     they will interfere with the shared segment symbols.  */
***************
*** 36,45 ****
                  + exec_aouthdr.a_text
  
  /* Macro for number of symbol table entries */
- #define END_OF_TEXT_DEFAULT					\
- 	(0xffffff)
- 
- /* Macro for number of symbol table entries */
  #define NUMBER_OF_SYMBOLS					\
  	(coffhdr.f_nsyms)
  
--- 37,42 ----
***************
*** 49,55 ****
  
  /* Macro for file-offset of string table (in NPL a.out format).  */
  #define STRING_TABLE_OFFSET					\
! 	(N_STROFF (coffhdr) + sizeof(int))
  
  /* Macro to store the length of the string table data in INTO.  */
  #define READ_STRING_TABLE_SIZE(INTO)				\
--- 46,52 ----
  
  /* Macro for file-offset of string table (in NPL a.out format).  */
  #define STRING_TABLE_OFFSET					\
! 	(N_STROFF (coffhdr))
  
  /* Macro to store the length of the string table data in INTO.  */
  #define READ_STRING_TABLE_SIZE(INTO)				\
***************
*** 77,83 ****
  #define	NS32GMAGIC	GNP1MAGIC
  #define	NS32SMAGIC	GPNMAGIC
  #ifndef HAVE_VPRINTF
! #define vprintf		printf
  #endif /* not HAVE_VPRINTF */
  
  /* Get rid of any system-imposed stack limit if possible.  */
--- 74,80 ----
  #define	NS32GMAGIC	GNP1MAGIC
  #define	NS32SMAGIC	GPNMAGIC
  #ifndef HAVE_VPRINTF
! #define vprintf(format, ap)		_doprnt (format, ap, stdout)
  #endif /* not HAVE_VPRINTF */
  
  /* Get rid of any system-imposed stack limit if possible.  */
***************
*** 90,95 ****
--- 87,96 ----
  /* Debugger information will be in DBX format.  */
  #define READ_DBX_FORMAT
  
+ /* MJD - Addresses of blocks are given as absolute address not relative to
+    to start of source address */
+ #define BLOCK_ADDRESS_ABSOLUTE
+ 
  /* Offset from address of function to start of its code.
     Zero on most machines.  */
  #define FUNCTION_START_OFFSET	8
***************
*** 180,186 ****
     the new frame is not set up until the new function executes
     some instructions.  True on NPL! Return address is in R1.
     The true return address is REALLY 4 past that location! */
! `#define SAVED_PC_AFTER_CALL(frame) \
  	(read_register(R1_REGNUM) + 4)
  
  /* Address of U in kernel space */
--- 181,187 ----
     the new frame is not set up until the new function executes
     some instructions.  True on NPL! Return address is in R1.
     The true return address is REALLY 4 past that location! */
! #define SAVED_PC_AFTER_CALL(frame) \
  	(read_register(R1_REGNUM) + 4)
  
  /* Address of U in kernel space */
***************
*** 193,199 ****
  #define INNER_THAN 		<
  
  /* Sequence of bytes for breakpoint instruction.  */
! #define BREAKPOINT 		{0x28, 0x09}
  
  /* Amount PC must be decremented by after a breakpoint.
     This is often the number of bytes in BREAKPOINT
--- 194,200 ----
  #define INNER_THAN 		<
  
  /* Sequence of bytes for breakpoint instruction.  */
! #define BREAKPOINT 		{0x28, 0x09, 0x00, 0x00}
  
  /* Amount PC must be decremented by after a breakpoint.
     This is often the number of bytes in BREAKPOINT
***************
*** 240,253 ****
     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 R1_REGNUM	1	/* Gr1 => return address of caller */
  #define R4_REGNUM	4	/* Gr4 => register save area */
  #define R5_REGNUM	5	/* Gr5 => register save area */
  #define R6_REGNUM	6	/* Gr6 => register save area */
  #define R7_REGNUM	7	/* Gr7 => register save area */
  #define B1_REGNUM	9	/* Br1 => start of this code routine */
! #define FP_REGNUM	10	/* Br2 == (sp) */
  #define AP_REGNUM	11	/* Br3 == (ap) */
! #define SP_REGNUM 	16	/* A copy of Br2 saved in trap */
  #define PS_REGNUM 	17	/* Contains processor status */
  #define PC_REGNUM 	18	/* Contains program counter */
  #define VE_REGNUM 	19	/* Vector end (user setup) register */
--- 241,255 ----
     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 R1_REGNUM	1	/* Gr1 => return address of caller */
+ #define R2_REGNUM	2	/* Gr2 => return value from function */
  #define R4_REGNUM	4	/* Gr4 => register save area */
  #define R5_REGNUM	5	/* Gr5 => register save area */
  #define R6_REGNUM	6	/* Gr6 => register save area */
  #define R7_REGNUM	7	/* Gr7 => register save area */
  #define B1_REGNUM	9	/* Br1 => start of this code routine */
! #define SP_REGNUM	10	/* Br2 == (sp) */
  #define AP_REGNUM	11	/* Br3 == (ap) */
! #define FP_REGNUM 	16	/* A copy of Br2 saved in trap */
  #define PS_REGNUM 	17	/* Contains processor status */
  #define PC_REGNUM 	18	/* Contains program counter */
  #define VE_REGNUM 	19	/* Vector end (user setup) register */
***************
*** 263,269 ****
  	if (regno == VE_REGNUM) addr = blockend - 9 * 4;		\
  	if (regno == PC_REGNUM) addr = blockend - 8 * 4;		\
  	if (regno == PS_REGNUM) addr = blockend - 7 * 4;		\
! 	if (regno == SP_REGNUM) addr = blockend - 6 * 4;		\
  	if (regno >= V1_REGNUM) 					\
  	    addr = blockend + 16 * 4 + (regno - V1_REGNUM) * VR_SIZE;	\
  }
--- 265,271 ----
  	if (regno == VE_REGNUM) addr = blockend - 9 * 4;		\
  	if (regno == PC_REGNUM) addr = blockend - 8 * 4;		\
  	if (regno == PS_REGNUM) addr = blockend - 7 * 4;		\
! 	if (regno == FP_REGNUM) addr = blockend - 6 * 4;		\
  	if (regno >= V1_REGNUM) 					\
  	    addr = blockend + 16 * 4 + (regno - V1_REGNUM) * VR_SIZE;	\
  }
***************
*** 319,325 ****
     On this machine this is a no-op, because gcc isn't used on it
     yet.  So this calling convention is not used. */
  
! #define STORE_STRUCT_RETURN(ADDR, SP)
  
  /* Extract from an arrary REGBUF containing the (raw) register state
     a function return value of type TYPE, and copy that, in virtual format,
--- 321,328 ----
     On this machine this is a no-op, because gcc isn't used on it
     yet.  So this calling convention is not used. */
  
! #define STORE_STRUCT_RETURN(ADDR, SP) \
!      push_word(SP + 8,ADDR)
  
  /* Extract from an arrary REGBUF containing the (raw) register state
     a function return value of type TYPE, and copy that, in virtual format,
***************
*** 326,345 ****
     into VALBUF. */
  
  #define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
! 	bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
! 
  /* 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).  */
--- 329,352 ----
     into VALBUF. */
  
  #define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
!       bcopy (((int *)(REGBUF))+2, (VALBUF), TYPE_LENGTH (TYPE));
  /* Write into appropriate registers a function return value
     of type TYPE, given in virtual format.  */
  
  #define STORE_RETURN_VALUE(TYPE,VALBUF) \
! 	write_register_bytes (REGISTER_BYTE (R2_REGNUM), 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)+2))
  
+ /* MJD - Size of structure that can be returned in registers */
+ 
+ #define REGISTER_STRUCT_RETURN_SIZE        8
+ 
  
  /* Describe the pointer in each stack frame to the previous stack frame
     (its caller).  */
***************
*** 374,380 ****
  	 read_memory_integer ((fi)->frame + 12, 4) : \
  	 read_register (AP_REGNUM))
  
! #define FRAME_LOCALS_ADDRESS(fi)	((fi)->frame + 80)
  
  /* Set VAL to the number of args passed to frame described by FI.
     Can set VAL to -1, meaning no way to tell.  */
--- 381,387 ----
  	 read_memory_integer ((fi)->frame + 12, 4) : \
  	 read_register (AP_REGNUM))
  
! #define FRAME_LOCALS_ADDRESS(fi)	((fi)->frame)
  
  /* Set VAL to the number of args passed to frame described by FI.
     Can set VAL to -1, meaning no way to tell.  */
***************
*** 395,400 ****
--- 402,408 ----
  #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs)		\
  {                                                                       \
    bzero (&frame_saved_regs, sizeof frame_saved_regs);			\
+   (frame_saved_regs).regs[SP_REGNUM] = framechain(frame_info);          \
    (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 8;		\
    (frame_saved_regs).regs[R4_REGNUM] = (frame_info)->frame + 0x30;	\
    (frame_saved_regs).regs[R5_REGNUM] = (frame_info)->frame + 0x34;	\
***************
*** 404,531 ****
  
  /* Things needed for making the inferior call functions.  */
  
  /* Push an empty stack frame, to record the current PC, etc.  */
  
  #define PUSH_DUMMY_FRAME \
! { register CORE_ADDR sp = read_register (SP_REGNUM);			\
!   register int regnum;							\
!   sp = push_word (sp, read_register (PC_REGNUM));			\
!   sp = push_word (sp, read_register (FP_REGNUM));			\
!   write_register (FP_REGNUM, sp);					\
!   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)			\
!     sp = push_word (sp, read_register (regnum));			\
!   sp = push_word (sp, read_register (PS_REGNUM));			\
!   write_register (SP_REGNUM, sp);  }
  
  /* Discard from the stack the innermost frame, 
     restoring all saved registers.  */
  
  #define POP_FRAME  \
! { register FRAME frame = get_current_frame ();			 \
!   register CORE_ADDR fp;					 \
!   register int regnum;						 \
!   struct frame_saved_regs fsr;					 \
!   struct frame_info *fi;					 \
!   fi = get_frame_info (frame);					 \
!   fp = fi->frame;						 \
!   get_frame_saved_regs (fi, &fsr);				 \
!   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)		 \
!     if (fsr.regs[regnum])					 \
!       write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
!   if (fsr.regs[PS_REGNUM])					 \
!     write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
!   write_register (FP_REGNUM, read_memory_integer (fp, 4));	 \
!   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
!   write_register (SP_REGNUM, fp + 8);				 \
!   flush_cached_frames ();					 \
!   set_current_frame ( create_new_frame (read_register (FP_REGNUM),\
! 					read_pc ())); }
  
! /* This sequence of words is the instructions:
!      halt
!      halt
!      halt
!      halt
!      suabr	b2, #<stacksize>
!      lwbr	b6, #con
!      stw	r1, 8(b2)	- save caller address, do we care?
!      lw		r2, 60(b2)	- arg1
!      labr	b3, 50(b2)
!      std	r4, 30(b2)	- save r4-r7
!      std	r6, 38(b2)
!      lwbr	b1, #<func>	- load function call address
!      brlnk	r1, 8(b1)	- call function
!      halt
!      halt
!      ld		r4, 30(b2)	- restore r4-r7
!      ld		r6, 38(b2)
  
!    Setup our stack frame, load argumemts, call and then restore registers.
! */
  
! #define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
  
! #define CALL_DUMMY_LENGTH 28
  
! #define CALL_DUMMY_START_OFFSET 12
  
! /* Insert the specified number of args and function address
!    into a call sequence of the above form stored at DUMMYNAME.  */
  
! #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type)     \
! { *(int *)((char *) dummyname + 20) = nargs * 4;  \
!   *(int *)((char *) dummyname + 14) = fun; }
! 
! /*
!  * No KDB support, Yet! */
! /* Interface definitions for kernel debugger KDB.  */
  
! /* Map machine fault codes into signal numbers.
!    First subtract 0, divide by 4, then index in a table.
!    Faults for which the entry in this table is 0
!    are not handled by KDB; the program's own trap handler
!    gets to handle then.  */
  
! #define FAULT_CODE_ORIGIN 0
! #define FAULT_CODE_UNITS 4
! #define FAULT_TABLE    \
! { 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
!   0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
!   0, 0, 0, 0, 0, 0, 0, 0, \
!   SIGILL }
  
! /* Start running with a stack stretching from BEG to END.
!    BEG and END should be symbols meaningful to the assembler.
!    This is used only for kdb.  */
  
! #define INIT_STACK(beg, end)  \
! { asm (".globl end");         \
!   asm ("movel $ end, sp");      \
!   asm ("clrl fp"); }
  
! /* Push the frame pointer register on the stack.  */
! #define PUSH_FRAME_PTR        \
!   asm ("movel fp, -(sp)");
  
- /* Copy the top-of-stack to the frame pointer register.  */
- #define POP_FRAME_PTR  \
-   asm ("movl (sp), fp");
- 
- /* After KDB is entered by a fault, push all registers
-    that GDB thinks about (all NUM_REGS of them),
-    so that they appear in order of ascending GDB register number.
-    The fault code will be on the stack beyond the last register.  */
- 
- #define PUSH_REGISTERS        \
- { asm ("clrw -(sp)");	      \
-   asm ("pea 10(sp)");	      \
-   asm ("movem $ 0xfffe,-(sp)"); }
- 
- /* Assuming the registers (including processor status) have been
-    pushed on the stack in order of ascending GDB register number,
-    restore them and return to the address in the saved PC register.  */
- 
- #define POP_REGISTERS          \
- { asm ("subil $8,28(sp)");     \
-   asm ("movem (sp),$ 0xffff"); \
-   asm ("rte"); }
--- 412,545 ----
  
  /* Things needed for making the inferior call functions.  */
  
+ /* Cannot execute with pc on the stack.  */
+ 
+ #define CANNOT_EXECUTE_STACK
+ 
  /* Push an empty stack frame, to record the current PC, etc.  */
  
  #define PUSH_DUMMY_FRAME \
! { register CORE_ADDR sp = read_register (SP_REGNUM); \
!   register int regnum;                               \
!   for (regnum = 0; regnum < FP_REGNUM; regnum++)     \
!     sp = push_word (sp, read_register (regnum));     \
!   sp = push_word (sp, read_register (PS_REGNUM));    \
!   sp = push_word (sp, read_register (PC_REGNUM));    \
!   write_register (SP_REGNUM, sp);}
  
  /* Discard from the stack the innermost frame, 
     restoring all saved registers.  */
  
  #define POP_FRAME  \
! { CORE_ADDR sp = read_register(SP_REGNUM);             \
!   REGISTER_TYPE reg;                                   \
!   int regnum;                                          \
!   for(regnum = 0;regnum < FP_REGNUM;regnum++){         \
!     sp-=sizeof(REGISTER_TYPE);                         \
!     read_memory(sp,&reg,sizeof(REGISTER_TYPE));        \
!     write_register(regnum,reg);}                       \
!   sp-=sizeof(REGISTER_TYPE);                           \
!   read_memory(sp,&reg,sizeof(REGISTER_TYPE));          \
!   write_register(PS_REGNUM,reg);                       \
!   sp-=sizeof(REGISTER_TYPE);                           \
!   read_memory(sp,&reg,sizeof(REGISTER_TYPE));          \
!   write_register(PC_REGNUM,reg);}
  
! /* MJD - Size of dummy frame pushed onto stack by PUSH_DUMMY_FRAME */
  
! #define DUMMY_FRAME_SIZE (0x48)
  
! /* MJD - The sequence of words in the instructions is
!    halt
!    halt
!    halt
!    halt
!    subr    b2,stack size,0             grab stack space for dummy call
!    labr    b3,x0(b2),0                 set AP_REGNUM to point at arguments
!    lw      r2,x8(b3),0                 load r2 with first argument    
!    lwbr    b1,arguments size(b2),0     load address of function to be called
!    brlnk   r1,x8(b1),0                 call function
!    halt
!    halt
!    labr    b2,stack size(b2),0         give back stack
!    break                               break
!    */
  
! #define CALL_DUMMY {0x00000000,  \
! 		    0x00000000,  \
! 		    0x59000000,  \
! 		    0x598a0000,  \
! 		    0xb5030008,  \
! 		    0x5c820000,  \
! 		    0x44810008,  \
! 		    0x00000000,  \
! 		    0x590a0000,  \
! 		    0x28090000 }
  
! #define CALL_DUMMY_LENGTH 40
  
! #define CALL_DUMMY_START_OFFSET 8
  
! #define CALL_DUMMY_STACK_ADJUST 8
  
! /* MJD - Fixup CALL_DUMMY for the specific function call.
!    OK heres the problems
!    1) On a trap there are two copies of the stack pointer, one in SP_REGNUM
!       which is read/write and one in FP_REGNUM which is only read. It seems
!       that when restarting the GOULD NP1 uses FP_REGNUM's value.
!    2) Loading function address into b1 looks a bit difficult if bigger than
!       0x0000fffc, infact from what I can tell the compiler sets up table of
!       function address in base3 through which function calls are referenced.
  
!    OK my solutions
!      Calculate the size of the dummy stack frame and do adjustments of
!      SP_REGNUM in the dummy call.
!      Push function address onto the stack and load it in the dummy call
!  */
  
! #define FIX_CALL_DUMMY(dummyname, sp, fun, nargs, type) \
!   {   int i;\
!       int arg_len = 0, total_len;\
!       old_sp = push_word(old_sp,fun);\
!       for(i = nargs - 1;i >= 0;i--)\
! 	arg_len += TYPE_LENGTH (VALUE_TYPE (value_arg_coerce (args[i])));\
!       if(struct_return)\
! 	arg_len += TYPE_LENGTH(value_type);\
!       total_len = DUMMY_FRAME_SIZE+CALL_DUMMY_STACK_ADJUST+4+arg_len;\
!       dummyname[0] += total_len;\
!       dummyname[2] += total_len;\
!       dummyname[5] += arg_len+CALL_DUMMY_STACK_ADJUST;\
!       dummyname[8] += total_len;}
  
! /* MJD - So the stack should end up looking like this
  
!                    | Normal stack frame  |
!                    | from normal program |
!                    | flow                |
!                    +---------------------+ <- Final sp - 0x08 - argument size
!                    |                     |    - 0x4 - dummy_frame_size
!                    | Pushed dummy frame  |
!                    |  b0-b7, r0-r7       |
!                    |  pc and ps          |
!                    |                     |
!                    +---------------------+
!                    | Function address    |
!                    +---------------------+ <- Final sp - 0x8 - arguments size
!                    |                     |
!                    |                     |
!                    |                     |
!                    |  Arguments to       |
!                    |       Function      |
!                    |                     |
!                    |                     |
!                    |                     |
!                    +---------------------+ <- Final sp - 0x8
!                    | Dummy_stack_adjust  |
!                    +---------------------+ <- Final sp
!                    |                     |
!                    | where call will     |
!                    |   build frame       |
! 
! /*
!  * No KDB support, Yet! */
  
*** npl-opcode.h.orig	Wed Jul  5 20:46:30 1989
--- npl-opcode.h	Sun Feb 25 14:41:20 1990
***************
*** 99,105 ****
  { "sthp",	0x94000001,	0xfc080001,	"r,xOA,X",	4 },
  { "stwp",	0x94000000,	0xfc080000,	"r,xOA,X",	4 },
  { "stdp",	0x94000002,	0xfc080002,	"r,xOA,X",	4 },
! { "lil",	0xf8080000,	0xfc7f0000,	"r,D",		4 },
  { "lwsl1",	0xec000000,	0xfc080000,	"r,xOA,X",	4 },
  { "lwsl2",	0xfc000000,	0xfc080000,	"r,xOA,X",	4 },
  { "lwsl3",	0xfc080000,	0xfc080000,	"r,xOA,X",	4 },
--- 99,105 ----
  { "sthp",	0x94000001,	0xfc080001,	"r,xOA,X",	4 },
  { "stwp",	0x94000000,	0xfc080000,	"r,xOA,X",	4 },
  { "stdp",	0x94000002,	0xfc080002,	"r,xOA,X",	4 },
! { "lil",	0xf80b0000,	0xfc7f0000,	"r,D",		4 },
  { "lwsl1",	0xec000000,	0xfc080000,	"r,xOA,X",	4 },
  { "lwsl2",	0xfc000000,	0xfc080000,	"r,xOA,X",	4 },
  { "lwsl3",	0xfc080000,	0xfc080000,	"r,xOA,X",	4 },

-- 
Mark Davies                       chpmjd@uk.ac.bath.gdr || chpmjd@gdr.bath.ac.uk
Tel: Bath 826826 ext 5105              "The rat race is over! The rats won."
Technical Details
Message-ID: <9003040017.AA25263@aeneas.MIT.EDU>
Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!NSFNET-RELAY.AC.UK!chpmjd%gdr.bath.ac.uk

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f5053,800355098123e44b,start
X-Google-Attributes: gidf5053,public
X-Google-ArrivalTime: 1990-03-03 16:07:20 PST
Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!NSFNET-RELAY.AC.UK!chpmjd%gdr.bath.ac.uk
From: chpmjd%gdr.bath.ac.uk@NSFNET-RELAY.AC.UK (Mark Davies)
Newsgroups: gnu.gdb.bug
Subject: Patches for gdb3.5 on the GOULD NP1
Message-ID: <9003040017.AA25263@aeneas.MIT.EDU>
Date: 4 Mar 90 00:07:20 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 825
Posted: Sun Mar  4 01:07:20 1990