[compiler-rt] r267547 - [sanitizer] [SystemZ] Implement internal_clone.
Marcin Koscielnicki via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 26 03:41:20 PDT 2016
Author: koriakin
Date: Tue Apr 26 05:41:19 2016
New Revision: 267547
URL: http://llvm.org/viewvc/llvm-project?rev=267547&view=rev
Log:
[sanitizer] [SystemZ] Implement internal_clone.
Differential Revision: http://reviews.llvm.org/D19159
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_s390.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h?rev=267547&r1=267546&r2=267547&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h Tue Apr 26 05:41:19 2016
@@ -44,7 +44,7 @@ uptr internal_prctl(int option, uptr arg
int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \
- || defined(__powerpc64__)
+ || defined(__powerpc64__) || defined(__s390__)
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr);
#endif
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_s390.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_s390.cc?rev=267547&r1=267546&r2=267547&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_s390.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_s390.cc Tue Apr 26 05:41:19 2016
@@ -18,6 +18,7 @@
#include "sanitizer_linux.h"
+#include <errno.h>
#include <sys/syscall.h>
#include <unistd.h>
@@ -52,6 +53,67 @@ uptr internal_mmap(void *addr, uptr leng
# endif
}
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+ int *parent_tidptr, void *newtls, int *child_tidptr) {
+ if (!fn || !child_stack)
+ return -EINVAL;
+ CHECK_EQ(0, (uptr)child_stack % 16);
+ // Minimum frame size.
+#ifdef __s390x__
+ child_stack = (char *)child_stack - 160;
+#else
+ child_stack = (char *)child_stack - 96;
+#endif
+ // Terminate unwind chain.
+ ((unsigned long *)child_stack)[0] = 0;
+ // And pass parameters.
+ ((unsigned long *)child_stack)[1] = (uptr)fn;
+ ((unsigned long *)child_stack)[2] = (uptr)arg;
+ register long res __asm__("r2");
+ register void *__cstack __asm__("r2") = child_stack;
+ register int __flags __asm__("r3") = flags;
+ register int * __ptidptr __asm__("r4") = parent_tidptr;
+ register int * __ctidptr __asm__("r5") = child_tidptr;
+ register void * __newtls __asm__("r6") = newtls;
+
+ __asm__ __volatile__(
+ /* Clone. */
+ "svc %1\n"
+
+ /* if (%r2 != 0)
+ * return;
+ */
+#ifdef __s390x__
+ "cghi %%r2, 0\n"
+#else
+ "chi %%r2, 0\n"
+#endif
+ "jne 1f\n"
+
+ /* Call "fn(arg)". */
+#ifdef __s390x__
+ "lmg %%r1, %%r2, 8(%%r15)\n"
+#else
+ "lm %%r1, %%r2, 4(%%r15)\n"
+#endif
+ "basr %%r14, %%r1\n"
+
+ /* Call _exit(%r2). */
+ "svc %2\n"
+
+ /* Return to parent. */
+ "1:\n"
+ : "=r" (res)
+ : "i"(__NR_clone), "i"(__NR_exit),
+ "r"(__cstack),
+ "r"(__flags),
+ "r"(__ptidptr),
+ "r"(__ctidptr),
+ "r"(__newtls)
+ : "memory", "cc");
+ return res;
+}
+
} // namespace __sanitizer
#endif // SANITIZER_LINUX && SANITIZER_S390
More information about the llvm-commits
mailing list