* 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.
This commit is contained in:
John Gilmore 1994-01-12 07:47:14 +00:00
parent a1c91916e8
commit eb5b74ca6c
3 changed files with 98 additions and 26 deletions

View File

@ -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.

View File

@ -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

View File

@ -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,15 +504,10 @@ 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. */
/* 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 *));