aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatoly Parshintsev <kupokupokupopo@gmail.com>2020-09-22 22:10:13 -0700
committerVitaly Buka <vitalybuka@google.com>2020-09-22 22:11:20 -0700
commit96034cb3d1d6d0e4ebe6848ef93707943aeca5dc (patch)
treed638f362e7aa0daa29cb6e34ed6f901b36676dfa
parent6c22d00d7896bd7aaad567aa98016c26e78d8dcf (diff)
downloadllvm-96034cb3d1d6d0e4ebe6848ef93707943aeca5dc.zip
llvm-96034cb3d1d6d0e4ebe6848ef93707943aeca5dc.tar.gz
llvm-96034cb3d1d6d0e4ebe6848ef93707943aeca5dc.tar.bz2
[RISCV][ASAN] implementation of clone interceptor for riscv64
[4/11] patch series to port ASAN for riscv64 Depends On D87572 Reviewed By: eugenis, vitalybuka Differential Revision: https://reviews.llvm.org/D87573
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp49
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux.h6
2 files changed, 52 insertions, 3 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 111592d..0b53210 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -1361,6 +1361,55 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
: "memory", "$29" );
return res;
}
+#elif SANITIZER_RISCV64
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+ int *parent_tidptr, void *newtls, int *child_tidptr) {
+ long long res;
+ if (!fn || !child_stack)
+ return -EINVAL;
+ CHECK_EQ(0, (uptr)child_stack % 16);
+ child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
+ ((unsigned long long *)child_stack)[0] = (uptr)fn;
+ ((unsigned long long *)child_stack)[1] = (uptr)arg;
+
+ register int (*__fn)(void *) __asm__("a0") = fn;
+ register void *__stack __asm__("a1") = child_stack;
+ register int __flags __asm__("a2") = flags;
+ register void *__arg __asm__("a3") = arg;
+ register int *__ptid __asm__("a4") = parent_tidptr;
+ register void *__tls __asm__("a5") = newtls;
+ register int *__ctid __asm__("a6") = child_tidptr;
+
+ __asm__ __volatile__(
+ "mv a0,a2\n" /* flags */
+ "mv a2,a4\n" /* ptid */
+ "mv a3,a5\n" /* tls */
+ "mv a4,a6\n" /* ctid */
+ "addi a7, zero, %9\n" /* clone */
+
+ "ecall\n"
+
+ /* if (%r0 != 0)
+ * return %r0;
+ */
+ "bnez a0, 1f\n"
+
+ /* In the child, now. Call "fn(arg)". */
+ "ld a0, 8(sp)\n"
+ "ld a1, 16(sp)\n"
+ "jalr a1\n"
+
+ /* Call _exit(%r0). */
+ "addi a7, zero, %10\n"
+ "ecall\n"
+ "1:\n"
+
+ : "=r"(res)
+ : "i"(-EINVAL), "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
+ "r"(__ptid), "r"(__tls), "r"(__ctid), "i"(__NR_clone), "i"(__NR_exit)
+ : "ra", "memory");
+ return res;
+}
#elif defined(__aarch64__)
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index 1adc120..a8625ca 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -60,9 +60,9 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
// internal_sigaction instead.
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(__s390__) || defined(__i386__) \
- || defined(__arm__)
+#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \
+ defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \
+ defined(__arm__) || SANITIZER_RISCV64
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr);
#endif