]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
powerpc64: Fix calls when r2 is not used [BZ #26173]
authorTulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Fri, 10 Jul 2020 22:41:06 +0000 (19:41 -0300)
committerTulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Fri, 10 Jul 2020 22:41:06 +0000 (19:41 -0300)
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
sysdeps/powerpc/powerpc64/configure
sysdeps/powerpc/powerpc64/configure.ac
sysdeps/powerpc/powerpc64/ppc-mcount.S
sysdeps/powerpc/powerpc64/setjmp-common.S
sysdeps/powerpc/powerpc64/sysdep.h
sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S

index d5e1f6819e63607777fbeb6085cf7d3473956afb..8dea97f625cc1d9a8e462c2def990fdc5e8bfacf 100644 (file)
@@ -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
 
index 7632a7be04005777212962c8f7d342c6a0877a2c..5ce77af631532b81d3e4ae1ede094c26b078e86a 100644 (file)
@@ -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
index f309ba35a8144a93477e11f86853358aadae413c..b77156f69655261867cdcbe33de7e7b2fa69cfaf 100644 (file)
@@ -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)])
index f7e9836cae1e49dcbe53d49123e578c3b50dda22..1adc0a18f3e9ae421084b2ba26d280f988047184 100644 (file)
@@ -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
index eb37000980a191bfa86ae23527f5235c2da97676..2409d1783164b9cf85fdd0ae2d9f47d5136beead 100644 (file)
@@ -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)
index d6616ac905b9f8deeebfd351825b5ba9ca8e79fd..d5570988982648278268d234ad02ba9a1018bfc8 100644 (file)
@@ -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
index e4d4575d68c8a41b8e2553b622f4b417c30f25a9..3c528aa4b75de8aae3674c6072d159f4e37d7a5f 100644 (file)
@@ -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