Article View: gnu.gdb.bug
Article #10190Patches for gdb3.5 on the GOULD NP1
From: Mark Davies
Date: Sun, 04 Mar 1990 00:07
Date: Sun, 04 Mar 1990 00:07
825 lines
30346 bytes
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,®,sizeof(REGISTER_TYPE)); \
! write_register(regnum,reg);} \
! sp-=sizeof(REGISTER_TYPE); \
! read_memory(sp,®,sizeof(REGISTER_TYPE)); \
! write_register(PS_REGNUM,reg); \
! sp-=sizeof(REGISTER_TYPE); \
! read_memory(sp,®,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.ukShow 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