Ticket #581: test-jit-might-work.c

File test-jit-might-work.c, 3.8 KB (added by Infinoid, 6 years ago)

test-jit-might-work.c from Santtu++

Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <malloc.h>
5#include <signal.h>
6#include <string.h>
7#include <setjmp.h>
8#include <assert.h>
9#include <sys/mman.h>
10
11#define MAGIC 0xfeedbeef
12#define PAGE_SIZE getpagesize()
13#define ALIGN(X,A) ((X) - (((unsigned long) (X)) % (A)))
14
15unsigned char load_asm[] = {
16  /* 080483c4 <plain_c>: */
17  /*  80483c4:       55                      push   %ebp */
18  /*  80483c5:       89 e5                   mov    %esp,%ebp */
19  /*  80483c7:       b8 ef be ed fe          mov    $0xfeedbeef,%eax */
20  /*  80483cc:       5d                      pop    %ebp */
21  /*  80483cd:       c3                      ret    */
22
23  /* Really we just need the mov and ret. Saving %ebp is unnecessary
24     since we're not going to change it. */
25  0xb8, 0xef, 0xbe, 0xed, 0xfe,                 /* mov */
26  0xc3                                          /* ret */
27};
28
29int plain_c()
30{
31  return MAGIC;
32}
33
34int plain_asm()
35{
36  volatile int result;
37  __asm__("movl %1, %0" : "=r" (result) : "i" (MAGIC));
38  return result;
39}
40
41sigjmp_buf segv_env;
42struct sigaction old_segv;
43
44void sig_segv(int sig)
45{
46  siglongjmp(segv_env, 1);
47}
48
49int segv_guard()
50{
51  struct sigaction our_segv;
52  int seen_segv = 0;
53
54  our_segv.sa_handler = sig_segv;
55  our_segv.sa_flags = 0;
56  sigemptyset(&our_segv.sa_mask);
57
58  sigaction(SIGSEGV, &our_segv, &old_segv);
59  seen_segv = sigsetjmp(segv_env, 1);
60
61  if (seen_segv) {
62    sigaction(SIGSEGV, &old_segv, NULL);
63    return 1;
64  }
65
66  return 0;
67}
68
69void segv_unguard()
70{
71  sigaction(SIGSEGV, &old_segv, NULL);
72}
73
74int call_mem(void *mem)
75{
76  register int *eax __asm("%eax");
77  int result;
78
79  if (segv_guard())
80    return 0;
81
82  __asm__("call *%1" : "=r" (eax) : "g"(mem));
83  result = (int) eax;
84
85  segv_unguard();
86
87  return result;
88}
89
90int indirect_c()
91{
92  return call_mem(plain_c);
93}
94
95int indirect_asm()
96{
97  return call_mem(plain_asm);
98}
99
100int asm_text()
101{
102  mprotect(ALIGN(load_asm, PAGE_SIZE), PAGE_SIZE,
103           PROT_READ|PROT_WRITE|PROT_EXEC);
104  return call_mem(load_asm);
105}
106
107int asm_stack()
108{
109  unsigned char buf[sizeof(load_asm)];
110  memcpy(buf, load_asm, sizeof(load_asm));
111  mprotect(ALIGN(buf, PAGE_SIZE), PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC);
112  return call_mem(buf);
113}
114
115int asm_heap()
116{
117  unsigned char *buf = memalign(PAGE_SIZE, PAGE_SIZE);
118  int result;
119  assert(buf);
120  memcpy(buf, load_asm, sizeof(load_asm));
121  mprotect(buf, PAGE_SIZE, PROT_READ|PROT_EXEC);
122  result = call_mem(buf);
123  free(buf);
124  return result;
125}
126
127int asm_mmap_rw()
128{
129  int result;
130  unsigned char *buf = mmap(NULL, sizeof(load_asm),
131                            PROT_EXEC|PROT_READ|PROT_WRITE,
132                            MAP_SHARED|MAP_ANONYMOUS,
133                            -1, 0);
134  if (buf == MAP_FAILED)
135    return 0;
136
137  memcpy(buf, load_asm, sizeof(load_asm));
138  result = call_mem(buf);
139  munmap(buf, sizeof(load_asm));
140  return result;
141}
142
143int asm_mmap_chg()
144{
145  int result;
146  unsigned char *buf = mmap(NULL, sizeof(load_asm),
147                            PROT_READ|PROT_WRITE,
148                            MAP_SHARED|MAP_ANONYMOUS,
149                            -1, 0);
150  if (buf == MAP_FAILED)
151    return 0;
152
153  memcpy(buf, load_asm, sizeof(load_asm));
154  mprotect(buf, sizeof(load_asm), PROT_READ|PROT_EXEC);
155  result = call_mem(buf);
156  munmap(buf, sizeof(load_asm));
157  return result;
158}
159
160int main()
161{
162#define ok(X) ((X) == MAGIC ? "ok" : "FAILURE")
163
164  printf("plain_c      = %s\n", ok(plain_c()));
165  printf("plain_asm    = %s\n", ok(plain_asm()));
166  printf("indirect_c   = %s\n", ok(indirect_c()));
167  printf("indirect_asm = %s\n", ok(indirect_asm()));
168  printf("asm_text     = %s\n", ok(asm_text()));
169  printf("asm_stack    = %s\n", ok(asm_stack()));
170  printf("asm_heap     = %s\n", ok(asm_heap()));
171  printf("asm_mmap_rw  = %s\n", ok(asm_mmap_rw()));
172  printf("asm_mmap_chg = %s\n", ok(asm_mmap_chg()));
173
174  return 0;
175}