public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [RFC] powerpc: restore TOC when static longjmp to shared object
@ 2018-05-15 17:29 Rogerio Alves
  2018-05-15 18:53 ` Florian Weimer
  0 siblings, 1 reply; 16+ messages in thread
From: Rogerio Alves @ 2018-05-15 17:29 UTC (permalink / raw)
  To: libc-alpha

Hi, everyone

I was trying to fix a issue related to setjmp/longjmp on powerpc64 
"ppc64 setjmp/longjmp not fully interoperable with static dlopen":

https://sourceware.org/bugzilla/show_bug.cgi?id=21895

The code sent by the person who reports this problem on bugzilla #21895 
uses a static dlopen to a function declared in a shared lib, this 
function foo() calls setjmp and a static function inside a static 
compiled file calls the longjmp. So the problem is in that case it's not 
restoring the r2 (TOC) to the frame as the code who calls the longjmp is 
compiled as static but, as setjmp is called inside a shared object file 
it will fails once it tries to retrieve the TOC pointer from the memory:

0x3fffb7fb0954 <foo+96>         ld      r2,24(r1)
Segmentation fault

The problem is that TOC is not being restored to the frame after the 
longjmp.  I find out those lines at 
sysdeps/powerpc/powerpc64/__longjmp-common.S:

#if defined SHARED && !IS_IN (rtld)
        std r2,FRAME_TOC_SAVE(r1)       /* Restore the callers TOC save 
area.  */
#endif
/*     std r2,FRAME_TOC_SAVE(r1)       Restore the TOC save area.  */


As described on bugzilla #269:

"In this (simple) case the appl calls [bsd]_setjmp() which transfers to 
__setjmp.  Both are in libc.so.  So by the time __setjmp() gets control 
libc.so's TOC is already loaded.  In this case we need to reach back 
into the  callers frame and retrieve the callers TOC from the TOC save 
area. But in the static case the TOC is not saved and has not changed.

In GLIBC sysdeps/powerpc/powerpc64/setjmp.S is built 4 times (static, 
shared, profiled, and a special version (rtld-setjmp) for the dynamic 
linker.  In the  SHARED case (libc.so), external calls to setjmp will 
save the TOC on the stack, but internal libc calls will not.  So the 
trick is to do the correct thing for each case."

Since the function who calls the longjmp is a static function in a 
static compiled file it will not restore the TOC. But, the function that 
setjmp is a function inside a share object called via dlopen.

One simple solution would be always restore the TOC pointer by uncomment 
the line bellow:

/*     std r2,FRAME_TOC_SAVE(r1)       Restore the TOC save area.  */

Or maybe we can check if we have a valid TOC pointer before restore it, 
instead #if defined SHARED.

However, I am not sure if this is something that we should work on. 
First of all, as far I known, glibc is deprecating the static dlopen. 
Also, on the code attached on bug #21895, after call setjmp function the 
code calls a alloca and a memset function and those function are 
destroying the caller stack somehow. Then when longjmp executes it gets 
a segmentation fault since alloca/memset destroyed the caller stack.

I would like to request for comments on this matter: Should we fix/work 
this? Is feasible to change longjmp to always restore TOC pointer? Any 
suggestions?

Regards

--
Rogerio Alves
Software Engineer - IBM

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-07-16 19:11 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <f88767a0-1a38-564d-7bd8-0b5db5bc04df@linux.vnet.ibm.com>
2018-05-22 18:41 ` [RFC] powerpc: restore TOC when static longjmp to shared object Rogerio Alves
2018-05-23  9:27   ` Alexander Monakov
2018-05-23 12:33     ` Rogerio Alves
2018-05-23 13:45       ` Tulio Magno Quites Machado Filho
2018-05-23 14:25       ` Alexander Monakov
2018-05-25 19:39         ` Rogerio Alves
2018-06-04 14:34           ` Rogerio Alves
2018-06-04 14:38             ` Florian Weimer
2018-06-21 19:14               ` Rogerio Alves
2018-07-16 19:11                 ` Tulio Magno Quites Machado Filho
2018-05-15 17:29 Rogerio Alves
2018-05-15 18:53 ` Florian Weimer
2018-05-15 19:15   ` Rogerio Alves
2018-05-15 20:49   ` Tulio Magno Quites Machado Filho
2018-05-16 19:36     ` Rogerio Alves
2018-05-16 20:56       ` Adhemerval Zanella

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 read-only IMAP folder(s) and NNTP newsgroup(s).