OSDN Git Service

2003-11-22 Andrew Cagney <cagney@redhat.com>
authorcagney <cagney>
Sat, 22 Nov 2003 21:12:24 +0000 (21:12 +0000)
committercagney <cagney>
Sat, 22 Nov 2003 21:12:24 +0000 (21:12 +0000)
* mips-tdep.c (skip_prologue_using_sal): New function.
(mips32_skip_prologue, mips16_skip_prologue): Use
skip_prologue_using_sal to get an upper bound on the search.

gdb/ChangeLog
gdb/mips-tdep.c

index 21a7720..368d960 100644 (file)
@@ -1,5 +1,9 @@
 2003-11-22  Andrew Cagney  <cagney@redhat.com>
 
+       * mips-tdep.c (skip_prologue_using_sal): New function.
+       (mips32_skip_prologue, mips16_skip_prologue): Use
+       skip_prologue_using_sal to get an upper bound on the search.
+
        * config/powerpc/tm-linux.h (PROLOGUE_FIRSTLINE_OVERLAP): Delete
        #if 0'ed macro.
        * infrun.c (step_into_function): Delete #ifdef
index 720c0ce..3ba9e28 100644 (file)
@@ -4307,6 +4307,61 @@ mips_step_skips_delay (CORE_ADDR pc)
 }
 
 
+/* Given PC at the function's start address, attempt to find the
+   prologue end using SAL information.  Return zero if the skip fails.
+
+   A non-optimized prologue traditionally has one SAL for the function
+   and a second for the function body.  A single line function has
+   them both pointing at the same line.
+
+   An optimized prologue is similar but the prologue may contain
+   instructions (SALs) from the instruction body.  Need to skip those
+   while not getting into the function body.
+
+   The functions end point and an increasing SAL line are used as
+   indicators of the prologue's endpoint.
+
+   This code is based on the function refine_prologue_limit (versions
+   found in both ia64 and ppc).  */
+
+static CORE_ADDR
+skip_prologue_using_sal (CORE_ADDR func_addr)
+{
+  struct symtab_and_line prologue_sal;
+  CORE_ADDR start_pc;
+  CORE_ADDR end_pc;
+
+  /* Get an initial range for the function.  */
+  find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
+  start_pc += FUNCTION_START_OFFSET;
+
+  prologue_sal = find_pc_line (start_pc, 0);
+  if (prologue_sal.line != 0)
+    {
+      while (prologue_sal.end < end_pc)
+       {
+         struct symtab_and_line sal;
+
+         sal = find_pc_line (prologue_sal.end, 0);
+         if (sal.line == 0)
+           break;
+         /* Assume that a consecutive SAL for the same (or larger)
+             line mark the prologue -> body transition.  */
+         if (sal.line >= prologue_sal.line)
+           break;
+         /* The case in which compiler's optimizer/scheduler has
+            moved instructions into the prologue.  We look ahead in
+            the function looking for address ranges whose
+            corresponding line number is less the first one that we
+            found for the function.  This is more conservative then
+            refine_prologue_limit which scans a large number of SALs
+            looking for any in the prologue */
+         prologue_sal = sal;
+       }
+    }
+  return prologue_sal.end;
+}
+
 /* Skip the PC past function prologue instructions (32-bit version).
    This is a helper function for mips_skip_prologue.  */
 
@@ -4318,10 +4373,15 @@ mips32_skip_prologue (CORE_ADDR pc)
   int seen_sp_adjust = 0;
   int load_immediate_bytes = 0;
 
+  /* Find an upper bound on the prologue.  */
+  end_pc = skip_prologue_using_sal (pc);
+  if (end_pc == 0)
+    end_pc = pc + 100; /* Magic.  */
+
   /* Skip the typical prologue instructions. These are the stack adjustment
      instruction and the instructions that save registers on the stack
      or in the gcc frame.  */
-  for (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN)
+  for (; pc < end_pc; pc += MIPS_INSTLEN)
     {
       unsigned long high_word;
 
@@ -4463,10 +4523,15 @@ mips16_skip_prologue (CORE_ADDR pc)
     }                          /* end of table marker */
   };
 
+  /* Find an upper bound on the prologue.  */
+  end_pc = skip_prologue_using_sal (pc);
+  if (end_pc == 0)
+    end_pc = pc + 100; /* Magic.  */
+
   /* Skip the typical prologue instructions. These are the stack adjustment
      instruction and the instructions that save registers on the stack
      or in the gcc frame.  */
-  for (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN)
+  for (; pc < end_pc; pc += MIPS16_INSTLEN)
     {
       unsigned short inst;
       int i;