about summary refs log tree commit diff
path: root/sysdeps/s390/tst-dl-runtime.c
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2018-08-10 09:07:43 +0200
committerStefan Liebler <stli@linux.ibm.com>2018-08-10 09:07:43 +0200
commit69e2444ab1444ab8210598abbcb4822701d368b9 (patch)
treedd8987d70c9f8365bb9d697cfc55cebf94aa2bff /sysdeps/s390/tst-dl-runtime.c
parentbde6320f39cfe56fe3cbafe55fc498d7b329ff05 (diff)
downloadglibc-69e2444ab1444ab8210598abbcb4822701d368b9.tar.gz
glibc-69e2444ab1444ab8210598abbcb4822701d368b9.tar.xz
glibc-69e2444ab1444ab8210598abbcb4822701d368b9.zip
S390: Test that lazy binding does not clobber R0
The following combinations need to be tested:
* 32- (g5, esa and zarch) and 64-bit
  * linux32 glibc/configure CC='gcc -m31 -march=g5'
  * linux32 glibc/configure CC='gcc -m31'
  * linux32 glibc/configure CC='gcc -m31 -mzarch'
* With and without VX:
  * glibc/configure libc_cv_asm_s390_vx=no
* With and without profiling (using LD_PROFILE)
* With and without pltexit (using LD_AUDIT)

ChangeLog:

	* sysdeps/s390/Makefile: Register the new tests.
	* sysdeps/s390/tst-dl-runtime-mod.S: New file.
	* sysdeps/s390/tst-dl-runtime-profile-audit.c: New file.
	* sysdeps/s390/tst-dl-runtime-profile-noaudit.c: New file.
	* sysdeps/s390/tst-dl-runtime-resolve-audit.c: New file.
	* sysdeps/s390/tst-dl-runtime-resolve-noaudit.c: New file.
	* sysdeps/s390/tst-dl-runtime.c: New file.
Diffstat (limited to 'sysdeps/s390/tst-dl-runtime.c')
-rw-r--r--sysdeps/s390/tst-dl-runtime.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/sysdeps/s390/tst-dl-runtime.c b/sysdeps/s390/tst-dl-runtime.c
new file mode 100644
index 0000000000..7ab3c076ba
--- /dev/null
+++ b/sysdeps/s390/tst-dl-runtime.c
@@ -0,0 +1,91 @@
+/* Test that lazy binding does not clobber r0.
+   Copyright (C) 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 <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#if defined (__s390x__)
+static const unsigned long magic_value = 0x0011223344556677UL;
+#else
+static const unsigned long magic_value = 0x00112233;
+#endif
+
+unsigned long r0x2_trampoline (unsigned long);
+
+/* Invoke r0x2, which doubles the value in r0.  If we get
+   value * 2 back, this means nothing clobbers r0, particularly,
+   _dl_runtime_resolve and _dl_runtime_profile.  */
+asm ("    .type r0x2_trampoline, @function\n"
+     "r0x2_trampoline:\n"
+#if defined (__s390x__)
+     "    lgr %r0,%r2\n"
+     "    stg %r14,112(%r15)\n"
+     "    aghi %r15,-160\n"
+     "    brasl %r14,r0x2@plt\n"
+     "    aghi %r15,160\n"
+     "    lg %r14,112(%r15)\n"
+     "    lgr %r2,%r0\n"
+     "    br %r14\n"
+#elif defined (__zarch__)
+     "    lr %r0,%r2\n"
+     "    st %r14,56(%r15)\n"
+     "    ahi %r15,-96\n"
+     "    brasl %r14,r0x2@plt\n"
+     "    ahi %r15,96\n"
+     "    l %r14,56(%r15)\n"
+     "    lr %r2,%r0\n"
+     "    br %r14\n"
+#else
+     "    lr %r0,%r2\n"
+     "    st %r14,56(%r15)\n"
+     "    ahi %r15,-96\n"
+     "    balr %r14,0\n"
+     "    l %r14,1f-.(%r14)\n"
+     "    basr %r14,%r14\n"
+     "    ahi %r15,96\n"
+     "    l %r14,56(%r15)\n"
+     "    lr %r2,%r0\n"
+     "    br %r14\n"
+     "1: .long r0x2\n"
+#endif
+     );
+
+static int
+do_test (void)
+{
+  int i;
+  unsigned long r0;
+  const char *run;
+
+  for (i = 0; i < 2; i++)
+    {
+      run = (i == 0) ? "lazy" : "non-lazy";
+      r0 = magic_value;
+      printf ("-> %s r0 = 0x%lx\n", run, r0);
+      r0 = r0x2_trampoline (r0);
+      printf ("<- %s r0 * 2 = 0x%lx\n", run, r0);
+      if (r0 != magic_value * 2)
+	return EXIT_FAILURE;
+    }
+  return EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>