├── jump_arm64_aapcs_elf_gas.S ├── jump_arm64_aapcs_macho_gas.S ├── jump_arm_aapcs_elf_gas.S ├── jump_arm_aapcs_macho_gas.S ├── jump_combined_sysv_macho_gas.S ├── jump_i386_ms_pe_gas.S ├── jump_i386_sysv_elf_gas.S ├── jump_i386_sysv_macho_gas.S ├── jump_i386_x86_64_sysv_macho_gas.S ├── jump_mips32_o32_elf_gas.S ├── jump_ppc32_ppc64_sysv_macho_gas.S ├── jump_ppc32_sysv_elf_gas.S ├── jump_ppc32_sysv_macho_gas.S ├── jump_ppc32_sysv_xcoff_gas.S ├── jump_ppc64_sysv_elf_gas.S ├── jump_ppc64_sysv_macho_gas.S ├── jump_ppc64_sysv_xcoff_gas.S ├── jump_sparc64_sysv_elf_gas.S ├── jump_sparc_sysv_elf_gas.S ├── jump_x86_64_ms_pe_gas.S ├── jump_x86_64_sysv_elf_gas.S ├── jump_x86_64_sysv_macho_gas.S ├── libcontext.cpp ├── libcontext.h ├── make_arm64_aapcs_elf_gas.S ├── make_arm64_aapcs_macho_gas.S ├── make_arm_aapcs_elf_gas.S ├── make_arm_aapcs_macho_gas.S ├── make_combined_sysv_macho_gas.S ├── make_i386_ms_pe_gas.S ├── make_i386_sysv_elf_gas.S ├── make_i386_sysv_macho_gas.S ├── make_i386_x86_64_sysv_macho_gas.S ├── make_libcontext.py ├── make_mips32_o32_elf_gas.S ├── make_ppc32_ppc64_sysv_macho_gas.S ├── make_ppc32_sysv_elf_gas.S ├── make_ppc32_sysv_macho_gas.S ├── make_ppc32_sysv_xcoff_gas.S ├── make_ppc64_sysv_elf_gas.S ├── make_ppc64_sysv_macho_gas.S ├── make_ppc64_sysv_xcoff_gas.S ├── make_sparc64_sysv_elf_gas.S ├── make_sparc_sysv_elf_gas.S ├── make_x86_64_ms_pe_gas.S ├── make_x86_64_sysv_elf_gas.S ├── make_x86_64_sysv_macho_gas.S └── tests ├── build-arm.sh ├── build-x86.sh ├── coroutine.h ├── coroutine_example.cpp └── delegate.h /jump_arm64_aapcs_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Edward Nevill 2015 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | /******************************************************* 8 | * * 9 | * ------------------------------------------------- * 10 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 11 | * ------------------------------------------------- * 12 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 13 | * ------------------------------------------------- * 14 | * | d8 | d9 | d10 | d11 | * 15 | * ------------------------------------------------- * 16 | * ------------------------------------------------- * 17 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 18 | * ------------------------------------------------- * 19 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 20 | * ------------------------------------------------- * 21 | * | d12 | d13 | d14 | d15 | * 22 | * ------------------------------------------------- * 23 | * ------------------------------------------------- * 24 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 25 | * ------------------------------------------------- * 26 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 27 | * ------------------------------------------------- * 28 | * | x19 | x20 | x21 | x22 | * 29 | * ------------------------------------------------- * 30 | * ------------------------------------------------- * 31 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 32 | * ------------------------------------------------- * 33 | * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * 34 | * ------------------------------------------------- * 35 | * | x23 | x24 | x25 | x26 | * 36 | * ------------------------------------------------- * 37 | * ------------------------------------------------- * 38 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 39 | * ------------------------------------------------- * 40 | * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * 41 | * ------------------------------------------------- * 42 | * | x27 | x28 | FP | LR | * 43 | * ------------------------------------------------- * 44 | * ------------------------------------------------- * 45 | * | 40 | 41 | 42 | 43 | | | * 46 | * ------------------------------------------------- * 47 | * | 0xa0| 0xa4| 0xa8| 0xac| | | * 48 | * ------------------------------------------------- * 49 | * | PC | align | | | * 50 | * ------------------------------------------------- * 51 | * * 52 | *******************************************************/ 53 | 54 | .cpu generic+fp+simd 55 | .text 56 | .align 2 57 | .global jump_fcontext 58 | .type jump_fcontext, %function 59 | jump_fcontext: 60 | # prepare stack for GP + FPU 61 | sub sp, sp, #0xb0 62 | 63 | # Because gcc may save integer registers in fp registers across a 64 | # function call we cannot skip saving the fp registers. 65 | # 66 | # Do not reinstate this test unless you fully understand what you 67 | # are doing. 68 | # 69 | # # test if fpu env should be preserved 70 | # cmp w3, #0 71 | # b.eq 1f 72 | 73 | # save d8 - d15 74 | stp d8, d9, [sp, #0x00] 75 | stp d10, d11, [sp, #0x10] 76 | stp d12, d13, [sp, #0x20] 77 | stp d14, d15, [sp, #0x30] 78 | 79 | 1: 80 | # save x19-x30 81 | stp x19, x20, [sp, #0x40] 82 | stp x21, x22, [sp, #0x50] 83 | stp x23, x24, [sp, #0x60] 84 | stp x25, x26, [sp, #0x70] 85 | stp x27, x28, [sp, #0x80] 86 | stp x29, x30, [sp, #0x90] 87 | 88 | # save LR as PC 89 | str x30, [sp, #0xa0] 90 | 91 | # store RSP (pointing to context-data) in first argument (x0). 92 | # STR cannot have sp as a target register 93 | mov x4, sp 94 | str x4, [x0] 95 | 96 | # restore RSP (pointing to context-data) from A2 (x1) 97 | mov sp, x1 98 | 99 | # # test if fpu env should be preserved 100 | # cmp w3, #0 101 | # b.eq 2f 102 | 103 | # load d8 - d15 104 | ldp d8, d9, [sp, #0x00] 105 | ldp d10, d11, [sp, #0x10] 106 | ldp d12, d13, [sp, #0x20] 107 | ldp d14, d15, [sp, #0x30] 108 | 109 | 2: 110 | # load x19-x30 111 | ldp x19, x20, [sp, #0x40] 112 | ldp x21, x22, [sp, #0x50] 113 | ldp x23, x24, [sp, #0x60] 114 | ldp x25, x26, [sp, #0x70] 115 | ldp x27, x28, [sp, #0x80] 116 | ldp x29, x30, [sp, #0x90] 117 | 118 | # use third arg as return value after jump 119 | # and as first arg in context function 120 | mov x0, x2 121 | 122 | # load pc 123 | ldr x4, [sp, #0xa0] 124 | 125 | # restore stack from GP + FPU 126 | add sp, sp, #0xb0 127 | 128 | ret x4 129 | .size jump_fcontext,.-jump_fcontext 130 | # Mark that we don't need executable stack. 131 | .section .note.GNU-stack,"",%progbits 132 | -------------------------------------------------------------------------------- /jump_arm64_aapcs_macho_gas.S: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | * * 3 | * ------------------------------------------------- * 4 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 5 | * ------------------------------------------------- * 6 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 7 | * ------------------------------------------------- * 8 | * | d8 | d9 | d10 | d11 | * 9 | * ------------------------------------------------- * 10 | * ------------------------------------------------- * 11 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 12 | * ------------------------------------------------- * 13 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 14 | * ------------------------------------------------- * 15 | * | d12 | d13 | d14 | d15 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 19 | * ------------------------------------------------- * 20 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 21 | * ------------------------------------------------- * 22 | * | x19 | x20 | x21 | x22 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 26 | * ------------------------------------------------- * 27 | * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * 28 | * ------------------------------------------------- * 29 | * | x23 | x24 | x25 | x26 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 33 | * ------------------------------------------------- * 34 | * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * 35 | * ------------------------------------------------- * 36 | * | x27 | x28 | FP | LR | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 40 | 41 | 42 | 43 | | | * 40 | * ------------------------------------------------- * 41 | * | 0xa0| 0xa4| 0xa8| 0xac| | | * 42 | * ------------------------------------------------- * 43 | * | PC | align | | | * 44 | * ------------------------------------------------- * 45 | * * 46 | *******************************************************/ 47 | 48 | .text 49 | .globl _jump_fcontext 50 | .balign 16 51 | _jump_fcontext: 52 | ; prepare stack for GP + FPU 53 | sub sp, sp, #0xb0 54 | 55 | #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) 56 | ; test if fpu env should be preserved 57 | cmp w3, #0 58 | b.eq 1f 59 | 60 | ; save d8 - d15 61 | stp d8, d9, [sp, #0x00] 62 | stp d10, d11, [sp, #0x10] 63 | stp d12, d13, [sp, #0x20] 64 | stp d14, d15, [sp, #0x30] 65 | 66 | 1: 67 | #endif 68 | 69 | ; save x19-x30 70 | stp x19, x20, [sp, #0x40] 71 | stp x21, x22, [sp, #0x50] 72 | stp x23, x24, [sp, #0x60] 73 | stp x25, x26, [sp, #0x70] 74 | stp x27, x28, [sp, #0x80] 75 | stp fp, lr, [sp, #0x90] 76 | 77 | ; save LR as PC 78 | str lr, [sp, #0xa0] 79 | 80 | ; store RSP (pointing to context-data) in first argument (x0). 81 | ; STR cannot have sp as a target register 82 | mov x4, sp 83 | str x4, [x0] 84 | 85 | ; restore RSP (pointing to context-data) from A2 (x1) 86 | mov sp, x1 87 | 88 | #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) 89 | ; test if fpu env should be preserved 90 | cmp w3, #0 91 | b.eq 2f 92 | 93 | ; load d8 - d15 94 | ldp d8, d9, [sp, #0x00] 95 | ldp d10, d11, [sp, #0x10] 96 | ldp d12, d13, [sp, #0x20] 97 | ldp d14, d15, [sp, #0x30] 98 | 99 | 2: 100 | #endif 101 | 102 | ; load x19-x30 103 | ldp x19, x20, [sp, #0x40] 104 | ldp x21, x22, [sp, #0x50] 105 | ldp x23, x24, [sp, #0x60] 106 | ldp x25, x26, [sp, #0x70] 107 | ldp x27, x28, [sp, #0x80] 108 | ldp fp, lr, [sp, #0x90] 109 | 110 | ; use third arg as return value after jump 111 | ; and as first arg in context function 112 | mov x0, x2 113 | 114 | ; load pc 115 | ldr x4, [sp, #0xa0] 116 | 117 | ; restore stack from GP + FPU 118 | add sp, sp, #0xb0 119 | 120 | ret x4 121 | -------------------------------------------------------------------------------- /jump_arm_aapcs_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 14 | * ------------------------------------------------- * 15 | * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 21 | * ------------------------------------------------- * 22 | * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 28 | * ------------------------------------------------- * 29 | * | v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | | * 33 | * ------------------------------------------------- * 34 | * | 0x60| 0x64| | * 35 | * ------------------------------------------------- * 36 | * | lr | pc | | * 37 | * ------------------------------------------------- * 38 | * * 39 | *******************************************************/ 40 | 41 | .text 42 | .globl jump_fcontext 43 | .align 2 44 | .type jump_fcontext,%function 45 | jump_fcontext: 46 | @ save LR as PC 47 | push {lr} 48 | @ save V1-V8,LR 49 | push {v1-v8,lr} 50 | 51 | @ prepare stack for FPU 52 | sub sp, sp, #64 53 | 54 | @ test if fpu env should be preserved 55 | cmp a4, #0 56 | beq 1f 57 | 58 | @ save S16-S31 59 | vstmia sp, {d8-d15} 60 | 61 | 1: 62 | 63 | @ store RSP (pointing to context-data) in A1 64 | str sp, [a1] 65 | 66 | @ restore RSP (pointing to context-data) from A2 67 | mov sp, a2 68 | 69 | @ test if fpu env should be preserved 70 | cmp a4, #0 71 | beq 2f 72 | 73 | @ restore S16-S31 74 | vldmia sp, {d8-d15} 75 | 2: 76 | 77 | @ prepare stack for FPU 78 | add sp, sp, #64 79 | 80 | @ use third arg as return value after jump 81 | @ and as first arg in context function 82 | mov a1, a3 83 | 84 | @ restore v1-V8,LR,PC 85 | pop {v1-v8,lr} 86 | pop {pc} 87 | .size jump_fcontext,.-jump_fcontext 88 | 89 | @ Mark that we don't need executable stack. 90 | .section .note.GNU-stack,"",%progbits 91 | -------------------------------------------------------------------------------- /jump_arm_aapcs_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 14 | * ------------------------------------------------- * 15 | * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 21 | * ------------------------------------------------- * 22 | * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 28 | * ------------------------------------------------- * 29 | * | sjlj| v1 | v2 | v3 | v4 | v5 | v6 | v7 | 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | | * 33 | * ------------------------------------------------- * 34 | * | 0x60| 0x64| 0x68| | * 35 | * ------------------------------------------------- * 36 | * | v8 | lr | pc | | * 37 | * ------------------------------------------------- * 38 | * * 39 | * *****************************************************/ 40 | 41 | .text 42 | .globl _jump_fcontext 43 | .align 2 44 | _jump_fcontext: 45 | @ save LR as PC 46 | push {lr} 47 | @ save V1-V8,LR 48 | push {v1-v8,lr} 49 | 50 | @ locate TLS to save/restore SjLj handler 51 | mrc p15, 0, v2, c13, c0, #3 52 | bic v2, v2, #3 53 | 54 | @ load TLS[__PTK_LIBC_DYLD_Unwind_SjLj_Key] 55 | ldr v1, [v2, #72] 56 | @ save SjLj handler 57 | push {v1} 58 | 59 | @ prepare stack for FPU 60 | sub sp, sp, #64 61 | 62 | #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) 63 | @ test if fpu env should be preserved 64 | cmp a4, #0 65 | beq 1f 66 | 67 | @ save S16-S31 68 | vstmia sp, {d8-d15} 69 | 70 | 1: 71 | #endif 72 | 73 | @ store RSP (pointing to context-data) in A1 74 | str sp, [a1] 75 | 76 | @ restore RSP (pointing to context-data) from A2 77 | mov sp, a2 78 | 79 | #if (defined(__VFP_FP__) && !defined(__SOFTFP__)) 80 | @ test if fpu env should be preserved 81 | cmp a4, #0 82 | beq 2f 83 | 84 | @ restore S16-S31 85 | vldmia sp, {d8-d15} 86 | 87 | 2: 88 | #endif 89 | 90 | @ prepare stack for FPU 91 | add sp, sp, #64 92 | 93 | @ restore SjLj handler 94 | pop {v1} 95 | @ store SjLj handler in TLS 96 | str v1, [v2, #72] 97 | 98 | @ use third arg as return value after jump 99 | @ and as first arg in context function 100 | mov a1, a3 101 | 102 | @ restore v1-V8,LR,PC 103 | pop {v1-v8,lr,pc} 104 | -------------------------------------------------------------------------------- /jump_combined_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "jump_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "jump_x86_64_sysv_macho_gas.S" 14 | #elif defined(__ppc__) 15 | #include "jump_ppc32_sysv_macho_gas.S" 16 | #elif defined(__ppc64__) 17 | #include "jump_ppc64_sysv_macho_gas.S" 18 | #else 19 | #error "No arch's" 20 | #endif 21 | -------------------------------------------------------------------------------- /jump_i386_ms_pe_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Copyright Thomas Sailer 2013. 4 | Distributed under the Boost Software License, Version 1.0. 5 | (See accompanying file LICENSE_1_0.txt or copy at 6 | http://www.boost.org/LICENSE_1_0.txt) 7 | */ 8 | 9 | 10 | .file "jump_i386_ms_pe_gas.S" 11 | .text 12 | .p2align 4,,15 13 | .globl _jump_fcontext 14 | .def _jump_fcontext; .scl 2; .type 32; .endef 15 | _jump_fcontext: 16 | 17 | mov 0x10(%esp),%ecx 18 | push %ebp 19 | push %ebx 20 | push %esi 21 | push %edi 22 | mov %fs:0x18,%edx 23 | mov (%edx),%eax 24 | push %eax 25 | mov 0x4(%edx),%eax 26 | push %eax 27 | mov 0x8(%edx),%eax 28 | push %eax 29 | mov 0xe0c(%edx),%eax 30 | push %eax 31 | mov 0x10(%edx),%eax 32 | push %eax 33 | lea -0x8(%esp),%esp 34 | test %ecx,%ecx 35 | je nxt1 36 | stmxcsr (%esp) 37 | fnstcw 0x4(%esp) 38 | 39 | nxt1: 40 | mov 0x30(%esp),%eax 41 | mov %esp,(%eax) 42 | mov 0x34(%esp),%edx 43 | mov 0x38(%esp),%eax 44 | mov %edx,%esp 45 | test %ecx,%ecx 46 | je nxt2 47 | ldmxcsr (%esp) 48 | fldcw 0x4(%esp) 49 | 50 | nxt2: 51 | lea 0x8(%esp),%esp 52 | mov %fs:0x18,%edx 53 | pop %ecx 54 | mov %ecx,0x10(%edx) 55 | pop %ecx 56 | mov %ecx,0xe0c(%edx) 57 | pop %ecx 58 | mov %ecx,0x8(%edx) 59 | pop %ecx 60 | mov %ecx,0x4(%edx) 61 | pop %ecx 62 | mov %ecx,(%edx) 63 | pop %edi 64 | pop %esi 65 | pop %ebx 66 | pop %ebp 67 | pop %edx 68 | mov %eax,0x4(%esp) 69 | jmp *%edx 70 | -------------------------------------------------------------------------------- /jump_i386_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * 16 | * ---------------------------------------------------------------------------------- * 17 | * * 18 | ****************************************************************************************/ 19 | 20 | .text 21 | .globl jump_fcontext 22 | .align 2 23 | .type jump_fcontext,@function 24 | jump_fcontext: 25 | /* fourth arg of jump_fcontext() == flag indicating preserving FPU */ 26 | movl 0x10(%esp), %ecx 27 | 28 | pushl %ebp /* save EBP */ 29 | pushl %ebx /* save EBX */ 30 | pushl %esi /* save ESI */ 31 | pushl %edi /* save EDI */ 32 | 33 | /* prepare stack for FPU */ 34 | leal -0x8(%esp), %esp 35 | 36 | /* test for flag preserve_fpu */ 37 | test %ecx, %ecx 38 | je 1f 39 | 40 | /* save MMX control- and status-word */ 41 | stmxcsr (%esp) 42 | /* save x87 control-word */ 43 | fnstcw 0x4(%esp) 44 | 45 | 1: 46 | /* first arg of jump_fcontext() == context jumping from */ 47 | movl 0x1c(%esp), %eax 48 | 49 | /* store ESP (pointing to context-data) in EAX */ 50 | movl %esp, (%eax) 51 | 52 | /* second arg of jump_fcontext() == context jumping to */ 53 | movl 0x20(%esp), %edx 54 | 55 | /* third arg of jump_fcontext() == value to be returned after jump */ 56 | movl 0x24(%esp), %eax 57 | 58 | /* restore ESP (pointing to context-data) from EDX */ 59 | movl %edx, %esp 60 | 61 | /* test for flag preserve_fpu */ 62 | test %ecx, %ecx 63 | je 2f 64 | 65 | /* restore MMX control- and status-word */ 66 | ldmxcsr (%esp) 67 | /* restore x87 control-word */ 68 | fldcw 0x4(%esp) 69 | 2: 70 | /* prepare stack for FPU */ 71 | leal 0x8(%esp), %esp 72 | 73 | popl %edi /* restore EDI */ 74 | popl %esi /* restore ESI */ 75 | popl %ebx /* restore EBX */ 76 | popl %ebp /* restore EBP */ 77 | 78 | /* restore return-address */ 79 | popl %edx 80 | 81 | /* use value in EAX as return-value after jump */ 82 | /* use value in EAX as first arg in context function */ 83 | movl %eax, 0x4(%esp) 84 | 85 | /* indirect jump to context */ 86 | jmp *%edx 87 | .size jump_fcontext,.-jump_fcontext 88 | 89 | /* Mark that we don't need executable stack. */ 90 | .section .note.GNU-stack,"",%progbits 91 | -------------------------------------------------------------------------------- /jump_i386_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * 16 | * ---------------------------------------------------------------------------------- * 17 | * * 18 | ****************************************************************************************/ 19 | 20 | .text 21 | .globl _jump_fcontext 22 | .align 2 23 | _jump_fcontext: 24 | /* fourth arg of jump_fcontext() == flag indicating preserving FPU */ 25 | movl 0x10(%esp), %ecx 26 | 27 | pushl %ebp /* save EBP */ 28 | pushl %ebx /* save EBX */ 29 | pushl %esi /* save ESI */ 30 | pushl %edi /* save EDI */ 31 | 32 | /* prepare stack for FPU */ 33 | leal -0x8(%esp), %esp 34 | 35 | /* test for flag preserve_fpu */ 36 | test %ecx, %ecx 37 | je 1f 38 | 39 | /* save MMX control- and status-word */ 40 | stmxcsr (%esp) 41 | /* save x87 control-word */ 42 | fnstcw 0x4(%esp) 43 | 44 | 1: 45 | /* first arg of jump_fcontext() == context jumping from */ 46 | movl 0x1c(%esp), %eax 47 | 48 | /* store ESP (pointing to context-data) in EAX */ 49 | movl %esp, (%eax) 50 | 51 | /* second arg of jump_fcontext() == context jumping to */ 52 | movl 0x20(%esp), %edx 53 | 54 | /* third arg of jump_fcontext() == value to be returned after jump */ 55 | movl 0x24(%esp), %eax 56 | 57 | /* restore ESP (pointing to context-data) from EDX */ 58 | movl %edx, %esp 59 | 60 | /* test for flag preserve_fpu */ 61 | test %ecx, %ecx 62 | je 2f 63 | 64 | /* restore MMX control- and status-word */ 65 | ldmxcsr (%esp) 66 | /* restore x87 control-word */ 67 | fldcw 0x4(%esp) 68 | 2: 69 | /* prepare stack for FPU */ 70 | leal 0x8(%esp), %esp 71 | 72 | popl %edi /* restore EDI */ 73 | popl %esi /* restore ESI */ 74 | popl %ebx /* restore EBX */ 75 | popl %ebp /* restore EBP */ 76 | 77 | /* restore return-address */ 78 | popl %edx 79 | 80 | /* use value in EAX as return-value after jump */ 81 | /* use value in EAX as first arg in context function */ 82 | movl %eax, 0x4(%esp) 83 | 84 | /* indirect jump to context */ 85 | jmp *%edx 86 | -------------------------------------------------------------------------------- /jump_i386_x86_64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "jump_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "jump_x86_64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /jump_mips32_o32_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F20 | F22 | F24 | F26 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F28 | F30 | S0 | S1 | S2 | S3 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | | * 28 | * ------------------------------------------------- * 29 | * | S4 | S5 | S6 | S7 | FP | RA | PC | | * 30 | * ------------------------------------------------- * 31 | * * 32 | * *****************************************************/ 33 | 34 | .text 35 | .globl jump_fcontext 36 | .align 2 37 | .type jump_fcontext,@function 38 | .ent jump_fcontext 39 | jump_fcontext: 40 | # reserve space on stack 41 | addiu $sp, $sp, -92 42 | 43 | sw $s0, 48($sp) # save S0 44 | sw $s1, 52($sp) # save S1 45 | sw $s2, 56($sp) # save S2 46 | sw $s3, 60($sp) # save S3 47 | sw $s4, 64($sp) # save S4 48 | sw $s5, 68($sp) # save S5 49 | sw $s6, 72($sp) # save S6 50 | sw $s7, 76($sp) # save S7 51 | sw $fp, 80($sp) # save FP 52 | sw $ra, 84($sp) # save RA 53 | sw $ra, 88($sp) # save RA as PC 54 | 55 | #if defined(__mips_hard_float) 56 | # test if fpu env should be preserved 57 | beqz $a3, 1f 58 | 59 | s.d $f20, ($sp) # save F20 60 | s.d $f22, 8($sp) # save F22 61 | s.d $f24, 16($sp) # save F24 62 | s.d $f26, 24($sp) # save F26 63 | s.d $f28, 32($sp) # save F28 64 | s.d $f30, 40($sp) # save F30 65 | 66 | 1: 67 | #endif 68 | 69 | # store SP (pointing to context-data) in A0 70 | sw $sp, ($a0) 71 | 72 | # restore SP (pointing to context-data) from A1 73 | move $sp, $a1 74 | 75 | 76 | #if defined(__mips_hard_float) 77 | # test if fpu env should be preserved 78 | beqz $a3, 2f 79 | 80 | l.d $f20, ($sp) # restore F20 81 | l.d $f22, 8($sp) # restore F22 82 | l.d $f24, 16($sp) # restore F24 83 | l.d $f26, 24($sp) # restore F26 84 | l.d $f28, 32($sp) # restore F28 85 | l.d $f30, 40($sp) # restore F30 86 | 87 | 2: 88 | #endif 89 | 90 | lw $s0, 48($sp) # restore S0 91 | lw $s1, 52($sp) # restore S1 92 | lw $s2, 56($sp) # restore S2 93 | lw $s3, 60($sp) # restore S3 94 | lw $s4, 64($sp) # restore S4 95 | lw $s5, 68($sp) # restore S5 96 | lw $s6, 72($sp) # restore S6 97 | lw $s7, 76($sp) # restore S7 98 | lw $fp, 80($sp) # restore FP 99 | lw $ra, 84($sp) # restore RA 100 | 101 | # load PC 102 | lw $t9, 88($sp) 103 | 104 | # adjust stack 105 | addiu $sp, $sp, 92 106 | 107 | # use third arg as return value after jump 108 | move $v0, $a2 109 | # use third arg as first arg in context function 110 | move $a0, $a2 111 | 112 | # jump to context 113 | jr $t9 114 | .end jump_fcontext 115 | .size jump_fcontext, .-jump_fcontext 116 | 117 | /* Mark that we don't need executable stack. */ 118 | .section .note.GNU-stack,"",%progbits 119 | -------------------------------------------------------------------------------- /jump_ppc32_ppc64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__ppc__) 11 | #include "jump_ppc32_sysv_macho_gas.S" 12 | #elif defined(__ppc64__) 13 | #include "jump_ppc64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /jump_ppc32_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | R13 | R14 | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | | * 63 | * ------------------------------------------------- * 64 | * | R31 | CR | LR | PC | | * 65 | * ------------------------------------------------- * 66 | * * 67 | *******************************************************/ 68 | 69 | .text 70 | .globl jump_fcontext 71 | .align 2 72 | .type jump_fcontext,@function 73 | jump_fcontext: 74 | # reserve space on stack 75 | subi %r1, %r1, 240 76 | 77 | stw %r13, 152(%r1) # save R13 78 | stw %r14, 156(%r1) # save R14 79 | stw %r15, 160(%r1) # save R15 80 | stw %r16, 164(%r1) # save R16 81 | stw %r17, 168(%r1) # save R17 82 | stw %r18, 172(%r1) # save R18 83 | stw %r19, 176(%r1) # save R19 84 | stw %r20, 180(%r1) # save R20 85 | stw %r21, 184(%r1) # save R21 86 | stw %r22, 188(%r1) # save R22 87 | stw %r23, 192(%r1) # save R23 88 | stw %r24, 196(%r1) # save R24 89 | stw %r25, 200(%r1) # save R25 90 | stw %r26, 204(%r1) # save R26 91 | stw %r27, 208(%r1) # save R27 92 | stw %r28, 212(%r1) # save R28 93 | stw %r29, 216(%r1) # save R29 94 | stw %r30, 220(%r1) # save R30 95 | stw %r31, 224(%r1) # save R31 96 | 97 | # save CR 98 | mfcr %r0 99 | stw %r0, 228(%r1) 100 | # save LR 101 | mflr %r0 102 | stw %r0, 232(%r1) 103 | # save LR as PC 104 | stw %r0, 236(%r1) 105 | 106 | # test if fpu env should be preserved 107 | cmpwi cr7, %r6, 0 108 | beq cr7, 1f 109 | 110 | stfd %f14, 0(%r1) # save F14 111 | stfd %f15, 8(%r1) # save F15 112 | stfd %f16, 16(%r1) # save F16 113 | stfd %f17, 24(%r1) # save F17 114 | stfd %f18, 32(%r1) # save F18 115 | stfd %f19, 40(%r1) # save F19 116 | stfd %f20, 48(%r1) # save F20 117 | stfd %f21, 56(%r1) # save F21 118 | stfd %f22, 64(%r1) # save F22 119 | stfd %f23, 72(%r1) # save F23 120 | stfd %f24, 80(%r1) # save F24 121 | stfd %f25, 88(%r1) # save F25 122 | stfd %f26, 96(%r1) # save F26 123 | stfd %f27, 104(%r1) # save F27 124 | stfd %f28, 112(%r1) # save F28 125 | stfd %f29, 120(%r1) # save F29 126 | stfd %f30, 128(%r1) # save F30 127 | stfd %f31, 136(%r1) # save F31 128 | mffs %f0 # load FPSCR 129 | stfd %f0, 144(%r1) # save FPSCR 130 | 131 | 1: 132 | # store RSP (pointing to context-data) in R3 133 | stw %r1, 0(%r3) 134 | 135 | # restore RSP (pointing to context-data) from R4 136 | mr %r1, %r4 137 | 138 | # test if fpu env should be preserved 139 | cmpwi cr7, %r6, 0 140 | beq cr7, 2f 141 | 142 | lfd %f14, 0(%r1) # restore F14 143 | lfd %f15, 8(%r1) # restore F15 144 | lfd %f16, 16(%r1) # restore F16 145 | lfd %f17, 24(%r1) # restore F17 146 | lfd %f18, 32(%r1) # restore F18 147 | lfd %f19, 40(%r1) # restore F19 148 | lfd %f20, 48(%r1) # restore F20 149 | lfd %f21, 56(%r1) # restore F21 150 | lfd %f22, 64(%r1) # restore F22 151 | lfd %f23, 72(%r1) # restore F23 152 | lfd %f24, 80(%r1) # restore F24 153 | lfd %f25, 88(%r1) # restore F25 154 | lfd %f26, 96(%r1) # restore F26 155 | lfd %f27, 104(%r1) # restore F27 156 | lfd %f28, 112(%r1) # restore F28 157 | lfd %f29, 120(%r1) # restore F29 158 | lfd %f30, 128(%r1) # restore F30 159 | lfd %f31, 136(%r1) # restore F31 160 | lfd %f0, 144(%r1) # load FPSCR 161 | mtfsf 0xff, %f0 # restore FPSCR 162 | 163 | 2: 164 | lwz %r13, 152(%r1) # restore R13 165 | lwz %r14, 156(%r1) # restore R14 166 | lwz %r15, 160(%r1) # restore R15 167 | lwz %r16, 164(%r1) # restore R16 168 | lwz %r17, 168(%r1) # restore R17 169 | lwz %r18, 172(%r1) # restore R18 170 | lwz %r19, 176(%r1) # restore R19 171 | lwz %r20, 180(%r1) # restore R20 172 | lwz %r21, 184(%r1) # restore R21 173 | lwz %r22, 188(%r1) # restore R22 174 | lwz %r23, 192(%r1) # restore R23 175 | lwz %r24, 196(%r1) # restore R24 176 | lwz %r25, 200(%r1) # restore R25 177 | lwz %r26, 204(%r1) # restore R26 178 | lwz %r27, 208(%r1) # restore R27 179 | lwz %r28, 212(%r1) # restore R28 180 | lwz %r29, 216(%r1) # restore R29 181 | lwz %r30, 220(%r1) # restore R30 182 | lwz %r31, 224(%r1) # restore R31 183 | 184 | # restore CR 185 | lwz %r0, 228(%r1) 186 | mtcr %r0 187 | # restore LR 188 | lwz %r0, 232(%r1) 189 | mtlr %r0 190 | 191 | # load PC 192 | lwz %r0, 236(%r1) 193 | # restore CTR 194 | mtctr %r0 195 | 196 | # adjust stack 197 | addi %r1, %r1, 240 198 | 199 | # use third arg as return value after jump 200 | # use third arg as first arg in context function 201 | mr %r3, %r5 202 | 203 | # jump to context 204 | bctr 205 | .size jump_fcontext, .-jump_fcontext 206 | 207 | /* Mark that we don't need executable stack. */ 208 | .section .note.GNU-stack,"",%progbits 209 | -------------------------------------------------------------------------------- /jump_ppc32_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | R13 | R14 | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | | * 63 | * ------------------------------------------------- * 64 | * | R31 | CR | LR | PC | | * 65 | * ------------------------------------------------- * 66 | * * 67 | *******************************************************/ 68 | 69 | .text 70 | .globl _jump_fcontext 71 | .align 2 72 | _jump_fcontext: 73 | ; reserve space on stack 74 | subi r1, r1, 240 75 | 76 | stw r13, 152(r1) ; save R13 77 | stw r14, 156(r1) ; save R14 78 | stw r15, 160(r1) ; save R15 79 | stw r16, 164(r1) ; save R16 80 | stw r17, 168(r1) ; save R17 81 | stw r18, 172(r1) ; save R18 82 | stw r19, 176(r1) ; save R19 83 | stw r20, 180(r1) ; save R20 84 | stw r21, 184(r1) ; save R21 85 | stw r22, 188(r1) ; save R22 86 | stw r23, 192(r1) ; save R23 87 | stw r24, 196(r1) ; save R24 88 | stw r25, 200(r1) ; save R25 89 | stw r26, 204(r1) ; save R26 90 | stw r27, 208(r1) ; save R27 91 | stw r28, 212(r1) ; save R28 92 | stw r29, 216(r1) ; save R29 93 | stw r30, 220(r1) ; save R30 94 | stw r31, 224(r1) ; save R31 95 | 96 | ; save CR 97 | mfcr r0 98 | stw r0, 228(r1) 99 | ; save LR 100 | mflr r0 101 | stw r0, 232(r1) 102 | ; save LR as PC 103 | stw r0, 236(r1) 104 | 105 | ; test if fpu env should be preserved 106 | cmpwi cr7, r6, 0 107 | beq cr7, l1 108 | 109 | stfd f14, 0(r1) ; save F14 110 | stfd f15, 8(r1) ; save F15 111 | stfd f16, 16(r1) ; save F16 112 | stfd f17, 24(r1) ; save F17 113 | stfd f18, 32(r1) ; save F18 114 | stfd f19, 40(r1) ; save F19 115 | stfd f20, 48(r1) ; save F20 116 | stfd f21, 56(r1) ; save F21 117 | stfd f22, 64(r1) ; save F22 118 | stfd f23, 72(r1) ; save F23 119 | stfd f24, 80(r1) ; save F24 120 | stfd f25, 88(r1) ; save F25 121 | stfd f26, 96(r1) ; save F26 122 | stfd f27, 104(r1) ; save F27 123 | stfd f28, 112(r1) ; save F28 124 | stfd f29, 120(r1) ; save F29 125 | stfd f30, 128(r1) ; save F30 126 | stfd f31, 136(r1) ; save F31 127 | mffs f0 ; load FPSCR 128 | stfd f0, 144(r1) ; save FPSCR 129 | 130 | l1: 131 | ; store RSP (pointing to context-data) in R3 132 | stw r1, 0(r3) 133 | 134 | ; restore RSP (pointing to context-data) from R4 135 | mr r1, r4 136 | 137 | ; test if fpu env should be preserved 138 | cmpwi cr7, r6, 0 139 | beq cr7, l2 140 | 141 | lfd f14, 0(r1) ; restore F14 142 | lfd f15, 8(r1) ; restore F15 143 | lfd f16, 16(r1) ; restore F16 144 | lfd f17, 24(r1) ; restore F17 145 | lfd f18, 32(r1) ; restore F18 146 | lfd f19, 40(r1) ; restore F19 147 | lfd f20, 48(r1) ; restore F20 148 | lfd f21, 56(r1) ; restore F21 149 | lfd f22, 64(r1) ; restore F22 150 | lfd f23, 72(r1) ; restore F23 151 | lfd f24, 80(r1) ; restore F24 152 | lfd f25, 88(r1) ; restore F25 153 | lfd f26, 96(r1) ; restore F26 154 | lfd f27, 104(r1) ; restore F27 155 | lfd f28, 112(r1) ; restore F28 156 | lfd f29, 120(r1) ; restore F29 157 | lfd f30, 128(r1) ; restore F30 158 | lfd f31, 136(r1) ; restore F31 159 | lfd f0, 144(r1) ; load FPSCR 160 | mtfsf 0xff, f0 ; restore FPSCR 161 | 162 | l2: 163 | lwz r13, 152(r1) ; restore R13 164 | lwz r14, 156(r1) ; restore R14 165 | lwz r15, 160(r1) ; restore R15 166 | lwz r16, 164(r1) ; restore R16 167 | lwz r17, 168(r1) ; restore R17 168 | lwz r18, 172(r1) ; restore R18 169 | lwz r19, 176(r1) ; restore R19 170 | lwz r20, 180(r1) ; restore R20 171 | lwz r21, 184(r1) ; restore R21 172 | lwz r22, 188(r1) ; restore R22 173 | lwz r23, 192(r1) ; restore R23 174 | lwz r24, 196(r1) ; restore R24 175 | lwz r25, 200(r1) ; restore R25 176 | lwz r26, 204(r1) ; restore R26 177 | lwz r27, 208(r1) ; restore R27 178 | lwz r28, 212(r1) ; restore R28 179 | lwz r29, 216(r1) ; restore R29 180 | lwz r30, 220(r1) ; restore R30 181 | lwz r31, 224(r1) ; restore R31 182 | 183 | ; restore CR 184 | lwz r0, 228(r1) 185 | mtcr r0 186 | ; restore LR 187 | lwz r0, 232(r1) 188 | mtlr r0 189 | 190 | ; load PC 191 | lwz r0, 236(r1) 192 | ; restore CTR 193 | mtctr r0 194 | 195 | ; adjust stack 196 | addi r1, r1, 240 197 | 198 | ; use third arg as return value after jump 199 | ; use third arg as first arg in context function 200 | mr r3, r5 201 | 202 | ; jump to context 203 | bctr 204 | -------------------------------------------------------------------------------- /jump_ppc32_sysv_xcoff_gas.S: -------------------------------------------------------------------------------- 1 | .globl .jump_fcontext 2 | .align 2 3 | .jump_fcontext: 4 | # reserve space on stack 5 | subi 1, 1, 240 6 | 7 | stw 13, 152(1) # save R13 8 | stw 14, 156(1) # save R14 9 | stw 15, 160(1) # save R15 10 | stw 16, 164(1) # save R16 11 | stw 17, 168(1) # save R17 12 | stw 18, 172(1) # save R18 13 | stw 19, 176(1) # save R19 14 | stw 20, 180(1) # save R20 15 | stw 21, 184(1) # save R21 16 | stw 22, 188(1) # save R22 17 | stw 23, 192(1) # save R23 18 | stw 24, 196(1) # save R24 19 | stw 25, 200(1) # save R25 20 | stw 26, 204(1) # save R26 21 | stw 27, 208(1) # save R27 22 | stw 28, 212(1) # save R28 23 | stw 29, 216(1) # save R29 24 | stw 30, 220(1) # save R30 25 | stw 31, 224(1) # save R31 26 | 27 | # save CR 28 | mfcr 0 29 | stw 0, 228(1) 30 | # save LR 31 | mflr 0 32 | stw 0, 232(1) 33 | # save LR as PC 34 | stw 0, 236(1) 35 | 36 | # test if fpu env should be preserved 37 | cmpwi 7, 6, 0 38 | beq 7, label1 39 | 40 | stfd 14, 0(1) # save F14 41 | stfd 15, 8(1) # save F15 42 | stfd 16, 16(1) # save F16 43 | stfd 17, 24(1) # save F17 44 | stfd 18, 32(1) # save F18 45 | stfd 19, 40(1) # save F19 46 | stfd 20, 48(1) # save F20 47 | stfd 21, 56(1) # save F21 48 | stfd 22, 64(1) # save F22 49 | stfd 23, 72(1) # save F23 50 | stfd 24, 80(1) # save F24 51 | stfd 25, 88(1) # save F25 52 | stfd 26, 96(1) # save F26 53 | stfd 27, 104(1) # save F27 54 | stfd 28, 112(1) # save F28 55 | stfd 29, 120(1) # save F29 56 | stfd 30, 128(1) # save F30 57 | stfd 31, 136(1) # save F31 58 | mffs 0 # load FPSCR 59 | stfd 0, 144(1) # save FPSCR 60 | 61 | label1: 62 | # store RSP (pointing to context-data) in R3 63 | stw 1, 0(3) 64 | 65 | # restore RSP (pointing to context-data) from R4 66 | mr 1, 4 67 | 68 | # test if fpu env should be preserved 69 | cmpwi 7, 6, 0 70 | beq 7, label2 71 | 72 | lfd 14, 0(1) # restore F14 73 | lfd 15, 8(1) # restore F15 74 | lfd 16, 16(1) # restore F16 75 | lfd 17, 24(1) # restore F17 76 | lfd 18, 32(1) # restore F18 77 | lfd 19, 40(1) # restore F19 78 | lfd 20, 48(1) # restore F20 79 | lfd 21, 56(1) # restore F21 80 | lfd 22, 64(1) # restore F22 81 | lfd 23, 72(1) # restore F23 82 | lfd 24, 80(1) # restore F24 83 | lfd 25, 88(1) # restore F25 84 | lfd 26, 96(1) # restore F26 85 | lfd 27, 104(1) # restore F27 86 | lfd 28, 112(1) # restore F28 87 | lfd 29, 120(1) # restore F29 88 | lfd 30, 128(1) # restore F30 89 | lfd 31, 136(1) # restore F31 90 | lfd 0, 144(1) # load FPSCR 91 | mtfsf 0xff, 0 # restore FPSCR 92 | 93 | label2: 94 | lwz 13, 152(1) # restore R13 95 | lwz 14, 156(1) # restore R14 96 | lwz 15, 160(1) # restore R15 97 | lwz 16, 164(1) # restore R16 98 | lwz 17, 168(1) # restore R17 99 | lwz 18, 172(1) # restore R18 100 | lwz 19, 176(1) # restore R19 101 | lwz 20, 180(1) # restore R20 102 | lwz 21, 184(1) # restore R21 103 | lwz 22, 188(1) # restore R22 104 | lwz 23, 192(1) # restore R23 105 | lwz 24, 196(1) # restore R24 106 | lwz 25, 200(1) # restore R25 107 | lwz 26, 204(1) # restore R26 108 | lwz 27, 208(1) # restore R27 109 | lwz 28, 212(1) # restore R28 110 | lwz 29, 216(1) # restore R29 111 | lwz 30, 220(1) # restore R30 112 | lwz 31, 224(1) # restore R31 113 | 114 | # restore CR 115 | lwz 0, 228(1) 116 | mtcr 0 117 | # restore LR 118 | lwz 0, 232(1) 119 | mtlr 0 120 | 121 | # load PC 122 | lwz 0, 236(1) 123 | # restore CTR 124 | mtctr 0 125 | 126 | # adjust stack 127 | addi 1, 1, 240 128 | 129 | # use third arg as return value after jump 130 | # use third arg as first arg in context function 131 | mr 3, 5 132 | 133 | # jump to context 134 | bctr 135 | -------------------------------------------------------------------------------- /jump_ppc64_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | TOC | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R14 | R15 | R16 | R17 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R18 | R19 | R20 | R21 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * 63 | * ------------------------------------------------- * 64 | * | R22 | R23 | R24 | R25 | * 65 | * ------------------------------------------------- * 66 | * ------------------------------------------------- * 67 | * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * 68 | * ------------------------------------------------- * 69 | * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * 70 | * ------------------------------------------------- * 71 | * | R26 | R27 | R28 | R29 | * 72 | * ------------------------------------------------- * 73 | * ------------------------------------------------- * 74 | * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * 75 | * ------------------------------------------------- * 76 | * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * 77 | * ------------------------------------------------- * 78 | * ------------------------------------------------- * 79 | * | R30 | R31 | CR | LR | * 80 | * ------------------------------------------------- * 81 | * ------------------------------------------------- * 82 | * | 80 | 81 | | * 83 | * ------------------------------------------------- * 84 | * | 320 | 324 | | * 85 | * ------------------------------------------------- * 86 | * | PC | | * 87 | * ------------------------------------------------- * 88 | * * 89 | *******************************************************/ 90 | 91 | .globl jump_fcontext 92 | #if _CALL_ELF == 2 93 | .text 94 | .align 2 95 | jump_fcontext: 96 | addis %r2, %r12, .TOC.-jump_fcontext@ha 97 | addi %r2, %r2, .TOC.-jump_fcontext@l 98 | .localentry jump_fcontext, . - jump_fcontext 99 | #else 100 | .section ".opd","aw" 101 | .align 3 102 | jump_fcontext: 103 | # ifdef _CALL_LINUX 104 | .quad .L.jump_fcontext,.TOC.@tocbase,0 105 | .type jump_fcontext,@function 106 | .text 107 | .align 2 108 | .L.jump_fcontext: 109 | # else 110 | .hidden .jump_fcontext 111 | .globl .jump_fcontext 112 | .quad .jump_fcontext,.TOC.@tocbase,0 113 | .size jump_fcontext,24 114 | .type .jump_fcontext,@function 115 | .text 116 | .align 2 117 | .jump_fcontext: 118 | # endif 119 | #endif 120 | # reserve space on stack 121 | subi %r1, %r1, 328 122 | 123 | #if _CALL_ELF != 2 124 | std %r2, 152(%r1) # save TOC 125 | #endif 126 | std %r14, 160(%r1) # save R14 127 | std %r15, 168(%r1) # save R15 128 | std %r16, 176(%r1) # save R16 129 | std %r17, 184(%r1) # save R17 130 | std %r18, 192(%r1) # save R18 131 | std %r19, 200(%r1) # save R19 132 | std %r20, 208(%r1) # save R20 133 | std %r21, 216(%r1) # save R21 134 | std %r22, 224(%r1) # save R22 135 | std %r23, 232(%r1) # save R23 136 | std %r24, 240(%r1) # save R24 137 | std %r25, 248(%r1) # save R25 138 | std %r26, 256(%r1) # save R26 139 | std %r27, 264(%r1) # save R27 140 | std %r28, 272(%r1) # save R28 141 | std %r29, 280(%r1) # save R29 142 | std %r30, 288(%r1) # save R30 143 | std %r31, 296(%r1) # save R31 144 | 145 | # save CR 146 | mfcr %r0 147 | std %r0, 304(%r1) 148 | # save LR 149 | mflr %r0 150 | std %r0, 312(%r1) 151 | # save LR as PC 152 | std %r0, 320(%r1) 153 | 154 | # test if fpu env should be preserved 155 | cmpwi cr7, %r6, 0 156 | beq cr7, 1f 157 | 158 | stfd %f14, 0(%r1) # save F14 159 | stfd %f15, 8(%r1) # save F15 160 | stfd %f16, 16(%r1) # save F16 161 | stfd %f17, 24(%r1) # save F17 162 | stfd %f18, 32(%r1) # save F18 163 | stfd %f19, 40(%r1) # save F19 164 | stfd %f20, 48(%r1) # save F20 165 | stfd %f21, 56(%r1) # save F21 166 | stfd %f22, 64(%r1) # save F22 167 | stfd %f23, 72(%r1) # save F23 168 | stfd %f24, 80(%r1) # save F24 169 | stfd %f25, 88(%r1) # save F25 170 | stfd %f26, 96(%r1) # save F26 171 | stfd %f27, 104(%r1) # save F27 172 | stfd %f28, 112(%r1) # save F28 173 | stfd %f29, 120(%r1) # save F29 174 | stfd %f30, 128(%r1) # save F30 175 | stfd %f31, 136(%r1) # save F31 176 | mffs %f0 # load FPSCR 177 | stfd %f0, 144(%r1) # save FPSCR 178 | 179 | 1: 180 | # store RSP (pointing to context-data) in R3 181 | std %r1, 0(%r3) 182 | 183 | # restore RSP (pointing to context-data) from R4 184 | mr %r1, %r4 185 | 186 | # test if fpu env should be preserved 187 | cmpwi cr7, %r6, 0 188 | beq cr7, 2f 189 | 190 | lfd %f14, 0(%r1) # restore F14 191 | lfd %f15, 8(%r1) # restore F15 192 | lfd %f16, 16(%r1) # restore F16 193 | lfd %f17, 24(%r1) # restore F17 194 | lfd %f18, 32(%r1) # restore F18 195 | lfd %f19, 40(%r1) # restore F19 196 | lfd %f20, 48(%r1) # restore F20 197 | lfd %f21, 56(%r1) # restore F21 198 | lfd %f22, 64(%r1) # restore F22 199 | lfd %f23, 72(%r1) # restore F23 200 | lfd %f24, 80(%r1) # restore F24 201 | lfd %f25, 88(%r1) # restore F25 202 | lfd %f26, 96(%r1) # restore F26 203 | lfd %f27, 104(%r1) # restore F27 204 | lfd %f28, 112(%r1) # restore F28 205 | lfd %f29, 120(%r1) # restore F29 206 | lfd %f30, 128(%r1) # restore F30 207 | lfd %f31, 136(%r1) # restore F31 208 | lfd %f0, 144(%r1) # load FPSCR 209 | mtfsf 0xff, %f0 # restore FPSCR 210 | 211 | 2: 212 | #if _CALL_ELF != 2 213 | ld %r2, 152(%r1) # restore TOC 214 | #endif 215 | ld %r14, 160(%r1) # restore R14 216 | ld %r15, 168(%r1) # restore R15 217 | ld %r16, 176(%r1) # restore R16 218 | ld %r17, 184(%r1) # restore R17 219 | ld %r18, 192(%r1) # restore R18 220 | ld %r19, 200(%r1) # restore R19 221 | ld %r20, 208(%r1) # restore R20 222 | ld %r21, 216(%r1) # restore R21 223 | ld %r22, 224(%r1) # restore R22 224 | ld %r23, 232(%r1) # restore R23 225 | ld %r24, 240(%r1) # restore R24 226 | ld %r25, 248(%r1) # restore R25 227 | ld %r26, 256(%r1) # restore R26 228 | ld %r27, 264(%r1) # restore R27 229 | ld %r28, 272(%r1) # restore R28 230 | ld %r29, 280(%r1) # restore R29 231 | ld %r30, 288(%r1) # restore R30 232 | ld %r31, 296(%r1) # restore R31 233 | 234 | # restore CR 235 | ld %r0, 304(%r1) 236 | mtcr %r0 237 | # restore LR 238 | ld %r0, 312(%r1) 239 | mtlr %r0 240 | 241 | # load PC 242 | ld %r12, 320(%r1) 243 | # restore CTR 244 | mtctr %r12 245 | 246 | # adjust stack 247 | addi %r1, %r1, 328 248 | 249 | # use third arg as return value after jump 250 | # use third arg as first arg in context function 251 | mr %r3, %r5 252 | 253 | # jump to context 254 | bctr 255 | #if _CALL_ELF == 2 256 | .size jump_fcontext, .-jump_fcontext 257 | #else 258 | # ifdef _CALL_LINUX 259 | .size .jump_fcontext, .-.L.jump_fcontext 260 | # else 261 | .size .jump_fcontext, .-.jump_fcontext 262 | # endif 263 | #endif 264 | 265 | 266 | /* Mark that we don't need executable stack. */ 267 | .section .note.GNU-stack,"",%progbits 268 | -------------------------------------------------------------------------------- /jump_ppc64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | R13 | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R14 | R15 | R16 | R17 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R18 | R19 | R20 | R21 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * 63 | * ------------------------------------------------- * 64 | * | R22 | R23 | R24 | R25 | * 65 | * ------------------------------------------------- * 66 | * ------------------------------------------------- * 67 | * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * 68 | * ------------------------------------------------- * 69 | * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * 70 | * ------------------------------------------------- * 71 | * | R26 | R27 | R28 | R29 | * 72 | * ------------------------------------------------- * 73 | * ------------------------------------------------- * 74 | * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * 75 | * ------------------------------------------------- * 76 | * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * 77 | * ------------------------------------------------- * 78 | * ------------------------------------------------- * 79 | * | R30 | R31 | CR | LR | * 80 | * ------------------------------------------------- * 81 | * ------------------------------------------------- * 82 | * | 80 | 81 | | * 83 | * ------------------------------------------------- * 84 | * | 320 | 324 | | * 85 | * ------------------------------------------------- * 86 | * | PC | | * 87 | * ------------------------------------------------- * 88 | * * 89 | *******************************************************/ 90 | 91 | .text 92 | .align 2 93 | .globl jump_fcontext 94 | 95 | _jump_fcontext: 96 | ; reserve space on stack 97 | subi r1, r1, 328 98 | 99 | std r13, 152(r1) ; save R13 100 | std r14, 160(r1) ; save R14 101 | std r15, 168(r1) ; save R15 102 | std r16, 176(r1) ; save R16 103 | std r17, 184(r1) ; save R17 104 | std r18, 192(r1) ; save R18 105 | std r19, 200(r1) ; save R19 106 | std r20, 208(r1) ; save R20 107 | std r21, 216(r1) ; save R21 108 | std r22, 224(r1) ; save R22 109 | std r23, 232(r1) ; save R23 110 | std r24, 240(r1) ; save R24 111 | std r25, 248(r1) ; save R25 112 | std r26, 256(r1) ; save R26 113 | std r27, 264(r1) ; save R27 114 | std r28, 272(r1) ; save R28 115 | std r29, 280(r1) ; save R29 116 | std r30, 288(r1) ; save R30 117 | std r31, 296(r1) ; save R31 118 | 119 | ; save CR 120 | mfcr r0 121 | std r0, 304(r1) 122 | ; save LR 123 | mflr r0 124 | std r0, 312(r1) 125 | ; save LR as PC 126 | std r0, 320(r1) 127 | 128 | ; test if fpu env should be preserved 129 | cmpwi cr7, r6, 0 130 | beq cr7, l1 131 | 132 | stfd f14, 0(r1) ; save F14 133 | stfd f15, 8(r1) ; save F15 134 | stfd f16, 16(r1) ; save F16 135 | stfd f17, 24(r1) ; save F17 136 | stfd f18, 32(r1) ; save F18 137 | stfd f19, 40(r1) ; save F19 138 | stfd f20, 48(r1) ; save F20 139 | stfd f21, 56(r1) ; save F21 140 | stfd f22, 64(r1) ; save F22 141 | stfd f23, 72(r1) ; save F23 142 | stfd f24, 80(r1) ; save F24 143 | stfd f25, 88(r1) ; save F25 144 | stfd f26, 96(r1) ; save F26 145 | stfd f27, 104(r1) ; save F27 146 | stfd f28, 112(r1) ; save F28 147 | stfd f29, 120(r1) ; save F29 148 | stfd f30, 128(r1) ; save F30 149 | stfd f31, 136(r1) ; save F31 150 | mffs f0 ; load FPSCR 151 | stfd f0, 144(r1) ; save FPSCR 152 | 153 | l1: 154 | ; store RSP (pointing to context-data) in R3 155 | stw r1, 0(r3) 156 | 157 | ; restore RSP (pointing to context-data) from R4 158 | mr r1, r4 159 | 160 | ; test if fpu env should be preserved 161 | cmpwi cr7, r6, 0 162 | beq cr7, l2 163 | 164 | lfd f14, 0(r1) ; restore F14 165 | lfd f15, 8(r1) ; restore F15 166 | lfd f16, 16(r1) ; restore F16 167 | lfd f17, 24(r1) ; restore F17 168 | lfd f18, 32(r1) ; restore F18 169 | lfd f19, 40(r1) ; restore F19 170 | lfd f20, 48(r1) ; restore F20 171 | lfd f21, 56(r1) ; restore F21 172 | lfd f22, 64(r1) ; restore F22 173 | lfd f23, 72(r1) ; restore F23 174 | lfd f24, 80(r1) ; restore F24 175 | lfd f25, 88(r1) ; restore F25 176 | lfd f26, 96(r1) ; restore F26 177 | lfd f27, 104(r1) ; restore F27 178 | lfd f28, 112(r1) ; restore F28 179 | lfd f29, 120(r1) ; restore F29 180 | lfd f30, 128(r1) ; restore F30 181 | lfd f31, 136(r1) ; restore F31 182 | lfd f0, 144(r1) ; load FPSCR 183 | mtfsf 0xff, f0 ; restore FPSCR 184 | 185 | 2: 186 | ld r13, 152(r1) ; restore R13 187 | ld r14, 160(r1) ; restore R14 188 | ld r15, 168(r1) ; restore R15 189 | ld r16, 176(r1) ; restore R16 190 | ld r17, 184(r1) ; restore R17 191 | ld r18, 192(r1) ; restore R18 192 | ld r19, 200(r1) ; restore R19 193 | ld r20, 208(r1) ; restore R20 194 | ld r21, 216(r1) ; restore R21 195 | ld r22, 224(r1) ; restore R22 196 | ld r23, 232(r1) ; restore R23 197 | ld r24, 240(r1) ; restore R24 198 | ld r25, 248(r1) ; restore R25 199 | ld r26, 256(r1) ; restore R26 200 | ld r27, 264(r1) ; restore R27 201 | ld r28, 272(r1) ; restore R28 202 | ld r29, 280(r1) ; restore R29 203 | ld r30, 288(r1) ; restore R30 204 | ld r31, 296(r1) ; restore R31 205 | 206 | ; restore CR 207 | ld r0, 304(r1) 208 | mtcr r0 209 | ; restore LR 210 | ld r0, 312(r1) 211 | mtlr r0 212 | 213 | ; load PC 214 | ld r0, 320(r1) 215 | ; restore CTR 216 | mtctr r0 217 | 218 | ; adjust stack 219 | addi r1, r1, 328 220 | 221 | ; use third arg as return value after jump 222 | ; use third arg as first arg in context function 223 | mr r3, r5 224 | 225 | ; jump to context 226 | bctr 227 | -------------------------------------------------------------------------------- /jump_ppc64_sysv_xcoff_gas.S: -------------------------------------------------------------------------------- 1 | .align 2 2 | .globl .jump_fcontext 3 | .jump_fcontext: 4 | # reserve space on stack 5 | subi 1, 1, 328 6 | 7 | std 13, 152(1) # save R13 8 | std 14, 160(1) # save R14 9 | std 15, 168(1) # save R15 10 | std 16, 176(1) # save R16 11 | std 17, 184(1) # save R17 12 | std 18, 192(1) # save R18 13 | std 19, 200(1) # save R19 14 | std 20, 208(1) # save R20 15 | std 21, 216(1) # save R21 16 | std 22, 224(1) # save R22 17 | std 23, 232(1) # save R23 18 | std 24, 240(1) # save R24 19 | std 25, 248(1) # save R25 20 | std 26, 256(1) # save R26 21 | std 27, 264(1) # save R27 22 | std 28, 272(1) # save R28 23 | std 29, 280(1) # save R29 24 | std 30, 288(1) # save R30 25 | std 31, 296(1) # save R31 26 | 27 | # save CR 28 | mfcr 0 29 | std 0, 304(1) 30 | # save LR 31 | mflr 0 32 | std 0, 312(1) 33 | # save LR as PC 34 | std 0, 320(1) 35 | 36 | # test if fpu env should be preserved 37 | cmpwi 7, 6, 0 38 | beq 7, label1 39 | 40 | stfd 14, 0(1) # save F14 41 | stfd 15, 8(1) # save F15 42 | stfd 16, 16(1) # save F16 43 | stfd 17, 24(1) # save F17 44 | stfd 18, 32(1) # save F18 45 | stfd 19, 40(1) # save F19 46 | stfd 20, 48(1) # save F20 47 | stfd 21, 56(1) # save F21 48 | stfd 22, 64(1) # save F22 49 | stfd 23, 72(1) # save F23 50 | stfd 24, 80(1) # save F24 51 | stfd 25, 88(1) # save F25 52 | stfd 26, 96(1) # save F26 53 | stfd 27, 104(1) # save F27 54 | stfd 28, 112(1) # save F28 55 | stfd 29, 120(1) # save F29 56 | stfd 30, 128(1) # save F30 57 | stfd 31, 136(1) # save F31 58 | mffs 0 # load FPSCR 59 | stfd 0, 144(1) # save FPSCR 60 | 61 | label1: 62 | # store RSP (pointing to context-data) in R3 63 | stw 1, 0(3) 64 | 65 | # restore RSP (pointing to context-data) from R4 66 | mr 1, 4 67 | 68 | # test if fpu env should be preserved 69 | cmpwi 7, 6, 0 70 | beq 7, label2 71 | 72 | lfd 14, 0(1) # restore F14 73 | lfd 15, 8(1) # restore F15 74 | lfd 16, 16(1) # restore F16 75 | lfd 17, 24(1) # restore F17 76 | lfd 18, 32(1) # restore F18 77 | lfd 19, 40(1) # restore F19 78 | lfd 20, 48(1) # restore F20 79 | lfd 21, 56(1) # restore F21 80 | lfd 22, 64(1) # restore F22 81 | lfd 23, 72(1) # restore F23 82 | lfd 24, 80(1) # restore F24 83 | lfd 25, 88(1) # restore F25 84 | lfd 26, 96(1) # restore F26 85 | lfd 27, 104(1) # restore F27 86 | lfd 28, 112(1) # restore F28 87 | lfd 29, 120(1) # restore F29 88 | lfd 30, 128(1) # restore F30 89 | lfd 31, 136(1) # restore F31 90 | lfd 0, 144(1) # load FPSCR 91 | mtfsf 0xff, 0 # restore FPSCR 92 | 93 | label2: 94 | ld 13, 152(1) # restore R13 95 | ld 14, 160(1) # restore R14 96 | ld 15, 168(1) # restore R15 97 | ld 16, 176(1) # restore R16 98 | ld 17, 184(1) # restore R17 99 | ld 18, 192(1) # restore R18 100 | ld 19, 200(1) # restore R19 101 | ld 20, 208(1) # restore R20 102 | ld 21, 216(1) # restore R21 103 | ld 22, 224(1) # restore R22 104 | ld 23, 232(1) # restore R23 105 | ld 24, 240(1) # restore R24 106 | ld 25, 248(1) # restore R25 107 | ld 26, 256(1) # restore R26 108 | ld 27, 264(1) # restore R27 109 | ld 28, 272(1) # restore R28 110 | ld 29, 280(1) # restore R29 111 | ld 30, 288(1) # restore R30 112 | ld 31, 296(1) # restore R31 113 | 114 | # restore CR 115 | ld 0, 304(1) 116 | mtcr 0 117 | # restore LR 118 | ld 0, 312(1) 119 | mtlr 0 120 | 121 | # load PC 122 | ld 0, 320(1) 123 | # restore CTR 124 | mtctr 0 125 | 126 | # adjust stack 127 | addi 1, 1, 328 128 | 129 | # use third arg as return value after jump 130 | # use third arg as first arg in context function 131 | mr 3, 5 132 | 133 | # jump to context 134 | bctr 135 | -------------------------------------------------------------------------------- /jump_sparc64_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Martin Husemann 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************************* 9 | * * 10 | * ------------------------------------------------------------- * 11 | * | Offset (in 4 or 8 byte units) | Content | * 12 | * ------------------------------------------------------------- * 13 | * | 0 | %sp | * 14 | * ------------------------------------------------------------- * 15 | * | 1 | %pc | * 16 | * ------------------------------------------------------------- * 17 | * | 2 | %i7 (return address) | * 18 | * ------------------------------------------------------------- * 19 | * | 3 | %g1 | * 20 | * ------------------------------------------------------------- * 21 | * | 4 | %g2 | * 22 | * ------------------------------------------------------------- * 23 | * | 5 | %g3 | * 24 | * ------------------------------------------------------------- * 25 | * | 6 | %g6 | * 26 | * ------------------------------------------------------------- * 27 | * | 7 | %g7 | * 28 | * ------------------------------------------------------------- * 29 | * The local and in registers are stored on the stack. * 30 | *******************************************************************/ 31 | 32 | #define OFF(N) (8*(N)) 33 | #define CCFSZ 176 // C Compiler Frame Size 34 | #define BIAS (2048-1) // Stack offset for 64 bit programs 35 | #define FC_SZ 448 // sizeof(fcontext_t) 36 | #define FC_STK 384 // offsetof(fcontext_t, fc_stack) 37 | #define FC_FPU 0 // offsetof(fcontext_t, fc_fp) 38 | #define FC_FSR 264 // offsetof(fcontext_t, fc_fp.fp_fsr) 39 | #define FC_FPRS 256 // offsetof(fcontext_t, fc_fp.fp_fprs) 40 | #define FC_GREG 320 // offsetof(fcontext_t, fc_greg) 41 | #define BLOCK_SIZE 64 42 | 43 | .register %g2,#ignore 44 | .register %g3,#ignore 45 | .register %g6,#ignore 46 | 47 | .text 48 | .globl jump_fcontext 49 | .align 4 50 | .type jump_fcontext,@function 51 | // intptr_t 52 | // jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp, 53 | // bool preserve_fpu = true); 54 | jump_fcontext: 55 | // %o0 = pointer to old fcontext, save current state here 56 | // %o1 = new context to jump to 57 | // %o2 = new return value in context %o0 58 | // %o3 = preserve fpu registers 59 | // Save current state in %o0 fcontext, then activate %o1. 60 | // If %o3, include fpu registers. 61 | 62 | flushw // make sure all shadow registers are up to date in the current stack 63 | 64 | // save current state to fcontext_t at %o0 65 | stx %sp, [%o0 + FC_GREG + OFF(0)] // current stack pointer 66 | add %o7, 8, %o4 // calculate next instruction past call 67 | stx %o4, [%o0 + FC_GREG + OFF(1)] // and store it as %pc in save context 68 | stx %o7, [%o0 + FC_GREG + OFF(2)] 69 | stx %g1, [%o0 + FC_GREG + OFF(3)] 70 | stx %g2, [%o0 + FC_GREG + OFF(4)] 71 | stx %g3, [%o0 + FC_GREG + OFF(5)] 72 | stx %g6, [%o0 + FC_GREG + OFF(6)] 73 | stx %g7, [%o0 + FC_GREG + OFF(7)] 74 | 75 | // do we need to handle fpu? 76 | brz %o3, Lno_fpu 77 | nop 78 | 79 | add %o0, FC_FPU, %o5 80 | stda %f0, [%o5] 0xf0 /* ASI_BLOCK_PRIMARY */ 81 | add %o5, BLOCK_SIZE, %o5 82 | stda %f16, [%o5] 0xf0 83 | add %o5, BLOCK_SIZE, %o5 84 | stda %f32, [%o5] 0xf0 85 | add %o5, BLOCK_SIZE, %o5 86 | stda %f48, [%o5] 0xf0 87 | stx %fsr, [%o0+FC_FSR] 88 | rd %fprs, %o4 89 | stx %o4, [%o0+FC_FPRS] 90 | 91 | add %o1, FC_FPU, %o5 92 | ldda [%o5] 0xf0 /* ASI_BLOCK_PRIMARY */, %f0 93 | add %o5, BLOCK_SIZE, %o5 94 | ldda [%o5] 0xf0, %f16 95 | add %o5, BLOCK_SIZE, %o5 96 | ldda [%o5] 0xf0, %f32 97 | add %o5, BLOCK_SIZE, %o5 98 | ldda [%o5] 0xf0, %f48 99 | ldx [%o1+FC_FSR], %fsr 100 | ldx [%o1+FC_FPRS], %o4 101 | wr %o4,0,%fprs 102 | 103 | Lno_fpu: 104 | // load new state from %o1 105 | ldx [%o1 + FC_GREG + OFF(1)], %o4 106 | ldx [%o1 + FC_GREG + OFF(2)], %o7 107 | ldx [%o1 + FC_GREG + OFF(3)], %g1 108 | ldx [%o1 + FC_GREG + OFF(4)], %g2 109 | ldx [%o1 + FC_GREG + OFF(5)], %g3 110 | ldx [%o1 + FC_GREG + OFF(6)], %g6 111 | ldx [%o1 + FC_GREG + OFF(7)], %g7 112 | // switch to new stack 113 | ldx [%o1 + FC_GREG + OFF(0)], %sp 114 | // and now reload from this stack the shadow regist bank contents 115 | ldx [%sp + BIAS + OFF(0)], %l0 116 | ldx [%sp + BIAS + OFF(1)], %l1 117 | ldx [%sp + BIAS + OFF(2)], %l2 118 | ldx [%sp + BIAS + OFF(3)], %l3 119 | ldx [%sp + BIAS + OFF(4)], %l4 120 | ldx [%sp + BIAS + OFF(5)], %l5 121 | ldx [%sp + BIAS + OFF(6)], %l6 122 | ldx [%sp + BIAS + OFF(7)], %l7 123 | ldx [%sp + BIAS + OFF(8)], %i0 124 | ldx [%sp + BIAS + OFF(9)], %i1 125 | ldx [%sp + BIAS + OFF(10)], %i2 126 | ldx [%sp + BIAS + OFF(11)], %i3 127 | ldx [%sp + BIAS + OFF(12)], %i4 128 | ldx [%sp + BIAS + OFF(13)], %i5 129 | ldx [%sp + BIAS + OFF(14)], %i6 130 | ldx [%sp + BIAS + OFF(15)], %i7 131 | 132 | // finally continue execution in new context 133 | jmp %o4 134 | mov %o2, %o0 // return arg as result 135 | 136 | .size jump_fcontext,.-jump_fcontext 137 | 138 | /* Mark that we don't need executable stack. */ 139 | .section .note.GNU-stack,"",%progbits 140 | -------------------------------------------------------------------------------- /jump_sparc_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Martin Husemann 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************************* 9 | * * 10 | * ------------------------------------------------------------- * 11 | * | Offset (in 4 or 8 byte units) | Content | * 12 | * ------------------------------------------------------------- * 13 | * | 0 | %sp | * 14 | * ------------------------------------------------------------- * 15 | * | 1 | %pc | * 16 | * ------------------------------------------------------------- * 17 | * | 2 | %i7 (return address) | * 18 | * ------------------------------------------------------------- * 19 | * | 3 | %g1 | * 20 | * ------------------------------------------------------------- * 21 | * | 4 | %g2 | * 22 | * ------------------------------------------------------------- * 23 | * | 5 | %g3 | * 24 | * ------------------------------------------------------------- * 25 | * | 6 | %g6 | * 26 | * ------------------------------------------------------------- * 27 | * | 7 | %g7 | * 28 | * ------------------------------------------------------------- * 29 | * The local and in registers are stored on the stack. * 30 | *******************************************************************/ 31 | 32 | #define OFF(N) (4*(N)) 33 | #define CCFSZ 96 34 | #define FC_SZ 176 35 | #define FC_stK 168 // offsetof(fcontext_t, fc_stack) 36 | #define FC_FPU 0 // offsetof(fcontext_t, fc_fp) 37 | #define FC_FSR 128 // offsetof(fcontext_t, fc_fp.fp_fsr) 38 | #define FC_GREG 136 // offsetof(fcontext_t, fc_greg) 39 | #define BLOCK_SIZE 8 40 | #ifdef __NetBSD__ 41 | #define FLUSHW t 0x83; nop // T_FLUSHWIN 42 | #endif 43 | 44 | .text 45 | .globl jump_fcontext 46 | .align 4 47 | .type jump_fcontext,@function 48 | // intptr_t 49 | // jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp, 50 | // bool preserve_fpu = true); 51 | jump_fcontext: 52 | // %o0 = pointer to old fcontext, save current state here 53 | // %o1 = new context to jump to 54 | // %o2 = new return value in context %o0 55 | // %o3 = preserve fpu registers 56 | // Save current state in %o0 fcontext, then activate %o1. 57 | // If %o3, include fpu registers. 58 | 59 | FLUSHW // make sure all shadow registers are up to date in the current stack 60 | 61 | // save current state to fcontext_t at %o0 62 | st %sp, [%o0 + FC_GREG + OFF(0)] // current stack pointer 63 | add %o7, 8, %o4 // calculate next instruction past call 64 | st %o4, [%o0 + FC_GREG + OFF(1)] // and store it as %pc in save context 65 | st %o7, [%o0 + FC_GREG + OFF(2)] 66 | st %g1, [%o0 + FC_GREG + OFF(3)] 67 | st %g2, [%o0 + FC_GREG + OFF(4)] 68 | st %g3, [%o0 + FC_GREG + OFF(5)] 69 | st %g6, [%o0 + FC_GREG + OFF(6)] 70 | st %g7, [%o0 + FC_GREG + OFF(7)] 71 | 72 | // do we need to handle fpu? 73 | cmp %o3, 0 74 | bz Lno_fpu 75 | nop 76 | 77 | add %o0, FC_FPU, %o5 78 | std %f0, [%o5] 79 | std %f2, [%o5+0x08] 80 | std %f4, [%o5+0x10] 81 | std %f6, [%o5+0x18] 82 | std %f8, [%o5+0x20] 83 | std %f10, [%o5+0x28] 84 | std %f12, [%o5+0x30] 85 | std %f14, [%o5+0x38] 86 | st %fsr, [%o0+FC_FSR] 87 | 88 | add %o1, FC_FPU, %o5 89 | ldd [%o5], %f0 90 | ldd [%o5+0x08], %f2 91 | ldd [%o5+0x10], %f4 92 | ldd [%o5+0x18], %f6 93 | ldd [%o5+0x20], %f8 94 | ldd [%o5+0x28], %f10 95 | ldd [%o5+0x30], %f12 96 | ldd [%o5+0x38], %f14 97 | ld [%o1+FC_FSR], %fsr 98 | 99 | Lno_fpu: 100 | // load new state from %o1 101 | ld [%o1 + FC_GREG + OFF(1)], %o4 102 | ld [%o1 + FC_GREG + OFF(2)], %o7 103 | ld [%o1 + FC_GREG + OFF(3)], %g1 104 | ld [%o1 + FC_GREG + OFF(4)], %g2 105 | ld [%o1 + FC_GREG + OFF(5)], %g3 106 | ld [%o1 + FC_GREG + OFF(6)], %g6 107 | ld [%o1 + FC_GREG + OFF(7)], %g7 108 | // switch to new stack 109 | ld [%o1 + FC_GREG + OFF(0)], %sp 110 | // and now reload from this stack the shadow regist bank contents 111 | ld [%sp + OFF(0)], %l0 112 | ld [%sp + OFF(1)], %l1 113 | ld [%sp + OFF(2)], %l2 114 | ld [%sp + OFF(3)], %l3 115 | ld [%sp + OFF(4)], %l4 116 | ld [%sp + OFF(5)], %l5 117 | ld [%sp + OFF(6)], %l6 118 | ld [%sp + OFF(7)], %l7 119 | ld [%sp + OFF(8)], %i0 120 | ld [%sp + OFF(9)], %i1 121 | ld [%sp + OFF(10)], %i2 122 | ld [%sp + OFF(11)], %i3 123 | ld [%sp + OFF(12)], %i4 124 | ld [%sp + OFF(13)], %i5 125 | ld [%sp + OFF(14)], %i6 126 | ld [%sp + OFF(15)], %i7 127 | 128 | // finally continue execution in new context 129 | jmp %o4 130 | mov %o2, %o0 // return arg as result 131 | 132 | .size jump_fcontext,.-jump_fcontext 133 | 134 | /* Mark that we don't need executable stack. */ 135 | .section .note.GNU-stack,"",%progbits 136 | -------------------------------------------------------------------------------- /jump_x86_64_ms_pe_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Copyright Thomas Sailer 2013. 4 | Distributed under the Boost Software License, Version 1.0. 5 | (See accompanying file LICENSE_1_0.txt or copy at 6 | http://www.boost.org/LICENSE_1_0.txt) 7 | */ 8 | 9 | 10 | .file "jump_x86_64_ms_pe_gas.S" 11 | .text 12 | .p2align 4,,15 13 | .globl jump_fcontext 14 | .def jump_fcontext; .scl 2; .type 32; .endef 15 | .seh_proc jump_fcontext 16 | jump_fcontext: 17 | .seh_endprologue 18 | push %rbp 19 | push %rbx 20 | push %rsi 21 | push %rdi 22 | push %r15 23 | push %r14 24 | push %r13 25 | push %r12 26 | mov %gs:0x30,%r10 27 | mov 0x8(%r10),%rax 28 | push %rax 29 | mov 0x10(%r10),%rax 30 | push %rax 31 | mov 0x1478(%r10),%rax 32 | push %rax 33 | mov 0x18(%r10),%rax 34 | push %rax 35 | lea -0xa8(%rsp),%rsp 36 | test %r9,%r9 37 | je nxt1 38 | stmxcsr 0xa0(%rsp) 39 | fnstcw 0xa4(%rsp) 40 | movaps %xmm6,(%rsp) 41 | movaps %xmm7,0x10(%rsp) 42 | movaps %xmm8,0x20(%rsp) 43 | movaps %xmm9,0x30(%rsp) 44 | movaps %xmm10,0x40(%rsp) 45 | movaps %xmm11,0x50(%rsp) 46 | movaps %xmm12,0x60(%rsp) 47 | movaps %xmm13,0x70(%rsp) 48 | movaps %xmm14,0x80(%rsp) 49 | movaps %xmm15,0x90(%rsp) 50 | nxt1: 51 | xor %r10,%r10 52 | push %r10 53 | mov %rsp,(%rcx) 54 | mov %rdx,%rsp 55 | pop %r10 56 | test %r9,%r9 57 | je nxt2 58 | ldmxcsr 0xa0(%rsp) 59 | fldcw 0xa4(%rsp) 60 | movaps (%rsp),%xmm6 61 | movaps 0x10(%rsp),%xmm7 62 | movaps 0x20(%rsp),%xmm8 63 | movaps 0x30(%rsp),%xmm9 64 | movaps 0x40(%rsp),%xmm10 65 | movaps 0x50(%rsp),%xmm11 66 | movaps 0x60(%rsp),%xmm12 67 | movaps 0x70(%rsp),%xmm13 68 | movaps 0x80(%rsp),%xmm14 69 | movaps 0x90(%rsp),%xmm15 70 | nxt2: 71 | mov $0xa8,%rcx 72 | test %r10,%r10 73 | je nxt3 74 | add $0x8,%rcx 75 | nxt3: 76 | lea (%rsp,%rcx,1),%rsp 77 | mov %gs:0x30,%r10 78 | pop %rax 79 | mov %rax,0x18(%r10) 80 | pop %rax 81 | mov %rax,0x1478(%r10) 82 | pop %rax 83 | mov %rax,0x10(%r10) 84 | pop %rax 85 | mov %rax,0x8(%r10) 86 | pop %r12 87 | pop %r13 88 | pop %r14 89 | pop %r15 90 | pop %rdi 91 | pop %rsi 92 | pop %rbx 93 | pop %rbp 94 | pop %r10 95 | mov %r8,%rax 96 | mov %r8,%rcx 97 | jmpq *%r10 98 | .seh_endproc 99 | -------------------------------------------------------------------------------- /jump_x86_64_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * 16 | * ---------------------------------------------------------------------------------- * 17 | * ---------------------------------------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ---------------------------------------------------------------------------------- * 20 | * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * 21 | * ---------------------------------------------------------------------------------- * 22 | * | R15 | RBX | RBP | RIP | * 23 | * ---------------------------------------------------------------------------------- * 24 | * ---------------------------------------------------------------------------------- * 25 | * | 16 | 17 | | * 26 | * ---------------------------------------------------------------------------------- * 27 | * | 0x40 | 0x44 | | * 28 | * ---------------------------------------------------------------------------------- * 29 | * | EXIT | | * 30 | * ---------------------------------------------------------------------------------- * 31 | * * 32 | ****************************************************************************************/ 33 | 34 | .text 35 | .globl jump_fcontext 36 | .type jump_fcontext,@function 37 | .align 16 38 | jump_fcontext: 39 | pushq %rbp /* save RBP */ 40 | pushq %rbx /* save RBX */ 41 | pushq %r15 /* save R15 */ 42 | pushq %r14 /* save R14 */ 43 | pushq %r13 /* save R13 */ 44 | pushq %r12 /* save R12 */ 45 | 46 | /* prepare stack for FPU */ 47 | leaq -0x8(%rsp), %rsp 48 | 49 | /* test for flag preserve_fpu */ 50 | cmp $0, %rcx 51 | je 1f 52 | 53 | /* save MMX control- and status-word */ 54 | stmxcsr (%rsp) 55 | /* save x87 control-word */ 56 | fnstcw 0x4(%rsp) 57 | 58 | 1: 59 | /* store RSP (pointing to context-data) in RDI */ 60 | movq %rsp, (%rdi) 61 | 62 | /* restore RSP (pointing to context-data) from RSI */ 63 | movq %rsi, %rsp 64 | 65 | /* test for flag preserve_fpu */ 66 | cmp $0, %rcx 67 | je 2f 68 | 69 | /* restore MMX control- and status-word */ 70 | ldmxcsr (%rsp) 71 | /* restore x87 control-word */ 72 | fldcw 0x4(%rsp) 73 | 74 | 2: 75 | /* prepare stack for FPU */ 76 | leaq 0x8(%rsp), %rsp 77 | 78 | popq %r12 /* restrore R12 */ 79 | popq %r13 /* restrore R13 */ 80 | popq %r14 /* restrore R14 */ 81 | popq %r15 /* restrore R15 */ 82 | popq %rbx /* restrore RBX */ 83 | popq %rbp /* restrore RBP */ 84 | 85 | /* restore return-address */ 86 | popq %r8 87 | 88 | /* use third arg as return-value after jump */ 89 | movq %rdx, %rax 90 | /* use third arg as first arg in context function */ 91 | movq %rdx, %rdi 92 | 93 | /* indirect jump to context */ 94 | jmp *%r8 95 | .size jump_fcontext,.-jump_fcontext 96 | 97 | /* Mark that we don't need executable stack. */ 98 | .section .note.GNU-stack,"",%progbits 99 | -------------------------------------------------------------------------------- /jump_x86_64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * 16 | * ---------------------------------------------------------------------------------- * 17 | * ---------------------------------------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ---------------------------------------------------------------------------------- * 20 | * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * 21 | * ---------------------------------------------------------------------------------- * 22 | * | R15 | RBX | RBP | RIP | * 23 | * ---------------------------------------------------------------------------------- * 24 | * ---------------------------------------------------------------------------------- * 25 | * | 16 | 17 | | * 26 | * ---------------------------------------------------------------------------------- * 27 | * | 0x40 | 0x44 | | * 28 | * ---------------------------------------------------------------------------------- * 29 | * | EXIT | | * 30 | * ---------------------------------------------------------------------------------- * 31 | * * 32 | ****************************************************************************************/ 33 | 34 | .text 35 | .globl _jump_fcontext 36 | .align 8 37 | _jump_fcontext: 38 | pushq %rbp /* save RBP */ 39 | pushq %rbx /* save RBX */ 40 | pushq %r15 /* save R15 */ 41 | pushq %r14 /* save R14 */ 42 | pushq %r13 /* save R13 */ 43 | pushq %r12 /* save R12 */ 44 | 45 | /* prepare stack for FPU */ 46 | leaq -0x8(%rsp), %rsp 47 | 48 | /* test for flag preserve_fpu */ 49 | cmp $0, %rcx 50 | je 1f 51 | 52 | /* save MMX control- and status-word */ 53 | stmxcsr (%rsp) 54 | /* save x87 control-word */ 55 | fnstcw 0x4(%rsp) 56 | 57 | 1: 58 | /* store RSP (pointing to context-data) in RDI */ 59 | movq %rsp, (%rdi) 60 | 61 | /* restore RSP (pointing to context-data) from RSI */ 62 | movq %rsi, %rsp 63 | 64 | /* test for flag preserve_fpu */ 65 | cmp $0, %rcx 66 | je 2f 67 | 68 | /* restore MMX control- and status-word */ 69 | ldmxcsr (%rsp) 70 | /* restore x87 control-word */ 71 | fldcw 0x4(%rsp) 72 | 73 | 2: 74 | /* prepare stack for FPU */ 75 | leaq 0x8(%rsp), %rsp 76 | 77 | popq %r12 /* restrore R12 */ 78 | popq %r13 /* restrore R13 */ 79 | popq %r14 /* restrore R14 */ 80 | popq %r15 /* restrore R15 */ 81 | popq %rbx /* restrore RBX */ 82 | popq %rbp /* restrore RBP */ 83 | 84 | /* restore return-address */ 85 | popq %r8 86 | 87 | /* use third arg as return-value after jump */ 88 | movq %rdx, %rax 89 | /* use third arg as first arg in context function */ 90 | movq %rdx, %rdi 91 | 92 | /* indirect jump to context */ 93 | jmp *%r8 94 | -------------------------------------------------------------------------------- /libcontext.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | auto-generated file, do not modify! 4 | libcontext - a slightly more portable version of boost::context 5 | Copyright Martin Husemann 2013. 6 | Copyright Oliver Kowalke 2009. 7 | Copyright Sergue E. Leontiev 2013 8 | Copyright Thomas Sailer 2013. 9 | Minor modifications by Tomasz Wlostowski 2016. 10 | 11 | Distributed under the Boost Software License, Version 1.0. 12 | (See accompanying file LICENSE_1_0.txt or copy at 13 | http://www.boost.org/LICENSE_1_0.txt) 14 | 15 | */ 16 | #include "libcontext.h" 17 | #if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc) 18 | __asm ( 19 | ".text\n" 20 | ".p2align 4,,15\n" 21 | ".globl _jump_fcontext\n" 22 | ".def _jump_fcontext; .scl 2; .type 32; .endef\n" 23 | "_jump_fcontext:\n" 24 | " mov 0x10(%esp),%ecx\n" 25 | " push %ebp\n" 26 | " push %ebx\n" 27 | " push %esi\n" 28 | " push %edi\n" 29 | " mov %fs:0x18,%edx\n" 30 | " mov (%edx),%eax\n" 31 | " push %eax\n" 32 | " mov 0x4(%edx),%eax\n" 33 | " push %eax\n" 34 | " mov 0x8(%edx),%eax\n" 35 | " push %eax\n" 36 | " mov 0xe0c(%edx),%eax\n" 37 | " push %eax\n" 38 | " mov 0x10(%edx),%eax\n" 39 | " push %eax\n" 40 | " lea -0x8(%esp),%esp\n" 41 | " test %ecx,%ecx\n" 42 | " je nxt1\n" 43 | " stmxcsr (%esp)\n" 44 | " fnstcw 0x4(%esp)\n" 45 | "nxt1:\n" 46 | " mov 0x30(%esp),%eax\n" 47 | " mov %esp,(%eax)\n" 48 | " mov 0x34(%esp),%edx\n" 49 | " mov 0x38(%esp),%eax\n" 50 | " mov %edx,%esp\n" 51 | " test %ecx,%ecx\n" 52 | " je nxt2\n" 53 | " ldmxcsr (%esp)\n" 54 | " fldcw 0x4(%esp)\n" 55 | "nxt2:\n" 56 | " lea 0x8(%esp),%esp\n" 57 | " mov %fs:0x18,%edx\n" 58 | " pop %ecx\n" 59 | " mov %ecx,0x10(%edx)\n" 60 | " pop %ecx\n" 61 | " mov %ecx,0xe0c(%edx)\n" 62 | " pop %ecx\n" 63 | " mov %ecx,0x8(%edx)\n" 64 | " pop %ecx\n" 65 | " mov %ecx,0x4(%edx)\n" 66 | " pop %ecx\n" 67 | " mov %ecx,(%edx)\n" 68 | " pop %edi\n" 69 | " pop %esi\n" 70 | " pop %ebx\n" 71 | " pop %ebp\n" 72 | " pop %edx\n" 73 | " mov %eax,0x4(%esp)\n" 74 | " jmp *%edx\n" 75 | ); 76 | 77 | #endif 78 | 79 | #if defined(LIBCONTEXT_PLATFORM_windows_i386) && defined(LIBCONTEXT_COMPILER_gcc) 80 | __asm ( 81 | ".text\n" 82 | ".p2align 4,,15\n" 83 | ".globl _make_fcontext\n" 84 | ".def _make_fcontext; .scl 2; .type 32; .endef\n" 85 | "_make_fcontext:\n" 86 | "mov 0x4(%esp),%eax\n" 87 | "lea -0x8(%eax),%eax\n" 88 | "and $0xfffffff0,%eax\n" 89 | "lea -0x3c(%eax),%eax\n" 90 | "mov 0x4(%esp),%ecx\n" 91 | "mov %ecx,0x14(%eax)\n" 92 | "mov 0x8(%esp),%edx\n" 93 | "neg %edx\n" 94 | "lea (%ecx,%edx,1),%ecx\n" 95 | "mov %ecx,0x10(%eax)\n" 96 | "mov %ecx,0xc(%eax)\n" 97 | "mov 0xc(%esp),%ecx\n" 98 | "mov %ecx,0x2c(%eax)\n" 99 | "stmxcsr (%eax)\n" 100 | "fnstcw 0x4(%eax)\n" 101 | "mov $finish,%ecx\n" 102 | "mov %ecx,0x30(%eax)\n" 103 | "mov %fs:0x0,%ecx\n" 104 | "walk:\n" 105 | "mov (%ecx),%edx\n" 106 | "inc %edx\n" 107 | "je found\n" 108 | "dec %edx\n" 109 | "xchg %edx,%ecx\n" 110 | "jmp walk\n" 111 | "found:\n" 112 | "mov 0x4(%ecx),%ecx\n" 113 | "mov %ecx,0x3c(%eax)\n" 114 | "mov $0xffffffff,%ecx\n" 115 | "mov %ecx,0x38(%eax)\n" 116 | "lea 0x38(%eax),%ecx\n" 117 | "mov %ecx,0x18(%eax)\n" 118 | "ret\n" 119 | "finish:\n" 120 | "xor %eax,%eax\n" 121 | "mov %eax,(%esp)\n" 122 | "call _exit\n" 123 | "hlt\n" 124 | ".def __exit; .scl 2; .type 32; .endef \n" 125 | ); 126 | 127 | #endif 128 | 129 | #if defined(LIBCONTEXT_PLATFORM_windows_x86_64) && defined(LIBCONTEXT_COMPILER_gcc) 130 | __asm ( 131 | ".text\n" 132 | ".p2align 4,,15\n" 133 | ".globl jump_fcontext\n" 134 | ".def jump_fcontext; .scl 2; .type 32; .endef\n" 135 | ".seh_proc jump_fcontext\n" 136 | "jump_fcontext:\n" 137 | ".seh_endprologue\n" 138 | " push %rbp\n" 139 | " push %rbx\n" 140 | " push %rsi\n" 141 | " push %rdi\n" 142 | " push %r15\n" 143 | " push %r14\n" 144 | " push %r13\n" 145 | " push %r12\n" 146 | " mov %gs:0x30,%r10\n" 147 | " mov 0x8(%r10),%rax\n" 148 | " push %rax\n" 149 | " mov 0x10(%r10),%rax\n" 150 | " push %rax\n" 151 | " mov 0x1478(%r10),%rax\n" 152 | " push %rax\n" 153 | " mov 0x18(%r10),%rax\n" 154 | " push %rax\n" 155 | " lea -0xa8(%rsp),%rsp\n" 156 | " test %r9,%r9\n" 157 | " je nxt1\n" 158 | " stmxcsr 0xa0(%rsp)\n" 159 | " fnstcw 0xa4(%rsp)\n" 160 | " movaps %xmm6,(%rsp)\n" 161 | " movaps %xmm7,0x10(%rsp)\n" 162 | " movaps %xmm8,0x20(%rsp)\n" 163 | " movaps %xmm9,0x30(%rsp)\n" 164 | " movaps %xmm10,0x40(%rsp)\n" 165 | " movaps %xmm11,0x50(%rsp)\n" 166 | " movaps %xmm12,0x60(%rsp)\n" 167 | " movaps %xmm13,0x70(%rsp)\n" 168 | " movaps %xmm14,0x80(%rsp)\n" 169 | " movaps %xmm15,0x90(%rsp)\n" 170 | "nxt1:\n" 171 | " xor %r10,%r10\n" 172 | " push %r10\n" 173 | " mov %rsp,(%rcx)\n" 174 | " mov %rdx,%rsp\n" 175 | " pop %r10\n" 176 | " test %r9,%r9\n" 177 | " je nxt2\n" 178 | " ldmxcsr 0xa0(%rsp)\n" 179 | " fldcw 0xa4(%rsp)\n" 180 | " movaps (%rsp),%xmm6\n" 181 | " movaps 0x10(%rsp),%xmm7\n" 182 | " movaps 0x20(%rsp),%xmm8\n" 183 | " movaps 0x30(%rsp),%xmm9\n" 184 | " movaps 0x40(%rsp),%xmm10\n" 185 | " movaps 0x50(%rsp),%xmm11\n" 186 | " movaps 0x60(%rsp),%xmm12\n" 187 | " movaps 0x70(%rsp),%xmm13\n" 188 | " movaps 0x80(%rsp),%xmm14\n" 189 | " movaps 0x90(%rsp),%xmm15\n" 190 | "nxt2:\n" 191 | " mov $0xa8,%rcx\n" 192 | " test %r10,%r10\n" 193 | " je nxt3\n" 194 | " add $0x8,%rcx\n" 195 | "nxt3:\n" 196 | " lea (%rsp,%rcx,1),%rsp\n" 197 | " mov %gs:0x30,%r10\n" 198 | " pop %rax\n" 199 | " mov %rax,0x18(%r10)\n" 200 | " pop %rax\n" 201 | " mov %rax,0x1478(%r10)\n" 202 | " pop %rax\n" 203 | " mov %rax,0x10(%r10)\n" 204 | " pop %rax\n" 205 | " mov %rax,0x8(%r10)\n" 206 | " pop %r12\n" 207 | " pop %r13\n" 208 | " pop %r14\n" 209 | " pop %r15\n" 210 | " pop %rdi\n" 211 | " pop %rsi\n" 212 | " pop %rbx\n" 213 | " pop %rbp\n" 214 | " pop %r10\n" 215 | " mov %r8,%rax\n" 216 | " mov %r8,%rcx\n" 217 | " jmpq *%r10\n" 218 | ".seh_endproc\n" 219 | ); 220 | 221 | #endif 222 | 223 | #if defined(LIBCONTEXT_PLATFORM_windows_x86_64) && defined(LIBCONTEXT_COMPILER_gcc) 224 | __asm ( 225 | ".text\n" 226 | ".p2align 4,,15\n" 227 | ".globl make_fcontext\n" 228 | ".def make_fcontext; .scl 2; .type 32; .endef\n" 229 | ".seh_proc make_fcontext\n" 230 | "make_fcontext:\n" 231 | ".seh_endprologue\n" 232 | "mov %rcx,%rax\n" 233 | "sub $0x28,%rax\n" 234 | "and $0xfffffffffffffff0,%rax\n" 235 | "sub $0x128,%rax\n" 236 | "mov %r8,0x118(%rax)\n" 237 | "mov %rcx,0xd0(%rax)\n" 238 | "neg %rdx\n" 239 | "lea (%rcx,%rdx,1),%rcx\n" 240 | "mov %rcx,0xc8(%rax)\n" 241 | "mov %rcx,0xc0(%rax)\n" 242 | "stmxcsr 0xa8(%rax)\n" 243 | "fnstcw 0xac(%rax)\n" 244 | "leaq finish(%rip), %rcx\n" 245 | "mov %rcx,0x120(%rax)\n" 246 | "mov $0x1,%rcx\n" 247 | "mov %rcx,(%rax)\n" 248 | "retq\n" 249 | "finish:\n" 250 | "xor %rcx,%rcx\n" 251 | "callq 0x63\n" 252 | "hlt\n" 253 | " .seh_endproc\n" 254 | ".def _exit; .scl 2; .type 32; .endef \n" 255 | ); 256 | 257 | #endif 258 | 259 | #if defined(LIBCONTEXT_PLATFORM_linux_i386) && defined(LIBCONTEXT_COMPILER_gcc) 260 | __asm ( 261 | ".text\n" 262 | ".globl jump_fcontext\n" 263 | ".align 2\n" 264 | ".type jump_fcontext,@function\n" 265 | "jump_fcontext:\n" 266 | " movl 0x10(%esp), %ecx\n" 267 | " pushl %ebp \n" 268 | " pushl %ebx \n" 269 | " pushl %esi \n" 270 | " pushl %edi \n" 271 | " leal -0x8(%esp), %esp\n" 272 | " test %ecx, %ecx\n" 273 | " je 1f\n" 274 | " stmxcsr (%esp)\n" 275 | " fnstcw 0x4(%esp)\n" 276 | "1:\n" 277 | " movl 0x1c(%esp), %eax\n" 278 | " movl %esp, (%eax)\n" 279 | " movl 0x20(%esp), %edx\n" 280 | " movl 0x24(%esp), %eax\n" 281 | " movl %edx, %esp\n" 282 | " test %ecx, %ecx\n" 283 | " je 2f\n" 284 | " ldmxcsr (%esp)\n" 285 | " fldcw 0x4(%esp)\n" 286 | "2:\n" 287 | " leal 0x8(%esp), %esp\n" 288 | " popl %edi \n" 289 | " popl %esi \n" 290 | " popl %ebx \n" 291 | " popl %ebp \n" 292 | " popl %edx\n" 293 | " movl %eax, 0x4(%esp)\n" 294 | " jmp *%edx\n" 295 | ".size jump_fcontext,.-jump_fcontext\n" 296 | ".section .note.GNU-stack,\"\",%progbits\n" 297 | ); 298 | 299 | #endif 300 | 301 | #if defined(LIBCONTEXT_PLATFORM_linux_i386) && defined(LIBCONTEXT_COMPILER_gcc) 302 | __asm ( 303 | ".text\n" 304 | ".globl make_fcontext\n" 305 | ".align 2\n" 306 | ".type make_fcontext,@function\n" 307 | "make_fcontext:\n" 308 | " movl 0x4(%esp), %eax\n" 309 | " leal -0x8(%eax), %eax\n" 310 | " andl $-16, %eax\n" 311 | " leal -0x20(%eax), %eax\n" 312 | " movl 0xc(%esp), %edx\n" 313 | " movl %edx, 0x18(%eax)\n" 314 | " stmxcsr (%eax)\n" 315 | " fnstcw 0x4(%eax)\n" 316 | " call 1f\n" 317 | "1: popl %ecx\n" 318 | " addl $finish-1b, %ecx\n" 319 | " movl %ecx, 0x1c(%eax)\n" 320 | " ret \n" 321 | "finish:\n" 322 | " call 2f\n" 323 | "2: popl %ebx\n" 324 | " addl $_GLOBAL_OFFSET_TABLE_+[.-2b], %ebx\n" 325 | " xorl %eax, %eax\n" 326 | " movl %eax, (%esp)\n" 327 | " call _exit@PLT\n" 328 | " hlt\n" 329 | ".size make_fcontext,.-make_fcontext\n" 330 | ".section .note.GNU-stack,\"\",%progbits\n" 331 | ); 332 | 333 | #endif 334 | 335 | #if defined(LIBCONTEXT_PLATFORM_linux_x86_64) && defined(LIBCONTEXT_COMPILER_gcc) 336 | __asm ( 337 | ".text\n" 338 | ".globl jump_fcontext\n" 339 | ".type jump_fcontext,@function\n" 340 | ".align 16\n" 341 | "jump_fcontext:\n" 342 | " pushq %rbp \n" 343 | " pushq %rbx \n" 344 | " pushq %r15 \n" 345 | " pushq %r14 \n" 346 | " pushq %r13 \n" 347 | " pushq %r12 \n" 348 | " leaq -0x8(%rsp), %rsp\n" 349 | " cmp $0, %rcx\n" 350 | " je 1f\n" 351 | " stmxcsr (%rsp)\n" 352 | " fnstcw 0x4(%rsp)\n" 353 | "1:\n" 354 | " movq %rsp, (%rdi)\n" 355 | " movq %rsi, %rsp\n" 356 | " cmp $0, %rcx\n" 357 | " je 2f\n" 358 | " ldmxcsr (%rsp)\n" 359 | " fldcw 0x4(%rsp)\n" 360 | "2:\n" 361 | " leaq 0x8(%rsp), %rsp\n" 362 | " popq %r12 \n" 363 | " popq %r13 \n" 364 | " popq %r14 \n" 365 | " popq %r15 \n" 366 | " popq %rbx \n" 367 | " popq %rbp \n" 368 | " popq %r8\n" 369 | " movq %rdx, %rax\n" 370 | " movq %rdx, %rdi\n" 371 | " jmp *%r8\n" 372 | ".size jump_fcontext,.-jump_fcontext\n" 373 | ".section .note.GNU-stack,\"\",%progbits\n" 374 | ); 375 | 376 | #endif 377 | 378 | #if defined(LIBCONTEXT_PLATFORM_linux_x86_64) && defined(LIBCONTEXT_COMPILER_gcc) 379 | __asm ( 380 | ".text\n" 381 | ".globl make_fcontext\n" 382 | ".type make_fcontext,@function\n" 383 | ".align 16\n" 384 | "make_fcontext:\n" 385 | " movq %rdi, %rax\n" 386 | " andq $-16, %rax\n" 387 | " leaq -0x48(%rax), %rax\n" 388 | " movq %rdx, 0x38(%rax)\n" 389 | " stmxcsr (%rax)\n" 390 | " fnstcw 0x4(%rax)\n" 391 | " leaq finish(%rip), %rcx\n" 392 | " movq %rcx, 0x40(%rax)\n" 393 | " ret \n" 394 | "finish:\n" 395 | " xorq %rdi, %rdi\n" 396 | " call _exit@PLT\n" 397 | " hlt\n" 398 | ".size make_fcontext,.-make_fcontext\n" 399 | ".section .note.GNU-stack,\"\",%progbits\n" 400 | ); 401 | 402 | #endif 403 | 404 | #if defined(LIBCONTEXT_PLATFORM_apple_x86_64) && defined(LIBCONTEXT_COMPILER_gcc) 405 | __asm ( 406 | ".text\n" 407 | ".globl _jump_fcontext\n" 408 | ".align 8\n" 409 | "_jump_fcontext:\n" 410 | " pushq %rbp \n" 411 | " pushq %rbx \n" 412 | " pushq %r15 \n" 413 | " pushq %r14 \n" 414 | " pushq %r13 \n" 415 | " pushq %r12 \n" 416 | " leaq -0x8(%rsp), %rsp\n" 417 | " cmp $0, %rcx\n" 418 | " je 1f\n" 419 | " stmxcsr (%rsp)\n" 420 | " fnstcw 0x4(%rsp)\n" 421 | "1:\n" 422 | " movq %rsp, (%rdi)\n" 423 | " movq %rsi, %rsp\n" 424 | " cmp $0, %rcx\n" 425 | " je 2f\n" 426 | " ldmxcsr (%rsp)\n" 427 | " fldcw 0x4(%rsp)\n" 428 | "2:\n" 429 | " leaq 0x8(%rsp), %rsp\n" 430 | " popq %r12 \n" 431 | " popq %r13 \n" 432 | " popq %r14 \n" 433 | " popq %r15 \n" 434 | " popq %rbx \n" 435 | " popq %rbp \n" 436 | " popq %r8\n" 437 | " movq %rdx, %rax\n" 438 | " movq %rdx, %rdi\n" 439 | " jmp *%r8\n" 440 | ); 441 | 442 | #endif 443 | 444 | #if defined(LIBCONTEXT_PLATFORM_apple_x86_64) && defined(LIBCONTEXT_COMPILER_gcc) 445 | __asm ( 446 | ".text\n" 447 | ".globl _make_fcontext\n" 448 | ".align 8\n" 449 | "_make_fcontext:\n" 450 | " movq %rdi, %rax\n" 451 | " movabs $-16, %r8\n" 452 | " andq %r8, %rax\n" 453 | " leaq -0x48(%rax), %rax\n" 454 | " movq %rdx, 0x38(%rax)\n" 455 | " stmxcsr (%rax)\n" 456 | " fnstcw 0x4(%rax)\n" 457 | " leaq finish(%rip), %rcx\n" 458 | " movq %rcx, 0x40(%rax)\n" 459 | " ret \n" 460 | "finish:\n" 461 | " xorq %rdi, %rdi\n" 462 | " call __exit\n" 463 | " hlt\n" 464 | ); 465 | 466 | #endif 467 | 468 | #if defined(LIBCONTEXT_PLATFORM_apple_i386) && defined(LIBCONTEXT_COMPILER_gcc) 469 | __asm ( 470 | ".text\n" 471 | ".globl _jump_fcontext\n" 472 | ".align 2\n" 473 | "_jump_fcontext:\n" 474 | " movl 0x10(%esp), %ecx\n" 475 | " pushl %ebp \n" 476 | " pushl %ebx \n" 477 | " pushl %esi \n" 478 | " pushl %edi \n" 479 | " leal -0x8(%esp), %esp\n" 480 | " test %ecx, %ecx\n" 481 | " je 1f\n" 482 | " stmxcsr (%esp)\n" 483 | " fnstcw 0x4(%esp)\n" 484 | "1:\n" 485 | " movl 0x1c(%esp), %eax\n" 486 | " movl %esp, (%eax)\n" 487 | " movl 0x20(%esp), %edx\n" 488 | " movl 0x24(%esp), %eax\n" 489 | " movl %edx, %esp\n" 490 | " test %ecx, %ecx\n" 491 | " je 2f\n" 492 | " ldmxcsr (%esp)\n" 493 | " fldcw 0x4(%esp)\n" 494 | "2:\n" 495 | " leal 0x8(%esp), %esp\n" 496 | " popl %edi \n" 497 | " popl %esi \n" 498 | " popl %ebx \n" 499 | " popl %ebp \n" 500 | " popl %edx\n" 501 | " movl %eax, 0x4(%esp)\n" 502 | " jmp *%edx\n" 503 | ); 504 | 505 | #endif 506 | 507 | #if defined(LIBCONTEXT_PLATFORM_apple_i386) && defined(LIBCONTEXT_COMPILER_gcc) 508 | __asm ( 509 | ".text\n" 510 | ".globl _make_fcontext\n" 511 | ".align 2\n" 512 | "_make_fcontext:\n" 513 | " movl 0x4(%esp), %eax\n" 514 | " leal -0x8(%eax), %eax\n" 515 | " andl $-16, %eax\n" 516 | " leal -0x20(%eax), %eax\n" 517 | " movl 0xc(%esp), %edx\n" 518 | " movl %edx, 0x18(%eax)\n" 519 | " stmxcsr (%eax)\n" 520 | " fnstcw 0x4(%eax)\n" 521 | " call 1f\n" 522 | "1: popl %ecx\n" 523 | " addl $finish-1b, %ecx\n" 524 | " movl %ecx, 0x1c(%eax)\n" 525 | " ret \n" 526 | "finish:\n" 527 | " xorl %eax, %eax\n" 528 | " movl %eax, (%esp)\n" 529 | " call __exit\n" 530 | " hlt\n" 531 | ); 532 | 533 | #endif 534 | 535 | #if defined(LIBCONTEXT_PLATFORM_linux_arm32) && defined(LIBCONTEXT_COMPILER_gcc) 536 | __asm ( 537 | ".text\n" 538 | ".globl jump_fcontext\n" 539 | ".align 2\n" 540 | ".type jump_fcontext,%function\n" 541 | "jump_fcontext:\n" 542 | " @ save LR as PC\n" 543 | " push {lr}\n" 544 | " @ save V1-V8,LR\n" 545 | " push {v1-v8,lr}\n" 546 | " @ prepare stack for FPU\n" 547 | " sub sp, sp, #64\n" 548 | " @ test if fpu env should be preserved\n" 549 | " cmp a4, #0\n" 550 | " beq 1f\n" 551 | " @ save S16-S31\n" 552 | " vstmia sp, {d8-d15}\n" 553 | "1:\n" 554 | " @ store RSP (pointing to context-data) in A1\n" 555 | " str sp, [a1]\n" 556 | " @ restore RSP (pointing to context-data) from A2\n" 557 | " mov sp, a2\n" 558 | " @ test if fpu env should be preserved\n" 559 | " cmp a4, #0\n" 560 | " beq 2f\n" 561 | " @ restore S16-S31\n" 562 | " vldmia sp, {d8-d15}\n" 563 | "2:\n" 564 | " @ prepare stack for FPU\n" 565 | " add sp, sp, #64\n" 566 | " @ use third arg as return value after jump\n" 567 | " @ and as first arg in context function\n" 568 | " mov a1, a3\n" 569 | " @ restore v1-V8,LR,PC\n" 570 | " pop {v1-v8,lr}\n" 571 | " pop {pc}\n" 572 | ".size jump_fcontext,.-jump_fcontext\n" 573 | "@ Mark that we don't need executable stack.\n" 574 | ".section .note.GNU-stack,\"\",%progbits\n" 575 | ); 576 | 577 | #endif 578 | 579 | #if defined(LIBCONTEXT_PLATFORM_linux_arm32) && defined(LIBCONTEXT_COMPILER_gcc) 580 | __asm ( 581 | ".text\n" 582 | ".globl make_fcontext\n" 583 | ".align 2\n" 584 | ".type make_fcontext,%function\n" 585 | "make_fcontext:\n" 586 | " @ shift address in A1 to lower 16 byte boundary\n" 587 | " bic a1, a1, #15\n" 588 | " @ reserve space for context-data on context-stack\n" 589 | " sub a1, a1, #104\n" 590 | " @ third arg of make_fcontext() == address of context-function\n" 591 | " str a3, [a1,#100]\n" 592 | " @ compute abs address of label finish\n" 593 | " adr a2, finish\n" 594 | " @ save address of finish as return-address for context-function\n" 595 | " @ will be entered after context-function returns\n" 596 | " str a2, [a1,#96]\n" 597 | " bx lr @ return pointer to context-data\n" 598 | "finish:\n" 599 | " @ exit code is zero\n" 600 | " mov a1, #0\n" 601 | " @ exit application\n" 602 | " bl _exit@PLT\n" 603 | ".size make_fcontext,.-make_fcontext\n" 604 | "@ Mark that we don't need executable stack.\n" 605 | ".section .note.GNU-stack,\"\",%progbits\n" 606 | ); 607 | 608 | #endif 609 | 610 | #if defined(LIBCONTEXT_PLATFORM_linux_arm64) && defined(LIBCONTEXT_COMPILER_gcc) 611 | __asm ( 612 | ".cpu generic+fp+simd\n" 613 | ".text\n" 614 | ".align 2\n" 615 | ".global jump_fcontext\n" 616 | ".type jump_fcontext, %function\n" 617 | "jump_fcontext:\n" 618 | " # prepare stack for GP + FPU\n" 619 | " sub sp, sp, #0xb0\n" 620 | "# Because gcc may save integer registers in fp registers across a\n" 621 | "# function call we cannot skip saving the fp registers.\n" 622 | "#\n" 623 | "# Do not reinstate this test unless you fully understand what you\n" 624 | "# are doing.\n" 625 | "#\n" 626 | "# # test if fpu env should be preserved\n" 627 | "# cmp w3, #0\n" 628 | "# b.eq 1f\n" 629 | " # save d8 - d15\n" 630 | " stp d8, d9, [sp, #0x00]\n" 631 | " stp d10, d11, [sp, #0x10]\n" 632 | " stp d12, d13, [sp, #0x20]\n" 633 | " stp d14, d15, [sp, #0x30]\n" 634 | "1:\n" 635 | " # save x19-x30\n" 636 | " stp x19, x20, [sp, #0x40]\n" 637 | " stp x21, x22, [sp, #0x50]\n" 638 | " stp x23, x24, [sp, #0x60]\n" 639 | " stp x25, x26, [sp, #0x70]\n" 640 | " stp x27, x28, [sp, #0x80]\n" 641 | " stp x29, x30, [sp, #0x90]\n" 642 | " # save LR as PC\n" 643 | " str x30, [sp, #0xa0]\n" 644 | " # store RSP (pointing to context-data) in first argument (x0).\n" 645 | " # STR cannot have sp as a target register\n" 646 | " mov x4, sp\n" 647 | " str x4, [x0]\n" 648 | " # restore RSP (pointing to context-data) from A2 (x1)\n" 649 | " mov sp, x1\n" 650 | "# # test if fpu env should be preserved\n" 651 | "# cmp w3, #0\n" 652 | "# b.eq 2f\n" 653 | " # load d8 - d15\n" 654 | " ldp d8, d9, [sp, #0x00]\n" 655 | " ldp d10, d11, [sp, #0x10]\n" 656 | " ldp d12, d13, [sp, #0x20]\n" 657 | " ldp d14, d15, [sp, #0x30]\n" 658 | "2:\n" 659 | " # load x19-x30\n" 660 | " ldp x19, x20, [sp, #0x40]\n" 661 | " ldp x21, x22, [sp, #0x50]\n" 662 | " ldp x23, x24, [sp, #0x60]\n" 663 | " ldp x25, x26, [sp, #0x70]\n" 664 | " ldp x27, x28, [sp, #0x80]\n" 665 | " ldp x29, x30, [sp, #0x90]\n" 666 | " # use third arg as return value after jump\n" 667 | " # and as first arg in context function\n" 668 | " mov x0, x2\n" 669 | " # load pc\n" 670 | " ldr x4, [sp, #0xa0]\n" 671 | " # restore stack from GP + FPU\n" 672 | " add sp, sp, #0xb0\n" 673 | " ret x4\n" 674 | ".size jump_fcontext,.-jump_fcontext\n" 675 | "# Mark that we don't need executable stack.\n" 676 | ".section .note.GNU-stack,\"\",%progbits\n" 677 | ); 678 | 679 | #endif 680 | 681 | #if defined(LIBCONTEXT_PLATFORM_linux_arm64) && defined(LIBCONTEXT_COMPILER_gcc) 682 | __asm ( 683 | ".cpu generic+fp+simd\n" 684 | ".text\n" 685 | ".align 2\n" 686 | ".global make_fcontext\n" 687 | ".type make_fcontext, %function\n" 688 | "make_fcontext:\n" 689 | " # shift address in x0 (allocated stack) to lower 16 byte boundary\n" 690 | " and x0, x0, ~0xF\n" 691 | " # reserve space for context-data on context-stack\n" 692 | " sub x0, x0, #0xb0\n" 693 | " # third arg of make_fcontext() == address of context-function\n" 694 | " # store address as a PC to jump in\n" 695 | " str x2, [x0, #0xa0]\n" 696 | " # save address of finish as return-address for context-function\n" 697 | " # will be entered after context-function returns (LR register)\n" 698 | " adr x1, finish\n" 699 | " str x1, [x0, #0x98]\n" 700 | " ret x30 \n" 701 | "finish:\n" 702 | " # exit code is zero\n" 703 | " mov x0, #0\n" 704 | " # exit application\n" 705 | " bl _exit\n" 706 | ".size make_fcontext,.-make_fcontext\n" 707 | "# Mark that we don't need executable stack.\n" 708 | ".section .note.GNU-stack,\"\",%progbits\n" 709 | ); 710 | 711 | #endif 712 | 713 | -------------------------------------------------------------------------------- /libcontext.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | libcontext - a slightly more portable version of boost::context 4 | 5 | Copyright Martin Husemann 2013. 6 | Copyright Oliver Kowalke 2009. 7 | Copyright Sergue E. Leontiev 2013. 8 | Copyright Thomas Sailer 2013. 9 | Minor modifications by Tomasz Wlostowski 2016. 10 | 11 | Distributed under the Boost Software License, Version 1.0. 12 | (See accompanying file LICENSE_1_0.txt or copy at 13 | http://www.boost.org/LICENSE_1_0.txt) 14 | 15 | */ 16 | 17 | #ifndef __LIBCONTEXT_H 18 | #define __LIBCONTEXT_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | #if defined(__GNUC__) || defined(__APPLE__) 26 | 27 | #define LIBCONTEXT_COMPILER_gcc 28 | 29 | #if defined(__linux__) 30 | #ifdef __x86_64__ 31 | #define LIBCONTEXT_PLATFORM_linux_x86_64 32 | #define LIBCONTEXT_CALL_CONVENTION 33 | 34 | #elif __i386__ 35 | #define LIBCONTEXT_PLATFORM_linux_i386 36 | #define LIBCONTEXT_CALL_CONVENTION 37 | #elif __arm__ 38 | #define LIBCONTEXT_PLATFORM_linux_arm32 39 | #define LIBCONTEXT_CALL_CONVENTION 40 | #elif __aarch64__ 41 | #define LIBCONTEXT_PLATFORM_linux_arm64 42 | #define LIBCONTEXT_CALL_CONVENTION 43 | #endif 44 | 45 | #elif defined(__MINGW32__) || defined (__MINGW64__) 46 | #if defined(__x86_64__) 47 | #define LIBCONTEXT_COMPILER_gcc 48 | #define LIBCONTEXT_PLATFORM_windows_x86_64 49 | #define LIBCONTEXT_CALL_CONVENTION 50 | #endif 51 | 52 | #if defined(__i386__) 53 | #define LIBCONTEXT_COMPILER_gcc 54 | #define LIBCONTEXT_PLATFORM_windows_i386 55 | #define LIBCONTEXT_CALL_CONVENTION __cdecl 56 | #endif 57 | #elif defined(__APPLE__) && defined(__MACH__) 58 | #if defined (__i386__) 59 | #define LIBCONTEXT_PLATFORM_apple_i386 60 | #define LIBCONTEXT_CALL_CONVENTION 61 | #elif defined (__x86_64__) 62 | #define LIBCONTEXT_PLATFORM_apple_x86_64 63 | #define LIBCONTEXT_CALL_CONVENTION 64 | #endif 65 | #endif 66 | #endif 67 | 68 | 69 | #if defined(_WIN32_WCE) 70 | typedef int intptr_t; 71 | #endif 72 | 73 | typedef void* fcontext_t; 74 | 75 | #ifdef __cplusplus 76 | extern "C"{ 77 | #endif 78 | 79 | 80 | intptr_t LIBCONTEXT_CALL_CONVENTION jump_fcontext( fcontext_t * ofc, fcontext_t nfc, 81 | intptr_t vp, bool preserve_fpu = false); 82 | fcontext_t LIBCONTEXT_CALL_CONVENTION make_fcontext( void * sp, size_t size, void (* fn)( intptr_t) ); 83 | 84 | #ifdef __cplusplus 85 | }; 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /make_arm64_aapcs_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Edward Nevill 2015 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | /******************************************************* 8 | * * 9 | * ------------------------------------------------- * 10 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 11 | * ------------------------------------------------- * 12 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 13 | * ------------------------------------------------- * 14 | * | d8 | d9 | d10 | d11 | * 15 | * ------------------------------------------------- * 16 | * ------------------------------------------------- * 17 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 18 | * ------------------------------------------------- * 19 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 20 | * ------------------------------------------------- * 21 | * | d12 | d13 | d14 | d15 | * 22 | * ------------------------------------------------- * 23 | * ------------------------------------------------- * 24 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 25 | * ------------------------------------------------- * 26 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 27 | * ------------------------------------------------- * 28 | * | x19 | x20 | x21 | x22 | * 29 | * ------------------------------------------------- * 30 | * ------------------------------------------------- * 31 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 32 | * ------------------------------------------------- * 33 | * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * 34 | * ------------------------------------------------- * 35 | * | x23 | x24 | x25 | x26 | * 36 | * ------------------------------------------------- * 37 | * ------------------------------------------------- * 38 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 39 | * ------------------------------------------------- * 40 | * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * 41 | * ------------------------------------------------- * 42 | * | x27 | x28 | FP | LR | * 43 | * ------------------------------------------------- * 44 | * ------------------------------------------------- * 45 | * | 40 | 41 | 42 | 43 | | | * 46 | * ------------------------------------------------- * 47 | * | 0xa0| 0xa4| 0xa8| 0xac| | | * 48 | * ------------------------------------------------- * 49 | * | PC | align | | | * 50 | * ------------------------------------------------- * 51 | * * 52 | *******************************************************/ 53 | 54 | .cpu generic+fp+simd 55 | .text 56 | .align 2 57 | .global make_fcontext 58 | .type make_fcontext, %function 59 | make_fcontext: 60 | # shift address in x0 (allocated stack) to lower 16 byte boundary 61 | and x0, x0, ~0xF 62 | 63 | # reserve space for context-data on context-stack 64 | sub x0, x0, #0xb0 65 | 66 | # third arg of make_fcontext() == address of context-function 67 | # store address as a PC to jump in 68 | str x2, [x0, #0xa0] 69 | 70 | # save address of finish as return-address for context-function 71 | # will be entered after context-function returns (LR register) 72 | adr x1, finish 73 | str x1, [x0, #0x98] 74 | 75 | ret x30 // return pointer to context-data (x0) 76 | 77 | finish: 78 | # exit code is zero 79 | mov x0, #0 80 | # exit application 81 | bl _exit 82 | 83 | .size make_fcontext,.-make_fcontext 84 | # Mark that we don't need executable stack. 85 | .section .note.GNU-stack,"",%progbits 86 | -------------------------------------------------------------------------------- /make_arm64_aapcs_macho_gas.S: -------------------------------------------------------------------------------- 1 | /******************************************************* 2 | * * 3 | * ------------------------------------------------- * 4 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 5 | * ------------------------------------------------- * 6 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 7 | * ------------------------------------------------- * 8 | * | d8 | d9 | d10 | d11 | * 9 | * ------------------------------------------------- * 10 | * ------------------------------------------------- * 11 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 12 | * ------------------------------------------------- * 13 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 14 | * ------------------------------------------------- * 15 | * | d12 | d13 | d14 | d15 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 19 | * ------------------------------------------------- * 20 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 21 | * ------------------------------------------------- * 22 | * | x19 | x20 | x21 | x22 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 26 | * ------------------------------------------------- * 27 | * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * 28 | * ------------------------------------------------- * 29 | * | x23 | x24 | x25 | x26 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 33 | * ------------------------------------------------- * 34 | * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * 35 | * ------------------------------------------------- * 36 | * | x27 | x28 | FP | LR | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 40 | 41 | 42 | 43 | | | * 40 | * ------------------------------------------------- * 41 | * | 0xa0| 0xa4| 0xa8| 0xac| | | * 42 | * ------------------------------------------------- * 43 | * | PC | align | | | * 44 | * ------------------------------------------------- * 45 | * * 46 | *******************************************************/ 47 | 48 | 49 | .text 50 | .globl _make_fcontext 51 | .balign 16 52 | 53 | _make_fcontext: 54 | ; shift address in x0 (allocated stack) to lower 16 byte boundary 55 | and x0, x0, ~0xF 56 | 57 | ; reserve space for context-data on context-stack 58 | sub x0, x0, #0xb0 59 | 60 | ; third arg of make_fcontext() == address of context-function 61 | ; store address as a PC to jump in 62 | str x2, [x0, #0xa0] 63 | 64 | ; compute abs address of label finish 65 | ; 0x0c = 3 instructions * size (4) before label 'finish' 66 | 67 | ; TODO: Numeric offset since llvm still does not support labels in ADR. Fix: 68 | ; http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140407/212336.html 69 | adr x1, 0x0c 70 | 71 | ; save address of finish as return-address for context-function 72 | ; will be entered after context-function returns (LR register) 73 | str x1, [x0, #0x98] 74 | 75 | ret lr ; return pointer to context-data (x0) 76 | 77 | finish: 78 | ; exit code is zero 79 | mov x0, #0 80 | ; exit application 81 | bl __exit 82 | 83 | 84 | -------------------------------------------------------------------------------- /make_arm_aapcs_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 14 | * ------------------------------------------------- * 15 | * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 21 | * ------------------------------------------------- * 22 | * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 28 | * ------------------------------------------------- * 29 | * | v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | | * 33 | * ------------------------------------------------- * 34 | * | 0x60| 0x64| | * 35 | * ------------------------------------------------- * 36 | * | lr | pc | | * 37 | * ------------------------------------------------- * 38 | * * 39 | *******************************************************/ 40 | 41 | .text 42 | .globl make_fcontext 43 | .align 2 44 | .type make_fcontext,%function 45 | make_fcontext: 46 | @ shift address in A1 to lower 16 byte boundary 47 | bic a1, a1, #15 48 | 49 | @ reserve space for context-data on context-stack 50 | sub a1, a1, #104 51 | 52 | @ third arg of make_fcontext() == address of context-function 53 | str a3, [a1,#100] 54 | 55 | @ compute abs address of label finish 56 | adr a2, finish 57 | @ save address of finish as return-address for context-function 58 | @ will be entered after context-function returns 59 | str a2, [a1,#96] 60 | 61 | bx lr @ return pointer to context-data 62 | 63 | finish: 64 | @ exit code is zero 65 | mov a1, #0 66 | @ exit application 67 | bl _exit@PLT 68 | .size make_fcontext,.-make_fcontext 69 | 70 | @ Mark that we don't need executable stack. 71 | .section .note.GNU-stack,"",%progbits 72 | -------------------------------------------------------------------------------- /make_arm_aapcs_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * 14 | * ------------------------------------------------- * 15 | * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * 21 | * ------------------------------------------------- * 22 | * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * 28 | * ------------------------------------------------- * 29 | * | sjlj| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | | * 33 | * ------------------------------------------------- * 34 | * | 0x60| 0x64| 0x68| | * 35 | * ------------------------------------------------- * 36 | * | v8 | lr | pc | | * 37 | * ------------------------------------------------- * 38 | * * 39 | *******************************************************/ 40 | 41 | .text 42 | .globl _make_fcontext 43 | .align 2 44 | _make_fcontext: 45 | @ shift address in A1 to lower 16 byte boundary 46 | bic a1, a1, #15 47 | 48 | @ reserve space for context-data on context-stack 49 | sub a1, a1, #108 50 | 51 | @ third arg of make_fcontext() == address of context-function 52 | str a3, [a1,#104] 53 | 54 | @ compute abs address of label finish 55 | adr a2, finish 56 | @ save address of finish as return-address for context-function 57 | @ will be entered after context-function returns 58 | str a2, [a1,#100] 59 | 60 | bx lr @ return pointer to context-data 61 | 62 | finish: 63 | @ exit code is zero 64 | mov a1, #0 65 | @ exit application 66 | bl __exit 67 | -------------------------------------------------------------------------------- /make_combined_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "make_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "make_x86_64_sysv_macho_gas.S" 14 | #elif defined(__ppc__) 15 | #include "make_ppc32_sysv_macho_gas.S" 16 | #elif defined(__ppc64__) 17 | #include "make_ppc64_sysv_macho_gas.S" 18 | #else 19 | #error "No arch's" 20 | #endif 21 | -------------------------------------------------------------------------------- /make_i386_ms_pe_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Copyright Thomas Sailer 2013. 4 | Distributed under the Boost Software License, Version 1.0. 5 | (See accompanying file LICENSE_1_0.txt or copy at 6 | http://www.boost.org/LICENSE_1_0.txt) 7 | */ 8 | 9 | .file "make_i386_ms_pe_gas.S" 10 | .text 11 | .p2align 4,,15 12 | .globl _make_fcontext 13 | .def _make_fcontext; .scl 2; .type 32; .endef 14 | _make_fcontext: 15 | mov 0x4(%esp),%eax 16 | lea -0x8(%eax),%eax 17 | and $0xfffffff0,%eax 18 | lea -0x3c(%eax),%eax 19 | mov 0x4(%esp),%ecx 20 | mov %ecx,0x14(%eax) 21 | mov 0x8(%esp),%edx 22 | neg %edx 23 | lea (%ecx,%edx,1),%ecx 24 | mov %ecx,0x10(%eax) 25 | mov %ecx,0xc(%eax) 26 | mov 0xc(%esp),%ecx 27 | mov %ecx,0x2c(%eax) 28 | stmxcsr (%eax) 29 | fnstcw 0x4(%eax) 30 | mov $finish,%ecx 31 | mov %ecx,0x30(%eax) 32 | mov %fs:0x0,%ecx 33 | 34 | walk: 35 | mov (%ecx),%edx 36 | inc %edx 37 | je found 38 | dec %edx 39 | xchg %edx,%ecx 40 | jmp walk 41 | 42 | found: 43 | mov 0x4(%ecx),%ecx 44 | mov %ecx,0x3c(%eax) 45 | mov $0xffffffff,%ecx 46 | mov %ecx,0x38(%eax) 47 | lea 0x38(%eax),%ecx 48 | mov %ecx,0x18(%eax) 49 | ret 50 | finish: 51 | xor %eax,%eax 52 | mov %eax,(%esp) 53 | call _exit 54 | hlt 55 | .def __exit; .scl 2; .type 32; .endef /* standard C library function */ 56 | -------------------------------------------------------------------------------- /make_i386_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * 16 | * ---------------------------------------------------------------------------------- * 17 | * * 18 | ****************************************************************************************/ 19 | 20 | .text 21 | .globl make_fcontext 22 | .align 2 23 | .type make_fcontext,@function 24 | make_fcontext: 25 | /* first arg of make_fcontext() == top of context-stack */ 26 | movl 0x4(%esp), %eax 27 | 28 | /* reserve space for first argument of context-function 29 | rax might already point to a 16byte border */ 30 | leal -0x8(%eax), %eax 31 | 32 | /* shift address in EAX to lower 16 byte boundary */ 33 | andl $-16, %eax 34 | 35 | /* reserve space for context-data on context-stack */ 36 | /* size for fc_mxcsr .. EIP + return-address for context-function */ 37 | /* on context-function entry: (ESP -0x4) % 8 == 0 */ 38 | leal -0x20(%eax), %eax 39 | 40 | /* third arg of make_fcontext() == address of context-function */ 41 | movl 0xc(%esp), %edx 42 | movl %edx, 0x18(%eax) 43 | 44 | /* save MMX control- and status-word */ 45 | stmxcsr (%eax) 46 | /* save x87 control-word */ 47 | fnstcw 0x4(%eax) 48 | 49 | /* compute abs address of label finish */ 50 | call 1f 51 | /* address of label 1 */ 52 | 1: popl %ecx 53 | /* compute abs address of label finish */ 54 | addl $finish-1b, %ecx 55 | /* save address of finish as return-address for context-function */ 56 | /* will be entered after context-function returns */ 57 | movl %ecx, 0x1c(%eax) 58 | 59 | ret /* return pointer to context-data */ 60 | 61 | finish: 62 | call 2f 63 | /* address of label 2 */ 64 | 2: popl %ebx 65 | /* compute address of GOT and store it in EBX */ 66 | addl $_GLOBAL_OFFSET_TABLE_+[.-2b], %ebx 67 | 68 | /* exit code is zero */ 69 | xorl %eax, %eax 70 | movl %eax, (%esp) 71 | /* exit application */ 72 | call _exit@PLT 73 | hlt 74 | .size make_fcontext,.-make_fcontext 75 | 76 | /* Mark that we don't need executable stack. */ 77 | .section .note.GNU-stack,"",%progbits 78 | -------------------------------------------------------------------------------- /make_i386_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * 16 | * ---------------------------------------------------------------------------------- * 17 | * * 18 | ****************************************************************************************/ 19 | 20 | .text 21 | .globl _make_fcontext 22 | .align 2 23 | _make_fcontext: 24 | /* first arg of make_fcontext() == top of context-stack */ 25 | movl 0x4(%esp), %eax 26 | 27 | /* reserve space for first argument of context-function 28 | rax might already point to a 16byte border */ 29 | leal -0x8(%eax), %eax 30 | 31 | /* shift address in EAX to lower 16 byte boundary */ 32 | andl $-16, %eax 33 | 34 | /* reserve space for context-data on context-stack */ 35 | /* size for fc_mxcsr .. EIP + return-address for context-function */ 36 | /* on context-function entry: (ESP -0x4) % 8 == 0 */ 37 | leal -0x20(%eax), %eax 38 | 39 | /* thrid arg of make_fcontext() == address of context-function */ 40 | movl 0xc(%esp), %edx 41 | movl %edx, 0x18(%eax) 42 | 43 | /* save MMX control- and status-word */ 44 | stmxcsr (%eax) 45 | /* save x87 control-word */ 46 | fnstcw 0x4(%eax) 47 | 48 | /* compute abs address of label finish */ 49 | call 1f 50 | /* address of label 1 */ 51 | 1: popl %ecx 52 | /* compute abs address of label finish */ 53 | addl $finish-1b, %ecx 54 | /* save address of finish as return-address for context-function */ 55 | /* will be entered after context-function returns */ 56 | movl %ecx, 0x1c(%eax) 57 | 58 | ret /* return pointer to context-data */ 59 | 60 | finish: 61 | /* exit code is zero */ 62 | xorl %eax, %eax 63 | movl %eax, (%esp) 64 | /* exit application */ 65 | call __exit 66 | hlt 67 | -------------------------------------------------------------------------------- /make_i386_x86_64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__i386__) 11 | #include "make_i386_sysv_macho_gas.S" 12 | #elif defined(__x86_64__) 13 | #include "make_x86_64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /make_libcontext.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import re 4 | 5 | files = [ 6 | ["jump_i386_ms_pe_gas.S", "windows_i386", "gcc"], 7 | ["make_i386_ms_pe_gas.S", "windows_i386", "gcc"], 8 | 9 | ["jump_x86_64_ms_pe_gas.S", "windows_x86_64", "gcc"], 10 | ["make_x86_64_ms_pe_gas.S", "windows_x86_64", "gcc"], 11 | 12 | ["jump_i386_sysv_elf_gas.S", "linux_i386", "gcc"], 13 | ["make_i386_sysv_elf_gas.S", "linux_i386", "gcc"], 14 | 15 | ["jump_x86_64_sysv_elf_gas.S", "linux_x86_64", "gcc"], 16 | ["make_x86_64_sysv_elf_gas.S", "linux_x86_64", "gcc"], 17 | 18 | ["jump_x86_64_sysv_macho_gas.S", "apple_x86_64", "gcc"], 19 | ["make_x86_64_sysv_macho_gas.S", "apple_x86_64", "gcc"], 20 | 21 | ["jump_i386_sysv_macho_gas.S", "apple_i386", "gcc"], 22 | ["make_i386_sysv_macho_gas.S", "apple_i386", "gcc"], 23 | 24 | ["jump_arm_aapcs_elf_gas.S", "linux_arm32", "gcc"], 25 | ["make_arm_aapcs_elf_gas.S", "linux_arm32", "gcc"], 26 | 27 | ["jump_arm64_aapcs_elf_gas.S", "linux_arm64", "gcc"], 28 | ["make_arm64_aapcs_elf_gas.S", "linux_arm64", "gcc"] 29 | 30 | #["jump_arm_aapcs_elf_gas.S", "linux_arm", "gcc"], 31 | #["jump_arm_aapcs_macho_gas.S", "apple_arm", "gcc"], 32 | #["jump_ppc32_sysv_elf_gas.S", "linux_ppc32", "gcc"], 33 | #["jump_ppc32_sysv_macho_gas.S", "apple_ppc32", "gcc"], 34 | #["jump_ppc64_sysv_elf_gas.S", "linux_ppc64", "gcc"], 35 | #["jump_ppc64_sysv_macho_gas.S", "apple_ppc64", "gcc"], 36 | #["jump_x86_64_sysv_macho_gas.S", "apple_x86_64", "gcc"], 37 | #["make_arm_aapcs_elf_gas.S", "linux_arm", "gcc"], 38 | #["make_arm_aapcs_macho_gas.S", "apple_arm", "gcc"], 39 | #["make_ppc32_sysv_elf_gas.S", "linux_ppc32", "gcc"], 40 | #["make_ppc32_sysv_macho_gas.S", "apple_ppc32", "gcc"], 41 | #["make_ppc64_sysv_elf_gas.S", "linux_ppc64", "gcc"], 42 | #["make_ppc64_sysv_macho_gas.S", "apple_ppc64", "gcc"], 43 | ]; 44 | 45 | 46 | def removeCCppComment( text ) : 47 | 48 | def blotOutNonNewlines( strIn ) : # Return a string containing only the newline chars contained in strIn 49 | return "" + ("\n" * strIn.count('\n')) 50 | 51 | def replacer( match ) : 52 | s = match.group(0) 53 | if s.startswith('/'): # Matched string is //...EOL or /*...*/ ==> Blot out all non-newline chars 54 | return blotOutNonNewlines(s) 55 | else: # Matched string is '...' or "..." ==> Keep unchanged 56 | return s 57 | 58 | pattern = re.compile( 59 | r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', 60 | re.DOTALL | re.MULTILINE 61 | ) 62 | 63 | return re.sub(pattern, replacer, text) 64 | 65 | ignore_tokens = [".file"] 66 | 67 | 68 | f_out=open("libcontext.cpp","w") 69 | 70 | f_out.write("/*\n") 71 | f_out.write("\n") 72 | f_out.write(" auto-generated file, do not modify!\n"); 73 | f_out.write(" libcontext - a slightly more portable version of boost::context\n"); 74 | f_out.write(" Copyright Martin Husemann 2013.\n"); 75 | f_out.write(" Copyright Oliver Kowalke 2009.\n"); 76 | f_out.write(" Copyright Sergue E. Leontiev 2013\n"); 77 | f_out.write(" Copyright Thomas Sailer 2013.\n"); 78 | f_out.write(" Minor modifications by Tomasz Wlostowski 2016.\n"); 79 | f_out.write("\n") 80 | f_out.write(" Distributed under the Boost Software License, Version 1.0.\n"); 81 | f_out.write(" (See accompanying file LICENSE_1_0.txt or copy at\n"); 82 | f_out.write(" http://www.boost.org/LICENSE_1_0.txt)\n"); 83 | f_out.write("\n") 84 | f_out.write("*/\n"); 85 | 86 | 87 | f_out.write("#include \"libcontext.h\"\n") 88 | 89 | 90 | for [f_name, platform, compiler] in files: 91 | f_out.write("#if defined(LIBCONTEXT_PLATFORM_%s) && defined(LIBCONTEXT_COMPILER_%s)\n" %( platform, compiler )) 92 | 93 | f_out.write("__asm (\n") 94 | 95 | for l in removeCCppComment (open(f_name).read()).split('\n'): 96 | tokens = l.split() 97 | 98 | if len(tokens) > 0 and tokens[0] not in ignore_tokens: 99 | f_out.write("\"%s\\n\"\n"%l.replace('"','\\"')) 100 | # f_out.write(l) 101 | f_out.write(");\n\n"); 102 | # f_out.write(t) 103 | 104 | f_out.write("#endif\n\n") 105 | 106 | f_out.close() 107 | -------------------------------------------------------------------------------- /make_mips32_o32_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F20 | F22 | F24 | F26 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F28 | F30 | S0 | S1 | S2 | S3 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | | * 28 | * ------------------------------------------------- * 29 | * | S4 | S5 | S6 | S7 | FP | RA | PC | | * 30 | * ------------------------------------------------- * 31 | * * 32 | * *****************************************************/ 33 | 34 | .text 35 | .globl make_fcontext 36 | .align 2 37 | .type make_fcontext,@function 38 | .ent make_fcontext 39 | make_fcontext: 40 | #ifdef __PIC__ 41 | .set noreorder 42 | .cpload $t9 43 | .set reorder 44 | #endif 45 | # first arg of make_fcontext() == top address of context-stack 46 | move $v0, $a0 47 | 48 | # shift address in A0 to lower 16 byte boundary 49 | move $v1, $v0 50 | li $v0, -16 # 0xfffffffffffffff0 51 | and $v0, $v1, $v0 52 | 53 | # reserve space for context-data on context-stack 54 | # including 48 byte of shadow space (sp % 16 == 0) 55 | addiu $v0, $v0, -140 56 | 57 | # third arg of make_fcontext() == address of context-function 58 | sw $a2, 88($v0) 59 | # save global pointer in context-data 60 | # S0 will contain address of global pointer 61 | sw $gp, 48($v0) 62 | 63 | # compute abs address of label finish 64 | la $t9, finish 65 | # save address of finish as return-address for context-function 66 | # will be entered after context-function returns 67 | sw $t9, 84($v0) 68 | 69 | jr $ra # return pointer to context-data 70 | 71 | finish: 72 | # allocate stack space (contains shadow space for subroutines) 73 | addiu $sp, $sp, -32 74 | # save return address 75 | sw $ra, 28($sp) 76 | 77 | # restore GP (global pointer) 78 | move $gp, $s0 79 | # exit code is zero 80 | move $a0, $zero 81 | # address of exit 82 | lw $t9, %call16(_exit)($gp) 83 | # exit application 84 | jalr $t9 85 | .end make_fcontext 86 | .size make_fcontext, .-make_fcontext 87 | 88 | /* Mark that we don't need executable stack. */ 89 | .section .note.GNU-stack,"",%progbits 90 | -------------------------------------------------------------------------------- /make_ppc32_ppc64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Sergue E. Leontiev 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | // Stub file for universal binary 9 | 10 | #if defined(__ppc__) 11 | #include "make_ppc32_sysv_macho_gas.S" 12 | #elif defined(__ppc64__) 13 | #include "make_ppc64_sysv_macho_gas.S" 14 | #else 15 | #error "No arch's" 16 | #endif 17 | -------------------------------------------------------------------------------- /make_ppc32_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | R13 | R14 | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | | * 63 | * ------------------------------------------------- * 64 | * | R31 | CR | LR | PC | | * 65 | * ------------------------------------------------- * 66 | * * 67 | *******************************************************/ 68 | 69 | .text 70 | .globl make_fcontext 71 | .align 2 72 | .type make_fcontext,@function 73 | make_fcontext: 74 | # save return address into R6 75 | mflr %r6 76 | 77 | # first arg of make_fcontext() == top address of context-function 78 | # shift address in R3 to lower 16 byte boundary 79 | clrrwi %r3, %r3, 4 80 | 81 | # reserve space for context-data on context-stack 82 | # including 64 byte of linkage + parameter area (R1 % 16 == 0) 83 | subi %r3, %r3, 304 84 | 85 | # third arg of make_fcontext() == address of context-function 86 | stw %r5, 236(%r3) 87 | 88 | # load LR 89 | mflr %r0 90 | # jump to label 1 91 | bl 1f 92 | 1: 93 | # load LR into R4 94 | mflr %r4 95 | # compute abs address of label finish 96 | addi %r4, %r4, finish - 1b 97 | # restore LR 98 | mtlr %r0 99 | # save address of finish as return-address for context-function 100 | # will be entered after context-function returns 101 | stw %r4, 232(%r3) 102 | 103 | # restore return address from R6 104 | mtlr %r6 105 | 106 | blr # return pointer to context-data 107 | 108 | finish: 109 | # save return address into R0 110 | mflr %r0 111 | # save return address on stack, set up stack frame 112 | stw %r0, 4(%r1) 113 | # allocate stack space, R1 % 16 == 0 114 | stwu %r1, -16(%r1) 115 | 116 | # exit code is zero 117 | li %r3, 0 118 | # exit application 119 | bl _exit@plt 120 | .size make_fcontext, .-make_fcontext 121 | 122 | /* Mark that we don't need executable stack. */ 123 | .section .note.GNU-stack,"",%progbits 124 | -------------------------------------------------------------------------------- /make_ppc32_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | R13 | R14 | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | | * 63 | * ------------------------------------------------- * 64 | * | R31 | CR | LR | PC | | * 65 | * ------------------------------------------------- * 66 | * * 67 | *******************************************************/ 68 | 69 | .text 70 | .globl _make_fcontext 71 | .align 2 72 | _make_fcontext: 73 | ; save return address into R6 74 | mflr r6 75 | 76 | ; first arg of make_fcontext() == top address of context-function 77 | ; shift address in R3 to lower 16 byte boundary 78 | clrrwi r3, r3, 4 79 | 80 | ; reserve space for context-data on context-stack 81 | ; including 64 byte of linkage + parameter area (R1 % 16 == 0) 82 | subi r3, r3, 304 83 | 84 | ; third arg of make_fcontext() == address of context-function 85 | stw r5, 236(%r3) 86 | 87 | ; load LR 88 | mflr r0 89 | ; jump to label 1 90 | bl l1 91 | l1: 92 | ; load LR into R4 93 | mflr r4 94 | ; compute abs address of label finish 95 | addi r4, r4, lo16((finish - .)+4) 96 | # restore LR 97 | mtlr r0 98 | ; save address of finish as return-address for context-function 99 | ; will be entered after context-function returns 100 | stw r4, 232(r3) 101 | 102 | ; restore return address from R6 103 | mtlr r6 104 | 105 | blr ; return pointer to context-data 106 | 107 | finish: 108 | ; save return address into R0 109 | mflr r0 110 | ; save return address on stack, set up stack frame 111 | stw r0, 4(r1) 112 | ; allocate stack space, R1 % 16 == 0 113 | stwu r1, -16(r1) 114 | 115 | ; exit code is zero 116 | li r3, 0 117 | ; exit application 118 | bl __exit 119 | -------------------------------------------------------------------------------- /make_ppc32_sysv_xcoff_gas.S: -------------------------------------------------------------------------------- 1 | .globl make_fcontext[DS] 2 | .globl .make_fcontext[PR] 3 | .align 2 4 | .csect .make_fcontext[PR], 3 5 | #.make_fcontext: 6 | # save return address into R6 7 | mflr 6 8 | 9 | # first arg of make_fcontext() == top address of context-function 10 | # shift address in R3 to lower 16 byte boundary 11 | clrrwi 3, 3, 4 12 | 13 | # reserve space for context-data on context-stack 14 | # including 64 byte of linkage + parameter area (R1 % 16 == 0) 15 | subi 3, 3, 304 16 | 17 | # third arg of make_fcontext() == address of context-function 18 | stw 5, 236(3) 19 | 20 | # load LR 21 | mflr 0 22 | # jump to label 1 23 | bl .Label 24 | .Label: 25 | # load LR into R4 26 | mflr 4 27 | # compute abs address of label .L_finish 28 | addi 4, 4, .L_finish - .Label 29 | # restore LR 30 | mtlr 0 31 | # save address of finish as return-address for context-function 32 | # will be entered after context-function returns 33 | stw 4, 232(3) 34 | 35 | # restore return address from R6 36 | mtlr 6 37 | 38 | blr # return pointer to context-data 39 | 40 | .L_finish: 41 | # save return address into R0 42 | mflr 0 43 | # save return address on stack, set up stack frame 44 | stw 0, 4(1) 45 | # allocate stack space, R1 % 16 == 0 46 | stwu 1, -16(1) 47 | 48 | # exit code is zero 49 | li 3, 0 50 | # exit application 51 | bl ._exit 52 | nop 53 | -------------------------------------------------------------------------------- /make_ppc64_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | TOC | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R14 | R15 | R16 | R17 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R18 | R19 | R20 | R21 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * 63 | * ------------------------------------------------- * 64 | * | R22 | R23 | R24 | R25 | * 65 | * ------------------------------------------------- * 66 | * ------------------------------------------------- * 67 | * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * 68 | * ------------------------------------------------- * 69 | * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * 70 | * ------------------------------------------------- * 71 | * | R26 | R27 | R28 | R29 | * 72 | * ------------------------------------------------- * 73 | * ------------------------------------------------- * 74 | * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * 75 | * ------------------------------------------------- * 76 | * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * 77 | * ------------------------------------------------- * 78 | * ------------------------------------------------- * 79 | * | R30 | R31 | CR | LR | * 80 | * ------------------------------------------------- * 81 | * ------------------------------------------------- * 82 | * | 80 | 81 | | * 83 | * ------------------------------------------------- * 84 | * | 320 | 324 | | * 85 | * ------------------------------------------------- * 86 | * | PC | | * 87 | * ------------------------------------------------- * 88 | * * 89 | *******************************************************/ 90 | 91 | .globl make_fcontext 92 | #if _CALL_ELF == 2 93 | .text 94 | .align 2 95 | make_fcontext: 96 | addis %r2, %r12, .TOC.-make_fcontext@ha 97 | addi %r2, %r2, .TOC.-make_fcontext@l 98 | .localentry make_fcontext, . - make_fcontext 99 | #else 100 | .section ".opd","aw" 101 | .align 3 102 | make_fcontext: 103 | # ifdef _CALL_LINUX 104 | .quad .L.make_fcontext,.TOC.@tocbase,0 105 | .type make_fcontext,@function 106 | .text 107 | .align 2 108 | .L.make_fcontext: 109 | # else 110 | .hidden .make_fcontext 111 | .globl .make_fcontext 112 | .quad .make_fcontext,.TOC.@tocbase,0 113 | .size make_fcontext,24 114 | .type .make_fcontext,@function 115 | .text 116 | .align 2 117 | .make_fcontext: 118 | # endif 119 | #endif 120 | # save return address into R6 121 | mflr %r6 122 | 123 | # first arg of make_fcontext() == top address of context-stack 124 | # shift address in R3 to lower 16 byte boundary 125 | clrrdi %r3, %r3, 4 126 | 127 | # reserve space for context-data on context-stack 128 | # including 64 byte of linkage + parameter area (R1 % 16 == 0) 129 | subi %r3, %r3, 392 130 | 131 | # third arg of make_fcontext() == address of context-function 132 | # entry point (ELFv2) or descriptor (ELFv1) 133 | #if _CALL_ELF == 2 134 | # save address of context-function entry point 135 | std %r5, 320(%r3) 136 | #else 137 | # save address of context-function entry point 138 | ld %r4, 0(%r5) 139 | std %r4, 320(%r3) 140 | # save TOC of context-function 141 | ld %r4, 8(%r5) 142 | std %r4, 152(%r3) 143 | #endif 144 | 145 | # load LR 146 | mflr %r0 147 | # jump to label 1 148 | bl 1f 149 | 1: 150 | # load LR into R4 151 | mflr %r4 152 | # compute abs address of label finish 153 | addi %r4, %r4, finish - 1b 154 | # restore LR 155 | mtlr %r0 156 | # save address of finish as return-address for context-function 157 | # will be entered after context-function returns 158 | std %r4, 312(%r3) 159 | 160 | # restore return address from R6 161 | mtlr %r6 162 | 163 | blr # return pointer to context-data 164 | 165 | finish: 166 | # save return address into R0 167 | mflr %r0 168 | # save return address on stack, set up stack frame 169 | std %r0, 8(%r1) 170 | # allocate stack space, R1 % 16 == 0 171 | stdu %r1, -32(%r1) 172 | 173 | # exit code is zero 174 | li %r3, 0 175 | # exit application 176 | bl _exit 177 | nop 178 | #if _CALL_ELF == 2 179 | .size make_fcontext, .-make_fcontext 180 | #else 181 | # ifdef _CALL_LINUX 182 | .size .make_fcontext, .-.L.make_fcontext 183 | # else 184 | .size .make_fcontext, .-.make_fcontext 185 | # endif 186 | #endif 187 | 188 | /* Mark that we don't need executable stack. */ 189 | .section .note.GNU-stack,"",%progbits 190 | -------------------------------------------------------------------------------- /make_ppc64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************* 9 | * * 10 | * ------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ------------------------------------------------- * 13 | * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * 14 | * ------------------------------------------------- * 15 | * | F14 | F15 | F16 | F17 | * 16 | * ------------------------------------------------- * 17 | * ------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ------------------------------------------------- * 20 | * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * 21 | * ------------------------------------------------- * 22 | * | F18 | F19 | F20 | F21 | * 23 | * ------------------------------------------------- * 24 | * ------------------------------------------------- * 25 | * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * 26 | * ------------------------------------------------- * 27 | * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * 28 | * ------------------------------------------------- * 29 | * | F22 | F23 | F24 | F25 | * 30 | * ------------------------------------------------- * 31 | * ------------------------------------------------- * 32 | * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * 33 | * ------------------------------------------------- * 34 | * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * 35 | * ------------------------------------------------- * 36 | * | F26 | F27 | F28 | F29 | * 37 | * ------------------------------------------------- * 38 | * ------------------------------------------------- * 39 | * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * 40 | * ------------------------------------------------- * 41 | * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * 42 | * ------------------------------------------------- * 43 | * | F30 | F31 | fpscr | R13 | * 44 | * ------------------------------------------------- * 45 | * ------------------------------------------------- * 46 | * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * 47 | * ------------------------------------------------- * 48 | * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * 49 | * ------------------------------------------------- * 50 | * | R14 | R15 | R16 | R17 | * 51 | * ------------------------------------------------- * 52 | * ------------------------------------------------- * 53 | * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * 54 | * ------------------------------------------------- * 55 | * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * 56 | * ------------------------------------------------- * 57 | * | R18 | R19 | R20 | R21 | * 58 | * ------------------------------------------------- * 59 | * ------------------------------------------------- * 60 | * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * 61 | * ------------------------------------------------- * 62 | * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * 63 | * ------------------------------------------------- * 64 | * | R22 | R23 | R24 | R25 | * 65 | * ------------------------------------------------- * 66 | * ------------------------------------------------- * 67 | * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * 68 | * ------------------------------------------------- * 69 | * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * 70 | * ------------------------------------------------- * 71 | * | R26 | R27 | R28 | R29 | * 72 | * ------------------------------------------------- * 73 | * ------------------------------------------------- * 74 | * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * 75 | * ------------------------------------------------- * 76 | * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * 77 | * ------------------------------------------------- * 78 | * ------------------------------------------------- * 79 | * | R30 | R31 | CR | LR | * 80 | * ------------------------------------------------- * 81 | * ------------------------------------------------- * 82 | * | 80 | 81 | | * 83 | * ------------------------------------------------- * 84 | * | 320 | 324 | | * 85 | * ------------------------------------------------- * 86 | * | PC | | * 87 | * ------------------------------------------------- * 88 | * * 89 | *******************************************************/ 90 | 91 | .text 92 | .globl _make_fcontext 93 | _make_fcontext: 94 | ; save return address into R6 95 | mflr r6 96 | 97 | ; first arg of make_fcontext() == top address of context-function 98 | ; shift address in R3 to lower 16 byte boundary 99 | clrrwi r3, r3, 4 100 | 101 | ; reserve space for context-data on context-stack 102 | ; including 64 byte of linkage + parameter area (R1 16 == 0) 103 | subi r3, r3, 392 104 | 105 | ; third arg of make_fcontext() == address of context-function 106 | stw r5, 320(r3) 107 | 108 | ; load LR 109 | mflr r0 110 | ; jump to label 1 111 | bl l1 112 | l1: 113 | ; load LR into R4 114 | mflr r4 115 | ; compute abs address of label finish 116 | addi r4, r4, lo16((finish - .) + 4) 117 | ; restore LR 118 | mtlr r0 119 | ; save address of finish as return-address for context-function 120 | ; will be entered after context-function returns 121 | std r4, 312(r3) 122 | 123 | ; restore return address from R6 124 | mtlr r6 125 | 126 | blr ; return pointer to context-data 127 | 128 | finish: 129 | ; save return address into R0 130 | mflr r0 131 | ; save return address on stack, set up stack frame 132 | stw r0, 8(r1) 133 | ; allocate stack space, R1 16 == 0 134 | stwu r1, -32(r1) 135 | 136 | ; set return value to zero 137 | li r3, 0 138 | ; exit application 139 | bl __exit 140 | nop 141 | -------------------------------------------------------------------------------- /make_ppc64_sysv_xcoff_gas.S: -------------------------------------------------------------------------------- 1 | .globl make_fcontext[DS] 2 | .globl .make_fcontext[PR] 3 | .align 2 4 | .csect .make_fcontext[PR], 3 5 | .globl _make_fcontext 6 | #._make_fcontext: 7 | # save return address into R6 8 | mflr 6 9 | 10 | # first arg of make_fcontext() == top address of context-function 11 | # shift address in R3 to lower 16 byte boundary 12 | clrrwi 3, 3, 4 13 | 14 | # reserve space for context-data on context-stack 15 | # including 64 byte of linkage + parameter area (R1 % 16 == 0) 16 | subi 3, 3, 392 17 | 18 | # third arg of make_fcontext() == address of context-function 19 | stw 5, 320(3) 20 | 21 | # load LR 22 | mflr 0 23 | # jump to label 1 24 | bl .Label 25 | .Label: 26 | # load LR into R4 27 | mflr 4 28 | # compute abs address of label .L_finish 29 | addi 4, 4, .L_finish - .Label 30 | # restore LR 31 | mtlr 0 32 | # save address of finish as return-address for context-function 33 | # will be entered after context-function returns 34 | stw 4, 312(3) 35 | 36 | # restore return address from R6 37 | mtlr 6 38 | 39 | blr # return pointer to context-data 40 | 41 | .L_finish: 42 | # save return address into R0 43 | mflr 0 44 | # save return address on stack, set up stack frame 45 | stw 0, 8(1) 46 | # allocate stack space, R1 % 16 == 0 47 | stwu 1, -32(1) 48 | 49 | # exit code is zero 50 | li 3, 0 51 | # exit application 52 | bl ._exit 53 | nop 54 | -------------------------------------------------------------------------------- /make_sparc64_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Martin Husemann 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************************* 9 | * * 10 | * ------------------------------------------------------------- * 11 | * | Offset (in 4 or 8 byte units) | Content | * 12 | * ------------------------------------------------------------- * 13 | * | 0 | %sp | * 14 | * ------------------------------------------------------------- * 15 | * | 1 | %pc | * 16 | * ------------------------------------------------------------- * 17 | * | 2 | %i7 (return address) | * 18 | * ------------------------------------------------------------- * 19 | * | 3 | %g1 | * 20 | * ------------------------------------------------------------- * 21 | * | 4 | %g2 | * 22 | * ------------------------------------------------------------- * 23 | * | 5 | %g3 | * 24 | * ------------------------------------------------------------- * 25 | * | 6 | %g6 | * 26 | * ------------------------------------------------------------- * 27 | * | 7 | %g7 | * 28 | * ------------------------------------------------------------- * 29 | * The local and in registers are stored on the stack. * 30 | *******************************************************************/ 31 | 32 | #define OFF(N) (8*(N)) 33 | #define CCFSZ 176 // C Compiler Frame Size 34 | #define BIAS (2048-1) // Stack offset for 64 bit programs 35 | #define FC_SZ 448 // sizeof(fcontext_t) 36 | #define FC_STK 384 // offsetof(fcontext_t, fc_stack) 37 | #define FC_FPU 0 // offsetof(fcontext_t, fc_fp) 38 | #define FC_FSR 264 // offsetof(fcontext_t, fc_fp.fp_fsr) 39 | #define FC_FPRS 256 // offsetof(fcontext_t, fc_fp.fp_fprs) 40 | #define FC_GREG 320 // offsetof(fcontext_t, fc_greg) 41 | #define BLOCK_SIZE 64 42 | 43 | .register %g2,#ignore 44 | .register %g3,#ignore 45 | .register %g6,#ignore 46 | 47 | .text 48 | .globl make_fcontext 49 | .align 4 50 | .type make_fcontext,@function 51 | // fcontext_t * 52 | // make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) ) 53 | make_fcontext: 54 | save %sp, -CCFSZ, %sp 55 | // %i0 initial stack pointer 56 | // %i1 stack size limit 57 | // %i2 function pointer for context start function 58 | 59 | sub %i0, FC_SZ, %i4 // allocate fcontext_t at on the new stack and keep pointer as return value 60 | andn %i4, BLOCK_SIZE-1, %i5 // force block ops usable alignement and keep pointer to fcontext in %i5 61 | 62 | stx %i0, [%i5+FC_STK+OFF(0)] // save fs_stack.sp 63 | stx %i1, [%i5+FC_STK+OFF(1)] // save fs_stack.size 64 | sub %i5, CCFSZ+BIAS, %o1 // leave space for one register window (and offset stack for 64bit) 65 | stx %o1, [%i5+FC_GREG+OFF(0)] // save new stack pointer 66 | stx %i2, [%i5+FC_GREG+OFF(1)] // save new %pc (function pointer) 67 | stx %g1, [%i5+FC_GREG+OFF(3)] 68 | stx %g2, [%i5+FC_GREG+OFF(4)] 69 | stx %g3, [%i5+FC_GREG+OFF(5)] 70 | stx %g6, [%i5+FC_GREG+OFF(6)] 71 | stx %g7, [%i5+FC_GREG+OFF(7)] 72 | 73 | // synthesize "return address": jump to finish 74 | 1: rd %pc, %i4 75 | add %i4, finish-1b-8, %i4 76 | stx %i4, [%i5+FC_GREG+OFF(2)] 77 | 78 | ret 79 | restore %g0, %i5, %o0 // return fcontext_t 80 | 81 | finish: 82 | mov %g0, %o0 83 | call _exit 84 | nop 85 | 86 | .size make_fcontext,.-make_fcontext 87 | 88 | /* Mark that we don't need executable stack. */ 89 | .section .note.GNU-stack,"",%progbits 90 | -------------------------------------------------------------------------------- /make_sparc_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Martin Husemann 2013. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /******************************************************************* 9 | * * 10 | * ------------------------------------------------------------- * 11 | * | Offset (in 4 or 8 byte units) | Content | * 12 | * ------------------------------------------------------------- * 13 | * | 0 | %sp | * 14 | * ------------------------------------------------------------- * 15 | * | 1 | %pc | * 16 | * ------------------------------------------------------------- * 17 | * | 2 | %i7 (return address) | * 18 | * ------------------------------------------------------------- * 19 | * | 3 | %g1 | * 20 | * ------------------------------------------------------------- * 21 | * | 4 | %g2 | * 22 | * ------------------------------------------------------------- * 23 | * | 5 | %g3 | * 24 | * ------------------------------------------------------------- * 25 | * | 6 | %g6 | * 26 | * ------------------------------------------------------------- * 27 | * | 7 | %g7 | * 28 | * ------------------------------------------------------------- * 29 | * The local and in registers are stored on the stack. * 30 | *******************************************************************/ 31 | 32 | #define OFF(N) (4*(N)) 33 | #define CCFSZ 96 34 | #define FC_SZ 176 35 | #define FC_stK 168 // offsetof(fcontext_t, fc_stack) 36 | #define FC_FPU 0 // offsetof(fcontext_t, fc_fp) 37 | #define FC_FSR 128 // offsetof(fcontext_t, fc_fp.fp_fsr) 38 | #define FC_GREG 136 // offsetof(fcontext_t, fc_greg) 39 | #define BLOCK_SIZE 8 40 | 41 | .text 42 | .globl make_fcontext 43 | .align 4 44 | .type make_fcontext,@function 45 | // fcontext_t * 46 | // make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) ) 47 | make_fcontext: 48 | save %sp, -CCFSZ, %sp 49 | // %i0 initial stack pointer 50 | // %i1 stack size limit 51 | // %i2 function pointer for context start function 52 | 53 | sub %i0, FC_SZ, %i4 // allocate fcontext_t at on the new stack and keep pointer as return value 54 | andn %i4, BLOCK_SIZE-1, %i5 // force block ops usable alignement and keep pointer to fcontext in %i5 55 | 56 | st %i0, [%i5+FC_stK+OFF(0)] // save fs_stack.sp 57 | st %i1, [%i5+FC_stK+OFF(1)] // save fs_stack.size 58 | sub %i5, CCFSZ, %o1 // leave space for one register window 59 | st %o1, [%i5+FC_GREG+OFF(0)] // save new stack pointer 60 | st %i2, [%i5+FC_GREG+OFF(1)] // save new %pc (function pointer) 61 | st %g1, [%i5+FC_GREG+OFF(3)] 62 | st %g2, [%i5+FC_GREG+OFF(4)] 63 | st %g3, [%i5+FC_GREG+OFF(5)] 64 | st %g6, [%i5+FC_GREG+OFF(6)] 65 | st %g7, [%i5+FC_GREG+OFF(7)] 66 | 67 | // synthesize "return address": jump to finish 68 | mov %i7, %l0 69 | 2: call 3f 70 | nop 71 | 3: add finish-2b-8, %o7, %i4 72 | st %i4, [%i5+FC_GREG+OFF(2)] 73 | 74 | ret 75 | restore %g0, %i5, %o0 // return fcontext_t 76 | 77 | finish: 78 | mov %g0, %o0 79 | call _exit 80 | nop 81 | 82 | .size make_fcontext,.-make_fcontext 83 | 84 | /* Mark that we don't need executable stack. */ 85 | .section .note.GNU-stack,"",%progbits 86 | -------------------------------------------------------------------------------- /make_x86_64_ms_pe_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Copyright Thomas Sailer 2013. 4 | Distributed under the Boost Software License, Version 1.0. 5 | (See accompanying file LICENSE_1_0.txt or copy at 6 | http://www.boost.org/LICENSE_1_0.txt) 7 | */ 8 | 9 | 10 | 11 | .file "make_x86_64_ms_pe_gas.S" 12 | .text 13 | .p2align 4,,15 14 | .globl make_fcontext 15 | .def make_fcontext; .scl 2; .type 32; .endef 16 | .seh_proc make_fcontext 17 | make_fcontext: 18 | .seh_endprologue 19 | mov %rcx,%rax 20 | sub $0x28,%rax 21 | and $0xfffffffffffffff0,%rax 22 | sub $0x128,%rax 23 | mov %r8,0x118(%rax) 24 | mov %rcx,0xd0(%rax) 25 | neg %rdx 26 | lea (%rcx,%rdx,1),%rcx 27 | mov %rcx,0xc8(%rax) 28 | mov %rcx,0xc0(%rax) 29 | stmxcsr 0xa8(%rax) 30 | fnstcw 0xac(%rax) 31 | leaq finish(%rip), %rcx 32 | mov %rcx,0x120(%rax) 33 | mov $0x1,%rcx 34 | mov %rcx,(%rax) 35 | retq 36 | finish: 37 | xor %rcx,%rcx 38 | callq 0x63 39 | hlt 40 | .seh_endproc 41 | 42 | .def _exit; .scl 2; .type 32; .endef /* standard C library function */ 43 | -------------------------------------------------------------------------------- /make_x86_64_sysv_elf_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * 16 | * ---------------------------------------------------------------------------------- * 17 | * ---------------------------------------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ---------------------------------------------------------------------------------- * 20 | * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * 21 | * ---------------------------------------------------------------------------------- * 22 | * | R15 | RBX | RBP | RIP | * 23 | * ---------------------------------------------------------------------------------- * 24 | * ---------------------------------------------------------------------------------- * 25 | * | 16 | 17 | | * 26 | * ---------------------------------------------------------------------------------- * 27 | * | 0x40 | 0x44 | | * 28 | * ---------------------------------------------------------------------------------- * 29 | * | EXIT | | * 30 | * ---------------------------------------------------------------------------------- * 31 | * * 32 | ****************************************************************************************/ 33 | 34 | .text 35 | .globl make_fcontext 36 | .type make_fcontext,@function 37 | .align 16 38 | make_fcontext: 39 | /* first arg of make_fcontext() == top of context-stack */ 40 | movq %rdi, %rax 41 | 42 | /* shift address in RAX to lower 16 byte boundary */ 43 | andq $-16, %rax 44 | 45 | /* reserve space for context-data on context-stack */ 46 | /* size for fc_mxcsr .. RIP + return-address for context-function */ 47 | /* on context-function entry: (RSP -0x8) % 16 == 0 */ 48 | leaq -0x48(%rax), %rax 49 | 50 | /* third arg of make_fcontext() == address of context-function */ 51 | movq %rdx, 0x38(%rax) 52 | 53 | /* save MMX control- and status-word */ 54 | stmxcsr (%rax) 55 | /* save x87 control-word */ 56 | fnstcw 0x4(%rax) 57 | 58 | /* compute abs address of label finish */ 59 | leaq finish(%rip), %rcx 60 | /* save address of finish as return-address for context-function */ 61 | /* will be entered after context-function returns */ 62 | movq %rcx, 0x40(%rax) 63 | 64 | ret /* return pointer to context-data */ 65 | 66 | finish: 67 | /* exit code is zero */ 68 | xorq %rdi, %rdi 69 | /* exit application */ 70 | call _exit@PLT 71 | hlt 72 | .size make_fcontext,.-make_fcontext 73 | 74 | /* Mark that we don't need executable stack. */ 75 | .section .note.GNU-stack,"",%progbits 76 | -------------------------------------------------------------------------------- /make_x86_64_sysv_macho_gas.S: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Oliver Kowalke 2009. 3 | Distributed under the Boost Software License, Version 1.0. 4 | (See accompanying file LICENSE_1_0.txt or copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /**************************************************************************************** 9 | * * 10 | * ---------------------------------------------------------------------------------- * 11 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * 12 | * ---------------------------------------------------------------------------------- * 13 | * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * 14 | * ---------------------------------------------------------------------------------- * 15 | * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * 16 | * ---------------------------------------------------------------------------------- * 17 | * ---------------------------------------------------------------------------------- * 18 | * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * 19 | * ---------------------------------------------------------------------------------- * 20 | * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * 21 | * ---------------------------------------------------------------------------------- * 22 | * | R15 | RBX | RBP | RIP | * 23 | * ---------------------------------------------------------------------------------- * 24 | * ---------------------------------------------------------------------------------- * 25 | * | 16 | 17 | | * 26 | * ---------------------------------------------------------------------------------- * 27 | * | 0x40 | 0x44 | | * 28 | * ---------------------------------------------------------------------------------- * 29 | * | EXIT | | * 30 | * ---------------------------------------------------------------------------------- * 31 | * * 32 | ****************************************************************************************/ 33 | 34 | .text 35 | .globl _make_fcontext 36 | .align 8 37 | _make_fcontext: 38 | /* first arg of make_fcontext() == top of context-stack */ 39 | movq %rdi, %rax 40 | 41 | /* shift address in RAX to lower 16 byte boundary */ 42 | movabs $-16, %r8 43 | andq %r8, %rax 44 | 45 | /* reserve space for context-data on context-stack */ 46 | /* size for fc_mxcsr .. RIP + return-address for context-function */ 47 | /* on context-function entry: (RSP -0x8) % 16 == 0 */ 48 | leaq -0x48(%rax), %rax 49 | 50 | /* third arg of make_fcontext() == address of context-function */ 51 | movq %rdx, 0x38(%rax) 52 | 53 | /* save MMX control- and status-word */ 54 | stmxcsr (%rax) 55 | /* save x87 control-word */ 56 | fnstcw 0x4(%rax) 57 | 58 | /* compute abs address of label finish */ 59 | leaq finish(%rip), %rcx 60 | /* save address of finish as return-address for context-function */ 61 | /* will be entered after context-function returns */ 62 | movq %rcx, 0x40(%rax) 63 | 64 | ret /* return pointer to context-data */ 65 | 66 | finish: 67 | /* exit code is zero */ 68 | xorq %rdi, %rdi 69 | /* exit application */ 70 | call __exit 71 | hlt 72 | -------------------------------------------------------------------------------- /tests/build-arm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | arm-linux-gnueabihf-g++-4.8 -static -mfloat-abi=hard -mcpu=cortex-a9 -Wall -g -I. coroutine_example.cpp ../libcontext.cpp -o test-linux-arm32 -I.. 3 | aarch64-linux-gnu-g++-4.8 -static -Wall -g -I. coroutine_example.cpp ../libcontext.cpp -o test-linux-arm64 -I.. 4 | -------------------------------------------------------------------------------- /tests/build-x86.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | g++ -Wall -g -m64 -I. coroutine_example.cpp ../libcontext.cpp -o test-linux-gcc-x86-64 -I.. 3 | g++ -Wall -g -m32 -I. coroutine_example.cpp ../libcontext.cpp -o test-linux-gcc-i386 -I.. 4 | clang++ -Wall -g -m64 -static -I. coroutine_example.cpp ../libcontext.cpp -o test-linux-clang-x86-64 -I.. 5 | clang++ -Wall -g -m32 -static -I. coroutine_example.cpp ../libcontext.cpp -o test-linux-clang-i386 -I.. 6 | i586-mingw32msvc-g++ -Wall -g -static -I. coroutine_example.cpp ../libcontext.cpp -o test-win32-i386.exe -I.. 7 | x86_64-w64-mingw32-g++ -Wall -g -static -I. coroutine_example.cpp ../libcontext.cpp -o test-win64-x86_64.exe -I.. -------------------------------------------------------------------------------- /tests/coroutine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program source code file is part of KiCad, a free EDA CAD application. 3 | * 4 | * Copyright (C) 2013 CERN 5 | * @author Tomasz Wlostowski 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, you may find one here: 19 | * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 20 | * or you may search the http://www.gnu.org website for the version 2 license, 21 | * or you may write to the Free Software Foundation, Inc., 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 | */ 24 | 25 | #ifndef __COROUTINE_H 26 | #define __COROUTINE_H 27 | 28 | #include 29 | #include 30 | 31 | #include "libcontext.h" 32 | 33 | #define BOOST_VERSION 105600 34 | 35 | #include "delegate.h" 36 | 37 | /** 38 | * Class COROUNTINE. 39 | * Implements a coroutine. Wikipedia has a good explanation: 40 | * 41 | * "Coroutines are computer program components that generalize subroutines to 42 | * allow multiple entry points for suspending and resuming execution at certain locations. 43 | * Coroutines are well-suited for implementing more familiar program components such as cooperative 44 | * tasks, exceptions, event loop, iterators, infinite lists and pipes." 45 | * 46 | * In other words, a coroutine can be considered a lightweight thread - which can be 47 | * preempted only when it deliberately yields the control to the caller. This way, 48 | * we avoid concurrency problems such as locking / race conditions. 49 | * 50 | * Uses boost::context library to do the actual context switching. 51 | * 52 | * This particular version takes a DELEGATE as an entry point, so it can invoke 53 | * methods within a given object as separate coroutines. 54 | * 55 | * See coroutine_example.cpp for sample code. 56 | */ 57 | 58 | template 59 | class COROUTINE 60 | { 61 | public: 62 | COROUTINE() : 63 | m_saved( NULL ), m_self( NULL ) ,m_stack( NULL ), m_stackSize( c_defaultStackSize ), 64 | m_running( false ) 65 | { 66 | } 67 | 68 | /** 69 | * Constructor 70 | * Creates a coroutine from a member method of an object 71 | */ 72 | template 73 | COROUTINE( T* object, ReturnType(T::* ptr)( ArgType ) ) : 74 | m_func( object, ptr ), m_saved( NULL ), m_self( NULL ), m_stack( NULL ), 75 | m_stackSize( c_defaultStackSize ), m_running( false ) 76 | { 77 | } 78 | 79 | /** 80 | * Constructor 81 | * Creates a coroutine from a delegate object 82 | */ 83 | COROUTINE( DELEGATE aEntry ) : 84 | m_func( aEntry ), m_saved( NULL ), m_self( NULL ), m_stack( NULL ), 85 | m_stackSize( c_defaultStackSize ), m_running( false ) 86 | { 87 | // Avoid not initialized members, and make static analysers quiet 88 | m_args = 0; 89 | m_retVal = 0; 90 | } 91 | 92 | ~COROUTINE() 93 | { 94 | if( m_saved ) 95 | delete m_saved; 96 | 97 | #if BOOST_VERSION >= 105600 98 | if( m_self ) 99 | delete m_self; 100 | #endif 101 | 102 | if( m_stack ) 103 | free( m_stack ); 104 | } 105 | 106 | /** 107 | * Function Yield() 108 | * 109 | * Stops execution of the coroutine and returns control to the caller. 110 | * After a yield, Call() or Resume() methods invoked by the caller will 111 | * immediately return true, indicating that we are not done yet, just asleep. 112 | */ 113 | void Yield() 114 | { 115 | jump( m_self, m_saved, 0 ); 116 | } 117 | 118 | /** 119 | * Function Yield() 120 | * 121 | * Yield with a value - passes a value of given type to the caller. 122 | * Useful for implementing generator objects. 123 | */ 124 | void Yield( ReturnType& aRetVal ) 125 | { 126 | m_retVal = aRetVal; 127 | jump( m_self, m_saved, 0 ); 128 | } 129 | 130 | /** 131 | * Function SetEntry() 132 | * 133 | * Defines the entry point for the coroutine, if not set in the constructor. 134 | */ 135 | void SetEntry( DELEGATE aEntry ) 136 | { 137 | m_func = aEntry; 138 | } 139 | 140 | /* Function Call() 141 | * 142 | * Starts execution of a coroutine, passing args as its arguments. 143 | * @return true, if the coroutine has yielded and false if it has finished its 144 | * execution (returned). 145 | */ 146 | bool Call( ArgType aArgs ) 147 | { 148 | // fixme: Clean up stack stuff. Add a guard 149 | m_stack = malloc( c_defaultStackSize ); 150 | 151 | // align to 16 bytes 152 | void* sp = (void*) ( ( ( (ptrdiff_t) m_stack ) + m_stackSize - 0xf ) & ( ~0x0f ) ); 153 | 154 | // correct the stack size 155 | m_stackSize -= ( (size_t) m_stack + m_stackSize - (size_t) sp ); 156 | 157 | assert( m_self == NULL ); 158 | assert( m_saved == NULL ); 159 | 160 | m_args = &aArgs; 161 | #if BOOST_VERSION >= 105600 162 | m_self = new fcontext_t(); 163 | *m_self = make_fcontext( sp, m_stackSize, callerStub ); 164 | printf("fcontext: %p %p\n", *m_self, sp); 165 | #else 166 | m_self = make_fcontext( sp, m_stackSize, callerStub ); 167 | #endif 168 | m_saved = new fcontext_t(); 169 | 170 | m_running = true; 171 | // off we go! 172 | jump( m_saved, m_self, reinterpret_cast( this ) ); 173 | return m_running; 174 | } 175 | 176 | /** 177 | * Function Resume() 178 | * 179 | * Resumes execution of a previously yielded coroutine. 180 | * @return true, if the coroutine has yielded again and false if it has finished its 181 | * execution (returned). 182 | */ 183 | bool Resume() 184 | { 185 | jump( m_saved, m_self, 0 ); 186 | 187 | return m_running; 188 | } 189 | 190 | /** 191 | * Function ReturnValue() 192 | * 193 | * Returns the yielded value (the argument Yield() was called with) 194 | */ 195 | const ReturnType& ReturnValue() const 196 | { 197 | return m_retVal; 198 | } 199 | 200 | /** 201 | * Function Running() 202 | * 203 | * @return true, if the coroutine is active 204 | */ 205 | bool Running() const 206 | { 207 | return m_running; 208 | } 209 | 210 | private: 211 | static const int c_defaultStackSize = 2000000; // fixme: make configurable 212 | 213 | /* real entry point of the coroutine */ 214 | static void callerStub( intptr_t aData ) 215 | { 216 | // get pointer to self 217 | COROUTINE* cor = reinterpret_cast*>( aData ); 218 | 219 | // call the coroutine method 220 | cor->m_retVal = cor->m_func( *cor->m_args ); 221 | cor->m_running = false; 222 | 223 | // go back to wherever we came from. 224 | jump( cor->m_self, cor->m_saved, 0 ); // reinterpret_cast( this )); 225 | } 226 | 227 | ///> Wrapper for jump_fcontext to assure compatibility between different boost versions 228 | static inline intptr_t jump(fcontext_t* aOld, fcontext_t* aNew, 229 | intptr_t aP, bool aPreserveFPU = true ) 230 | { 231 | #if BOOST_VERSION >= 105600 232 | return jump_fcontext( aOld, *aNew, aP, aPreserveFPU ); 233 | #else 234 | return jump_fcontext( aOld, aNew, aP, aPreserveFPU ); 235 | #endif 236 | } 237 | 238 | template 239 | struct strip_ref 240 | { 241 | typedef T result; 242 | }; 243 | 244 | template 245 | struct strip_ref 246 | { 247 | typedef T result; 248 | }; 249 | 250 | DELEGATE m_func; 251 | 252 | ///< pointer to coroutine entry arguments. Stripped of references 253 | ///< to avoid compiler errors. 254 | typename strip_ref::result* m_args; 255 | ReturnType m_retVal; 256 | 257 | ///< saved caller context 258 | fcontext_t* m_saved; 259 | 260 | ///< saved coroutine context 261 | fcontext_t* m_self; 262 | 263 | ///< coroutine stack 264 | void* m_stack; 265 | 266 | size_t m_stackSize; 267 | 268 | bool m_running; 269 | }; 270 | 271 | #endif 272 | -------------------------------------------------------------------------------- /tests/coroutine_example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | typedef COROUTINE MyCoroutine; 7 | 8 | class MyClass 9 | { 10 | public: 11 | int CountTo( int n ); 12 | void Run(); 13 | MyCoroutine cofunc; 14 | }; 15 | 16 | 17 | int MyClass::CountTo( int n ) 18 | 19 | { 20 | printf( "%s: Coroutine says hi. I will count from 1 to %d and yield each value.\n", 21 | __FUNCTION__, 22 | n ); 23 | 24 | for( int i = 1; i <= n; i++ ) 25 | { 26 | printf( "%s: Yielding %d\n", __FUNCTION__, i ); 27 | cofunc.Yield( i ); 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | void MyClass::Run() 34 | { 35 | cofunc = MyCoroutine( this, &MyClass::CountTo ); 36 | printf( "%s: Calling coroutine that will count from 1 to 5.\n", __FUNCTION__ ); 37 | cofunc.Call( 5 ); 38 | 39 | while( cofunc.Running() ) 40 | { 41 | printf( "%s: Got value: %d\n", __FUNCTION__, cofunc.ReturnValue() ); 42 | cofunc.Resume(); 43 | } 44 | 45 | printf( "%s: Done!\n", __FUNCTION__ ); 46 | } 47 | 48 | 49 | 50 | 51 | int main() { 52 | MyClass obj; 53 | 54 | obj.Run(); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tests/delegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program source code file is part of KiCad, a free EDA CAD application. 3 | * 4 | * Copyright (C) 2013 CERN 5 | * @author Tomasz Wlostowski 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, you may find one here: 19 | * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 20 | * or you may search the http://www.gnu.org website for the version 2 license, 21 | * or you may write to the Free Software Foundation, Inc., 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 | */ 24 | 25 | #ifndef __DELEGATE_H 26 | #define __DELEGATE_H 27 | 28 | 29 | /** 30 | * class DELEGATE 31 | * A trivial delegate (pointer to member method of an object) pattern implementation. 32 | * Check delegate_example.cpp for a coding sample. 33 | */ 34 | 35 | template 36 | class DELEGATE 37 | { 38 | public: 39 | typedef ReturnType (DELEGATE::* MemberPointer)( Arg ); 40 | typedef ReturnType _ReturnType; 41 | typedef Arg _ArgType; 42 | 43 | DELEGATE() 44 | { 45 | } 46 | 47 | template 48 | DELEGATE( T* aObject, ReturnType(T::* aPtr)( Arg ) ) 49 | { 50 | m_ptr = reinterpret_cast( aPtr ); 51 | m_object = reinterpret_cast( aObject ); 52 | }; 53 | 54 | 55 | ReturnType operator()( Arg aA ) const 56 | { 57 | DELEGATE* casted = reinterpret_cast*>( m_object ); 58 | return (casted->*m_ptr)( aA ); 59 | } 60 | 61 | private: 62 | MemberPointer m_ptr; 63 | void* m_object; 64 | }; 65 | 66 | /** 67 | * Class DELEGATE0 68 | * Same as DELEGATE, but with no arguments. 69 | */ 70 | template 71 | class DELEGATE0 72 | { 73 | public: 74 | typedef ReturnType ( DELEGATE0::* MemberPointer )(); 75 | typedef ReturnType _ReturnType; 76 | 77 | DELEGATE0() 78 | { 79 | } 80 | 81 | template 82 | DELEGATE0( T* aObject, ReturnType(T::* aPtr)() ) 83 | { 84 | m_ptr = reinterpret_cast( aPtr ); 85 | m_object = reinterpret_cast( aObject ); 86 | }; 87 | 88 | 89 | ReturnType operator()() const 90 | { 91 | DELEGATE0* casted = reinterpret_cast*>( m_object ); 92 | return ( casted->*m_ptr )(); 93 | } 94 | 95 | private: 96 | MemberPointer m_ptr; 97 | void* m_object; 98 | }; 99 | 100 | #endif 101 | --------------------------------------------------------------------------------