From d93689d414137926818429fe0910ad9a9e6ef0dd Mon Sep 17 00:00:00 2001 From: Prica Date: Tue, 19 Dec 2017 14:29:09 +0100 Subject: [PATCH] [PATCH] Fix for prologue processing on PowerPc One of conditions in skip_prologue() is never visited because it expects non shifted `lr_reg`. That condtition is supposed to set PC offset. When body of this condition is visited PC offset is set and there will be no need to look for it in next frames nor to use frame unwind directives. gdb/ChangeLog: *rs600-tdep.c (skip_prologue): Remove shifting for lr_reg and assign shifted lr_reg to fdata->lr_register when lr_reg is set. If iteration do not hit lim_pc lr_register is set as -1. *testsuite/gdb.arch/ppc-prologue-frame.s: New file. *testsuite/gdb.arch/ppc-prologue-frame.c: Likewise. *testsuite/gdb.arch/ppr-prologue-frame.exp: Likewise. --- gdb/rs6000-tdep.c | 14 ++++--- gdb/testsuite/gdb.arch/powerpc-prologue-frame.S | 35 +++++++++++++++++ gdb/testsuite/gdb.arch/powerpc-prologue-frame.c | 28 ++++++++++++++ gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp | 47 +++++++++++++++++++++++ 4 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 gdb/testsuite/gdb.arch/powerpc-prologue-frame.S create mode 100644 gdb/testsuite/gdb.arch/powerpc-prologue-frame.c create mode 100644 gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 456dbcc..7bf4f60 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1655,9 +1655,13 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, remember just the first one, but skip over additional ones. */ if (lr_reg == -1) - lr_reg = (op & 0x03e00000) >> 21; - if (lr_reg == 0) - r0_contains_arg = 0; + { + lr_reg = (op & 0x03e00000); + fdata->lr_register = lr_reg >> 21; + } + if (lr_reg == 0) + r0_contains_arg = 0; + continue; } else if ((op & 0xfc1fffff) == 0x7c000026) @@ -2180,8 +2184,8 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, } #endif /* 0 */ - if (pc == lim_pc && lr_reg >= 0) - fdata->lr_register = lr_reg; + if (pc != lim_pc && lr_reg != -1) + fdata->lr_register = -1; fdata->offset = -fdata->offset; return last_prologue_pc; diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue-frame.S b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.S new file mode 100644 index 0000000..e30ca23 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.S @@ -0,0 +1,35 @@ +/* This test is part of GDB, the GNU debugger. + + Copyright 2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +FUNC_START(foo) + stwu 1,-32(1) + mflr 3 + stw 3,36(1) + stw 31,28(1) + mr 31,1 + bl bar + mr 9,3 + mr 3,9 + addi 11,31,32 + lwz 0,4(11) + mtlr 0 + lwz 31,-4(11) + mr 1,11 + blr +FUNC_END(foo) diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue-frame.c b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.c new file mode 100644 index 0000000..8cab6f2 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.c @@ -0,0 +1,28 @@ +/* This test is part of GDB, the GNU debugger. + + Copyright 2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +int bar() +{ + return 0; +} + +int foo(); + +int main(void) +{ + return foo(); +} diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp new file mode 100644 index 0000000..4f988db --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-prologue-frame.exp @@ -0,0 +1,47 @@ +# Copyright 2018 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see + +if {![istarget "powerpc*"] } { + verbose "Skipping powerpc back trace test." + return +} + +standard_testfile .c .S +set binfile [standard_output_file ${testfile}] + +if {![istarget "powerpc-*-*"]} then { + verbose "Skipping PowerPC instructions disassembly." + return -1 +} + + +if {[gdb_compile \ + [list ${srcdir}/${subdir}/$srcfile ${srcdir}/${subdir}/$srcfile2] \ + "${binfile}" executable {}] != ""} { + untested "failed to build $binfile" + return -1 +} + + +clean_restart ${binfile} + +if ![runto bar] { + untested "could not run to bar" + return -1 +} + +gdb_test "bt" \ + "#0\[ \t\]*$hex in bar.*\r\n#1\[ \t\]*$hex in foo.*\r\n#2\[ \t\]*$hex in main.*" \ + "Backtrace to the main frame" -- 2.7.4