From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Subject: Re: possible bug in setjmp implementation for ppc64
Date: Wed, 2 Aug 2017 10:46:12 -0400 [thread overview]
Message-ID: <20170802144612.GI1627@brightrain.aerifal.cx> (raw)
In-Reply-To: <20170802133825.GB5455@dora.lan>
On Wed, Aug 02, 2017 at 08:38:25AM -0500, Bobby Bingham wrote:
> On Wed, Aug 02, 2017 at 12:58:16AM -0400, Rich Felker wrote:
> > > sigsetjmp calls setjmp, but I believe this will always use the intra-dso
> > > entry point. Same for the call siglongjmp makes to longjmp. So calls
> > > via sigsetjmp/siglongjmp will always be detected as local calls, even
> > > when the originally caller of jig*jmp is in a different dso.
> > >
> > > My plan right now is create a __setjmp_toc function which is identical
> > > to the normal setjmp except that the TOC pointer to save is passed in as
> > > another parameter. setjmp will detect which entry point is used, pull
> > > the TOC pointer from the right place, and call __setjmp_toc. sigsetjmp
> > > will be updated similarly to detect which entry point is used and to
> > > call __setjmp_toc directly instead of going through setjmp.
> >
> > I've been thinking about it and at first thought it sounded overly
> > fragile and hard to understand, but now I think it makes sense and
> > should work. It would just involve copying r2 to a call-clobbered
> > argument register before loading the new value, right?
>
> I'm not sure what "new value" you're referring to here.
>
> The idea is basically:
>
> setjmp: # non-local entry point
> r5 = r1[24]
> goto __setjmp_toc
>
> .localentry # local entry point
> r5 = r2
>
> __setjmp_toc:
> # all the existing code from setjmp, but save r5 instead of r2
For sigsetjmp, I think in this case you also need to duplicate the
assembler-generated code that would load a new r2; otherwise you can't
subsequently call __sigsetjmp_tail. For setjmp itself the above should
suffice since setjmp does not need a TOC itself.
Otherwise the pseudo-code above looks like what I expected after
thinking about it for a bit.
> > I was considering whether you could just avoid loading the TOC pointer
> > at all (leaving the correct value in r2 for setjmp to save), and this
> > might work, but I think it would make calling __sigsetjmp_tail
> > difficult and error-prone.
> >
> > > siglongjmp is current written in C by just calling longjmp. I'm tempted
> > > to just add a "siglongjmp:" label in the asm for longjmp and add an
> > > empty powerpc64/siglongjmp.c file to suppress the default
> > > implementation. I want to ask if there's any reason it wouldn't be
> > > valid for these two functions to have the same address.
> >
> > I don't see any reason to make this change (it won't make any
> > functional difference -- call frames and such don't matter at this
> > point), and at least the siglongjmp symbol would have to be weak to
> > respect namespace if you did it that way.
>
> I'm not sure why a change like this wouldn't be required.
>
> The requirements on longjmp here are:
> * when called through the local entry point, restore the TOC pointer
> into r2
> * when called via the PLT stub, restore the TOC pointer to the stack
>
> And siglongjmp needs to have the same behavior. If the main program
> makes a cross-dso call to siglongjmp, it needs to restore the TOC
> pointer to the stack. But siglongjmp works by making a local call to
> longjmp, meaning without this change, it will only ever restore the TOC
> pointer to r2.
Whether the call to longjmp/siglongjmp was local or not is irrelevant.
It's only whether the original call to setjmp/sigsetjmp was local or
not that's relevant. And in either case I'm pretty sure it suffices to
restore the saved value to both *(r1+24) and r2. Per the ABI, *(r1+24)
can't be used for any purpose except saving the TOC, so upon return
from setjmp, the caller's only options are to treat the value at
*(r1+24) as indeterminate or assume it contains the TOC pointer.
Likewise for r2, if the call was non-local, r2 is call-clobbered so it
doesn't matter what it contains after return, and if the call was
local, r2 is expected to contain the caller's TOC pointer.
Rich
next prev parent reply other threads:[~2017-08-02 14:46 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-31 20:06 felix.winkelmann
2017-07-31 20:30 ` Rich Felker
2017-08-01 5:10 ` Bobby Bingham
2017-08-01 5:28 ` Alexander Monakov
2017-08-01 22:45 ` Rich Felker
2017-08-01 23:07 ` Rich Felker
2017-08-02 0:28 ` Bobby Bingham
2017-08-02 3:55 ` Rich Felker
2017-08-02 4:31 ` Bobby Bingham
2017-08-02 4:58 ` Rich Felker
2017-08-02 13:38 ` Bobby Bingham
2017-08-02 14:46 ` Rich Felker [this message]
2017-08-03 0:19 ` Bobby Bingham
2017-08-01 15:33 ` David Edelsohn
2017-08-02 23:00 ` Alexander Monakov
2017-08-02 23:02 ` Rich Felker
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=20170802144612.GI1627@brightrain.aerifal.cx \
--to=dalias@libc.org \
--cc=musl@lists.openwall.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.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).