mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
powerpc64: Fix calls when r2 is not used [BZ #26173]
Teach the linker that __mcount_internal, __sigjmp_save_symbol, __syscall_error and __GI_exit do not use r2, so that it does not need to recover r2 after the call. Test at configure time if the assembler supports @notoc and define USE_PPC64_NOTOC.
This commit is contained in:
@ -20,6 +20,9 @@
|
|||||||
/* On powerpc64, use overlapping .opd entries. */
|
/* On powerpc64, use overlapping .opd entries. */
|
||||||
#undef USE_PPC64_OVERLAPPING_OPD
|
#undef USE_PPC64_OVERLAPPING_OPD
|
||||||
|
|
||||||
|
/* On powerpc64, use @notoc. */
|
||||||
|
#undef USE_PPC64_NOTOC
|
||||||
|
|
||||||
/* Define if _Unwind_Find_FDE should be exported from glibc. */
|
/* Define if _Unwind_Find_FDE should be exported from glibc. */
|
||||||
#undef EXPORT_UNWIND_FIND_FDE
|
#undef EXPORT_UNWIND_FIND_FDE
|
||||||
|
|
||||||
|
28
sysdeps/powerpc/powerpc64/configure
vendored
28
sysdeps/powerpc/powerpc64/configure
vendored
@ -31,3 +31,31 @@ if test x$libc_cv_overlapping_opd = xyes; then
|
|||||||
$as_echo "#define USE_PPC64_OVERLAPPING_OPD 1" >>confdefs.h
|
$as_echo "#define USE_PPC64_OVERLAPPING_OPD 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# @notoc started to be supported in GNU Binutils 2.31.
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler supports @notoc" >&5
|
||||||
|
$as_echo_n "checking if the assembler supports @notoc... " >&6; }
|
||||||
|
if ${libc_cv_ppc64_notoc+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
void foo (void) {asm("b foo@notoc");}
|
||||||
|
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_compile "$LINENO"; then :
|
||||||
|
libc_cv_ppc64_notoc=yes
|
||||||
|
else
|
||||||
|
libc_cv_ppc64_notoc=no
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ppc64_notoc" >&5
|
||||||
|
$as_echo "$libc_cv_ppc64_notoc" >&6; }
|
||||||
|
if test x$libc_cv_ppc64_notoc = xyes; then :
|
||||||
|
$as_echo "#define USE_PPC64_NOTOC 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
@ -21,3 +21,14 @@ rm -f conftest.c conftest.s
|
|||||||
if test x$libc_cv_overlapping_opd = xyes; then
|
if test x$libc_cv_overlapping_opd = xyes; then
|
||||||
AC_DEFINE(USE_PPC64_OVERLAPPING_OPD)
|
AC_DEFINE(USE_PPC64_OVERLAPPING_OPD)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# @notoc started to be supported in GNU Binutils 2.31.
|
||||||
|
AC_CACHE_CHECK([if the assembler supports @notoc],
|
||||||
|
libc_cv_ppc64_notoc, [
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||||
|
void foo (void) {asm("b foo@notoc");}
|
||||||
|
])],
|
||||||
|
[libc_cv_ppc64_notoc=yes],
|
||||||
|
[libc_cv_ppc64_notoc=no])])
|
||||||
|
AS_IF([test x$libc_cv_ppc64_notoc = xyes],
|
||||||
|
[AC_DEFINE(USE_PPC64_NOTOC)])
|
||||||
|
@ -29,7 +29,7 @@ ENTRY(_mcount)
|
|||||||
cfi_adjust_cfa_offset (FRAME_MIN_SIZE)
|
cfi_adjust_cfa_offset (FRAME_MIN_SIZE)
|
||||||
cfi_offset (lr, FRAME_LR_SAVE)
|
cfi_offset (lr, FRAME_LR_SAVE)
|
||||||
ld r3, FRAME_LR_SAVE(r11)
|
ld r3, FRAME_LR_SAVE(r11)
|
||||||
bl JUMPTARGET(__mcount_internal)
|
bl JUMPTARGET (NOTOC (__mcount_internal))
|
||||||
#ifndef SHARED
|
#ifndef SHARED
|
||||||
nop
|
nop
|
||||||
#endif
|
#endif
|
||||||
|
@ -217,7 +217,7 @@ L(no_vmx):
|
|||||||
li r3,0
|
li r3,0
|
||||||
blr
|
blr
|
||||||
#elif defined SHARED
|
#elif defined SHARED
|
||||||
b JUMPTARGET (__sigjmp_save_symbol)
|
b JUMPTARGET (NOTOC (__sigjmp_save_symbol))
|
||||||
#else
|
#else
|
||||||
mflr r0
|
mflr r0
|
||||||
std r0,FRAME_LR_SAVE(r1)
|
std r0,FRAME_LR_SAVE(r1)
|
||||||
|
@ -278,7 +278,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
|
|||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
#define TAIL_CALL_SYSCALL_ERROR \
|
#define TAIL_CALL_SYSCALL_ERROR \
|
||||||
b JUMPTARGET(__syscall_error)
|
b JUMPTARGET (NOTOC (__syscall_error))
|
||||||
#else
|
#else
|
||||||
/* Static version might be linked into a large app with a toc exceeding
|
/* Static version might be linked into a large app with a toc exceeding
|
||||||
64k. We can't put a toc adjusting stub on a plain branch, so can't
|
64k. We can't put a toc adjusting stub on a plain branch, so can't
|
||||||
@ -366,6 +366,12 @@ LT_LABELSUFFIX(name,_name_end): ; \
|
|||||||
lwz rOUT,0(rOUT)
|
lwz rOUT,0(rOUT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PPC64_NOTOC
|
||||||
|
# define NOTOC(l) l@notoc
|
||||||
|
#else
|
||||||
|
# define NOTOC(l) l
|
||||||
|
#endif
|
||||||
|
|
||||||
#else /* !__ASSEMBLER__ */
|
#else /* !__ASSEMBLER__ */
|
||||||
|
|
||||||
#if _CALL_ELF != 2
|
#if _CALL_ELF != 2
|
||||||
|
@ -160,7 +160,7 @@ L(exitcode):
|
|||||||
li r3,-1
|
li r3,-1
|
||||||
L(do_exit):
|
L(do_exit):
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
b JUMPTARGET(__GI_exit);
|
b JUMPTARGET (NOTOC (__GI_exit));
|
||||||
#else
|
#else
|
||||||
b JUMPTARGET(exit);
|
b JUMPTARGET(exit);
|
||||||
nop
|
nop
|
||||||
|
Reference in New Issue
Block a user