[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
This commit is contained in:
Anatoly Parshintsev 2020-09-22 22:10:13 -07:00 committed by Vitaly Buka
parent 6c22d00d78
commit 96034cb3d1
2 changed files with 52 additions and 3 deletions

View File

@ -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) {

View File

@ -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