#include "../multiarch/noexec.c.inc" static void *arch_mcontext_pc(const mcontext_t *ctx) { return (void *)ctx->psw.addr; } static int arch_mcontext_arg(const mcontext_t *ctx) { return ctx->gregs[2]; } static void arch_flush(void *p, int len) { } extern char noexec_1[]; extern char noexec_2[]; extern char noexec_end[]; asm("noexec_1:\n" " lgfi %r2,1\n" /* %r2 is 0 on entry, set 1. */ "noexec_2:\n" " lgfi %r2,2\n" /* %r2 is 0/1; set 2. */ " br %r14\n" /* return */ "noexec_end:"); extern char exrl_1[]; extern char exrl_2[]; extern char exrl_end[]; asm("exrl_1:\n" " exrl %r0, exrl_2\n" " br %r14\n" "exrl_2:\n" " lgfi %r2,2\n" "exrl_end:"); int main(void) { struct noexec_test noexec_tests[] = { { .name = "fallthrough", .test_code = noexec_1, .test_len = noexec_end - noexec_1, .page_ofs = noexec_1 - noexec_2, .entry_ofs = noexec_1 - noexec_2, .expected_si_ofs = 0, .expected_pc_ofs = 0, .expected_arg = 1, }, { .name = "jump", .test_code = noexec_1, .test_len = noexec_end - noexec_1, .page_ofs = noexec_1 - noexec_2, .entry_ofs = 0, .expected_si_ofs = 0, .expected_pc_ofs = 0, .expected_arg = 0, }, { .name = "exrl", .test_code = exrl_1, .test_len = exrl_end - exrl_1, .page_ofs = exrl_1 - exrl_2, .entry_ofs = exrl_1 - exrl_2, .expected_si_ofs = 0, .expected_pc_ofs = exrl_1 - exrl_2, .expected_arg = 0, }, { .name = "fallthrough [cross]", .test_code = noexec_1, .test_len = noexec_end - noexec_1, .page_ofs = noexec_1 - noexec_2 - 2, .entry_ofs = noexec_1 - noexec_2 - 2, .expected_si_ofs = 0, .expected_pc_ofs = -2, .expected_arg = 1, }, { .name = "jump [cross]", .test_code = noexec_1, .test_len = noexec_end - noexec_1, .page_ofs = noexec_1 - noexec_2 - 2, .entry_ofs = -2, .expected_si_ofs = 0, .expected_pc_ofs = -2, .expected_arg = 0, }, { .name = "exrl [cross]", .test_code = exrl_1, .test_len = exrl_end - exrl_1, .page_ofs = exrl_1 - exrl_2 - 2, .entry_ofs = exrl_1 - exrl_2 - 2, .expected_si_ofs = 0, .expected_pc_ofs = exrl_1 - exrl_2 - 2, .expected_arg = 0, }, }; return test_noexec(noexec_tests, sizeof(noexec_tests) / sizeof(noexec_tests[0])); }