mirror of git://sourceware.org/git/glibc.git
powerpc64: Always restore TOC on longjmp [BZ #21895]
This patch changes longjmp to always restore the TOC pointer (r2 register) to the caller frame on powerpc64 and powerpc64le. This is related to bug 21895 that reports a situation where you have a static longjmp to a shared object file. [BZ #21895] * sysdeps/powerpc/powerpc64/__longjmp-common.S: Remove condition code for restoring r2 in longjmp. * sysdeps/powerpc/powerpc64/Makefile: Added tst-setjmp-bug21895-static to test list. Added rules to build test tst-setjmp-bug21895-static. Added module setjmp-bug21895 and rules to build a shared object from it. * sysdeps/powerpc/powerpc64/setjmp-bug21895.c: New test file. * sysdeps/powerpc/powerpc64/tst-setjmp-bug21895-static.c: New test file. Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
This commit is contained in:
parent
3ae725dfb6
commit
52b2a80fae
12
ChangeLog
12
ChangeLog
|
|
@ -1,3 +1,15 @@
|
|||
2018-07-16 Rogerio A. Cardoso <rcardoso@linux.vnet.ibm.com>
|
||||
|
||||
[BZ #21895]
|
||||
* sysdeps/powerpc/powerpc64/__longjmp-common.S: Remove condition code for
|
||||
restore r2 on longjmp.
|
||||
* sysdeps/powerpc/powerpc64/Makefile: Added tst-setjmp-bug21895-static to
|
||||
test list.
|
||||
Added rules to build test tst-setjmp-bug21895-static.
|
||||
Added module setjmp-bug21895 and rules to build a shared object from it.
|
||||
* sysdeps/powerpc/powerpc64/setjmp-bug21895.c: New test file.
|
||||
* sysdeps/powerpc/powerpc64/tst-setjmp-bug21895-static.c: New test file.
|
||||
|
||||
2018-07-15 Wilco Dijkstra <wdijkstr@arm.com>
|
||||
|
||||
* benchtests/bench-strcasestr.c: Rename __strnlen to strnlen.
|
||||
|
|
|
|||
|
|
@ -47,3 +47,15 @@ ifeq ($(subdir),gmon)
|
|||
CFLAGS-mcount.c += $(no-special-regs)
|
||||
sysdep_routines += ppc-mcount
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),setjmp)
|
||||
tests += tst-setjmp-bug21895-static
|
||||
tests-static += tst-setjmp-bug21895-static
|
||||
modules-names += setjmp-bug21895
|
||||
|
||||
$(objpfx)tst-setjmp-bug21895-static: $(common-objpfx)dlfcn/libdl.a
|
||||
$(objpfx)tst-setjmp-bug21895-static.out: $(objpfx)setjmp-bug21895.so
|
||||
|
||||
tst-setjmp-bug21895-static-ENV = \
|
||||
LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)setjmp:$(common-objpfx)elf
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -130,9 +130,6 @@ L(no_vmx):
|
|||
ld r0,(JB_LR*8)(r3)
|
||||
ld r14,((JB_GPRS+0)*8)(r3)
|
||||
lfd fp14,((JB_FPRS+0)*8)(r3)
|
||||
#if defined SHARED && !IS_IN (rtld)
|
||||
std r2,FRAME_TOC_SAVE(r1) /* Restore the callers TOC save area. */
|
||||
#endif
|
||||
ld r15,((JB_GPRS+1)*8)(r3)
|
||||
lfd fp15,((JB_FPRS+1)*8)(r3)
|
||||
ld r16,((JB_GPRS+2)*8)(r3)
|
||||
|
|
@ -152,7 +149,7 @@ L(no_vmx):
|
|||
second argument (-4@4), and target address (8@0), respectively. */
|
||||
LIBC_PROBE (longjmp, 3, 8@3, -4@4, 8@0)
|
||||
mtlr r0
|
||||
/* std r2,FRAME_TOC_SAVE(r1) Restore the TOC save area. */
|
||||
std r2,FRAME_TOC_SAVE(r1) /* Restore the TOC save area. */
|
||||
ld r21,((JB_GPRS+7)*8)(r3)
|
||||
lfd fp21,((JB_FPRS+7)*8)(r3)
|
||||
ld r22,((JB_GPRS+8)*8)(r3)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/* Shared object part of test for setjmp interoperability with static
|
||||
dlopen BZ #21895.
|
||||
Copyright (C) 2017-2018 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/* Copy r1 adress to a local variable. */
|
||||
#define GET_STACK_POINTER(sp) \
|
||||
({ \
|
||||
asm volatile ("mr %0, 1\n\t" \
|
||||
: "=r" (sp)); \
|
||||
})
|
||||
|
||||
jmp_buf jb;
|
||||
void (*bar)(jmp_buf, unsigned long);
|
||||
|
||||
void
|
||||
lbar (unsigned long sp)
|
||||
{
|
||||
bar(jb, sp);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
unsigned long sp;
|
||||
/* Copy r1 (stack pointer) to sp. It will be use later to get
|
||||
TOC area. */
|
||||
GET_STACK_POINTER(sp);
|
||||
setjmp(jb);
|
||||
lbar(sp);
|
||||
|
||||
for(;;);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* Test setjmp interoperability with static dlopen BZ #21895.
|
||||
Copyright (C) 2017-2018 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
/* Set TOC area pointed by sp to zero. */
|
||||
#define SET_TOC_TO_ZERO(sp) \
|
||||
({ \
|
||||
unsigned int zero = 0; \
|
||||
asm volatile ("std %0, 24(%1)\n\t" :: "r" (zero), "r" (sp)); \
|
||||
})
|
||||
|
||||
static void
|
||||
bar (jmp_buf jb, unsigned long sp)
|
||||
{
|
||||
static int i;
|
||||
if (i++==1)
|
||||
exit(0); /* Success. */
|
||||
|
||||
/* This will set TOC are on caller frame (foo) to zero. __longjmp
|
||||
must restore r2 otherwise a segmentation fault will happens after
|
||||
it jumps back to foo. */
|
||||
SET_TOC_TO_ZERO(sp);
|
||||
longjmp(jb, i);
|
||||
}
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
void *h = dlopen("setjmp-bug21895.so", RTLD_NOW);
|
||||
if (!h)
|
||||
{
|
||||
puts(dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
void (*pfoo)(void) = dlsym(h, "foo");
|
||||
if (!pfoo)
|
||||
{
|
||||
puts(dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
void (**ppbar)(jmp_buf, unsigned long) = dlsym(h, "bar");
|
||||
if (!ppbar)
|
||||
{
|
||||
puts(dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
*ppbar = bar;
|
||||
pfoo();
|
||||
|
||||
for(;;);
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
||||
Loading…
Reference in New Issue