1 // clang-format off
2 // Uncomment this line to see crashes in these tests.
3 #define USE_CLANG_JMP
4 #include "qemu/osdep.h"
5 #include "cpu.h"
6 #include "compiler_tests.h"
7 // clang-format on
8 
long_jump_preserve_int_params(uint64_t a,uint64_t b,uint64_t c,uint64_t d)9 uint64_t long_jump_preserve_int_params(uint64_t a,
10                                        uint64_t b,
11                                        uint64_t c,
12                                        uint64_t d) {
13     CPUState local_cpu;
14     if (sigsetjmp(local_cpu.jmp_env, 0x0)) {
15         return a + b + c + d;
16     }
17 
18     siglongjmp(local_cpu.jmp_env, 1);
19     return 0;
20 }
21 
22 
setjmp_sets_fields()23 int setjmp_sets_fields() {
24     CPUState local_cpu;
25     jmp_buf test;
26     memset(test, 0xAA, sizeof(test));
27     memset(local_cpu.jmp_env, 0xAA, sizeof(local_cpu.jmp_env));
28     sigsetjmp(local_cpu.jmp_env, 0x0);
29     return memcmp(test, local_cpu.jmp_env, sizeof(test)) != 0;
30 }
31 
long_jump_preserve_float_params(float a,float b,float c,float d)32 int long_jump_preserve_float_params(float a, float b, float c, float d) {
33     CPUState local_cpu;
34     float aa = a;
35     float bb = b;
36     float cc = c;
37     float dd = d;
38     if (sigsetjmp(local_cpu.jmp_env, 0x0)) {;
39         return aa == a && bb == b && cc == c && dd == d;
40     }
41 
42     siglongjmp(local_cpu.jmp_env, 1);
43     return 0;
44 }
45 
jump_back(CPUState * local_cpu)46 void jump_back(CPUState* local_cpu) {
47     siglongjmp(local_cpu->jmp_env, 1);
48 }
49 
long_jump_stack_test()50 int long_jump_stack_test() {
51     CPUState local_cpu;
52     memset(local_cpu.jmp_env, 0xAA, sizeof(local_cpu.jmp_env));
53      if (sigsetjmp(local_cpu.jmp_env, 0x0)) {
54         return 1;
55     }
56 
57     // This adds a new stack frame, which should work, as we are not
58     // overriding our stack frame.
59     jump_back(&local_cpu);
60     return 0;
61 }
62 
long_jump_double_call()63 int long_jump_double_call() {
64     CPUState local_cpu;
65 
66     if (sigsetjmp(local_cpu.jmp_env, 0x0)) {
67         return 0;
68     }
69 
70     // Overrides the first, so we should return here.
71     if (sigsetjmp(local_cpu.jmp_env, 0x0)) {
72         return 1;
73     }
74 
75     siglongjmp(local_cpu.jmp_env, 1);
76     return 0;
77 }
78 
long_jump_ret_value()79 int long_jump_ret_value() {
80     CPUState local_cpu;
81     int x = sigsetjmp(local_cpu.jmp_env, 0x0);
82     if (x) {
83         return x == 0xFF;
84     }
85 
86     siglongjmp(local_cpu.jmp_env, 0xFF);
87     return 0;
88 }
89