From: Petr Pavlu Date: Tue, 11 Apr 2023 19:30:43 +0000 (+0000) Subject: riscv64: Add initial support: test modifications X-Git-Tag: VALGRIND_3_25_0~131 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e3432fc94d5dc2164d130194dd36a98bd770d593;p=thirdparty%2Fvalgrind.git riscv64: Add initial support: test modifications The following people contributed to the initial RISC-V support: Petr Pavlu Xeonacid laokz Chelsea E. Manning zhaomingxin Jojo R Some integration fixes were added by Mark Wielaard - helgrind/tests/tc11_XCHG.c: Fix XCHG_M_R guard https://bugs.kde.org/show_bug.cgi?id=493507 --- diff --git a/helgrind/tests/annotate_hbefore.c b/helgrind/tests/annotate_hbefore.c index 259d3b64c..52dce3e76 100644 --- a/helgrind/tests/annotate_hbefore.c +++ b/helgrind/tests/annotate_hbefore.c @@ -314,6 +314,36 @@ UWord do_acasW ( UWord* addr, UWord expected, UWord nyu ) return success; } +#elif defined(VGA_riscv64) + +// riscv64 +/* return 1 if success, 0 if failure */ +UWord do_acasW ( UWord* addr, UWord expected, UWord nyu ) +{ + UWord success; + UWord block[3] = { (UWord)addr, nyu, expected}; + + __asm__ __volatile__( + "ld t0, 0(%1)" "\n\t" + "ld t2, 16(%1)" "\n\t" + "ld t3, 8(%1)" "\n\t" + "lr.d t1, 0(t0)" "\n\t" + "bne t1, t2, 1f" "\n\t" + "sc.d t1, t3, 0(t0)" "\n\t" + "xori %0, t1, 1" "\n\t" + "j 2f" "\n\t" + "1:" "\n\t" + "mv %0, zero" "\n\t" + "2:" "\n\t" + : /*out*/ "=r"(success) + : /*in*/ "r"(&block[0]) + : /*trash*/ "t0", "t1", "t2", "t3", "memory" + ); + + assert(success == 0 || success == 1); + return success; +} + #endif void atomic_incW ( UWord* w ) diff --git a/helgrind/tests/tc07_hbl1.c b/helgrind/tests/tc07_hbl1.c index a4250c62c..ee0564d20 100644 --- a/helgrind/tests/tc07_hbl1.c +++ b/helgrind/tests/tc07_hbl1.c @@ -19,6 +19,7 @@ #undef PLAT_arm64_linux #undef PLAT_s390x_linux #undef PLAT_mips32_linux +#undef PLAT_riscv64_linux #undef PLAT_x86_solaris #undef PLAT_amd64_solaris @@ -50,6 +51,8 @@ # define PLAT_mips32_linux 1 #elif defined(__linux__) && defined(__nanomips__) # define PLAT_nanomips_linux 1 +#elif defined(__linux__) && defined(__riscv) && (__riscv_xlen == 64) +# define PLAT_riscv64_linux 1 #elif defined(__sun__) && defined(__i386__) # define PLAT_x86_solaris 1 #elif defined(__sun__) && defined(__x86_64__) @@ -134,6 +137,13 @@ : /*out*/ : /*in*/ "r"(&(_lval)) \ : /*trash*/ "$t0", "$t1", "memory" \ ) +#elif defined(PLAT_riscv64_linux) +# define INC(_lval,_lqual) \ + __asm__ __volatile__ ( \ + " amoadd.w zero, %1, (%0)\n" \ + : /*out*/ : /*in*/ "r"(&(_lval)), "r"(1) \ + : /*trash*/ "memory" \ + ) #else # error "Fix Me for this platform" #endif diff --git a/helgrind/tests/tc08_hbl2.c b/helgrind/tests/tc08_hbl2.c index 6a8543fa1..be2b78b01 100644 --- a/helgrind/tests/tc08_hbl2.c +++ b/helgrind/tests/tc08_hbl2.c @@ -36,6 +36,7 @@ #undef PLAT_s390x_linux #undef PLAT_mips32_linux #undef PLAT_mips64_linux +#undef PLAT_riscv64_linux #undef PLAT_x86_solaris #undef PLAT_amd64_solaris @@ -71,6 +72,8 @@ #endif #elif defined(__linux__) && defined(__nanomips__) # define PLAT_nanomips_linux 1 +#elif defined(__linux__) && defined(__riscv) && (__riscv_xlen == 64) +# define PLAT_riscv64_linux 1 #elif defined(__sun__) && defined(__i386__) # define PLAT_x86_solaris 1 #elif defined(__sun__) && defined(__x86_64__) @@ -154,6 +157,13 @@ : /*out*/ : /*in*/ "r"(&(_lval)) \ : /*trash*/ "$t0", "$t1", "memory" \ ) +#elif defined(PLAT_riscv64_linux) +# define INC(_lval,_lqual) \ + __asm__ __volatile__ ( \ + " amoadd.w zero, %1, (%0)\n" \ + : /*out*/ : /*in*/ "r"(&(_lval)), "r"(1) \ + : /*trash*/ "memory" \ + ) #else # error "Fix Me for this platform" #endif diff --git a/helgrind/tests/tc11_XCHG.c b/helgrind/tests/tc11_XCHG.c index cc00ba38f..e92b671b7 100644 --- a/helgrind/tests/tc11_XCHG.c +++ b/helgrind/tests/tc11_XCHG.c @@ -21,6 +21,7 @@ #undef PLAT_arm_linux #undef PLAT_s390x_linux #undef PLAT_mips32_linux +#undef PLAT_riscv64_linux #undef PLAT_x86_solaris #undef PLAT_amd64_solaris @@ -52,6 +53,8 @@ # define PLAT_mips32_linux 1 #elif defined(__linux__) && defined(__nanomips__) # define PLAT_nanomips_linux 1 +#elif defined(__linux__) && defined(__riscv) && (__riscv_xlen == 64) +# define PLAT_riscv64_linux 1 #elif defined(__sun__) && defined(__i386__) # define PLAT_x86_solaris 1 #elif defined(__sun__) && defined(__x86_64__) @@ -128,7 +131,8 @@ #elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \ || defined(PLAT_arm_linux) || defined(PLAT_arm64_linux) \ - || defined(PLAT_arm64_freebsd) + || defined(PLAT_arm64_freebsd) \ + || defined(PLAT_riscv64_linux) # if defined(HAVE_BUILTIN_ATOMIC) # define XCHG_M_R(_addr,_lval) \ do { \ diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index bfdd86c7e..a4ca2853f 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -53,6 +53,9 @@ endif if VGCONF_PLATFORMS_INCLUDE_ARM64_LINUX SUBDIRS += arm64-linux endif +if VGCONF_PLATFORMS_INCLUDE_RISCV64_LINUX +SUBDIRS += riscv64-linux +endif if VGCONF_PLATFORMS_INCLUDE_X86_SOLARIS SUBDIRS += x86-solaris endif @@ -67,7 +70,7 @@ SUBDIRS += amd64-freebsd endif DIST_SUBDIRS = x86 amd64 arm64 ppc32 ppc64 s390x linux \ - darwin solaris x86-linux amd64-linux arm64-linux \ + darwin solaris x86-linux amd64-linux arm64-linux riscv64-linux \ x86-solaris amd64-solaris mips32 mips64 \ freebsd amd64-freebsd x86-freebsd \ common . diff --git a/memcheck/tests/atomic_incs.c b/memcheck/tests/atomic_incs.c index 1c738c530..89b6e1f75 100644 --- a/memcheck/tests/atomic_incs.c +++ b/memcheck/tests/atomic_incs.c @@ -245,6 +245,26 @@ __attribute__((noinline)) void atomic_add_8bit ( char* p, int n ) ); } while (block[2] != 1); #endif +#elif defined(VGA_riscv64) + unsigned long long int block[3] + = { (unsigned long long int)p, (unsigned long long int)n, + 0xFFFFFFFFFFFFFFFFULL}; + do { + __asm__ __volatile__( + "mv t0, %0" "\n\t" + "ld t1, (t0)" "\n\t" // p + "ld t2, 8(t0)" "\n\t" // n + "lr.w t3, (t1)" "\n\t" + "slli t3, t3, 56" "\n\t" // sign-extend + "srai t3, t3, 56" "\n\t" + "add t3, t3, t2" "\n\t" + "sc.w t4, t3, (t1)" "\n\t" + "sd t4, 16(t0)" "\n\t" + : /*out*/ + : /*in*/ "r"(&block[0]) + : /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4" + ); + } while (block[2] != 0); #else # error "Unsupported arch" #endif @@ -461,6 +481,26 @@ __attribute__((noinline)) void atomic_add_16bit ( short* p, int n ) ); } while (block[2] != 1); #endif +#elif defined(VGA_riscv64) + unsigned long long int block[3] + = { (unsigned long long int)p, (unsigned long long int)n, + 0xFFFFFFFFFFFFFFFFULL}; + do { + __asm__ __volatile__( + "mv t0, %0" "\n\t" + "ld t1, (t0)" "\n\t" // p + "ld t2, 8(t0)" "\n\t" // n + "lr.w t3, (t1)" "\n\t" + "slli t3, t3, 48" "\n\t" // sign-extend + "srai t3, t3, 48" "\n\t" + "add t3, t3, t2" "\n\t" + "sc.w t4, t3, (t1)" "\n\t" + "sd t4, 16(t0)" "\n\t" + : /*out*/ + : /*in*/ "r"(&block[0]) + : /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4" + ); + } while (block[2] != 0); #else # error "Unsupported arch" #endif @@ -616,6 +656,24 @@ __attribute__((noinline)) void atomic_add_32bit ( int* p, int n ) : /*trash*/ "memory", "t0", "t1", "t2", "t3" ); } while (block[2] != 1); +#elif defined(VGA_riscv64) + unsigned long long int block[3] + = { (unsigned long long int)p, (unsigned long long int)n, + 0xFFFFFFFFFFFFFFFFULL}; + do { + __asm__ __volatile__( + "mv t0, %0" "\n\t" + "ld t1, (t0)" "\n\t" // p + "ld t2, 8(t0)" "\n\t" // n + "lr.w t3, (t1)" "\n\t" + "add t3, t3, t2" "\n\t" + "sc.w t4, t3, (t1)" "\n\t" + "sd t4, 16(t0)" "\n\t" + : /*out*/ + : /*in*/ "r"(&block[0]) + : /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4" + ); + } while (block[2] != 0); #else # error "Unsupported arch" #endif @@ -718,6 +776,24 @@ __attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n ) : /*trash*/ "memory", "t0", "t1", "t2", "t3" ); } while (block[2] != 1); +#elif defined(VGA_riscv64) + unsigned long long int block[3] + = { (unsigned long long int)p, (unsigned long long int)n, + 0xFFFFFFFFFFFFFFFFULL}; + do { + __asm__ __volatile__( + "mv t0, %0" "\n\t" + "ld t1, (t0)" "\n\t" // p + "ld t2, 8(t0)" "\n\t" // n + "lr.d t3, (t1)" "\n\t" + "add t3, t3, t2" "\n\t" + "sc.d t4, t3, (t1)" "\n\t" + "sd t4, 16(t0)" "\n\t" + : /*out*/ + : /*in*/ "r"(&block[0]) + : /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4" + ); + } while (block[2] != 0); #else # error "Unsupported arch" #endif @@ -731,7 +807,7 @@ __attribute__((noinline)) void atomic_add_128bit ( MyU128* p, || defined(VGA_amd64) \ || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ || defined(VGA_arm) \ - || defined(VGA_s390x) + || defined(VGA_s390x) || defined(VGA_riscv64) /* do nothing; is not supported */ #elif defined(VGA_arm64) unsigned long long int block[3] diff --git a/memcheck/tests/leak-segv-jmp.c b/memcheck/tests/leak-segv-jmp.c index 30fe2a1a9..15cc9f8fb 100644 --- a/memcheck/tests/leak-segv-jmp.c +++ b/memcheck/tests/leak-segv-jmp.c @@ -183,6 +183,23 @@ extern UWord do_syscall_WRK ( return out; } +#elif defined(VGP_riscv64_linux) +extern UWord do_syscall_WRK ( + UWord a1, UWord a2, UWord a3, + UWord a4, UWord a5, UWord a6, + UWord syscall_no + ); +asm( +".text\n" +".globl do_syscall_WRK\n" +"do_syscall_WRK:\n" +" mv a7, a6\n" +" li a6, 0\n" +" ecall\n" +" ret\n" +".previous\n" +); + #elif defined(VGP_x86_solaris) extern ULong do_syscall_WRK(UWord a1, UWord a2, UWord a3, @@ -369,7 +386,7 @@ static void non_simd_mprotect (long tid, void* addr, long len) &err); if (err) mprotect_result = -1; -#elif defined(VGP_arm64_linux) +#elif defined(VGP_arm64_linux) || defined(VGP_riscv64_linux) mprotect_result = do_syscall_WRK((UWord) addr, len, PROT_NONE, 0, 0, 0, __NR_mprotect); diff --git a/memcheck/tests/leak-segv-jmp.stderr.exp b/memcheck/tests/leak-segv-jmp.stderr.exp index 147bdf8cd..e18418d44 100644 --- a/memcheck/tests/leak-segv-jmp.stderr.exp +++ b/memcheck/tests/leak-segv-jmp.stderr.exp @@ -14,8 +14,8 @@ To see them, rerun with: --leak-check=full --show-leak-kinds=all expecting a leak 1,000 bytes in 1 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-segv-jmp.c:420) - by 0x........: main (leak-segv-jmp.c:495) + by 0x........: f (leak-segv-jmp.c:437) + by 0x........: main (leak-segv-jmp.c:512) LEAK SUMMARY: definitely lost: 1,000 bytes in 1 blocks @@ -30,8 +30,8 @@ mprotect result 0 expecting a leak again 1,000 bytes in 1 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-segv-jmp.c:420) - by 0x........: main (leak-segv-jmp.c:495) + by 0x........: f (leak-segv-jmp.c:437) + by 0x........: main (leak-segv-jmp.c:512) LEAK SUMMARY: definitely lost: 1,000 bytes in 1 blocks @@ -46,8 +46,8 @@ full mprotect result 0 expecting a leak again after full mprotect 1,000 bytes in 1 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-segv-jmp.c:420) - by 0x........: main (leak-segv-jmp.c:495) + by 0x........: f (leak-segv-jmp.c:437) + by 0x........: main (leak-segv-jmp.c:512) LEAK SUMMARY: definitely lost: 1,000 bytes in 1 blocks @@ -62,13 +62,13 @@ mprotect result 0 expecting heuristic not to crash after full mprotect 1,000 bytes in 1 blocks are definitely lost in loss record ... of ... at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: f (leak-segv-jmp.c:420) - by 0x........: main (leak-segv-jmp.c:495) + by 0x........: f (leak-segv-jmp.c:437) + by 0x........: main (leak-segv-jmp.c:512) 200,000 bytes in 1 blocks are possibly lost in loss record ... of ... at 0x........: calloc (vg_replace_malloc.c:...) - by 0x........: f (leak-segv-jmp.c:467) - by 0x........: main (leak-segv-jmp.c:495) + by 0x........: f (leak-segv-jmp.c:484) + by 0x........: main (leak-segv-jmp.c:512) LEAK SUMMARY: definitely lost: 1,000 bytes in 1 blocks diff --git a/memcheck/tests/leak.h b/memcheck/tests/leak.h index bf78d5866..f9a2db290 100644 --- a/memcheck/tests/leak.h +++ b/memcheck/tests/leak.h @@ -181,6 +181,11 @@ __asm__ __volatile__ ("mov x17, 0\n\t"); \ __asm__ __volatile__ ("mov x18, 0\n\t"); \ } while (0) +#elif defined(__riscv) +#define CLEAR_CALLER_SAVED_REGS \ + do { \ + __asm__ __volatile__( "li a0, 0" : : :/*trash*/"a0" ); \ + } while (0) #else #define CLEAR_CALLER_SAVED_REGS /*nothing*/ #endif diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index 7ceb0052b..d119c74a1 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -35,6 +35,9 @@ endif if VGCONF_ARCHS_INCLUDE_NANOMIPS SUBDIRS += nanomips endif +if VGCONF_ARCHS_INCLUDE_RISCV64 +SUBDIRS += riscv64 +endif # OS-specific tests @@ -75,8 +78,9 @@ SUBDIRS += x86-freebsd endif DIST_SUBDIRS = x86 amd64 ppc32 ppc64 arm arm64 s390x mips32 mips64 nanomips \ - linux darwin solaris freebsd amd64-linux x86-linux amd64-darwin \ - x86-darwin amd64-solaris x86-solaris x86-freebsd scripts . + riscv64 linux darwin solaris freebsd amd64-linux x86-linux \ + amd64-darwin x86-darwin amd64-solaris x86-solaris x86-freebsd \ + scripts . dist_noinst_SCRIPTS = \ filter_cmdline0 \ @@ -401,6 +405,11 @@ libvex_test_CFLAGS = $(AM_CFLAGS) @FLAG_FSANITIZE@ libvex_test_LDADD = ../../VEX/libvex-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a \ @LIB_UBSAN@ libvexmultiarch_test_CFLAGS= $(AM_CFLAGS) @FLAG_FSANITIZE@ +if VGCONF_ARCHS_INCLUDE_RISCV64 +# Disable RISC-V linker relaxation, it takes GNU ld 2.39 tens of minutes to sort +# it through on this large test. +libvexmultiarch_test_LDFLAGS = -Wl,--no-relax +endif libvexmultiarch_test_LDADD = \ ../../VEX/libvexmultiarch-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a \ ../../VEX/libvex-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a @LIB_UBSAN@ diff --git a/none/tests/allexec_prepare_prereq b/none/tests/allexec_prepare_prereq index a541f4299..fa4d31706 100755 --- a/none/tests/allexec_prepare_prereq +++ b/none/tests/allexec_prepare_prereq @@ -34,5 +34,6 @@ pair s390x_unexisting_in_32bits s390x pair arm arm64 pair mips32 mips64 pair nanomips nanoMIPS_unexisting_in_64bits +pair riscv_unexisting_in_32bits riscv64 exit 0 diff --git a/none/tests/faultstatus.c b/none/tests/faultstatus.c index 9e262395b..a83546b54 100644 --- a/none/tests/faultstatus.c +++ b/none/tests/faultstatus.c @@ -11,7 +11,7 @@ #include "../../config.h" /* Division by zero triggers a SIGFPE on x86 and x86_64, - but not on the PowerPC architecture. + but not on the PowerPC, AArch64 and RISC-V architectures. On ARM-Linux, we do get a SIGFPE, but not from the faulting of a division instruction (there isn't any such thing) but rather @@ -19,7 +19,7 @@ Hence we get a SIGFPE but the SI_CODE is different from that on x86/amd64-linux. */ -#if defined(__powerpc__) || defined(__aarch64__) +#if defined(__powerpc__) || defined(__aarch64__) || defined(__riscv) # define DIVISION_BY_ZERO_TRIGGERS_FPE 0 #if defined(VGO_freebsd) # define DIVISION_BY_ZERO_SI_CODE SI_LWP diff --git a/none/tests/libvex_test.c b/none/tests/libvex_test.c index 5b57a4c2e..6a8086ace 100644 --- a/none/tests/libvex_test.c +++ b/none/tests/libvex_test.c @@ -76,6 +76,8 @@ __attribute__((noinline)) static void get_guest_arch(VexArch *ga) *ga = VexArchMIPS64; #elif defined(VGA_nanomips) *ga = VexArchNANOMIPS; +#elif defined(VGA_riscv64) + *ga = VexArchRISCV64; #else missing arch; #endif @@ -113,6 +115,7 @@ static VexEndness arch_endness (VexArch va) { else return VexEndnessBE; } + case VexArchRISCV64: return VexEndnessLE; default: failure_exit(); } } @@ -139,6 +142,7 @@ static UInt arch_hwcaps (VexArch va) { case VexArchMIPS64: return VEX_PRID_COMP_MIPS | VEX_MIPS_HOST_FR; #endif case VexArchNANOMIPS: return 0; + case VexArchRISCV64: return 0; default: failure_exit(); } } @@ -156,6 +160,7 @@ static Bool mode64 (VexArch va) { case VexArchMIPS32: return False; case VexArchMIPS64: return True; case VexArchNANOMIPS: return False; + case VexArchRISCV64: return True; default: failure_exit(); } } @@ -275,7 +280,7 @@ int main(int argc, char **argv) // explicitly via command line arguments. if (multiarch) { VexArch va; - for (va = VexArchX86; va <= VexArchNANOMIPS; va++) { + for (va = VexArchX86; va <= VexArchRISCV64; va++) { vta.arch_host = va; vta.archinfo_host.endness = arch_endness (vta.arch_host); vta.archinfo_host.hwcaps = arch_hwcaps (vta.arch_host); diff --git a/tests/arch_test.c b/tests/arch_test.c index 4dbb8ca10..84b1f1307 100644 --- a/tests/arch_test.c +++ b/tests/arch_test.c @@ -34,6 +34,7 @@ char* all_archs[] = { "mips32", "mips64", "nanomips", + "riscv64", NULL }; @@ -79,6 +80,10 @@ static Bool go(char* arch) #elif defined(VGP_nanomips_linux) if ( 0 == strcmp( arch, "nanomips" ) ) return True; + +#elif defined(VGP_riscv64_linux) + if ( 0 == strcmp( arch, "riscv64" ) ) return True; + #else # error Unknown platform #endif // VGP_* diff --git a/tests/platform_test b/tests/platform_test index c23a4f645..9762d0c09 100644 --- a/tests/platform_test +++ b/tests/platform_test @@ -14,6 +14,7 @@ all_platforms= all_platforms="$all_platforms x86-linux amd64-linux ppc32-linux ppc64-linux" all_platforms="$all_platforms arm-linux arm64-linux" all_platforms="$all_platforms s390x-linux mips32-linux mips64-linux" +all_platforms="$all_platforms riscv64-linux" all_platforms="$all_platforms x86-darwin amd64-darwin" all_platforms="$all_platforms x86-solaris amd64-solaris" all_platforms="$all_platforms x86-freebsd amd64-freebsd"