RFA: Adjust PowerPC prologue analyzer for PIC

Daniel Jacobowitz
2005-12-11T17:15:45Z

This patch is based on Till's patch from GNATS. One of the three changes
(b1 in the diff attached to 2029) was fixed independently by Michael Snyder
last year, but I think it needs a small improvement: there's a comment that
says "skip over additional [mflr instructions]", and checks lr_reg < 0. Now
that should be lr_reg == -1, since -2 means we've seen one and stored it.

(a) seems right - we should recognize "bcl 20,31,.+4" as a skippable
prologue instruction. GCC generates this for PIC code, and in fact
backtracing out of shared libraries on GNU/Linux works badly without
recognizing this instruction. I left out recognition for the equivalent bc
instruction. Is there any reason I'm missing why this should be generated?

I left out (b) because I'm not sure that it's correct, and I don't have a
testcase for it. That changed

! && (lr_reg == -1 || fdata->nosavedpc == 0))
to
! && (fdata->nosavedpc == 0))

but if lr_reg is -1, meaning we haven't seen an mflr, maybe we won't. I
guess that's necessary only in the case where instructions get scheduled
before the mflr? If you still believe that's correct, let's try it
separately.

I've tested this patch on powerpc-linux, where it showed no change in the
testsuite results. It also fixes Debian bug #312059.

Is this patch OK?

--
Daniel Jacobowitz
CodeSourcery, LLC

2005-12-10 Daniel Jacobowitz <dan@codesourcery.com>

PR tdep/2029
Suggested by Till Straumann <strauman@slac.stanford.edu>:
* rs6000-tdep.c (skip_prologue): Update check for later mtlr
instructions. Handle PIC bcl.

Index: gdb-6.4/gdb/rs6000-tdep.c
===================================================================
--- gdb-6.4.orig/gdb/rs6000-tdep.c 2005-11-01 14:32:36.000000000 -0500
+++ gdb-6.4/gdb/rs6000-tdep.c 2005-12-10 00:22:15.000000000 -0500
@@ -911,7 +911,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR l

remember just the first one, but skip over additional
ones. */
- if (lr_reg < 0)
+ if (lr_reg == -1)
lr_reg = (op & 0x03e00000);
if (lr_reg == 0)
r0_contains_arg = 0;
@@ -1024,6 +1024,13 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR l
continue;

}
+ else if ((op & 0xfe80ffff) == 0x42800005 && lr_reg != -1)
+ {
+ /* bcl 20,xx,.+4 is used to get the current PC, with or without
+ prediction bits. If the LR has already been saved, we can
+ skip it. */
+ continue;
+ }
else if (op == 0x48000005)
{ /* bl .+4 used in
-mrelocatable */