[PATCHv2] powerpc64: Fix calls when r2 is not used [BZ #26173]
Commit Message
Paul E Murphy via Libc-alpha <libc-alpha@sourceware.org> writes:
> Will this also require a newer version of binutils?
Yes. Fixed in this version.
Thanks!
Changes since v1:
- Detect at configure time if the assembler supports @notoc. Use @notoc only
when available.
---8<---
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.
---
config.h.in | 3 ++
sysdeps/powerpc/powerpc64/configure | 28 +++++++++++++++++++
sysdeps/powerpc/powerpc64/configure.ac | 11 ++++++++
sysdeps/powerpc/powerpc64/ppc-mcount.S | 2 +-
sysdeps/powerpc/powerpc64/setjmp-common.S | 2 +-
sysdeps/powerpc/powerpc64/sysdep.h | 8 +++++-
.../linux/powerpc/powerpc64/makecontext.S | 2 +-
7 files changed, 52 insertions(+), 4 deletions(-)
Comments
On 7/1/20 3:50 PM, Tulio Magno Quites Machado Filho wrote:
> Paul E Murphy via Libc-alpha <libc-alpha@sourceware.org> writes:
>
>> Will this also require a newer version of binutils?
>
> Yes. Fixed in this version.
>
> Thanks!
>
> Changes since v1:
>
> - Detect at configure time if the assembler supports @notoc. Use @notoc only
> when available.
>
> ---8<---
>
> 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.
> ---
> config.h.in | 3 ++
> sysdeps/powerpc/powerpc64/configure | 28 +++++++++++++++++++
> sysdeps/powerpc/powerpc64/configure.ac | 11 ++++++++
> sysdeps/powerpc/powerpc64/ppc-mcount.S | 2 +-
> sysdeps/powerpc/powerpc64/setjmp-common.S | 2 +-
> sysdeps/powerpc/powerpc64/sysdep.h | 8 +++++-
> .../linux/powerpc/powerpc64/makecontext.S | 2 +-
> 7 files changed, 52 insertions(+), 4 deletions(-)
>
> diff --git a/config.h.in b/config.h.in
> index 831eca2fe1..6598d4573a 100644
> --- a/config.h.in
> +++ b/config.h.in
> @@ -20,6 +20,9 @@
> /* On powerpc64, use overlapping .opd entries. */
> #undef USE_PPC64_OVERLAPPING_OPD
>
> +/* On powerpc64, use @notoc. */
> +#undef USE_PPC64_NOTOC
> +
> /* Define if _Unwind_Find_FDE should be exported from glibc. */
> #undef EXPORT_UNWIND_FIND_FDE
>
> diff --git a/sysdeps/powerpc/powerpc64/configure b/sysdeps/powerpc/powerpc64/configure
> index 7632a7be04..5ce77af631 100644
> --- a/sysdeps/powerpc/powerpc64/configure
> +++ b/sysdeps/powerpc/powerpc64/configure
> @@ -31,3 +31,31 @@ if test x$libc_cv_overlapping_opd = xyes; then
> $as_echo "#define USE_PPC64_OVERLAPPING_OPD 1" >>confdefs.h
>
> fi
> +
> +# @notoc started to be supported in GNU Binutils 2.31.
An optional rewording suggestion: s/started to be supported/was added/.
I also did a quick compile test with binutils 2.30
and 2.34. LGTM.
Paul E Murphy via Libc-alpha <libc-alpha@sourceware.org> writes:
> An optional rewording suggestion: s/started to be supported/was added/.
>
> I also did a quick compile test with binutils 2.30
> and 2.34. LGTM.
Pushed as 7c7bcf3634e44cf7e001aaa302138c1ee0e58f8c.
Thanks!
@@ -20,6 +20,9 @@
/* On powerpc64, use overlapping .opd entries. */
#undef USE_PPC64_OVERLAPPING_OPD
+/* On powerpc64, use @notoc. */
+#undef USE_PPC64_NOTOC
+
/* Define if _Unwind_Find_FDE should be exported from glibc. */
#undef EXPORT_UNWIND_FIND_FDE
@@ -31,3 +31,31 @@ if test x$libc_cv_overlapping_opd = xyes; then
$as_echo "#define USE_PPC64_OVERLAPPING_OPD 1" >>confdefs.h
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
AC_DEFINE(USE_PPC64_OVERLAPPING_OPD)
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_offset (lr, FRAME_LR_SAVE)
ld r3, FRAME_LR_SAVE(r11)
- bl JUMPTARGET(__mcount_internal)
+ bl JUMPTARGET (NOTOC (__mcount_internal))
#ifndef SHARED
nop
#endif
@@ -217,7 +217,7 @@ L(no_vmx):
li r3,0
blr
#elif defined SHARED
- b JUMPTARGET (__sigjmp_save_symbol)
+ b JUMPTARGET (NOTOC (__sigjmp_save_symbol))
#else
mflr r0
std r0,FRAME_LR_SAVE(r1)
@@ -278,7 +278,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
#ifdef SHARED
#define TAIL_CALL_SYSCALL_ERROR \
- b JUMPTARGET(__syscall_error)
+ b JUMPTARGET (NOTOC (__syscall_error))
#else
/* 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
@@ -366,6 +366,12 @@ LT_LABELSUFFIX(name,_name_end): ; \
lwz rOUT,0(rOUT)
#endif
+#ifdef USE_PPC64_NOTOC
+# define NOTOC(l) l@notoc
+#else
+# define NOTOC(l) l
+#endif
+
#else /* !__ASSEMBLER__ */
#if _CALL_ELF != 2
@@ -160,7 +160,7 @@ L(exitcode):
li r3,-1
L(do_exit):
#ifdef SHARED
- b JUMPTARGET(__GI_exit);
+ b JUMPTARGET (NOTOC (__GI_exit));
#else
b JUMPTARGET(exit);
nop