Re: [patch] Strange stepping behaviour with ppc32 with secure PLTs

Alan Modra
2006-05-15T00:56:26Z

On Sat, May 13, 2006 at 10:58:29AM -0400, Daniel Jacobowitz wrote:
> On Sun, May 14, 2006 at 12:01:41AM +0930, Alan Modra wrote:
> > Not too hard, but messy. The only real difficulty is finding the stubs.
> > We don't have any handy symbols or relocs to identify them, so that
> > means code reading.
> >
> > We do have --emit-stub-syms to emit symbols on stubs at link time. I
> > probably should have made the linker always emit the first stub sym so
> > we could easily find all the stubs.

In thinking about this some more, I remembered why I didn't implement
synthetic stub syms for powerpc. There is a really difficult problem
with -fPIC code, which can have multiple GOTs. The stubs for -fPIC
-shared or -fPIC -pie code calculate the plt entry from the got pointer
used by the calling function. That means we might need multiple stubs
for any given plt entry. eg. printf called from f1 and f2 where f1 uses
a different GOT to f2 will require two stubs and one .plt entry. So we
can't just start from the first stub and match one for one with plt
entries. Worse, code reading the stub doesn't give us a clue about the
got pointer value. So BFD can't match stubs to plt entries without
finding where the stub is falled *from*, and then analysing the function
prologue. This is way too hard.

> Hmm. Do they still end up in a section named .plt? That'd probably
> make it easier for both gdb and binutils.

No. If people use the default linker scripts, stubs are at the end of
.text. .plt is just an array of addresses.

> > > The right thing to do then is probably to create the synthetic symbols
> > > at exactly those same addresses.
> >
> > No, if I understand correctly, Paul wants to use a stub symbol as a
> > means of letting gdb know that it is in a plt call trampoline. Putting
> > the symbol in .plt won't do that for you. Best just teach gdb what a
> > plt call stub looks like.
>
> There's two things necessary to make stepping and shared libraries play
> nice.
>
> 1. Be able to unwind from the stub, so that we can see we've stepped
> into something. We need symbols or some other similar code reading in
> order to make this work.
>
> 2. Be able to identify this debug-info-less block of code as a stub,
> so that we can skip it if we're going to step into a shared library
> function that has debug info. I pointed Paul at the right function for
> handling this earlier, but it's somewhat orthogonal.

I think code reading is the way to go on both of these. Presumably gdb
knows the register state for both of these problems, so finding the
caller (from lr) isn't hard, and you reach the callee just by
single-stepping a few insns.

-shared and -pie stubs look like:

lwz 11,(plt_entry-got_pointer)(30)
mtctr 11
bctr
nop

or

addis 11,30,(plt_entry-got_pointer)@ha
lwz 11,(plt_entry-got_pointer)@l(11)
mtctr 11
bctr

depending on the size of (plt_entry-got_pointer).

Non-shared, non-pie stubs look like:

lis 11,plt_entry@ha
lwz 11,plt_entry@l(11)
mtctr
bctr

These sequences are different to those emitted by gcc for indirect
function calls.

--
Alan Modra
IBM OzLabs - Linux Technology Centre