From: Daniel Jacobowitz Date: Tue, 13 Mar 2007 17:34:23 +0000 (+0000) Subject: * rs6000-tdep.c (rs6000_skip_prologue): Use skip_prologue_using_sal. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4e463ff5459d8c72eb1c5c1a7859e8556dbd69e2;p=binutils-gdb.git * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3766bc1643e..8624df056fa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2007-03-13 Daniel Jacobowitz + + * 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 * 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 25fa5508f64..cc2f074121b 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 f12834dd1cd..c427c98637a 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 9300ec35b4f..bfa0b8758af 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2007-03-13 Daniel Jacobowitz + + * 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 * 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 9f3836a6d6a..6dcec2fcf63 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 c50c56bb029..9bacb9997e8 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"