正在显示
2 个修改的文件
包含
104 行增加
和
27 行删除
1 | /* | 1 | /* |
2 | # see: https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_SrsLinuxArm | 2 | # see: https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_SrsLinuxArm |
3 | + g++ -g -O0 -o jmp jmp.cpp | ||
3 | arm-linux-gnueabi-g++ -o jmp jmp.cpp -static | 4 | arm-linux-gnueabi-g++ -o jmp jmp.cpp -static |
4 | arm-linux-gnueabi-strip jmp | 5 | arm-linux-gnueabi-strip jmp |
5 | */ | 6 | */ |
6 | #include <stdio.h> | 7 | #include <stdio.h> |
7 | #include <stdlib.h> | 8 | #include <stdlib.h> |
9 | +#include <unistd.h> | ||
8 | #include <setjmp.h> | 10 | #include <setjmp.h> |
9 | 11 | ||
12 | +bool func1_ok = false, func2_ok = false; | ||
10 | jmp_buf env_func1, env_func2; | 13 | jmp_buf env_func1, env_func2; |
11 | 14 | ||
12 | int sum = 0; | 15 | int sum = 0; |
13 | 16 | ||
14 | void func1() { | 17 | void func1() { |
15 | int ret = setjmp(env_func1); | 18 | int ret = setjmp(env_func1); |
16 | - printf("setjmp func1 ret=%d\n", ret); | 19 | + printf("[func1] setjmp ret=%d, sum++=%d\n", ret, sum++); |
20 | + func1_ok = true; | ||
17 | 21 | ||
18 | - if (sum <= 0) { | ||
19 | - return; | ||
20 | - } | ||
21 | - | ||
22 | - if (sum++ > 1000) { | ||
23 | - return; | ||
24 | - } | 22 | + sleep(1); |
25 | 23 | ||
26 | // jmp to func2 | 24 | // jmp to func2 |
27 | - longjmp(env_func2, 3); | 25 | + if (func2_ok) { |
26 | + longjmp(env_func2, 1); | ||
27 | + } | ||
28 | } | 28 | } |
29 | 29 | ||
30 | void func2() { | 30 | void func2() { |
31 | int ret = setjmp(env_func2); | 31 | int ret = setjmp(env_func2); |
32 | - printf("setjmp func2 ret=%d\n", ret); | 32 | + printf("[func2] setjmp ret=%d, sum++=%d\n", ret, sum++); |
33 | + func2_ok = true; | ||
33 | 34 | ||
34 | - if (sum <= 0) { | ||
35 | - return; | ||
36 | - } | 35 | + sleep(1); |
37 | 36 | ||
38 | // jmp to func1 | 37 | // jmp to func1 |
38 | + if (func1_ok) { | ||
39 | longjmp(env_func1, 2); | 39 | longjmp(env_func1, 2); |
40 | + } | ||
40 | } | 41 | } |
41 | 42 | ||
42 | int main(int argc, char** argv) { | 43 | int main(int argc, char** argv) { |
43 | printf("hello, setjmp/longjmp!\n"); | 44 | printf("hello, setjmp/longjmp!\n"); |
44 | func1(); | 45 | func1(); |
45 | - sum++; | ||
46 | func2(); | 46 | func2(); |
47 | printf("jmp finished, sum=%d\n", sum); | 47 | printf("jmp finished, sum=%d\n", sum); |
48 | return 0; | 48 | return 0; |
1 | /* | 1 | /* |
2 | # see: https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_SrsLinuxArm | 2 | # see: https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_SrsLinuxArm |
3 | + g++ -g -O0 -o jmp_sp jmp_sp.cpp | ||
3 | arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static | 4 | arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static |
4 | arm-linux-gnueabi-strip jmp_sp | 5 | arm-linux-gnueabi-strip jmp_sp |
5 | */ | 6 | */ |
@@ -7,33 +8,109 @@ | @@ -7,33 +8,109 @@ | ||
7 | #include <stdlib.h> | 8 | #include <stdlib.h> |
8 | #include <setjmp.h> | 9 | #include <setjmp.h> |
9 | 10 | ||
10 | -int main(int argc, char** argv) { | 11 | +jmp_buf env_func1; |
12 | + | ||
13 | +void func1() | ||
14 | +{ | ||
11 | #if defined(__amd64__) || defined(__x86_64__) | 15 | #if defined(__amd64__) || defined(__x86_64__) |
12 | - printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, sizeof(int)=%d\n", (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int)); | ||
13 | -#else | ||
14 | - printf("arm sizeof(long int)=%d, sizeof(long)=%d, sizeof(int)=%d\n", (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int)); | ||
15 | -#endif | 16 | + register long int rsp0 asm("rsp"); |
17 | + printf("in func1, rsp=%#lx, longjmp to func0\n", rsp0); | ||
16 | 18 | ||
17 | - jmp_buf env; | 19 | + longjmp(env_func1, 0x101); |
18 | 20 | ||
19 | - int ret = setjmp(env); | ||
20 | - printf("setjmp func1 ret=%d\n", ret); | 21 | + printf("func1 terminated\n"); |
22 | +#endif | ||
23 | +} | ||
21 | 24 | ||
25 | +void func0(int* pv0, int* pv1) | ||
26 | +{ | ||
27 | + /** | ||
28 | + the definition of jmp_buf: | ||
29 | + typedef struct __jmp_buf_tag jmp_buf[1]; | ||
30 | + struct __jmp_buf_tag { | ||
31 | + __jmp_buf __jmpbuf; | ||
32 | + int __mask_was_saved; | ||
33 | + __sigset_t __saved_mask; | ||
34 | + }; | ||
35 | + */ | ||
22 | #if defined(__amd64__) || defined(__x86_64__) | 36 | #if defined(__amd64__) || defined(__x86_64__) |
23 | - // typedef lint64_t __jmp_buf[8]; | 37 | + /** |
38 | + here, the __jmp_buf is 8*8=64 bytes | ||
39 | + # if __WORDSIZE == 64 | ||
40 | + typedef long int __jmp_buf[8]; | ||
41 | + */ | ||
42 | + /** | ||
43 | + the layout for setjmp of x86_64 | ||
44 | + # | ||
45 | + # The jmp_buf is assumed to contain the following, in order: | ||
46 | + # %rbx | ||
47 | + # %rsp (post-return) | ||
48 | + # %rbp | ||
49 | + # %r12 | ||
50 | + # %r13 | ||
51 | + # %r14 | ||
52 | + # %r15 | ||
53 | + # <return address> | ||
54 | + # | ||
55 | + */ | ||
56 | + register long int rsp0 asm("rsp"); | ||
57 | + | ||
58 | + int ret = setjmp(env_func1); | ||
59 | + printf("setjmp func0 ret=%d, rsp=%#lx\n", ret, rsp0); | ||
60 | + | ||
24 | printf("after setjmp: "); | 61 | printf("after setjmp: "); |
25 | for (int i = 0; i < 8; i++) { | 62 | for (int i = 0; i < 8; i++) { |
26 | - printf("env[%d]=%#x, ", i, (int)env[0].__jmpbuf[i]); | 63 | + printf("env[%d]=%#x, ", i, (int)env_func1[0].__jmpbuf[i]); |
27 | } | 64 | } |
28 | printf("\n"); | 65 | printf("\n"); |
29 | #else | 66 | #else |
30 | - // typedef int32_t __jmp_buf[64] __attribute__((__aligned__ (8))); | 67 | + /** |
68 | + /usr/arm-linux-gnueabi/include/bits/setjmp.h | ||
69 | + #ifndef _ASM | ||
70 | + The exact set of registers saved may depend on the particular core | ||
71 | + in use, as some coprocessor registers may need to be saved. The C | ||
72 | + Library ABI requires that the buffer be 8-byte aligned, and | ||
73 | + recommends that the buffer contain 64 words. The first 28 words | ||
74 | + are occupied by v1-v6, sl, fp, sp, pc, d8-d15, and fpscr. (Note | ||
75 | + that d8-15 require 17 words, due to the use of fstmx.) | ||
76 | + typedef int __jmp_buf[64] __attribute__((__aligned__ (8))); | ||
77 | + | ||
78 | + the layout of setjmp for arm: | ||
79 | + 0-5: v1-v6 | ||
80 | + 6: sl | ||
81 | + 7: fp | ||
82 | + 8: sp | ||
83 | + 9: pc | ||
84 | + 10-26: d8-d15 17words | ||
85 | + 27: fpscr | ||
86 | + */ | ||
87 | + int ret = setjmp(env_func1); | ||
88 | + printf("setjmp func1 ret=%d\n", ret); | ||
89 | + | ||
31 | printf("after setjmp: "); | 90 | printf("after setjmp: "); |
32 | for (int i = 0; i < 64; i++) { | 91 | for (int i = 0; i < 64; i++) { |
33 | - printf("env[%d]=%#x, ", i, (int)env[0].__jmpbuf[i]); | 92 | + printf("env[%d]=%#x, ", i, (int)env_func1[0].__jmpbuf[i]); |
34 | } | 93 | } |
35 | - printf("\n"); | 94 | + |
95 | + printf("func0 terminated\n"); | ||
36 | #endif | 96 | #endif |
97 | +} | ||
98 | + | ||
99 | +int main(int argc, char** argv) { | ||
100 | +#if defined(__amd64__) || defined(__x86_64__) | ||
101 | + printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, sizeof(int)=%d, __WORDSIZE=%d\n", | ||
102 | + (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), (int)__WORDSIZE); | ||
103 | +#else | ||
104 | + printf("arm sizeof(long int)=%d, sizeof(long)=%d, sizeof(int)=%d\n", | ||
105 | + (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int)); | ||
106 | +#endif | ||
107 | + | ||
108 | + int pv0 = 0xf0; | ||
109 | + int pv1 = 0xf1; | ||
110 | + func0(&pv0, &pv1); | ||
111 | + func1(); | ||
112 | + | ||
113 | + printf("terminated\n"); | ||
37 | 114 | ||
38 | return 0; | 115 | return 0; |
39 | } | 116 | } |
-
请 注册 或 登录 后发表评论