]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* mips-tdep.c (init_extra_frame_info): Check to see whether the
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 12 Nov 1993 16:35:59 +0000 (16:35 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 12 Nov 1993 16:35:59 +0000 (16:35 +0000)
registers mentioned in the proc_desc have been saved.  This
generalizes mips_in_lenient_prologue in the sense that we keep
searching until we've found saves for all the registers, not just
look for a "lenient prologue" pattern.
* mips-tdep.c: #if 0 lenient prologue code.

* mips-tdep.c (heuristic_proc_desc): Don't assume a host short
is 16 bits.

gdb/ChangeLog
gdb/mips-tdep.c

index 984c6f68987806ae8fd00dc175a5722f4f9744cb..6b733ad221838255e236c1921459fef239309bc9 100644 (file)
@@ -1,3 +1,15 @@
+Fri Nov 12 09:53:26 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
+
+       * mips-tdep.c (init_extra_frame_info): Check to see whether the
+       registers mentioned in the proc_desc have been saved.  This
+       generalizes mips_in_lenient_prologue in the sense that we keep
+       searching until we've found saves for all the registers, not just
+       look for a "lenient prologue" pattern.
+       * mips-tdep.c: #if 0 lenient prologue code.
+
+       * mips-tdep.c (heuristic_proc_desc): Don't assume a host short
+       is 16 bits.
+
 Thu Nov 11 19:58:05 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        * config/i386/i386sol2.mh: Comment out corelow.o.
index f7b4f28ba44ac98624ea66cdb609bc82e9860bfb..c5f870f89910739027ab46753bd113a195eda32d 100644 (file)
@@ -34,7 +34,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #define VM_MIN_ADDRESS (unsigned)0x400000
 \f
+#if 0
 static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
+#endif
 
 /* Some MIPS boards don't support floating point, so we permit the
    user to turn it off.  */
@@ -210,16 +212,16 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
        else if ((word & 0xFFE00000) == 0xafa00000) { /* sw reg,offset($sp) */
            int reg = (word & 0x001F0000) >> 16;
            reg_mask |= 1 << reg;
-           temp_saved_regs.regs[reg] = sp + (short)word;
+           temp_saved_regs.regs[reg] = sp + (word & 0xffff);
        }
        else if ((word & 0xFFFF0000) == 0x27be0000) { /* addiu $30,$sp,size */
-           if ((unsigned short)word != frame_size)
-               reg30 = sp + (unsigned short)word;
+           if ((word & 0xffff) != frame_size)
+               reg30 = sp + (word & 0xffff);
            else if (!has_frame_reg) {
                int alloca_adjust;
                has_frame_reg = 1;
                reg30 = read_next_frame_reg(next_frame, 30);
-               alloca_adjust = reg30 - (sp + (unsigned short)word);
+               alloca_adjust = reg30 - (sp + (word & 0xffff));
                if (alloca_adjust > 0) {
                    /* FP > SP + frame_size. This may be because
                    /* of an alloca or somethings similar.
@@ -233,7 +235,7 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
        else if ((word & 0xFFE00000) == 0xafc00000) { /* sw reg,offset($30) */
            int reg = (word & 0x001F0000) >> 16;
            reg_mask |= 1 << reg;
-           temp_saved_regs.regs[reg] = reg30 + (short)word;
+           temp_saved_regs.regs[reg] = reg30 + (word & 0xffff);
        }
     }
     if (has_frame_reg) {
@@ -386,38 +388,26 @@ init_extra_frame_info(fci)
        fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
                      + PROC_FRAME_OFFSET(proc_desc);
 
-      /* If this is the innermost frame, and we are still in the
-        prologue (loosely defined), then the registers may not have
-        been saved yet.  */
-      if (fci->next == NULL
-          && !PROC_DESC_IS_DUMMY(proc_desc)
-         && mips_in_lenient_prologue (PROC_LOW_ADDR (proc_desc), fci->pc))
-       {
-         /* Can't just say that the registers are not saved, because they
-            might get clobbered halfway through the prologue.
-            heuristic_proc_desc already has the right code to figure out
-            exactly what has been saved, so use it.  As far as I know we
-            could be doing this (as we do on the 68k, for example)
-            regardless of whether we are in the prologue; I'm leaving in
-            the check for being in the prologue only out of conservatism
-            (I'm not sure whether heuristic_proc_desc handles all cases,
-            for example).
-
-            This stuff is ugly (and getting uglier by the minute).  Probably
-            the best way to clean it up is to ignore the proc_desc's from
-            the symbols altogher, and get all the information we need by
-            examining the prologue (provided we can make the prologue
-            examining code good enough to get all the cases...).  */
-         proc_desc =
-           heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
-                                fci->pc,
-                                fci->next);
-       }
-
       if (proc_desc == &temp_proc_desc)
        *fci->saved_regs = temp_saved_regs;
-      else
+      else if (/* In any frame other than the innermost, we assume that all
+                 registers have been saved.  This assumes that all register
+                 saves in a function happen before the first function
+                 call.  */
+              fci->next != NULL
+
+              /* In a dummy frame we know exactly where things are saved.  */
+              || PROC_DESC_IS_DUMMY (proc_desc)
+
+              /* Not sure exactly what kernel_trap means, but if it means
+                 the kernel saves the registers without a prologue doing it,
+                 we better not examine the prologue to see whether registers
+                 have been saved yet.  */
+              || kernel_trap)
        {
+         /* All the registers which will be saved have been saved, so we
+            can believe the proc_desc.  */
+
          /* find which general-purpose registers were saved */
          reg_position = fci->frame + PROC_REG_OFFSET(proc_desc);
          mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
@@ -441,6 +431,58 @@ init_extra_frame_info(fci)
                reg_position -= 4;
              }
        }
+      else
+       {
+         /* We need to figure out whether the registers that the proc_desc
+            claims are saved have been saved yet.  */
+
+         CORE_ADDR addr;
+         int status;
+         char buf[4];
+         unsigned long inst;
+         /* Bitmasks; set if the proc_desc claims the register is saved and we
+            haven't found a save instruction for it yet.  */
+         unsigned long gen_mask, float_mask;
+
+         gen_mask = PROC_REG_MASK (proc_desc);
+         float_mask = PROC_FREG_MASK (proc_desc);
+
+         for (addr = PROC_LOW_ADDR (proc_desc);
+              addr < fci->pc && (gen_mask | float_mask);
+              addr += 4)
+           {
+             status = read_memory_nobpt (addr, buf, 4);
+             if (status)
+               memory_error (status, addr);
+             inst = extract_unsigned_integer (buf, 4);
+             if (/* sw reg,n($sp) */
+                 (inst & 0xffe00000) == 0xafa00000
+
+                 /* sw reg,n($r30) */
+                 || (inst & 0xffe00000) == 0xafc00000)
+               {
+                 /* We assume that all saves are relative to the
+                    PROC_FRAME_REG, which is what we used to set up
+                    ->frame.  */
+                 int reg = (inst & 0x001f0000) >> 16;
+                 if (gen_mask & (1 << reg))
+                   fci->saved_regs.regs[reg] = fci->frame + (inst & 0xffff);
+                 gen_mask &= ~(1 << reg);
+               }
+             else if (/* swc1 freg,n($sp) */
+                      (inst & 0xffe00000) == 0xe7a00000
+
+                      /* swc1 freg,n($r30) */
+                      (inst & 0xffe00000) == 0xe7c00000)
+               {
+                 int reg = ((inst & 0x001f0000) >> 16);
+                 if (float_mask & (1 << reg))
+                   fci->saved_regs.regs[FP0_REGNUM + reg]
+                     = fci->frame + (inst & 0xffff);
+                 float_mask &= ~(1 << reg);
+               }
+           }
+       }
 
       /* hack: if argument regs are saved, guess these contain args */
       if ((PROC_REG_MASK(proc_desc) & 0xF0) == 0) fci->num_args = -1;
@@ -773,6 +815,7 @@ mips_frame_num_args(fip)
        return -1;
 }
 \f
+#if 0
 /* Is this a branch with a delay slot?  */
 static int
 is_delayed (insn)
@@ -788,6 +831,7 @@ is_delayed (insn)
                                       | INSN_COND_BRANCH_DELAY
                                       | INSN_COND_BRANCH_LIKELY)));
 }
+#endif
 
 /* To skip prologues, I use this predicate.  Returns either PC itself
    if the code at PC does not look like a function prologue; otherwise
@@ -822,8 +866,10 @@ mips_skip_prologue (pc, lenient)
          memory_error (status, pc + offset);
        inst = extract_unsigned_integer (buf, 4);
 
+#if 0
        if (lenient && is_delayed (inst))
          continue;
+#endif
 
        if ((inst & 0xffff0000) == 0x27bd0000)  /* addiu $sp,$sp,offset */
            seen_sp_adjust = 1;
@@ -874,6 +920,11 @@ mips_skip_prologue (pc, lenient)
 #endif
 }
 
+#if 0
+/* The lenient prologue stuff should be superceded by the code in
+   init_extra_frame_info which looks to see whether the stores mentioned
+   in the proc_desc have actually taken place.  */
+
 /* Is address PC in the prologue (loosely defined) for function at
    STARTADDR?  */
 
@@ -885,6 +936,7 @@ mips_in_lenient_prologue (startaddr, pc)
   CORE_ADDR end_prologue = mips_skip_prologue (startaddr, 1);
   return pc >= startaddr && pc < end_prologue;
 }
+#endif
 
 /* Given a return value in `regbuf' with a type `valtype', 
    extract and copy its value into `valbuf'.  */