From: Nikola Prica <nikola.prica@rt-rk.com>
To: Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>,
Kevin Buettner <kevinb@redhat.com>
Cc: gdb-patches@sourceware.org,
"Ananthakrishna Sowda (asowda)" <asowda@cisco.com>,
"Ivan Baev (ibaev)" <ibaev@cisco.com>,
'Nemanja Popov' <nemanja.popov@rt-rk.com>,
Djordje Todorovic <Djordje.Todorovic@rt-rk.com>,
Ulrich.Weigand@de.ibm.com
Subject: Re: [PING][PATCH] Fix for prologue processing on PowerPC
Date: Tue, 09 Jan 2018 11:22:00 -0000 [thread overview]
Message-ID: <f127aabe-a185-4ab2-0e3e-cc7776317646@rt-rk.com> (raw)
In-Reply-To: <87608p4dgr.fsf@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 3469 bytes --]
Hiello Pedro,
>> > - I think it's more clear to only set lr_register when needed (pc
>> > reaches the limit), as opposed to resetting it to -1 if pc didn't reach
>> > the limit.
>>
>> The body of condition that becomes visitable after this patch
>> invalidates lr_reg by setting it to -2 before reaching the limit.
>
> Sorry, I was referring to to fdata->lr_register. What I meant is that it
> seems better to me to only set fdata->lr_register to lr_reg >> 21 at the end
> of the function (as Kevin had suggested), as opposed to setting it to -1
> at the end of the function, in this part:
>
I didn't explain it right. The catch is that fdata->lr_register is set
by shifting lr_reg variable which is set only once and it can be
invalidated druing the loop iteration. For example, lets say that
firstly lr_reg is set to some value, then in some further loop iteration
the next code gets visited:
else if (lr_reg >= 0 &&
/* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
(((op & 0xffff0000) == (lr_reg | 0xf8010000)) ||
/* stw Rx, NUM(r1) */
((op & 0xffff0000) == (lr_reg | 0x90010000)) ||
/* stwu Rx, NUM(r1) */
((op & 0xffff0000) == (lr_reg | 0x94010000))))
{ /* where Rx == lr */
fdata->lr_offset = offset;
fdata->nosavedpc = 0;
/* Invalidate lr_reg, but don't set it to -1.
That would mean that it had never been set. */
lr_reg = -2;
This part of code was previously never visited because of lr_reg
shifting. The last line in upper code overwrites value of lr_reg. If in
the furtherer iteration lim_pc would be reached, -2 value would be
shifted and set to fdata->lr_register and that is not what we want.
>
> Previously if there was a mflr/stw sequence that invalidated lr_reg,
> fdata->lr_register would be -1 when the function exited, even if pc ==
> lim_pc (because of the second term of the condition).
>
Previously if there was s mflr/stw sequence lr_reg would never be
invalidated (set to -2) because part of the code that does this
invalidation was never visitable due to shifting of lr_reg. Invalidation
is performed so that the upper code never gets visited again in same
iteration. lr_reg is set only once and it's value is used only in the
condition of upper part of the code. In other conditions it is only
checked whether it is set (different than -1). The comment where lr_reg
is changed from -1 to some value says the following:
"remember just the first one, but skip over additional ones."
Which means that we need to deal only with one value of lr_reg. And the
fdata->lr_register basically saves the register number that we get by
shifting lr_reg.
>
> In any case, for this part to be correct, shouldn't the condition be the
> full complement of the original condition?
>
> That is,
>
> if (pc != lim_pc || lr_reg < 0)
>
> Which is the complement of:
>
> if (pc == lim_pc && lr_reg >= 0)
>
> Instead of:
>
>> + if (pc != lim_pc)
I've changed this condition to following:
if (pc != lim_pc && lr_reg != -1)
This is more appropriate condition because this condition requires
change of lr_reg.
> Still, I think it's safer to keep fdata->lr_register == -1 and set it at
> the end if needed.
>
This could be achieved by using one more variable that would be backup
for lr_reg in case it is set to -2. But I think that this approach with
setting it to -1 is more appropriate than that?
Thanks,
Nikola Prica
[-- Attachment #2: 0001-PATCH-Fix-for-prologue-processing-on-PowerPc.patch --]
[-- Type: text/x-patch, Size: 6391 bytes --]
From d93689d414137926818429fe0910ad9a9e6ef0dd Mon Sep 17 00:00:00 2001
From: Prica <nprica@rt-rk.com>
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 <http://www.gnu.org/licenses/>. */
+
+#include <ppc-asm.h>
+
+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 <http://www.gnu.org/licenses/>. */
+
+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 <http://www.gnu.org/licenses/>
+
+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
next prev parent reply other threads:[~2018-01-09 11:22 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-22 12:11 Nikola Prica
2017-10-05 2:01 ` Kevin Buettner
2017-10-26 10:02 ` [PING]Fix " Nikola Prica
2017-11-08 16:58 ` Kevin Buettner
2017-11-09 18:15 ` [PING][PATCH] Fix " Nikola Prica
2017-12-01 19:37 ` pedromfc
2017-12-19 15:57 ` Nikola Prica
2017-12-29 18:05 ` Pedro Franco de Carvalho
2018-01-09 11:22 ` Nikola Prica [this message]
2018-01-10 17:26 ` Pedro Franco de Carvalho
2018-01-11 15:12 ` Nikola Prica
2018-01-19 7:49 ` Nikola Prica
2018-01-19 19:01 ` Pedro Franco de Carvalho
2018-01-19 19:08 ` Pedro Franco de Carvalho
2018-01-27 14:32 ` Nikola Prica
2018-01-31 18:04 ` Pedro Franco de Carvalho
2018-01-31 18:28 ` Ulrich Weigand
2018-02-01 13:09 ` Nikola Prica
2018-01-02 10:29 ` Yao Qi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f127aabe-a185-4ab2-0e3e-cc7776317646@rt-rk.com \
--to=nikola.prica@rt-rk.com \
--cc=Djordje.Todorovic@rt-rk.com \
--cc=Ulrich.Weigand@de.ibm.com \
--cc=asowda@cisco.com \
--cc=gdb-patches@sourceware.org \
--cc=ibaev@cisco.com \
--cc=kevinb@redhat.com \
--cc=nemanja.popov@rt-rk.com \
--cc=pedromfc@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox