winlin

Merge branch 'srs.master'

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 - arm-linux-gnueabi-g++ -o jmp jmp.cpp -static  
4 - arm-linux-gnueabi-strip jmp 3 + g++ -g -O0 -o jmp jmp.cpp
  4 + arm-linux-gnueabi-g++ -o jmp jmp.cpp -static
  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
39 - longjmp(env_func1, 2); 38 + if (func1_ok) {
  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 - arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static  
4 - arm-linux-gnueabi-strip jmp_sp 3 + g++ -g -O0 -o jmp_sp jmp_sp.cpp
  4 + arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static
  5 + arm-linux-gnueabi-strip jmp_sp
5 */ 6 */
6 #include <stdio.h> 7 #include <stdio.h>
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 -  
17 - jmp_buf env; 16 + register long int rsp0 asm("rsp");
  17 + printf("in func1, rsp=%#lx, longjmp to func0\n", rsp0);
18 18
19 - int ret = setjmp(env);  
20 - printf("setjmp func1 ret=%d\n", ret); 19 + longjmp(env_func1, 0x101);
21 20
  21 + printf("func1 terminated\n");
  22 +#endif
  23 +}
  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 }