Tue Sep 28 09:45:38 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index f006fccd75dea584c45d5f220a00702009fc80c0..82371aaecc3ffe68ccc286134ce345c6710c78ee 100644 (file)
@@ -187,8 +187,8 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
     unsigned long reg_mask = 0;
 
     if (start_pc == 0) return NULL;
-    bzero(&temp_proc_desc, sizeof(temp_proc_desc));
-    bzero(&temp_saved_regs, sizeof(struct frame_saved_regs));
+    memset(&temp_proc_desc, '\0', sizeof(temp_proc_desc));
+    memset(&temp_saved_regs, '\0', sizeof(struct frame_saved_regs));
     PROC_LOW_ADDR(&temp_proc_desc) = start_pc;
 
     if (start_pc + 200 < limit_pc) limit_pc = start_pc + 200;
@@ -341,8 +341,22 @@ mips_frame_chain(frame)
       return 0;
 
     cached_proc_desc = proc_desc;
-    return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
-      + PROC_FRAME_OFFSET(proc_desc);
+
+    /* If no frame pointer and frame size is zero, we must be at end
+       of stack (or otherwise hosed).  If we don't check frame size,
+       we loop forever if we see a zero size frame.  */
+    if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+       && PROC_FRAME_OFFSET (proc_desc) == 0
+       /* Frameless functions, which can happen on the innermost frame
+          or a frame which was innermost when a signal happened, can
+          have frame size zero.  No need to check for non-frameless
+          functions in these situations, though (I don't think).  */
+       && frame->next != NULL
+       && !frame->next->signal_handler_caller)
+      return 0;
+    else
+      return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
+       + PROC_FRAME_OFFSET(proc_desc);
 }
 
 void
@@ -762,7 +776,7 @@ mips_frame_num_args(fip)
        return -1;
 }
 \f
-/* Does this instruction involve use of a delay slot?  */
+/* Is this a branch with a delay slot?  */
 static int
 is_delayed (insn)
      unsigned long insn;
@@ -772,7 +786,10 @@ is_delayed (insn)
     if (mips_opcodes[i].pinfo != INSN_MACRO
        && (insn & mips_opcodes[i].mask) == mips_opcodes[i].match)
       break;
-  return i < NUMOPCODES && (mips_opcodes[i].pinfo & ANY_DELAY);
+  return (i < NUMOPCODES
+         && (mips_opcodes[i].pinfo & (INSN_UNCOND_BRANCH_DELAY
+                                      | INSN_COND_BRANCH_DELAY
+                                      | INSN_COND_BRANCH_LIKELY)));
 }
 
 /* To skip prologues, I use this predicate.  Returns either PC itself
@@ -910,12 +927,28 @@ mips_store_return_value (valtype, valbuf)
   write_register_bytes(REGISTER_BYTE (regnum), raw_buffer, TYPE_LENGTH (valtype));
 }
 
-/* Let the user turn off floating point and set the fence post for
-   heuristic_proc_start.  */
+static void reinit_frame_cache_sfunc PARAMS ((char *, int,
+                                             struct cmd_list_element *));
+
+/* Just like reinit_frame_cache, but with the right arguments to be
+   callable as an sfunc.  */
+static void
+reinit_frame_cache_sfunc (args, from_tty, c)
+     char *args;
+     int from_tty;
+     struct cmd_list_element *c;
+{
+  reinit_frame_cache ();
+}
 
 void
 _initialize_mips_tdep ()
 {
+  struct cmd_list_element *c;
+
+  /* Let the user turn off floating point and set the fence post for
+     heuristic_proc_start.  */
+
   add_show_from_set
     (add_set_cmd ("mipsfpu", class_support, var_boolean,
                  (char *) &mips_fpu,
@@ -924,14 +957,19 @@ Turn off to avoid using floating point instructions when calling functions\n\
 or dealing with return values.", &setlist),
      &showlist);
 
-  add_show_from_set
-    (add_set_cmd ("heuristic-fence-post", class_support, var_uinteger,
-                 (char *) &heuristic_fence_post,
-                 "\
+  /* We really would like to have both "0" and "unlimited" work, but
+     command.c doesn't deal with that.  So make it a var_zinteger
+     because the user can always use "999999" or some such for unlimited.  */
+  c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger,
+                  (char *) &heuristic_fence_post,
+                  "\
 Set the distance searched for the start of a function.\n\
 If you are debugging a stripped executable, GDB needs to search through the\n\
 program for the start of a function.  This command sets the distance of the\n\
 search.  The only need to set it is when debugging a stripped executable.",
-                 &setlist),
-     &showlist);
+                  &setlist);
+  /* We need to throw away the frame cache when we set this, since it
+     might change our ability to get backtraces.  */
+  c->function.sfunc = reinit_frame_cache_sfunc;
+  add_show_from_set (c, &showlist);
 }
This page took 0.026725 seconds and 4 git commands to generate.