From: Mark W. <ma...@so...> - 2025-02-25 16:52:29
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=c01bc3e869d4575c4efd16989d8ef58bcbb14325 commit c01bc3e869d4575c4efd16989d8ef58bcbb14325 Author: Petr Pavlu <pet...@da...> Date: Tue Apr 11 19:30:42 2023 +0000 riscv64: Add initial support: new port-specific test files The following people contributed to the initial RISC-V support: Petr Pavlu <pet...@da...> Xeonacid <h.d...@gm...> laokz <la...@fo...> Chelsea E. Manning <me...@xy...> zhaomingxin <zha...@al...> Jojo R <rj...@li...> https://bugs.kde.org/show_bug.cgi?id=493507 Diff: --- memcheck/tests/riscv64-linux/Makefile.am | 18 + memcheck/tests/riscv64-linux/context_float.c | 548 ++++++ .../tests/riscv64-linux/context_float.stderr.exp | 299 ++++ .../tests/riscv64-linux/context_float.stdout.exp | 102 ++ memcheck/tests/riscv64-linux/context_float.vgtest | 2 + memcheck/tests/riscv64-linux/context_integer.c | 374 ++++ .../tests/riscv64-linux/context_integer.stderr.exp | 216 +++ .../tests/riscv64-linux/context_integer.stdout.exp | 69 + .../tests/riscv64-linux/context_integer.vgtest | 2 + memcheck/tests/riscv64-linux/filter_stderr | 3 + memcheck/tests/riscv64-linux/scalar.c | 127 ++ memcheck/tests/riscv64-linux/scalar.stderr.exp | 156 ++ memcheck/tests/riscv64-linux/scalar.vgtest | 3 + none/tests/riscv64/Makefile.am | 31 + none/tests/riscv64/allexec.c | 1 + none/tests/riscv64/atomic.c | 280 +++ none/tests/riscv64/atomic.stderr.exp | 0 none/tests/riscv64/atomic.stdout.exp | 467 +++++ none/tests/riscv64/atomic.vgtest | 2 + none/tests/riscv64/compressed.c | 456 +++++ none/tests/riscv64/compressed.stderr.exp | 0 none/tests/riscv64/compressed.stdout.exp | 917 ++++++++++ none/tests/riscv64/compressed.vgtest | 2 + none/tests/riscv64/csr.c | 96 + none/tests/riscv64/csr.stderr.exp | 0 none/tests/riscv64/csr.stdout.exp | 145 ++ none/tests/riscv64/csr.vgtest | 2 + none/tests/riscv64/filter_stderr | 3 + none/tests/riscv64/float32.c | 1588 +++++++++++++++++ none/tests/riscv64/float32.stderr.exp | 0 none/tests/riscv64/float32.stdout.exp | 1556 ++++++++++++++++ none/tests/riscv64/float32.vgtest | 2 + none/tests/riscv64/float64.c | 1580 +++++++++++++++++ none/tests/riscv64/float64.stderr.exp | 0 none/tests/riscv64/float64.stdout.exp | 1551 ++++++++++++++++ none/tests/riscv64/float64.vgtest | 2 + none/tests/riscv64/integer.c | 823 +++++++++ none/tests/riscv64/integer.stderr.exp | 0 none/tests/riscv64/integer.stdout.exp | 1858 ++++++++++++++++++++ none/tests/riscv64/integer.vgtest | 2 + none/tests/riscv64/muldiv.c | 351 ++++ none/tests/riscv64/muldiv.stderr.exp | 0 none/tests/riscv64/muldiv.stdout.exp | 435 +++++ none/tests/riscv64/muldiv.vgtest | 2 + none/tests/riscv64/testinst.h | 758 ++++++++ 45 files changed, 14829 insertions(+) diff --git a/memcheck/tests/riscv64-linux/Makefile.am b/memcheck/tests/riscv64-linux/Makefile.am new file mode 100644 index 0000000000..b2757b7cae --- /dev/null +++ b/memcheck/tests/riscv64-linux/Makefile.am @@ -0,0 +1,18 @@ + +include $(top_srcdir)/Makefile.tool-tests.am + +dist_noinst_SCRIPTS = filter_stderr + +EXTRA_DIST = \ + context_float.stdout.exp context_float.stderr.exp context_float.vgtest \ + context_integer.stdout.exp context_integer.stderr.exp context_integer.vgtest \ + scalar.stderr.exp scalar.vgtest + +check_PROGRAMS = \ + context_float \ + context_integer \ + scalar + +AM_CFLAGS += @FLAG_M64@ +AM_CXXFLAGS += @FLAG_M64@ +AM_CCASFLAGS += @FLAG_M64@ diff --git a/memcheck/tests/riscv64-linux/context_float.c b/memcheck/tests/riscv64-linux/context_float.c new file mode 100644 index 0000000000..462385a5cf --- /dev/null +++ b/memcheck/tests/riscv64-linux/context_float.c @@ -0,0 +1,548 @@ +/* Test if values in floating-point registers are correctly propagated into and + out of a signal handler and also check that the same applies for + uninitialised values and their origins. + + Register usage in the test: + before signal -> in signal handler -> after return + f0 -- 0,def -> unchanged -> 0,def + f1 -- 0,undef -> unchanged -> 0,undef + f2 -- 0,def -> set to 0,undef -> 0,undef + f3 -- 0,undef -> set to 0,def -> 0,def + f4 -- 1,def -> increment by 1,def -> 2,def + f5 -- 1,undef -> increment by 1,def -> 2,undef + f6 -- 1,def -> increment by 1,undef -> 2,undef + f7 -- 1,undef -> increment by 1,undef -> 2,undef + f8 -- DBL_MAX,def -> unchanged -> DBL_MAX,def + f9 -- DBL_MAX,undef -> unchanged -> DBL_MAX,undef + f10 -- DBL_MAX,def -> set to 0,undef -> 0,undef + f11 -- DBL_MAX,undef -> set to 0,def -> 0,def + f12 -- 0,def -> set to DBL_MAX,def -> DBL_MAX,def + f13 -- 0,undef -> set to DBL_MAX,undef -> DBL_MAX,undef + f14 -- 0,def -> decrement by 0,def -> 0,def + f15 -- 0,undef -> decrement by 0,def -> 0,undef + f16 -- 0,def -> decrement by 0,undef -> 0,undef + f17 -- 0,undef -> decrement by 0,undef -> 0,undef + f18 -- 0,def -> decrement by 1,def -> -1,def + f19 -- 0,undef -> decrement by 1,def -> -1,undef + f20 -- 0,def -> decrement by 1,undef -> -1,undef + f21 -- 0,undef -> decrement by 1,undef -> -1,undef + f22-f30 -- 0,def -> set to 1,undef -> 1,undef + f31 -- 1,undef -> set 0,def -> 0,def + fcsr: + fflags -- 0b10101,def -> set to 0b01010,undef -> 0b01010,undef + frm -- 0b001,undef -> set to 0b100,def -> 0b100,def + */ + +#include <assert.h> +#include <float.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/syscall.h> +#include <sys/ucontext.h> +#include <unistd.h> +#include <valgrind.h> + +typedef union { + unsigned long u64; + double f64; +} uf64; + +static ucontext_t uc; +static unsigned long x0, x1; +static unsigned long dbl_max, dbl_p1, dbl_m1, dbl_p2; + +static void sighandler(int sig, siginfo_t* sip, void* arg) +{ + ucontext_t* ucp = (ucontext_t*)arg; + + uc = *ucp; + + /* Reset fcsr so its undefinedness doesn't affect the following calculations. + */ + __asm__ __volatile__("fscsr zero"); + +#define FPREG_MOD(fpreg, op, mod) \ + do { \ + uf64 t1, t2; \ + t1.u64 = fpreg; \ + t2.u64 = mod; \ + t1.f64 op t2.f64; \ + fpreg = t1.u64; \ + } while (0) + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[2], =, x0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[3], =, 0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[4], +=, dbl_p1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[5], +=, dbl_p1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[6], +=, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[7], +=, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[10], =, x0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[11], =, 0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[12], =, dbl_max); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[13], =, dbl_max + x0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[14], -=, 0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[15], -=, 0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[16], -=, x0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[17], -=, x0); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[18], -=, dbl_p1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[19], -=, dbl_p1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[20], -=, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[21], -=, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[22], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[23], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[24], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[25], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[26], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[27], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[28], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[29], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[30], =, dbl_p1 + x1); + FPREG_MOD(ucp->uc_mcontext.__fpregs.__d.__f[31], =, 0); +#undef FPREG_MOD + + ucp->uc_mcontext.__fpregs.__d.__fcsr = + 0b100 << 5 | ((0b01010 | x0) & 0b11111); +} + +int main(void) +{ + /* Uninitialised, but we know px0[0] is 0x0. */ + unsigned long* px0 = malloc(sizeof(*px0)); + x0 = px0[0]; + + /* Uninitialised, but we know px1[0] is 0x0. */ + unsigned long* px1 = malloc(sizeof(*px1)); + x1 = px1[0]; + + uf64 tmp; + tmp.f64 = DBL_MAX; + dbl_max = tmp.u64; + tmp.f64 = 1.0; + dbl_p1 = tmp.u64; + tmp.f64 = -1.0; + dbl_m1 = tmp.u64; + tmp.f64 = 2.0; + dbl_p2 = tmp.u64; + + struct sigaction sa = {}; + sa.sa_sigaction = sighandler; + if (sigaction(SIGUSR1, &sa, NULL)) { + perror("sigaction"); + return 1; + } + + unsigned long regs_in[33] = { + 0, + x0, + 0, + x0, + dbl_p1, + dbl_p1 + x1, + dbl_p1, + dbl_p1 + x1, + dbl_max, + dbl_max + x0, + dbl_max, + dbl_max + x0, + 0, + x0, + 0, + x0, + 0, + x0, + 0, + x0, + 0, + x0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + dbl_p1 + x1, + ((0b001 | x0) & 0b111) << 5 | 0b10101, + }; + unsigned long regs_out[33] = {}; + + pid_t pid = getpid(); + register unsigned long* t0 asm("t0") = regs_in; + register unsigned long* t1 asm("t1") = regs_out; + register unsigned long a7 asm("a7") = SYS_kill; + register unsigned long a0 asm("a0") = pid; + register unsigned long a1 asm("a1") = SIGUSR1; + __asm__ __volatile__( + /* Spill all test registers, keep the 16-byte sp alignment. */ + "add sp, sp, -272\n\t" + "fsd f0, 0(sp)\n\t" + "fsd f1, 8(sp)\n\t" + "fsd f2, 16(sp)\n\t" + "fsd f3, 24(sp)\n\t" + "fsd f4, 32(sp)\n\t" + "fsd f5, 40(sp)\n\t" + "fsd f6, 48(sp)\n\t" + "fsd f7, 56(sp)\n\t" + "fsd f8, 64(sp)\n\t" + "fsd f9, 72(sp)\n\t" + "fsd f10, 80(sp)\n\t" + "fsd f11, 88(sp)\n\t" + "fsd f12, 96(sp)\n\t" + "fsd f13, 104(sp)\n\t" + "fsd f14, 112(sp)\n\t" + "fsd f15, 120(sp)\n\t" + "fsd f16, 128(sp)\n\t" + "fsd f17, 136(sp)\n\t" + "fsd f18, 144(sp)\n\t" + "fsd f19, 152(sp)\n\t" + "fsd f20, 160(sp)\n\t" + "fsd f21, 168(sp)\n\t" + "fsd f22, 176(sp)\n\t" + "fsd f23, 184(sp)\n\t" + "fsd f24, 192(sp)\n\t" + "fsd f25, 200(sp)\n\t" + "fsd f26, 208(sp)\n\t" + "fsd f27, 216(sp)\n\t" + "fsd f28, 224(sp)\n\t" + "fsd f29, 232(sp)\n\t" + "fsd f30, 240(sp)\n\t" + "fsd f31, 248(sp)\n\t" + "frcsr t2\n\t" + "sd t2, 256(sp)\n\t" + + /* Set values in the test registers. */ + "fld f0, 0(%[in])\n\t" + "fld f1, 8(%[in])\n\t" + "fld f2, 16(%[in])\n\t" + "fld f3, 24(%[in])\n\t" + "fld f4, 32(%[in])\n\t" + "fld f5, 40(%[in])\n\t" + "fld f6, 48(%[in])\n\t" + "fld f7, 56(%[in])\n\t" + "fld f8, 64(%[in])\n\t" + "fld f9, 72(%[in])\n\t" + "fld f10, 80(%[in])\n\t" + "fld f11, 88(%[in])\n\t" + "fld f12, 96(%[in])\n\t" + "fld f13, 104(%[in])\n\t" + "fld f14, 112(%[in])\n\t" + "fld f15, 120(%[in])\n\t" + "fld f16, 128(%[in])\n\t" + "fld f17, 136(%[in])\n\t" + "fld f18, 144(%[in])\n\t" + "fld f19, 152(%[in])\n\t" + "fld f20, 160(%[in])\n\t" + "fld f21, 168(%[in])\n\t" + "fld f22, 176(%[in])\n\t" + "fld f23, 184(%[in])\n\t" + "fld f24, 192(%[in])\n\t" + "fld f25, 200(%[in])\n\t" + "fld f26, 208(%[in])\n\t" + "fld f27, 216(%[in])\n\t" + "fld f28, 224(%[in])\n\t" + "fld f29, 232(%[in])\n\t" + "fld f30, 240(%[in])\n\t" + "fld f31, 248(%[in])\n\t" + "ld t2, 256(%[in])\n\t" + "fscsr t2\n\t" + + /* Trigger the signal handler. */ + "ecall\n\t" + + /* Store updated values in the test registers. */ + "fsd f0, 0(%[out])\n\t" + "fsd f1, 8(%[out])\n\t" + "fsd f2, 16(%[out])\n\t" + "fsd f3, 24(%[out])\n\t" + "fsd f4, 32(%[out])\n\t" + "fsd f5, 40(%[out])\n\t" + "fsd f6, 48(%[out])\n\t" + "fsd f7, 56(%[out])\n\t" + "fsd f8, 64(%[out])\n\t" + "fsd f9, 72(%[out])\n\t" + "fsd f10, 80(%[out])\n\t" + "fsd f11, 88(%[out])\n\t" + "fsd f12, 96(%[out])\n\t" + "fsd f13, 104(%[out])\n\t" + "fsd f14, 112(%[out])\n\t" + "fsd f15, 120(%[out])\n\t" + "fsd f16, 128(%[out])\n\t" + "fsd f17, 136(%[out])\n\t" + "fsd f18, 144(%[out])\n\t" + "fsd f19, 152(%[out])\n\t" + "fsd f20, 160(%[out])\n\t" + "fsd f21, 168(%[out])\n\t" + "fsd f22, 176(%[out])\n\t" + "fsd f23, 184(%[out])\n\t" + "fsd f24, 192(%[out])\n\t" + "fsd f25, 200(%[out])\n\t" + "fsd f26, 208(%[out])\n\t" + "fsd f27, 216(%[out])\n\t" + "fsd f28, 224(%[out])\n\t" + "fsd f29, 232(%[out])\n\t" + "fsd f30, 240(%[out])\n\t" + "fsd f31, 248(%[out])\n\t" + "frcsr t2\n\t" + "sd t2, 256(%[out])\n\t" + + /* Restore their original values. */ + "fld f0, 0(sp)\n\t" + "fld f1, 8(sp)\n\t" + "fld f2, 16(sp)\n\t" + "fld f3, 24(sp)\n\t" + "fld f4, 32(sp)\n\t" + "fld f5, 40(sp)\n\t" + "fld f6, 48(sp)\n\t" + "fld f7, 56(sp)\n\t" + "fld f8, 64(sp)\n\t" + "fld f9, 72(sp)\n\t" + "fld f10, 80(sp)\n\t" + "fld f11, 88(sp)\n\t" + "fld f12, 96(sp)\n\t" + "fld f13, 104(sp)\n\t" + "fld f14, 112(sp)\n\t" + "fld f15, 120(sp)\n\t" + "fld f16, 128(sp)\n\t" + "fld f17, 136(sp)\n\t" + "fld f18, 144(sp)\n\t" + "fld f19, 152(sp)\n\t" + "fld f20, 160(sp)\n\t" + "fld f21, 168(sp)\n\t" + "fld f22, 176(sp)\n\t" + "fld f23, 184(sp)\n\t" + "fld f24, 192(sp)\n\t" + "fld f25, 200(sp)\n\t" + "fld f26, 208(sp)\n\t" + "fld f27, 216(sp)\n\t" + "fld f28, 224(sp)\n\t" + "fld f29, 232(sp)\n\t" + "fld f30, 240(sp)\n\t" + "fld f31, 248(sp)\n\t" + "ld t2, 256(sp)\n\t" + "fscsr t2\n\t" + "add sp, sp, 272\n\t" + : + : [in] "r"(t0), [out] "r"(t1), "r"(a7), "r"(a0), "r"(a1) + : "t2", "memory"); + + printf("Values before the signal:\n"); + VALGRIND_DISABLE_ERROR_REPORTING; + printf(" f0=%#lx\n", regs_in[0]); + printf(" f1=%#lx\n", regs_in[1]); + printf(" f2=%#lx\n", regs_in[2]); + printf(" f3=%#lx\n", regs_in[3]); + printf(" f4=%#lx\n", regs_in[4]); + printf(" f5=%#lx\n", regs_in[5]); + printf(" f6=%#lx\n", regs_in[6]); + printf(" f7=%#lx\n", regs_in[7]); + printf(" f8=%#lx\n", regs_in[8]); + printf(" f9=%#lx\n", regs_in[9]); + printf(" f10=%#lx\n", regs_in[10]); + printf(" f11=%#lx\n", regs_in[11]); + printf(" f12=%#lx\n", regs_in[12]); + printf(" f13=%#lx\n", regs_in[13]); + printf(" f14=%#lx\n", regs_in[14]); + printf(" f15=%#lx\n", regs_in[15]); + printf(" f16=%#lx\n", regs_in[16]); + printf(" f17=%#lx\n", regs_in[17]); + printf(" f18=%#lx\n", regs_in[18]); + printf(" f19=%#lx\n", regs_in[19]); + printf(" f20=%#lx\n", regs_in[20]); + printf(" f21=%#lx\n", regs_in[21]); + printf(" f22=%#lx\n", regs_in[22]); + printf(" f23=%#lx\n", regs_in[23]); + printf(" f24=%#lx\n", regs_in[24]); + printf(" f25=%#lx\n", regs_in[25]); + printf(" f26=%#lx\n", regs_in[26]); + printf(" f27=%#lx\n", regs_in[27]); + printf(" f28=%#lx\n", regs_in[28]); + printf(" f29=%#lx\n", regs_in[29]); + printf(" f30=%#lx\n", regs_in[30]); + printf(" f31=%#lx\n", regs_in[31]); + printf(" fcsr=%#lx\n", regs_in[32]); + VALGRIND_ENABLE_ERROR_REPORTING; + /* Check which registers contain uninitialized values. */ + assert(regs_in[0] == 0); + assert(regs_in[1] == 0); + assert(regs_in[2] == 0); + assert(regs_in[3] == 0); + assert(regs_in[4] == dbl_p1); + assert(regs_in[5] == dbl_p1); + assert(regs_in[6] == dbl_p1); + assert(regs_in[7] == dbl_p1); + assert(regs_in[8] == dbl_max); + assert(regs_in[9] == dbl_max); + assert(regs_in[10] == dbl_max); + assert(regs_in[11] == dbl_max); + assert(regs_in[12] == 0); + assert(regs_in[13] == 0); + assert(regs_in[14] == 0); + assert(regs_in[15] == 0); + assert(regs_in[16] == 0); + assert(regs_in[17] == 0); + assert(regs_in[18] == 0); + assert(regs_in[19] == 0); + assert(regs_in[20] == 0); + assert(regs_in[21] == 0); + assert(regs_in[22] == 0); + assert(regs_in[23] == 0); + assert(regs_in[24] == 0); + assert(regs_in[25] == 0); + assert(regs_in[26] == 0); + assert(regs_in[27] == 0); + assert(regs_in[28] == 0); + assert(regs_in[29] == 0); + assert(regs_in[30] == 0); + assert(regs_in[31] == dbl_p1); + assert(((regs_in[32] >> 0) & 0b11111) == 0b10101); + assert(((regs_in[32] >> 5) & 0b111) == 0b001); + + printf("Values in the signal handler:\n"); + VALGRIND_DISABLE_ERROR_REPORTING; + printf(" f0=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[0]); + printf(" f1=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[1]); + printf(" f2=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[2]); + printf(" f3=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[3]); + printf(" f4=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[4]); + printf(" f5=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[5]); + printf(" f6=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[6]); + printf(" f7=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[7]); + printf(" f8=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[8]); + printf(" f9=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[9]); + printf(" f10=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[10]); + printf(" f11=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[11]); + printf(" f12=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[12]); + printf(" f13=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[13]); + printf(" f14=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[14]); + printf(" f15=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[15]); + printf(" f16=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[16]); + printf(" f17=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[17]); + printf(" f18=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[18]); + printf(" f19=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[19]); + printf(" f20=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[20]); + printf(" f21=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[21]); + printf(" f22=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[22]); + printf(" f23=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[23]); + printf(" f24=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[24]); + printf(" f25=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[25]); + printf(" f26=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[26]); + printf(" f27=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[27]); + printf(" f28=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[28]); + printf(" f29=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[29]); + printf(" f30=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[30]); + printf(" f31=%#llx\n", uc.uc_mcontext.__fpregs.__d.__f[31]); + printf(" fcsr=%#x\n", uc.uc_mcontext.__fpregs.__d.__fcsr); + VALGRIND_ENABLE_ERROR_REPORTING; + assert(uc.uc_mcontext.__fpregs.__d.__f[0] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[1] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[2] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[3] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[4] == dbl_p1); + assert(uc.uc_mcontext.__fpregs.__d.__f[5] == dbl_p1); + assert(uc.uc_mcontext.__fpregs.__d.__f[6] == dbl_p1); + assert(uc.uc_mcontext.__fpregs.__d.__f[7] == dbl_p1); + assert(uc.uc_mcontext.__fpregs.__d.__f[8] == dbl_max); + assert(uc.uc_mcontext.__fpregs.__d.__f[9] == dbl_max); + assert(uc.uc_mcontext.__fpregs.__d.__f[10] == dbl_max); + assert(uc.uc_mcontext.__fpregs.__d.__f[11] == dbl_max); + assert(uc.uc_mcontext.__fpregs.__d.__f[12] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[13] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[14] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[15] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[16] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[17] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[18] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[19] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[20] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[21] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[22] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[23] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[24] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[25] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[26] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[27] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[28] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[29] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[30] == 0); + assert(uc.uc_mcontext.__fpregs.__d.__f[31] == dbl_p1); + assert(((uc.uc_mcontext.__fpregs.__d.__fcsr >> 0) & 0b11111) == 0b10101); + assert(((uc.uc_mcontext.__fpregs.__d.__fcsr >> 5) & 0b111) == 0b001); + + printf("Values after return from the signal handler:\n"); + VALGRIND_DISABLE_ERROR_REPORTING; + printf(" f0=%#lx\n", regs_out[0]); + printf(" f1=%#lx\n", regs_out[1]); + printf(" f2=%#lx\n", regs_out[2]); + printf(" f3=%#lx\n", regs_out[3]); + printf(" f4=%#lx\n", regs_out[4]); + printf(" f5=%#lx\n", regs_out[5]); + printf(" f6=%#lx\n", regs_out[6]); + printf(" f7=%#lx\n", regs_out[7]); + printf(" f8=%#lx\n", regs_out[8]); + printf(" f9=%#lx\n", regs_out[9]); + printf(" f10=%#lx\n", regs_out[10]); + printf(" f11=%#lx\n", regs_out[11]); + printf(" f12=%#lx\n", regs_out[12]); + printf(" f13=%#lx\n", regs_out[13]); + printf(" f14=%#lx\n", regs_out[14]); + printf(" f15=%#lx\n", regs_out[15]); + printf(" f16=%#lx\n", regs_out[16]); + printf(" f17=%#lx\n", regs_out[17]); + printf(" f18=%#lx\n", regs_out[18]); + printf(" f19=%#lx\n", regs_out[19]); + printf(" f20=%#lx\n", regs_out[20]); + printf(" f21=%#lx\n", regs_out[21]); + printf(" f22=%#lx\n", regs_out[22]); + printf(" f23=%#lx\n", regs_out[23]); + printf(" f24=%#lx\n", regs_out[24]); + printf(" f25=%#lx\n", regs_out[25]); + printf(" f26=%#lx\n", regs_out[26]); + printf(" f27=%#lx\n", regs_out[27]); + printf(" f28=%#lx\n", regs_out[28]); + printf(" f29=%#lx\n", regs_out[29]); + printf(" f30=%#lx\n", regs_out[30]); + printf(" f31=%#lx\n", regs_out[31]); + printf(" fcsr=%#lx\n", regs_out[32]); + VALGRIND_ENABLE_ERROR_REPORTING; + assert(regs_out[0] == 0); + assert(regs_out[1] == 0); + assert(regs_out[2] == 0); + assert(regs_out[3] == 0); + assert(regs_out[4] == dbl_p2); + assert(regs_out[5] == dbl_p2); + assert(regs_out[6] == dbl_p2); + assert(regs_out[7] == dbl_p2); + assert(regs_out[8] == dbl_max); + assert(regs_out[9] == dbl_max); + assert(regs_out[10] == 0); + assert(regs_out[11] == 0); + assert(regs_out[12] == dbl_max); + assert(regs_out[13] == dbl_max); + assert(regs_out[14] == 0); + assert(regs_out[15] == 0); + assert(regs_out[16] == 0); + assert(regs_out[17] == 0); + assert(regs_out[18] == dbl_m1); + assert(regs_out[19] == dbl_m1); + assert(regs_out[20] == dbl_m1); + assert(regs_out[21] == dbl_m1); + assert(regs_out[22] == dbl_p1); + assert(regs_out[23] == dbl_p1); + assert(regs_out[24] == dbl_p1); + assert(regs_out[25] == dbl_p1); + assert(regs_out[26] == dbl_p1); + assert(regs_out[27] == dbl_p1); + assert(regs_out[28] == dbl_p1); + assert(regs_out[29] == dbl_p1); + assert(regs_out[30] == dbl_p1); + assert(regs_out[31] == 0); + assert(((regs_out[32] >> 0) & 0b11111) == 0b01010); + assert(((regs_out[32] >> 5) & 0b111) == 0b100); + + free(px0); + free(px1); + + return 0; +} diff --git a/memcheck/tests/riscv64-linux/context_float.stderr.exp b/memcheck/tests/riscv64-linux/context_float.stderr.exp new file mode 100644 index 0000000000..34f59181d5 --- /dev/null +++ b/memcheck/tests/riscv64-linux/context_float.stderr.exp @@ -0,0 +1,299 @@ +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:368) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:370) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:372) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:374) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:376) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:378) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:380) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:382) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:384) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:386) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:388) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:398) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:400) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:439) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:441) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:443) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:445) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:447) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:449) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:451) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:453) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:455) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:457) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:459) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:469) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:471) + Uninitialised value was created + at 0x........: main (context_float.c:177) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:510) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:511) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:514) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:515) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:516) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:518) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:519) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:522) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:524) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:525) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:526) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:528) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:529) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:530) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:531) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:532) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:533) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:534) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:535) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:536) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:537) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:538) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:539) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:114) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_float.c:541) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_float.c:110) + diff --git a/memcheck/tests/riscv64-linux/context_float.stdout.exp b/memcheck/tests/riscv64-linux/context_float.stdout.exp new file mode 100644 index 0000000000..588063bf9e --- /dev/null +++ b/memcheck/tests/riscv64-linux/context_float.stdout.exp @@ -0,0 +1,102 @@ +Values before the signal: + f0=0 + f1=0 + f2=0 + f3=0 + f4=0x3ff0000000000000 + f5=0x3ff0000000000000 + f6=0x3ff0000000000000 + f7=0x3ff0000000000000 + f8=0x7fefffffffffffff + f9=0x7fefffffffffffff + f10=0x7fefffffffffffff + f11=0x7fefffffffffffff + f12=0 + f13=0 + f14=0 + f15=0 + f16=0 + f17=0 + f18=0 + f19=0 + f20=0 + f21=0 + f22=0 + f23=0 + f24=0 + f25=0 + f26=0 + f27=0 + f28=0 + f29=0 + f30=0 + f31=0x3ff0000000000000 + fcsr=0x35 +Values in the signal handler: + f0=0 + f1=0 + f2=0 + f3=0 + f4=0x3ff0000000000000 + f5=0x3ff0000000000000 + f6=0x3ff0000000000000 + f7=0x3ff0000000000000 + f8=0x7fefffffffffffff + f9=0x7fefffffffffffff + f10=0x7fefffffffffffff + f11=0x7fefffffffffffff + f12=0 + f13=0 + f14=0 + f15=0 + f16=0 + f17=0 + f18=0 + f19=0 + f20=0 + f21=0 + f22=0 + f23=0 + f24=0 + f25=0 + f26=0 + f27=0 + f28=0 + f29=0 + f30=0 + f31=0x3ff0000000000000 + fcsr=0x35 +Values after return from the signal handler: + f0=0 + f1=0 + f2=0 + f3=0 + f4=0x4000000000000000 + f5=0x4000000000000000 + f6=0x4000000000000000 + f7=0x4000000000000000 + f8=0x7fefffffffffffff + f9=0x7fefffffffffffff + f10=0 + f11=0 + f12=0x7fefffffffffffff + f13=0x7fefffffffffffff + f14=0 + f15=0 + f16=0 + f17=0 + f18=0xbff0000000000000 + f19=0xbff0000000000000 + f20=0xbff0000000000000 + f21=0xbff0000000000000 + f22=0x3ff0000000000000 + f23=0x3ff0000000000000 + f24=0x3ff0000000000000 + f25=0x3ff0000000000000 + f26=0x3ff0000000000000 + f27=0x3ff0000000000000 + f28=0x3ff0000000000000 + f29=0x3ff0000000000000 + f30=0x3ff0000000000000 + f31=0 + fcsr=0x8a diff --git a/memcheck/tests/riscv64-linux/context_float.vgtest b/memcheck/tests/riscv64-linux/context_float.vgtest new file mode 100644 index 0000000000..0f2a88cd2a --- /dev/null +++ b/memcheck/tests/riscv64-linux/context_float.vgtest @@ -0,0 +1,2 @@ +prog: context_float +vgopts: -q --track-origins=yes diff --git a/memcheck/tests/riscv64-linux/context_integer.c b/memcheck/tests/riscv64-linux/context_integer.c new file mode 100644 index 0000000000..070a9f759b --- /dev/null +++ b/memcheck/tests/riscv64-linux/context_integer.c @@ -0,0 +1,374 @@ +/* Test if values in integer registers are correctly propagated into and out of + a signal handler and also check that the same applies for uninitialised + values and their origins. + + Register usage in the test: + zero (x0) -- unused + ra (x1) -- unused + sp (x2) -- unused + gp (x3) -- unused + tp (x4) -- unused + + t0 (x5) -- holds address of regs_in + t1 (x6) -- holds address of regs_out + a0 (x10) -- current pid + a1 (x11) -- SIGUSR1 + a7 (x17) -- SYS_kill + + before signal -> in signal handler -> after return + t2 (x7) -- 0,def -> unchanged -> 0,def + s0 (x8) -- 0,undef -> unchanged -> 0,undef + s1 (x9) -- 0,def -> set to 0,undef -> 0,undef + a2 (x12) -- 0,undef -> set to 0,def -> 0,def + a3 (x13) -- 1,def -> increment by 1,def -> 2,def + a4 (x14) -- 1,undef -> increment by 1,def -> 2,undef + a5 (x15) -- 1,def -> increment by 1,undef -> 2,undef + a6 (x16) -- 1,undef -> increment by 1,undef -> 2,undef + s2 (x18) -- ULONG_MAX,def -> unchanged -> ULONG_MAX,def + s3 (x19) -- ULONG_MAX,undef -> unchanged -> ULONG_MAX,undef + s4 (x20) -- ULONG_MAX,def -> set to 0,undef -> 0,undef + s5 (x21) -- ULONG_MAX,undef -> set to 0,def -> 0,def + s6 (x22) -- 0,def -> set to ULONG_MAX,def -> ULONG_MAX,def + s7 (x23) -- 0,undef -> set to ULONG_MAX,undef -> ULONG_MAX,undef + s8 (x24) -- 0,def -> decrement by 0,def -> 0,def + s9 (x25) -- 0,undef -> decrement by 0,def -> 0,undef + s10 (x26) -- 0,def -> decrement by 0,undef -> 0,undef + s11 (x27) -- 0,undef -> decrement by 0,undef -> 0,undef + t3 (x28) -- 0,def -> decrement by 1,def -> ULONG_MAX,def + t4 (x29) -- 0,undef -> decrement by 1,def -> ULONG_MAX,undef + t5 (x30) -- 0,def -> decrement by 1,undef -> ULONG_MAX,undef + t6 (x31) -- 0,undef -> decrement by 1,undef -> ULONG_MAX,undef + */ + +#include <assert.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/syscall.h> +#include <sys/ucontext.h> +#include <unistd.h> +#include <valgrind.h> + +static ucontext_t uc; +static unsigned long x0, x1; + +static void sighandler(int sig, siginfo_t* sip, void* arg) +{ + ucontext_t* ucp = (ucontext_t*)arg; + + uc = *ucp; + + ucp->uc_mcontext.__gregs[9] = x0; + ucp->uc_mcontext.__gregs[12] = 0; + ucp->uc_mcontext.__gregs[13] += 1; + ucp->uc_mcontext.__gregs[14] += 1; + ucp->uc_mcontext.__gregs[15] += x1; + ucp->uc_mcontext.__gregs[16] += x1; + ucp->uc_mcontext.__gregs[20] = x0; + ucp->uc_mcontext.__gregs[21] = 0; + ucp->uc_mcontext.__gregs[22] = ULONG_MAX; + ucp->uc_mcontext.__gregs[23] = ULONG_MAX + x0; + ucp->uc_mcontext.__gregs[24] -= 0; + ucp->uc_mcontext.__gregs[25] -= 0; + ucp->uc_mcontext.__gregs[26] -= x0; + ucp->uc_mcontext.__gregs[27] -= x0; + ucp->uc_mcontext.__gregs[28] -= 1; + ucp->uc_mcontext.__gregs[29] -= 1; + ucp->uc_mcontext.__gregs[30] -= x1; + ucp->uc_mcontext.__gregs[31] -= x1; +} + +int main(void) +{ + /* Uninitialised, but we know px0[0] is 0x0. */ + unsigned long* px0 = malloc(sizeof(*px0)); + x0 = px0[0]; + + /* Uninitialised, but we know px1[0] is 0x0. */ + unsigned long* px1 = malloc(sizeof(*px1)); + x1 = px1[0] + 1; + + struct sigaction sa = {}; + sa.sa_sigaction = sighandler; + if (sigaction(SIGUSR1, &sa, NULL)) { + perror("sigaction"); + return 1; + } + + unsigned long regs_in[22] = { + 0, x0, + 0, x0, + 1, x1, + 1, x1, + ULONG_MAX, ULONG_MAX + x0, + ULONG_MAX, ULONG_MAX + x0, + 0, x0, + 0, x0, + 0, x0, + 0, x0, + 0, x0, + }; + unsigned long regs_out[22] = {}; + + pid_t pid = getpid(); + register unsigned long* t0 asm("t0") = regs_in; + register unsigned long* t1 asm("t1") = regs_out; + register unsigned long a7 asm("a7") = SYS_kill; + register unsigned long a0 asm("a0") = pid; + register unsigned long a1 asm("a1") = SIGUSR1; + __asm__ __volatile__( + /* Spill all test registers, keep the 16-byte sp alignment. */ + "add sp, sp, -176\n\t" + "sd t2, 0(sp)\n\t" + "sd s0, 8(sp)\n\t" + "sd s1, 16(sp)\n\t" + "sd a2, 24(sp)\n\t" + "sd a3, 32(sp)\n\t" + "sd a4, 40(sp)\n\t" + "sd a5, 48(sp)\n\t" + "sd a6, 56(sp)\n\t" + "sd s2, 64(sp)\n\t" + "sd s3, 72(sp)\n\t" + "sd s4, 80(sp)\n\t" + "sd s5, 88(sp)\n\t" + "sd s6, 96(sp)\n\t" + "sd s7, 104(sp)\n\t" + "sd s8, 112(sp)\n\t" + "sd s9, 120(sp)\n\t" + "sd s10, 128(sp)\n\t" + "sd s11, 136(sp)\n\t" + "sd t3, 144(sp)\n\t" + "sd t4, 152(sp)\n\t" + "sd t5, 160(sp)\n\t" + "sd t6, 168(sp)\n\t" + + /* Set values in the test registers. */ + "ld t2, 0(%[in])\n\t" + "ld s0, 8(%[in])\n\t" + "ld s1, 16(%[in])\n\t" + "ld a2, 24(%[in])\n\t" + "ld a3, 32(%[in])\n\t" + "ld a4, 40(%[in])\n\t" + "ld a5, 48(%[in])\n\t" + "ld a6, 56(%[in])\n\t" + "ld s2, 64(%[in])\n\t" + "ld s3, 72(%[in])\n\t" + "ld s4, 80(%[in])\n\t" + "ld s5, 88(%[in])\n\t" + "ld s6, 96(%[in])\n\t" + "ld s7, 104(%[in])\n\t" + "ld s8, 112(%[in])\n\t" + "ld s9, 120(%[in])\n\t" + "ld s10, 128(%[in])\n\t" + "ld s11, 136(%[in])\n\t" + "ld t3, 144(%[in])\n\t" + "ld t4, 152(%[in])\n\t" + "ld t5, 160(%[in])\n\t" + "ld t6, 168(%[in])\n\t" + + /* Trigger the signal handler. */ + "ecall\n\t" + + /* Store updated values in the test registers. */ + "sd t2, 0(%[out])\n\t" + "sd s0, 8(%[out])\n\t" + "sd s1, 16(%[out])\n\t" + "sd a2, 24(%[out])\n\t" + "sd a3, 32(%[out])\n\t" + "sd a4, 40(%[out])\n\t" + "sd a5, 48(%[out])\n\t" + "sd a6, 56(%[out])\n\t" + "sd s2, 64(%[out])\n\t" + "sd s3, 72(%[out])\n\t" + "sd s4, 80(%[out])\n\t" + "sd s5, 88(%[out])\n\t" + "sd s6, 96(%[out])\n\t" + "sd s7, 104(%[out])\n\t" + "sd s8, 112(%[out])\n\t" + "sd s9, 120(%[out])\n\t" + "sd s10, 128(%[out])\n\t" + "sd s11, 136(%[out])\n\t" + "sd t3, 144(%[out])\n\t" + "sd t4, 152(%[out])\n\t" + "sd t5, 160(%[out])\n\t" + "sd t6, 168(%[out])\n\t" + + /* Restore their original values. */ + "ld t2, 0(sp)\n\t" + "ld s0, 8(sp)\n\t" + "ld s1, 16(sp)\n\t" + "ld a2, 24(sp)\n\t" + "ld a3, 32(sp)\n\t" + "ld a4, 40(sp)\n\t" + "ld a5, 48(sp)\n\t" + "ld a6, 56(sp)\n\t" + "ld s2, 64(sp)\n\t" + "ld s3, 72(sp)\n\t" + "ld s4, 80(sp)\n\t" + "ld s5, 88(sp)\n\t" + "ld s6, 96(sp)\n\t" + "ld s7, 104(sp)\n\t" + "ld s8, 112(sp)\n\t" + "ld s9, 120(sp)\n\t" + "ld s10, 128(sp)\n\t" + "ld s11, 136(sp)\n\t" + "ld t3, 144(sp)\n\t" + "ld t4, 152(sp)\n\t" + "ld t5, 160(sp)\n\t" + "ld t6, 168(sp)\n\t" + "add sp, sp, 176\n\t" + : + : [in] "r"(t0), [out] "r"(t1), "r"(a7), "r"(a0), "r"(a1) + : "memory"); + + printf("Values before the signal:\n"); + VALGRIND_DISABLE_ERROR_REPORTING; + printf(" t2=%#lx\n", regs_in[0]); + printf(" s0=%#lx\n", regs_in[1]); + printf(" s1=%#lx\n", regs_in[2]); + printf(" a2=%#lx\n", regs_in[3]); + printf(" a3=%#lx\n", regs_in[4]); + printf(" a4=%#lx\n", regs_in[5]); + printf(" a5=%#lx\n", regs_in[6]); + printf(" a6=%#lx\n", regs_in[7]); + printf(" s2=%#lx\n", regs_in[8]); + printf(" s3=%#lx\n", regs_in[9]); + printf(" s4=%#lx\n", regs_in[10]); + printf(" s5=%#lx\n", regs_in[11]); + printf(" s6=%#lx\n", regs_in[12]); + printf(" s7=%#lx\n", regs_in[13]); + printf(" s8=%#lx\n", regs_in[14]); + printf(" s9=%#lx\n", regs_in[15]); + printf(" s10=%#lx\n", regs_in[16]); + printf(" s11=%#lx\n", regs_in[17]); + printf(" t3=%#lx\n", regs_in[18]); + printf(" t4=%#lx\n", regs_in[19]); + printf(" t5=%#lx\n", regs_in[20]); + printf(" t6=%#lx\n", regs_in[21]); + VALGRIND_ENABLE_ERROR_REPORTING; + /* Check which registers contain uninitialized values. */ + assert(regs_in[0] == 0); + assert(regs_in[1] == 0); + assert(regs_in[2] == 0); + assert(regs_in[3] == 0); + assert(regs_in[4] == 1); + assert(regs_in[5] == 1); + assert(regs_in[6] == 1); + assert(regs_in[7] == 1); + assert(regs_in[8] == ULONG_MAX); + assert(regs_in[9] == ULONG_MAX); + assert(regs_in[10] == ULONG_MAX); + assert(regs_in[11] == ULONG_MAX); + assert(regs_in[12] == 0); + assert(regs_in[13] == 0); + assert(regs_in[14] == 0); + assert(regs_in[15] == 0); + assert(regs_in[16] == 0); + assert(regs_in[17] == 0); + assert(regs_in[18] == 0); + assert(regs_in[19] == 0); + assert(regs_in[20] == 0); + assert(regs_in[21] == 0); + + printf("Values in the signal handler:\n"); + VALGRIND_DISABLE_ERROR_REPORTING; + printf(" t2=%#lx\n", uc.uc_mcontext.__gregs[7]); + printf(" s0=%#lx\n", uc.uc_mcontext.__gregs[8]); + printf(" s1=%#lx\n", uc.uc_mcontext.__gregs[9]); + printf(" a2=%#lx\n", uc.uc_mcontext.__gregs[12]); + printf(" a3=%#lx\n", uc.uc_mcontext.__gregs[13]); + printf(" a4=%#lx\n", uc.uc_mcontext.__gregs[14]); + printf(" a5=%#lx\n", uc.uc_mcontext.__gregs[15]); + printf(" a6=%#lx\n", uc.uc_mcontext.__gregs[16]); + printf(" s2=%#lx\n", uc.uc_mcontext.__gregs[18]); + printf(" s3=%#lx\n", uc.uc_mcontext.__gregs[19]); + printf(" s4=%#lx\n", uc.uc_mcontext.__gregs[20]); + printf(" s5=%#lx\n", uc.uc_mcontext.__gregs[21]); + printf(" s6=%#lx\n", uc.uc_mcontext.__gregs[22]); + printf(" s7=%#lx\n", uc.uc_mcontext.__gregs[23]); + printf(" s8=%#lx\n", uc.uc_mcontext.__gregs[24]); + printf(" s9=%#lx\n", uc.uc_mcontext.__gregs[25]); + printf(" s10=%#lx\n", uc.uc_mcontext.__gregs[26]); + printf(" s11=%#lx\n", uc.uc_mcontext.__gregs[27]); + printf(" t3=%#lx\n", uc.uc_mcontext.__gregs[28]); + printf(" t4=%#lx\n", uc.uc_mcontext.__gregs[29]); + printf(" t5=%#lx\n", uc.uc_mcontext.__gregs[30]); + printf(" t6=%#lx\n", uc.uc_mcontext.__gregs[31]); + VALGRIND_ENABLE_ERROR_REPORTING; + assert(uc.uc_mcontext.__gregs[7] == 0); + assert(uc.uc_mcontext.__gregs[8] == 0); + assert(uc.uc_mcontext.__gregs[9] == 0); + assert(uc.uc_mcontext.__gregs[12] == 0); + assert(uc.uc_mcontext.__gregs[13] == 1); + assert(uc.uc_mcontext.__gregs[14] == 1); + assert(uc.uc_mcontext.__gregs[15] == 1); + assert(uc.uc_mcontext.__gregs[16] == 1); + assert(uc.uc_mcontext.__gregs[18] == ULONG_MAX); + assert(uc.uc_mcontext.__gregs[19] == ULONG_MAX); + assert(uc.uc_mcontext.__gregs[20] == ULONG_MAX); + assert(uc.uc_mcontext.__gregs[21] == ULONG_MAX); + assert(uc.uc_mcontext.__gregs[22] == 0); + assert(uc.uc_mcontext.__gregs[23] == 0); + assert(uc.uc_mcontext.__gregs[24] == 0); + assert(uc.uc_mcontext.__gregs[25] == 0); + assert(uc.uc_mcontext.__gregs[26] == 0); + assert(uc.uc_mcontext.__gregs[27] == 0); + assert(uc.uc_mcontext.__gregs[28] == 0); + assert(uc.uc_mcontext.__gregs[29] == 0); + assert(uc.uc_mcontext.__gregs[30] == 0); + assert(uc.uc_mcontext.__gregs[31] == 0); + + printf("Values after return from the signal handler:\n"); + VALGRIND_DISABLE_ERROR_REPORTING; + printf(" t2=%#lx\n", regs_out[0]); + printf(" s0=%#lx\n", regs_out[1]); + printf(" s1=%#lx\n", regs_out[2]); + printf(" a2=%#lx\n", regs_out[3]); + printf(" a3=%#lx\n", regs_out[4]); + printf(" a4=%#lx\n", regs_out[5]); + printf(" a5=%#lx\n", regs_out[6]); + printf(" a6=%#lx\n", regs_out[7]); + printf(" s2=%#lx\n", regs_out[8]); + printf(" s3=%#lx\n", regs_out[9]); + printf(" s4=%#lx\n", regs_out[10]); + printf(" s5=%#lx\n", regs_out[11]); + printf(" s6=%#lx\n", regs_out[12]); + printf(" s7=%#lx\n", regs_out[13]); + printf(" s8=%#lx\n", regs_out[14]); + printf(" s9=%#lx\n", regs_out[15]); + printf(" s10=%#lx\n", regs_out[16]); + printf(" s11=%#lx\n", regs_out[17]); + printf(" t3=%#lx\n", regs_out[18]); + printf(" t4=%#lx\n", regs_out[19]); + printf(" t5=%#lx\n", regs_out[20]); + printf(" t6=%#lx\n", regs_out[21]); + VALGRIND_ENABLE_ERROR_REPORTING; + assert(regs_out[0] == 0); + assert(regs_out[1] == 0); + assert(regs_out[2] == 0); + assert(regs_out[3] == 0); + assert(regs_out[4] == 2); + assert(regs_out[5] == 2); + assert(regs_out[6] == 2); + assert(regs_out[7] == 2); + assert(regs_out[8] == ULONG_MAX); + assert(regs_out[9] == ULONG_MAX); + assert(regs_out[10] == 0); + assert(regs_out[11] == 0); + assert(regs_out[12] == ULONG_MAX); + assert(regs_out[13] == ULONG_MAX); + assert(regs_out[14] == 0); + assert(regs_out[15] == 0); + assert(regs_out[16] == 0); + assert(regs_out[17] == 0); + assert(regs_out[18] == ULONG_MAX); + assert(regs_out[19] == ULONG_MAX); + assert(regs_out[20] == ULONG_MAX); + assert(regs_out[21] == ULONG_MAX); + + free(px0); + free(px1); + + return 0; +} diff --git a/memcheck/tests/riscv64-linux/context_integer.stderr.exp b/memcheck/tests/riscv64-linux/context_integer.stderr.exp new file mode 100644 index 0000000000..20cf89090e --- /dev/null +++ b/memcheck/tests/riscv64-linux/context_integer.stderr.exp @@ -0,0 +1,216 @@ +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:252) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:254) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:256) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:89) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:258) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:89) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:260) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:262) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:264) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:266) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:268) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:270) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:272) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:300) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:302) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:304) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:89) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:306) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:89) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:308) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:310) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:312) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:314) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:316) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:318) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:320) + Uninitialised value was created by a heap allocation + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (context_integer.c:85) + +Conditional jump or move depends on uninitialised value(s) + at 0x........: main (context_integer.c:348) + Uninitialised value was created by a heap allocation + at 0... [truncated message content] |