* stabsread.c (get_substring): Declare second arg as int.
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 2bd7127b12be33319d9d3a3d0338fa06e7610f6b..6a37d1a44b36a10565d0bed5cc0ceba3e394666c 100644 (file)
@@ -18,9 +18,10 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
+#include "gdb_string.h"
 #include "frame.h"
 #include "inferior.h"
 #include "symtab.h"
@@ -43,6 +44,15 @@ extern struct obstack frame_cache_obstack;
 static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
 #endif
 
+static void mips_print_register PARAMS ((int, int));
+
+static mips_extra_func_info_t
+heuristic_proc_desc PARAMS ((CORE_ADDR, CORE_ADDR, struct frame_info *));
+
+static CORE_ADDR heuristic_proc_start PARAMS ((CORE_ADDR));
+
+static int read_next_frame_reg PARAMS ((struct frame_info *, int));
+
 static void mips_set_fpu_command PARAMS ((char *, int,
                                          struct cmd_list_element *));
 
@@ -58,6 +68,12 @@ static void mips_show_processor_type_command PARAMS ((char *, int));
 static void reinit_frame_cache_sfunc PARAMS ((char *, int,
                                              struct cmd_list_element *));
 
+static mips_extra_func_info_t
+  find_proc_desc PARAMS ((CORE_ADDR pc, struct frame_info *next_frame));
+
+static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc,
+                                        mips_extra_func_info_t proc_desc));
+
 /* This value is the model of MIPS in use.  It is derived from the value
    of the PrID register.  */
 
@@ -185,6 +201,44 @@ struct linked_proc_info
 } *linked_proc_desc_table = NULL;
 
 \f
+
+/* This returns the PC of the first inst after the prologue.  If we can't
+   find the prologue, then return 0.  */
+
+static CORE_ADDR
+after_prologue (pc, proc_desc)
+     CORE_ADDR pc;
+     mips_extra_func_info_t proc_desc;
+{
+  struct symtab_and_line sal;
+  CORE_ADDR func_addr, func_end;
+
+  if (!proc_desc)
+    proc_desc = find_proc_desc (pc, NULL);
+
+  if (proc_desc)
+    {
+      /* If function is frameless, then we need to do it the hard way.  I
+        strongly suspect that frameless always means prologueless... */
+      if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+         && PROC_FRAME_OFFSET (proc_desc) == 0)
+       return 0;
+    }
+
+  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+    return 0;                  /* Unknown */
+
+  sal = find_pc_line (func_addr, 0);
+
+  if (sal.end < func_end)
+    return sal.end;
+
+  /* The line after the prologue is after the end of the function.  In this
+     case, tell the caller to find the prologue the hard way.  */
+
+  return 0;
+}
+
 /* Guaranteed to set fci->saved_regs to some values (it never leaves it
    NULL).  */
 
@@ -257,6 +311,11 @@ mips_find_saved_regs (fci)
       /* In a dummy frame we know exactly where things are saved.  */
       && !PROC_DESC_IS_DUMMY (proc_desc)
 
+      /* Don't bother unless we are inside a function prologue.  Outside the
+        prologue, we know where everything is. */
+
+      && in_prologue (fci->pc, PROC_LOW_ADDR (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
@@ -665,11 +724,22 @@ init_extra_frame_info(fci)
 
       if (proc_desc == &temp_proc_desc)
        {
-         fci->saved_regs = (struct frame_saved_regs*)
-           obstack_alloc (&frame_cache_obstack,
-                          sizeof (struct frame_saved_regs));
-         *fci->saved_regs = temp_saved_regs;
-         fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
+         char *name;
+
+         /* Do not set the saved registers for a sigtramp frame,
+            mips_find_saved_registers will do that for us.
+            We can't use fci->signal_handler_caller, it is not yet set.  */
+         find_pc_partial_function (fci->pc, &name,
+                                   (CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
+         if (!IN_SIGTRAMP (fci->pc, name))
+           {
+             fci->saved_regs = (struct frame_saved_regs*)
+               obstack_alloc (&frame_cache_obstack,
+                              sizeof (struct frame_saved_regs));
+             *fci->saved_regs = temp_saved_regs;
+             fci->saved_regs->regs[PC_REGNUM]
+               = fci->saved_regs->regs[RA_REGNUM];
+           }
        }
 
       /* hack: if argument regs are saved, guess these contain args */
@@ -1026,7 +1096,7 @@ mips_do_registers_info (regnum, fpregs)
     }
   else
     {
-      int did_newline;
+      int did_newline = 0;
 
       for (regnum = 0; regnum < NUM_REGS; )
        {
@@ -1117,6 +1187,19 @@ mips_skip_prologue (pc, lenient)
     int offset;
     int seen_sp_adjust = 0;
     int load_immediate_bytes = 0;
+    CORE_ADDR post_prologue_pc;
+
+    /* See if we can determine the end of the prologue via the symbol table.
+       If so, then return either PC, or the PC after the prologue, whichever
+       is greater.  */
+
+    post_prologue_pc = after_prologue (pc, NULL);
+
+    if (post_prologue_pc != 0)
+      return max (pc, post_prologue_pc);
+
+    /* Can't determine prologue from the symbol table, need to examine
+       instructions.  */
 
     /* Skip the typical prologue instructions. These are the stack adjustment
        instruction and the instructions that save registers on the stack
@@ -1272,10 +1355,6 @@ mips_store_return_value (valtype, valbuf)
   write_register_bytes(REGISTER_BYTE (regnum), raw_buffer, TYPE_LENGTH (valtype));
 }
 
-/* These exist in mdebugread.c.  */
-extern CORE_ADDR sigtramp_address, sigtramp_end;
-extern void fixup_sigtramp PARAMS ((void));
-
 /* Exported procedure: Is PC in the signal trampoline code */
 
 int
@@ -1426,7 +1505,7 @@ mips_read_processor_type ()
 
   prid = read_register (PRID_REGNUM);
 
-  if (prid & ~0xf == 0x700)
+  if ((prid & ~0xf) == 0x700)
     return savestring ("r3041", strlen("r3041"));
 
   return NULL;
This page took 0.025001 seconds and 4 git commands to generate.