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