1 #include "../multiarch/noexec.c.inc"
2
arch_mcontext_pc(const mcontext_t * ctx)3 static void *arch_mcontext_pc(const mcontext_t *ctx)
4 {
5 return (void *)ctx->__gregs[REG_PC];
6 }
7
arch_mcontext_arg(const mcontext_t * ctx)8 static int arch_mcontext_arg(const mcontext_t *ctx)
9 {
10 return ctx->__gregs[REG_A0];
11 }
12
arch_flush(void * p,int len)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
main(void)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