qemu

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

branch-relative-long.c (1623B)


      1 #include <stddef.h>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <sys/mman.h>
      5 
      6 #define DEFINE_ASM(_name, _code) \
      7     extern const char _name[]; \
      8     extern const char _name ## _end[]; \
      9     asm("    .globl " #_name "\n" \
     10         #_name ":\n" \
     11         "    " _code "\n" \
     12         "    .globl " #_name "_end\n" \
     13         #_name "_end:\n");
     14 
     15 DEFINE_ASM(br_r14, "br %r14");
     16 DEFINE_ASM(brasl_r0, "brasl %r0,-0x100000000");
     17 DEFINE_ASM(brcl_0xf, "brcl 0xf,-0x100000000");
     18 
     19 struct test {
     20     const char *code;
     21     const char *code_end;
     22 };
     23 
     24 static const struct test tests[] = {
     25     {
     26         .code = brasl_r0,
     27         .code_end = brasl_r0_end,
     28     },
     29     {
     30         .code = brcl_0xf,
     31         .code_end = brcl_0xf_end,
     32     },
     33 };
     34 
     35 int main(void)
     36 {
     37     unsigned char *buf;
     38     size_t length = 0;
     39     size_t i;
     40 
     41     for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
     42         size_t test_length = 0x100000000 + (tests[i].code_end - tests[i].code);
     43 
     44         if (test_length > length) {
     45             length = test_length;
     46         }
     47     }
     48 
     49     buf = mmap(NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC,
     50                MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
     51     if (buf == MAP_FAILED) {
     52         perror("SKIP: mmap() failed");
     53         return 0;
     54     }
     55 
     56     memcpy(buf, br_r14, br_r14_end - br_r14);
     57     for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
     58         void (*code)(void) = (void *)(buf + 0x100000000);
     59 
     60         memcpy(code, tests[i].code, tests[i].code_end - tests[i].code);
     61         code();
     62         memset(code, 0, tests[i].code_end - tests[i].code);
     63     }
     64 
     65     munmap(buf, length);
     66 
     67     return 0;
     68 }