This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Improve Sparc epilogue analysis



Unlike other ports, Sparc only had a manual prologue discovery
mechanism.  Most other port have a manual prologue examiner, but they
also first try to use line number information.

To this end, we look for line number information (the first two ".loc"
entries for a function have the same line number, the second one
begins at the end of the prologue) and if found we use it.  Else
we just drop into the existing code.

Also, in sparc_init_extra_frame_info we were using grotty code to find
out if the save instruction in the prologue had executed yet.
Firstly, this relied on the debugging info being there.  Secondly
such things need to be done within the prologue range only, and
examine_prologue was created to figure this out.

Due to a bug in dwarf2 gas up until a week ago, gas would eliminate
these duplicate .loc entries used for prologue discovery by accident.

For those of you playing at home:

		sparc32			sparc64
failures before	88			124
failures after	83			111

More to come.

2002-04-19  David S. Miller  <davem@redhat.com>

	* sparc-tdep.c (examine_prologue): Put forward declaration before
	sparc_init_extra_frame_info.
	(sparc_init_extra_frame_info): Use it to determine if the save
	instruction has been executed yet instead of solely relying upon
	line number information.  Some versions of gas delete duplicates.
	(examine_prologue): Use line number information to find end of
	prologue, if available.  Else, use existing by-hand insn
	examination.

--- sparc-tdep.c.~1~	Fri Apr 19 23:03:54 2002
+++ sparc-tdep.c	Fri Apr 19 23:53:57 2002
@@ -279,6 +279,9 @@ struct frame_extra_info 
   int sp_offset;
 };
 
+static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *,
+				   CORE_ADDR *);
+
 /* Call this for each newly created frame.  For SPARC, we need to
    calculate the bottom of the frame, and do some extra work if the
    prologue has been generated via the -mflat option to GCC.  In
@@ -393,25 +396,20 @@ sparc_init_extra_frame_info (int fromlea
 	     to the current value of the stack pointer and set
 	     the in_prologue flag.  */
 	  CORE_ADDR addr;
-	  struct symtab_and_line sal;
 
-	  sal = find_pc_line (prologue_start, 0);
-	  if (sal.line == 0)	/* no line info, use PC */
-	    prologue_end = fi->pc;
-	  else if (sal.end < prologue_end)
-	    prologue_end = sal.end;
+	  prologue_end = examine_prologue (prologue_start, 0, NULL, NULL);
 	  if (fi->pc < prologue_end)
 	    {
-	      for (addr = prologue_start; addr < fi->pc; addr += 4)
+	      for (addr = fi->pc; addr < prologue_end; addr += 4)
 		{
 		  insn = read_memory_integer (addr, 4);
 		  if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
 		    break;	/* SAVE seen, stop searching */
 		}
-	      if (addr >= fi->pc)
+	      if (addr < prologue_end)
 		{
 		  fi->extra_info->in_prologue = 1;
-		  fi->frame = read_register (SP_REGNUM);
+		  fi->frame = read_sp ();
 		}
 	    }
 	}
@@ -546,9 +544,6 @@ setup_arbitrary_frame (int argc, CORE_AD
    This routine should be more specific in its actions; making sure
    that it uses the same register in the initial prologue section.  */
 
-static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *,
-				   CORE_ADDR *);
-
 static CORE_ADDR
 examine_prologue (CORE_ADDR start_pc, int frameless_p, struct frame_info *fi,
 		  CORE_ADDR *saved_regs)
@@ -557,7 +552,21 @@ examine_prologue (CORE_ADDR start_pc, in
   int dest = -1;
   CORE_ADDR pc = start_pc;
   int is_flat = 0;
+  struct symtab_and_line sal;
+  CORE_ADDR func_start, func_end;
+
+  /* This is the preferred method, find the end of the prologue by
+     using the debugging information.  */
+  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
+    {
+      sal = find_pc_line (func_start, 0);
+
+      if (sal.end < func_end
+	  && start_pc <= sal.end)
+	return sal.end;
+    }
 
+  /* Oh well, examine the code by hand.  */
   insn = fetch_instruction (pc);
 
   /* Recognize the `sethi' insn and record its destination.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]