]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 465782 - s390x: Avoid __builtin_setjmp
authorAndreas Arnez <arnez@linux.ibm.com>
Wed, 15 Feb 2023 17:02:37 +0000 (18:02 +0100)
committerAndreas Arnez <arnez@linux.ibm.com>
Wed, 10 May 2023 14:03:45 +0000 (16:03 +0200)
Currently Clang doesn't support __builtin_setjmp() on s390x.  Since
Valgrind already has an alternate implementation of setjmp/longjmp for
many other platforms, just add one for s390x as well, to get rid of this
dependency.

coregrind/m_libcsetjmp.c
include/pub_tool_libcsetjmp.h

index 4f1ecb1502a661165d06683ae5066226e0ec9f2f..f53a22352854afc54f500c2983cbc70c12402ed4 100644 (file)
@@ -36,9 +36,9 @@
 
 /* See include/pub_tool_libcsetjmp.h for background and rationale. */
 
-/* The alternative implementations are for ppc{32,64}-linux and
+/* The alternative implementations are for s390x-linux, ppc{32,64}-linux, and
    {amd64,x86}-{linux,darwin,solaris,freebsd}.  See #259977.  That leaves only
-   {arm,s390x}-linux using the gcc builtins now.
+   arm-linux using the gcc builtins now.
 */
 
 /* ------------ ppc32-linux ------------ */
@@ -741,6 +741,46 @@ __asm__(
 );
 #endif  /* VGP_nanomips_linux */
 
+/* ------------ s390x-linux ------------ */
+
+#if defined(VGP_s390x_linux)
+__asm__(
+".text"                                "\n"
+".align 4"                             "\n"
+".globl VG_MINIMAL_SETJMP"             "\n"
+".type VG_MINIMAL_SETJMP, @function"   "\n"
+"VG_MINIMAL_SETJMP:"                   "\n"
+"        stmg    6,15,0(2)"            "\n"
+"        std     8,80(2)"              "\n"
+"        std     9,88(2)"              "\n"
+"        std     10,96(2)"             "\n"
+"        std     11,104(2)"            "\n"
+"        std     12,112(2)"            "\n"
+"        std     13,120(2)"            "\n"
+"        std     14,128(2)"            "\n"
+"        std     15,136(2)"            "\n"
+// return zero
+"        lghi    2,0"                  "\n"
+"        br      14"                   "\n"
+
+".align 4"                             "\n"
+".globl VG_MINIMAL_LONGJMP"            "\n"
+".type VG_MINIMAL_LONGJMP, @function"  "\n"
+"VG_MINIMAL_LONGJMP:"                  "\n"
+"        lmg     6,15,0(2)"            "\n"
+"        ld      8,80(2)"              "\n"
+"        ld      9,88(2)"              "\n"
+"        ld      10,96(2)"             "\n"
+"        ld      11,104(2)"            "\n"
+"        ld      12,112(2)"            "\n"
+"        ld      13,120(2)"            "\n"
+"        ld      14,128(2)"            "\n"
+"        ld      15,136(2)"            "\n"
+// return the argument (nonzero)
+"        br      14"                   "\n"
+);
+#endif /* VGP_s390x_linux */
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index 6b278d285ba2866a183482032f18c2c655121107..a3a386f806ad4b8db4b4919b4fe38d7dbb866844 100644 (file)
@@ -126,6 +126,14 @@ UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
 __attribute__((noreturn))
 void  VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
 
+#elif defined(VGP_s390x_linux)
+
+#define VG_MINIMAL_JMP_BUF(_name)        ULong _name [10 + 8]
+__attribute__((returns_twice))
+UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
+__attribute__((noreturn))
+void  VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
+
 #else
 
 /* The default implementation. */