xref: /qemu/tests/tcg/riscv64/noexec.c (revision a976a99a)
1 #include "../multiarch/noexec.c.inc"
2 
3 static void *arch_mcontext_pc(const mcontext_t *ctx)
4 {
5     return (void *)ctx->__gregs[REG_PC];
6 }
7 
8 static int arch_mcontext_arg(const mcontext_t *ctx)
9 {
10     return ctx->__gregs[REG_A0];
11 }
12 
13 static void arch_flush(void *p, int len)
14 {
15     __builtin___clear_cache(p, p + len);
16 }
17 
18 extern char noexec_1[];
19 extern char noexec_2[];
20 extern char noexec_end[];
21 
22 asm(".option push\n"
23     ".option norvc\n"
24     "noexec_1:\n"
25     "   li a0,1\n"       /* a0 is 0 on entry, set 1. */
26     "noexec_2:\n"
27     "   li a0,2\n"      /* a0 is 0/1; set 2. */
28     "   ret\n"
29     "noexec_end:\n"
30     ".option pop");
31 
32 int main(void)
33 {
34     struct noexec_test noexec_tests[] = {
35         {
36             .name = "fallthrough",
37             .test_code = noexec_1,
38             .test_len = noexec_end - noexec_1,
39             .page_ofs = noexec_1 - noexec_2,
40             .entry_ofs = noexec_1 - noexec_2,
41             .expected_si_ofs = 0,
42             .expected_pc_ofs = 0,
43             .expected_arg = 1,
44         },
45         {
46             .name = "jump",
47             .test_code = noexec_1,
48             .test_len = noexec_end - noexec_1,
49             .page_ofs = noexec_1 - noexec_2,
50             .entry_ofs = 0,
51             .expected_si_ofs = 0,
52             .expected_pc_ofs = 0,
53             .expected_arg = 0,
54         },
55         {
56             .name = "fallthrough [cross]",
57             .test_code = noexec_1,
58             .test_len = noexec_end - noexec_1,
59             .page_ofs = noexec_1 - noexec_2 - 2,
60             .entry_ofs = noexec_1 - noexec_2 - 2,
61             .expected_si_ofs = 0,
62             .expected_pc_ofs = -2,
63             .expected_arg = 1,
64         },
65         {
66             .name = "jump [cross]",
67             .test_code = noexec_1,
68             .test_len = noexec_end - noexec_1,
69             .page_ofs = noexec_1 - noexec_2 - 2,
70             .entry_ofs = -2,
71             .expected_si_ofs = 0,
72             .expected_pc_ofs = -2,
73             .expected_arg = 0,
74         },
75     };
76 
77     return test_noexec(noexec_tests,
78                        sizeof(noexec_tests) / sizeof(noexec_tests[0]));
79 }
80