This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFC] frv-tdep.c: Use refine_prologue_limit() instead ofskip_prologue_using_sal()
- From: Kevin Buettner <kevinb at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Fri, 30 Jul 2004 15:24:19 -0700
- Subject: [RFC] frv-tdep.c: Use refine_prologue_limit() instead ofskip_prologue_using_sal()
- Organization: Red Hat
On FR-V, I've encountered an optimized prologue in which
skip_prologue_using_sal() fails to making it past the first
prologue -> body transition. The prologue in question is not all that
unusual (for an optimized prologue) which leads me to wonder about the
efficacy of skip_prologue_using_sal() with regard to optimized
prologues in general. I've read the comments and code in
skip_prologue_using_sal(), however, and it does seem to be operating
as intended.
That said, it seems like a shame to introduce yet another private copy
of refine_prologue_limit(). (Though I was careful to keep this one
the same as that defined in rs6000-tdep.c. The IA-64 version differs
slightly.) Perhaps it's time to move refine_prologue_limit to
symtab.c? Or perhaps skip_prologue_using_sal() should be revised
somewhat so that it provides more useful results?
Comments?
* frv-tdep.c (max_skip_non_prologue_insns): New static global.
(refine_prologue_limit): New function copied verbatim from
rs6000-tdep.c.
(frv_analyze_prologue): Use refine_prologue_limit() instead of
skip_prologue_using_sal().
Index: frv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/frv-tdep.c,v
retrieving revision 1.87
diff -u -p -r1.87 frv-tdep.c
--- frv-tdep.c 20 Jul 2004 19:45:05 -0000 1.87
+++ frv-tdep.c 30 Jul 2004 21:25:10 -0000
@@ -504,6 +504,64 @@ is_argument_reg (int reg)
return (8 <= reg && reg <= 13);
}
+/* Limit the number of skipped non-prologue instructions, as the examining
+ of the prologue is expensive. */
+static int max_skip_non_prologue_insns = 10;
+
+/* Given PC representing the starting address of a function, and
+ LIM_PC which is the (sloppy) limit to which to scan when looking
+ for a prologue, attempt to further refine this limit by using
+ the line data in the symbol table. If successful, a better guess
+ on where the prologue ends is returned, otherwise the previous
+ value of lim_pc is returned. */
+
+/* Note: cagney/2004-02-14: This function and logic have largely been
+ superseded by skip_prologue_using_sal.
+ Note: kevinb/2004-07-29: Not true. On FR-V, I've encountered a
+ case where skip_prologue_using_sal() doesn't make it past the
+ first prologue -> body transition. */
+
+static CORE_ADDR
+refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc)
+{
+ struct symtab_and_line prologue_sal;
+
+ prologue_sal = find_pc_line (pc, 0);
+ if (prologue_sal.line != 0)
+ {
+ int i;
+ CORE_ADDR addr = prologue_sal.end;
+
+ /* Handle the case in which compiler's optimizer/scheduler
+ has moved instructions into the prologue. We scan ahead
+ in the function looking for address ranges whose corresponding
+ line number is less than or equal to the first one that we
+ found for the function. (It can be less than when the
+ scheduler puts a body instruction before the first prologue
+ instruction.) */
+ for (i = 2 * max_skip_non_prologue_insns;
+ i > 0 && (lim_pc == 0 || addr < lim_pc);
+ i--)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (addr, 0);
+ if (sal.line == 0)
+ break;
+ if (sal.line <= prologue_sal.line
+ && sal.symtab == prologue_sal.symtab)
+ {
+ prologue_sal = sal;
+ }
+ addr = sal.end;
+ }
+
+ if (lim_pc == 0 || prologue_sal.end < lim_pc)
+ lim_pc = prologue_sal.end;
+ }
+ return lim_pc;
+}
+
/* Scan an FR-V prologue, starting at PC, until frame->PC.
If FRAME is non-zero, fill in its saved_regs with appropriate addresses.
We assume FRAME's saved_regs array has already been allocated and cleared.
@@ -573,17 +631,18 @@ frv_analyze_prologue (CORE_ADDR pc, stru
last_prologue_pc = pc;
- /* Try to compute an upper limit (on how far to scan) based on the
- line number info. */
- lim_pc = skip_prologue_using_sal (pc);
- /* If there's no line number info, lim_pc will be 0. In that case,
- set the limit to be 100 instructions away from pc. Hopefully, this
- will be far enough away to account for the entire prologue. Don't
- worry about overshooting the end of the function. The scan loop
- below contains some checks to avoid scanning unreasonably far. */
+ /* Set the initial limit to be 100 instructions away from pc.
+ Hopefully, this will be far enough away to account for the entire
+ prologue. Don't worry about overshooting the end of the
+ function. The scan loop below contains some checks to avoid
+ scanning unreasonably far. */
if (lim_pc == 0)
lim_pc = pc + 400;
+ /* Attempt to refine (reduce) the limit based on available line number
+ info. */
+ lim_pc = refine_prologue_limit (pc, lim_pc);
+
/* If we have a frame, we don't want to scan past the frame's pc. This
will catch those cases where the pc is in the prologue. */
if (next_frame)