[sanitizer] [SystemZ] Implement internal_clone.
Differential Revision: http://reviews.llvm.org/D19159 llvm-svn: 267547
This commit is contained in:
parent
0cfb612413
commit
f98076b6a1
|
@ -44,7 +44,7 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
|
|||
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
|
||||
|
|
|
@ -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 length, int prot, int flags, int fd,
|
|||
# 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
|
||||
|
|
Loading…
Reference in New Issue