diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/a29k-tdep.c | 84 | ||||
-rw-r--r-- | gdb/config/a29k/tm-a29k.h | 30 |
3 files changed, 98 insertions, 26 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1893326..86b4b61 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +Tue Jan 11 00:53:46 1994 John Gilmore (gnu@cygnus.com) + + * a29k-tdep.c (init_frame_info): Cast null arg to examine_tag. + (pop_frame): Restore PC2 and LR0 from dummy frames. + (push_dummy_frame): Save PC2 and LR0 into dummy frames. + (setup_arbitrary_frame): Handle 3 args and set up real frames. + * config/a29k/tm-a29k.h (FRAME_NUM_ARGS): Update comments. + (DUMMY_FRAME_RSIZE): Add 2 longwords for PC2 and LR0. + (SETUP_ARBITRARY_FRAME): Define. + Tue Jan 11 06:59:10 1994 Jim Kingdon (kingdon@deneb.cygnus.com) * infrun.c, config/mips/tm-irix5.h: Remove #if 0'd AT_FUNCTION_START. diff --git a/gdb/a29k-tdep.c b/gdb/a29k-tdep.c index 20e9d53..ce8a912 100644 --- a/gdb/a29k-tdep.c +++ b/gdb/a29k-tdep.c @@ -437,14 +437,14 @@ init_frame_info (innermost_frame, fci) after the trace-back tag. */ p += 4; } + /* We've found the start of the function. - * Try looking for a tag word that indicates whether there is a - * memory frame pointer and what the memory stack allocation is. - * If one doesn't exist, try using a more exhaustive search of - * the prologue. For now we don't care about the argcount or - * whether or not the routine is transparent. - */ - if (examine_tag(p-4,&trans,NULL,&msize,&mfp_used)) /* Found a good tag */ + Try looking for a tag word that indicates whether there is a + memory frame pointer and what the memory stack allocation is. + If one doesn't exist, try using a more exhaustive search of + the prologue. */ + + if (examine_tag(p-4,&trans,(int *)NULL,&msize,&mfp_used)) /* Found good tag */ examine_prologue (p, &rsize, 0, 0); else /* No tag try prologue */ examine_prologue (p, &rsize, &msize, &mfp_used); @@ -730,6 +730,8 @@ pop_frame () CORE_ADDR rfb = read_register (RFB_REGNUM); CORE_ADDR gr1 = fi->frame + fi->rsize; CORE_ADDR lr1; + CORE_ADDR original_lr0; + int must_fix_lr0 = 0; int i; /* If popping a dummy frame, need to restore registers. */ @@ -744,15 +746,23 @@ pop_frame () write_register (SR_REGNUM(i+160), read_register (lrnum++)); for (i = 0; i < DUMMY_SAVE_GREGS; ++i) write_register (RETURN_REGNUM + i, read_register (lrnum++)); - /* Restore the PCs. */ + /* Restore the PCs and prepare to restore LR0. */ write_register(PC_REGNUM, read_register (lrnum++)); - write_register(NPC_REGNUM, read_register (lrnum)); + write_register(NPC_REGNUM, read_register (lrnum++)); + write_register(PC2_REGNUM, read_register (lrnum++)); + original_lr0 = read_register (lrnum++); + must_fix_lr0 = 1; } /* Restore the memory stack pointer. */ write_register (MSP_REGNUM, fi->saved_msp); /* Restore the register stack pointer. */ write_register (GR1_REGNUM, gr1); + + /* If we popped a dummy frame, restore lr0 now that gr1 has been restored. */ + if (must_fix_lr0) + write_register (LR0_REGNUM, original_lr0); + /* Check whether we need to fill registers. */ lr1 = read_register (LR0_REGNUM + 1); if (lr1 > rfb) @@ -782,8 +792,13 @@ push_dummy_frame () long w; CORE_ADDR rab, gr1; CORE_ADDR msp = read_register (MSP_REGNUM); - int lrnum, i, saved_lr0; - + int lrnum, i; + CORE_ADDR original_lr0; + + /* Read original lr0 before changing gr1. This order isn't really needed + since GDB happens to have a snapshot of all the regs and doesn't toss + it when gr1 is changed. But it's The Right Thing To Do. */ + original_lr0 = read_register (LR0_REGNUM); /* Allocate the new frame. */ gr1 = read_register (GR1_REGNUM) - DUMMY_FRAME_RSIZE; @@ -826,11 +841,54 @@ push_dummy_frame () write_register (lrnum++, read_register (SR_REGNUM (i + 160))); for (i = 0; i < DUMMY_SAVE_GREGS; ++i) write_register (lrnum++, read_register (RETURN_REGNUM + i)); - /* Save the PCs. */ + /* Save the PCs and LR0. */ write_register (lrnum++, read_register (PC_REGNUM)); - write_register (lrnum, read_register (NPC_REGNUM)); + write_register (lrnum++, read_register (NPC_REGNUM)); + write_register (lrnum++, read_register (PC2_REGNUM)); + write_register (lrnum++, original_lr0); } + + +/* + This routine takes three arguments and makes the cached frames look + as if these arguments defined a frame on the cache. This allows the + rest of `info frame' to extract the important arguments without much + difficulty. Since an individual frame on the 29K is determined by + three values (FP, PC, and MSP), we really need all three to do a + good job. */ + +FRAME +setup_arbitrary_frame (argc, argv) + int argc; + FRAME_ADDR *argv; +{ + FRAME fid; + + if (argc != 3) + error ("AMD 29k frame specifications require three arguments: rsp pc msp"); + + fid = create_new_frame (argv[0], argv[1]); + + if (!fid) + fatal ("internal: create_new_frame returned invalid frame id"); + + /* Creating a new frame munges the `frame' value from the current + GR1, so we restore it again here. FIXME, untangle all this + 29K frame stuff... */ + fid->frame = argv[0]; + + /* Our MSP is in argv[2]. It'd be intelligent if we could just + save this value in the FRAME. But the way it's set up (FIXME), + we must save our caller's MSP. We compute that by adding our + memory stack frame size to our MSP. */ + fid->saved_msp = argv[2] + fid->msize; + + return fid; +} + + + enum a29k_processor_types processor_type = a29k_unknown; void diff --git a/gdb/config/a29k/tm-a29k.h b/gdb/config/a29k/tm-a29k.h index cf5fbca..c87b572 100644 --- a/gdb/config/a29k/tm-a29k.h +++ b/gdb/config/a29k/tm-a29k.h @@ -1,5 +1,5 @@ -/* Parameters for target machine of AMD 29000, for GDB, the GNU debugger. - Copyright 1990, 1991, 1993 Free Software Foundation, Inc. +/* Parameters for target machine AMD 29000, for GDB, the GNU debugger. + Copyright 1990, 1991, 1993, 1994 Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Jim Kingdon. This file is part of GDB. @@ -504,16 +504,11 @@ extern CORE_ADDR frame_locals_address (); /* Return number of args passed to a frame. Can return -1, meaning no way to tell. */ -/* While we could go the effort of finding the tags word and getting - the argcount field from it, - (1) It only counts arguments in registers, i.e. the first 16 words - of arguments - (2) It gives the number of arguments the function was declared with - not how many it was called with (or some variation, like all 16 - words for varadic functions). This makes argcount pretty much - redundant with -g info, even for varadic functions. - So don't bother. */ -#define FRAME_NUM_ARGS(numargs, fi) ((numargs) = -1) +/* We tried going to the effort of finding the tags word and getting + the argcount field from it, to support debugging assembler code. + Problem was, the "argcount" field never did hold the argument + count. */ +#define FRAME_NUM_ARGS(numargs, fi) ((numargs) = -1) #define FRAME_ARGS_ADDRESS(fi) FRAME_LOCALS_ADDRESS (fi) @@ -544,6 +539,7 @@ extern CORE_ADDR frame_locals_address (); |____________|<-msp 0 <-----------mfp_dummy_____| | | | (at start) | save regs | | | arg_slop | | pc0,pc1 | | + | | | pc2,lr0 sproc | | | (16 words) | | gr96-gr124 | | |____________|<-msp 1--after | sr160-sr162 | | | | PUSH_DUMMY_FRAME| sr128-sr135 | | @@ -591,7 +587,7 @@ extern CORE_ADDR frame_locals_address (); #define DUMMY_FRAME_RSIZE \ (4 /* mfp_dummy */ \ - + 2 * 4 /* pc0, pc1 */ \ + + 4 * 4 /* pc0, pc1, pc2, lr0 */ \ + DUMMY_SAVE_GREGS * 4 \ + DUMMY_SAVE_SR160 * 4 \ + DUMMY_SAVE_SR128 * 4 \ @@ -716,3 +712,11 @@ extern enum a29k_processor_types { /* Bit 0x400 of the CPS does identify freeze mode, i.e. 29050. */ a29k_freeze_mode } processor_type; + +/* We need three arguments for a general frame specification for the + "frame" or "info frame" command. */ + +#define SETUP_ARBITRARY_FRAME(argc, argv) setup_arbitrary_frame (argc, argv) +/* FIXME: Depends on equivalence between FRAME and "struct frame_info *", + and equivalence between CORE_ADDR and FRAME_ADDR. */ +extern struct frame_info *setup_arbitrary_frame PARAMS ((int, CORE_ADDR *)); |