qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

noexec.c (2867B)


      1 #include "../multiarch/noexec.c.inc"
      2 
      3 static void *arch_mcontext_pc(const mcontext_t *ctx)
      4 {
      5     return (void *)ctx->psw.addr;
      6 }
      7 
      8 static int arch_mcontext_arg(const mcontext_t *ctx)
      9 {
     10     return ctx->gregs[2];
     11 }
     12 
     13 static void arch_flush(void *p, int len)
     14 {
     15 }
     16 
     17 extern char noexec_1[];
     18 extern char noexec_2[];
     19 extern char noexec_end[];
     20 
     21 asm("noexec_1:\n"
     22     "   lgfi %r2,1\n"       /* %r2 is 0 on entry, set 1. */
     23     "noexec_2:\n"
     24     "   lgfi %r2,2\n"       /* %r2 is 0/1; set 2. */
     25     "   br %r14\n"          /* return */
     26     "noexec_end:");
     27 
     28 extern char exrl_1[];
     29 extern char exrl_2[];
     30 extern char exrl_end[];
     31 
     32 asm("exrl_1:\n"
     33     "   exrl %r0, exrl_2\n"
     34     "   br %r14\n"
     35     "exrl_2:\n"
     36     "   lgfi %r2,2\n"
     37     "exrl_end:");
     38 
     39 int main(void)
     40 {
     41     struct noexec_test noexec_tests[] = {
     42         {
     43             .name = "fallthrough",
     44             .test_code = noexec_1,
     45             .test_len = noexec_end - noexec_1,
     46             .page_ofs = noexec_1 - noexec_2,
     47             .entry_ofs = noexec_1 - noexec_2,
     48             .expected_si_ofs = 0,
     49             .expected_pc_ofs = 0,
     50             .expected_arg = 1,
     51         },
     52         {
     53             .name = "jump",
     54             .test_code = noexec_1,
     55             .test_len = noexec_end - noexec_1,
     56             .page_ofs = noexec_1 - noexec_2,
     57             .entry_ofs = 0,
     58             .expected_si_ofs = 0,
     59             .expected_pc_ofs = 0,
     60             .expected_arg = 0,
     61         },
     62         {
     63             .name = "exrl",
     64             .test_code = exrl_1,
     65             .test_len = exrl_end - exrl_1,
     66             .page_ofs = exrl_1 - exrl_2,
     67             .entry_ofs = exrl_1 - exrl_2,
     68             .expected_si_ofs = 0,
     69             .expected_pc_ofs = exrl_1 - exrl_2,
     70             .expected_arg = 0,
     71         },
     72         {
     73             .name = "fallthrough [cross]",
     74             .test_code = noexec_1,
     75             .test_len = noexec_end - noexec_1,
     76             .page_ofs = noexec_1 - noexec_2 - 2,
     77             .entry_ofs = noexec_1 - noexec_2 - 2,
     78             .expected_si_ofs = 0,
     79             .expected_pc_ofs = -2,
     80             .expected_arg = 1,
     81         },
     82         {
     83             .name = "jump [cross]",
     84             .test_code = noexec_1,
     85             .test_len = noexec_end - noexec_1,
     86             .page_ofs = noexec_1 - noexec_2 - 2,
     87             .entry_ofs = -2,
     88             .expected_si_ofs = 0,
     89             .expected_pc_ofs = -2,
     90             .expected_arg = 0,
     91         },
     92         {
     93             .name = "exrl [cross]",
     94             .test_code = exrl_1,
     95             .test_len = exrl_end - exrl_1,
     96             .page_ofs = exrl_1 - exrl_2 - 2,
     97             .entry_ofs = exrl_1 - exrl_2 - 2,
     98             .expected_si_ofs = 0,
     99             .expected_pc_ofs = exrl_1 - exrl_2 - 2,
    100             .expected_arg = 0,
    101         },
    102     };
    103 
    104     return test_noexec(noexec_tests,
    105                        sizeof(noexec_tests) / sizeof(noexec_tests[0]));
    106 }