aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-03-13 17:34:23 +0000
committerDaniel Jacobowitz <drow@false.org>2007-03-13 17:34:23 +0000
commit4e463ff5459d8c72eb1c5c1a7859e8556dbd69e2 (patch)
tree53db7049f2fd0de140d1c84c26136fbde1e65141
parent35d9dd2fb8ba23282114af75003ff0c2bee9661a (diff)
downloadgdb-4e463ff5459d8c72eb1c5c1a7859e8556dbd69e2.zip
gdb-4e463ff5459d8c72eb1c5c1a7859e8556dbd69e2.tar.gz
gdb-4e463ff5459d8c72eb1c5c1a7859e8556dbd69e2.tar.bz2
* rs6000-tdep.c (rs6000_skip_prologue): Use skip_prologue_using_sal.
(rs6000_in_function_epilogue_p): Use extract_unsigned_integer. (refine_prologue_limit): Delete. (skip_prologue): Don't call it. Use extract_unsigned_integer. Assume lim_pc is set. Correct check for incomplete prologues. Do not skip clobbers of the frame pointer. * symtab.c (skip_prologue_using_sal): Fail if there is only one sal. * gdb.arch/powerpc-prologue.c (optimized_1_marker, gdb2029_marker) (optimized_1): New. (main): Call optimized_1. (gdb2029): Correct typos. Call gdb2029_marker. * gdb.arch/powerpc-prologue.exp: Run new test. Use a breakpoint for gdb2029.
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/rs6000-tdep.c105
-rw-r--r--gdb/symtab.c2
-rw-r--r--gdb/testsuite/ChangeLog9
-rw-r--r--gdb/testsuite/gdb.arch/powerpc-prologue.c39
-rw-r--r--gdb/testsuite/gdb.arch/powerpc-prologue.exp32
6 files changed, 117 insertions, 81 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3766bc1..8624df0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2007-03-13 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * rs6000-tdep.c (rs6000_skip_prologue): Use skip_prologue_using_sal.
+ (rs6000_in_function_epilogue_p): Use extract_unsigned_integer.
+ (refine_prologue_limit): Delete.
+ (skip_prologue): Don't call it. Use extract_unsigned_integer.
+ Assume lim_pc is set. Correct check for incomplete prologues.
+ Do not skip clobbers of the frame pointer.
+ * symtab.c (skip_prologue_using_sal): Fail if there is only one
+ sal.
+
2007-03-13 Nathan Froyd <froydnj@codesourcery.com>
* frame.c (frame_pop): Check to see whether there's a frame to
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 25fa550..cc2f074 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -482,7 +482,29 @@ static CORE_ADDR
rs6000_skip_prologue (CORE_ADDR pc)
{
struct rs6000_framedata frame;
- pc = skip_prologue (pc, 0, &frame);
+ CORE_ADDR limit_pc, func_addr;
+
+ /* 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. */
+ if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+ {
+ CORE_ADDR post_prologue_pc = skip_prologue_using_sal (func_addr);
+ if (post_prologue_pc != 0)
+ return max (pc, post_prologue_pc);
+ }
+
+ /* Can't determine prologue from the symbol table, need to examine
+ instructions. */
+
+ /* Find an upper limit on the function prologue using the debug
+ information. If the debug information could not be used to provide
+ that bound, then use an arbitrary large number as the upper bound. */
+ limit_pc = skip_prologue_using_sal (pc);
+ if (limit_pc == 0)
+ limit_pc = pc + 100; /* Magic. */
+
+ pc = skip_prologue (pc, limit_pc, &frame);
return pc;
}
@@ -565,7 +587,7 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
return 0;
- insn = extract_signed_integer (insn_buf, PPC_INSN_SIZE);
+ insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
if (insn == 0x4e800020)
break;
if (insn_changes_sp_or_jumps (insn))
@@ -580,7 +602,7 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (!safe_frame_unwind_memory (curfrm, scan_pc, insn_buf, PPC_INSN_SIZE))
return 0;
- insn = extract_signed_integer (insn_buf, PPC_INSN_SIZE);
+ insn = extract_unsigned_integer (insn_buf, PPC_INSN_SIZE);
if (insn_changes_sp_or_jumps (insn))
return 1;
}
@@ -775,57 +797,6 @@ rs6000_software_single_step (enum target_signal signal,
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. */
-
-/* FIXME: cagney/2004-02-14: This function and logic have largely been
- superseded by skip_prologue_using_sal. */
-
-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;
-}
-
/* Return nonzero if the given instruction OP can be part of the prologue
of a function and saves a parameter on the stack. FRAMEP should be
set if one of the previous instructions in the function has set the
@@ -945,21 +916,6 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
int r0_contains_arg = 0;
const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-
- /* Attempt to find the end of the prologue when no limit is specified.
- Note that refine_prologue_limit() has been written so that it may
- be used to "refine" the limits of non-zero PC values too, but this
- is only safe if we 1) trust the line information provided by the
- compiler and 2) iterate enough to actually find the end of the
- prologue.
-
- It may become a good idea at some point (for both performance and
- accuracy) to unconditionally call refine_prologue_limit(). But,
- until we can make a clear determination that this is beneficial,
- we'll play it safe and only use it to obtain a limit when none
- has been specified. */
- if (lim_pc == 0)
- lim_pc = refine_prologue_limit (pc, lim_pc);
memset (fdata, 0, sizeof (struct rs6000_framedata));
fdata->saved_gpr = -1;
@@ -980,7 +936,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
last_prologue_pc = pc;
/* Stop scanning if we've hit the limit. */
- if (lim_pc != 0 && pc >= lim_pc)
+ if (pc >= lim_pc)
break;
prev_insn_was_prologue_insn = 1;
@@ -988,7 +944,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
/* Fetch the instruction and convert it to an integer. */
if (target_read_memory (pc, buf, 4))
break;
- op = extract_signed_integer (buf, 4);
+ op = extract_unsigned_integer (buf, 4);
if ((op & 0xfc1fffff) == 0x7c0802a6)
{ /* mflr Rx */
@@ -1221,9 +1177,11 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
offset = fdata->offset;
continue;
}
- /* Load up minimal toc pointer */
+ /* Load up minimal toc pointer. Do not treat an epilogue restore
+ of r31 as a minimal TOC load. */
else if (((op >> 22) == 0x20f || /* l r31,... or l r30,... */
(op >> 22) == 0x3af) /* ld r31,... or ld r30,... */
+ && !framep
&& !minimal_toc_loaded)
{
minimal_toc_loaded = 1;
@@ -1446,8 +1404,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
Handle optimizer code motions into the prologue by continuing
the search if we have no valid frame yet or if the return
address is not yet saved in the frame. */
- if (fdata->frameless == 0
- && (lr_reg == -1 || fdata->nosavedpc == 0))
+ if (fdata->frameless == 0 && fdata->nosavedpc == 0)
break;
if (op == 0x4e800020 /* blr */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index f12834d..c427c98 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4092,7 +4092,7 @@ skip_prologue_using_sal (CORE_ADDR func_addr)
then it is probably a single line function, like
"foo(){}". */
if (prologue_sal.end == end_pc)
- return start_pc;
+ return 0;
while (prologue_sal.end < end_pc)
{
struct symtab_and_line sal;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 9300ec3..bfa0b87 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2007-03-13 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * gdb.arch/powerpc-prologue.c (optimized_1_marker, gdb2029_marker)
+ (optimized_1): New.
+ (main): Call optimized_1.
+ (gdb2029): Correct typos. Call gdb2029_marker.
+ * gdb.arch/powerpc-prologue.exp: Run new test. Use a breakpoint
+ for gdb2029.
+
2007-03-12 Mark Kettenis <kettenis@gnu.org>
* gdb.gdb/selftest.exp (do_steps_and_nexts): Match spaces as well
diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue.c b/gdb/testsuite/gdb.arch/powerpc-prologue.c
index 9f3836a..6dcec2f 100644
--- a/gdb/testsuite/gdb.arch/powerpc-prologue.c
+++ b/gdb/testsuite/gdb.arch/powerpc-prologue.c
@@ -31,23 +31,54 @@ int
main (void)
{
gdb2029 ();
+ optimized_1 ();
return 0;
}
+void
+optimized_1_marker (void)
+{
+}
+
+void
+gdb2029_marker (void)
+{
+}
+
/* A typical PIC prologue from GCC. */
asm(".text\n"
- " .align 8\n"
+ " .p2align 3\n"
SYMBOL (gdb2029) ":\n"
- " stw %r1, -32(%r1)\n"
+ " stwu %r1, -32(%r1)\n"
" mflr %r0\n"
" bcl- 20,31,.+4\n"
" stw %r30, 24(%r1)\n"
" mflr %r30\n"
" stw %r0, 36(%r1)\n"
- " twge %r2, %r2\n"
+ " bl gdb2029_marker\n"
" lwz %r0, 36(%r1)\n"
" lwz %r30, 24(%r1)\n"
" mtlr %r0\n"
- " addi %r0, %r0, 32\n"
+ " addi %r1, %r1, 32\n"
+ " blr");
+
+/* A heavily scheduled prologue. */
+asm(".text\n"
+ " .p2align 3\n"
+ SYMBOL (optimized_1) ":\n"
+ " stwu %r1,-32(%r1)\n"
+ " lis %r9,-16342\n"
+ " lis %r11,-16342\n"
+ " mflr %r0\n"
+ " addi %r11,%r11,3776\n"
+ " stmw %r27,12(%r1)\n"
+ " addi %r31,%r9,3152\n"
+ " cmplw %cr7,%r31,%r11\n"
+ " stw %r0,36(%r1)\n"
+ " mr %r30,%r3\n"
+ " bl optimized_1_marker\n"
+ " lwz %r0,36(%r1)\n"
+ " lmw %r27,12(%r1)\n"
+ " addi %r1,%r1,32\n"
" blr");
diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue.exp b/gdb/testsuite/gdb.arch/powerpc-prologue.exp
index c50c56b..9bacb99 100644
--- a/gdb/testsuite/gdb.arch/powerpc-prologue.exp
+++ b/gdb/testsuite/gdb.arch/powerpc-prologue.exp
@@ -50,12 +50,40 @@ if ![runto_main] then {
# Testcase for PIC prologue.
-gdb_test "continue" "Program received signal SIGTRAP.*" "continue to PIC"
+gdb_breakpoint "gdb2029_marker"
+gdb_test "continue" "Breakpoint $decimal, $hex in gdb2029_marker \\(\\)" \
+ "continue to PIC"
gdb_test "backtrace 10" \
- "#0\[ \t\]*$hex in gdb2029.*\r\n#1\[ \t\]*$hex in main.*" \
+ "#0\[ \t\]*$hex in gdb2029_marker.*\r\n#1\[ \t\]*$hex in gdb2029.*\r\n#2\[ \t\]*$hex in main.*" \
+ "backtrace in PIC marker"
+
+gdb_test "finish" ".*$hex in gdb2029 .*" "finish from PIC"
+
+gdb_test "backtrace 10" \
+ "#0\[ \t\]*$hex in gdb2029 .*\r\n#1\[ \t\]*$hex in main.*" \
"backtrace in PIC"
gdb_test "info frame" \
".*Saved registers:.*r30 at.*r31 at.*pc at.*lr at.*" \
"saved registers in PIC"
+
+# Testcase for scheduled prologue.
+
+gdb_breakpoint "optimized_1_marker"
+gdb_test "continue" "Breakpoint $decimal, $hex in optimized_1_marker \\(\\)" \
+ "continue to optimized"
+
+gdb_test "backtrace 10" \
+ "#0\[ \t\]*$hex in optimized_1_marker.*\r\n#1\[ \t\]*$hex in optimized_1.*\r\n#2\[ \t\]*$hex in main.*" \
+ "backtrace in optimized marker"
+
+gdb_test "finish" ".*$hex in optimized_1 .*" "finish from optimized"
+
+gdb_test "backtrace 10" \
+ "#0\[ \t\]*$hex in optimized_1 .*\r\n#1\[ \t\]*$hex in main.*" \
+ "backtrace in optimized"
+
+gdb_test "info frame" \
+ ".*Saved registers:.*r30 at.*r31 at.*pc at.*lr at.*" \
+ "saved registers in optimized"