* a29k-tdep.c (init_frame_info): Cast null arg to examine_tag.
authorJohn Gilmore <gnu@cygnus>
Wed, 12 Jan 1994 07:47:14 +0000 (07:47 +0000)
committerJohn Gilmore <gnu@cygnus>
Wed, 12 Jan 1994 07:47:14 +0000 (07:47 +0000)
(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.

gdb/ChangeLog
gdb/a29k-tdep.c
gdb/config/a29k/tm-a29k.h

index 1893326101e11b44a9e89b79e4167538556bac28..86b4b61b52e8ef33828a18df54a731761a540ad8 100644 (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.
index 20e9d53731766cda9147450e5e6ef044679204c0..ce8a91202f1a26ae2a0a2597f8449c07daba510e 100644 (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
index cf5fbcab3bfd8678a916f06a14c7c7a046655c3f..c87b572bfd0f4728006cf6b05bafb295973d428f 100644 (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,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 *));