diff options
Diffstat (limited to 'vendor/psm/src/arch')
-rw-r--r-- | vendor/psm/src/arch/aarch64_armasm.asm | 38 | ||||
-rw-r--r-- | vendor/psm/src/arch/aarch_aapcs64.s | 85 | ||||
-rw-r--r-- | vendor/psm/src/arch/arm_aapcs.s | 106 | ||||
-rw-r--r-- | vendor/psm/src/arch/arm_armasm.asm | 39 | ||||
-rw-r--r-- | vendor/psm/src/arch/mips64_eabi.s | 87 | ||||
-rw-r--r-- | vendor/psm/src/arch/mips_eabi.s | 88 | ||||
-rw-r--r-- | vendor/psm/src/arch/powerpc32.s | 76 | ||||
-rw-r--r-- | vendor/psm/src/arch/powerpc64.s | 90 | ||||
-rw-r--r-- | vendor/psm/src/arch/powerpc64_openpower.s | 86 | ||||
-rw-r--r-- | vendor/psm/src/arch/psm.h | 10 | ||||
-rw-r--r-- | vendor/psm/src/arch/riscv.s | 64 | ||||
-rw-r--r-- | vendor/psm/src/arch/riscv64.s | 64 | ||||
-rw-r--r-- | vendor/psm/src/arch/sparc64.s | 67 | ||||
-rw-r--r-- | vendor/psm/src/arch/sparc_sysv.s | 65 | ||||
-rw-r--r-- | vendor/psm/src/arch/wasm32.s | 60 | ||||
-rw-r--r-- | vendor/psm/src/arch/x86.s | 91 | ||||
-rw-r--r-- | vendor/psm/src/arch/x86_64.s | 87 | ||||
-rw-r--r-- | vendor/psm/src/arch/x86_64_msvc.asm | 61 | ||||
-rw-r--r-- | vendor/psm/src/arch/x86_64_windows_gnu.s | 95 | ||||
-rw-r--r-- | vendor/psm/src/arch/x86_msvc.asm | 70 | ||||
-rw-r--r-- | vendor/psm/src/arch/x86_windows_gnu.s | 94 | ||||
-rw-r--r-- | vendor/psm/src/arch/zseries_linux.s | 75 |
22 files changed, 1598 insertions, 0 deletions
diff --git a/vendor/psm/src/arch/aarch64_armasm.asm b/vendor/psm/src/arch/aarch64_armasm.asm new file mode 100644 index 000000000..95349f9cc --- /dev/null +++ b/vendor/psm/src/arch/aarch64_armasm.asm @@ -0,0 +1,38 @@ + AREA |.text|, CODE, READONLY + + GLOBAL |rust_psm_stack_direction| + ALIGN 4 +|rust_psm_stack_direction| PROC + orr w0, wzr, #2 + ret + ENDP + + + GLOBAL |rust_psm_stack_pointer| + ALIGN 4 +|rust_psm_stack_pointer| PROC + mov x0, sp + ret + ENDP + + + GLOBAL |rust_psm_replace_stack| + ALIGN 4 +|rust_psm_replace_stack| PROC + mov sp, x2 + br x1 + ENDP + + GLOBAL |rust_psm_on_stack| + ALIGN 4 +|rust_psm_on_stack| PROC + stp x29, x30, [sp, #-16]! + mov x29, sp + mov sp, x3 + blr x2 + mov sp, x29 + ldp x29, x30, [sp], #16 + ret + ENDP + + END diff --git a/vendor/psm/src/arch/aarch_aapcs64.s b/vendor/psm/src/arch/aarch_aapcs64.s new file mode 100644 index 000000000..55917f329 --- /dev/null +++ b/vendor/psm/src/arch/aarch_aapcs64.s @@ -0,0 +1,85 @@ +#include "psm.h" + +.text + +#if CFG_TARGET_OS_darwin || CFG_TARGET_OS_macos || CFG_TARGET_OS_ios + +#define GLOBL(fnname) .globl _##fnname +#define TYPE(fnname) +#define FUNCTION(fnname) _##fnname +#define SIZE(fnname,endlabel) + +#else + +#define GLOBL(fnname) .globl fnname +#define TYPE(fnname) .type fnname,@function +#define FUNCTION(fnname) fnname +#define SIZE(fnname,endlabel) .size fnname,endlabel-fnname + +#endif + + +GLOBL(rust_psm_stack_direction) +.p2align 2 +TYPE(rust_psm_stack_direction) +FUNCTION(rust_psm_stack_direction): +/* extern "C" fn() -> u8 */ +.cfi_startproc + orr w0, wzr, #STACK_DIRECTION_DESCENDING + ret +.rust_psm_stack_direction_end: +SIZE(rust_psm_stack_direction,.rust_psm_stack_direction_end) +.cfi_endproc + + +GLOBL(rust_psm_stack_pointer) +.p2align 2 +TYPE(rust_psm_stack_pointer) +FUNCTION(rust_psm_stack_pointer): +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + mov x0, sp + ret +.rust_psm_stack_pointer_end: +SIZE(rust_psm_stack_pointer,.rust_psm_stack_pointer_end) +.cfi_endproc + + +GLOBL(rust_psm_replace_stack) +.p2align 2 +TYPE(rust_psm_replace_stack) +FUNCTION(rust_psm_replace_stack): +/* extern "C" fn(r0: usize, r1: extern "C" fn(usize), r2: *mut u8) */ +.cfi_startproc +/* All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi */ + mov sp, x2 + br x1 +.rust_psm_replace_stack_end: +SIZE(rust_psm_replace_stack,.rust_psm_replace_stack_end) +.cfi_endproc + + +GLOBL(rust_psm_on_stack) +.p2align 2 +TYPE(rust_psm_on_stack) +FUNCTION(rust_psm_on_stack): +/* extern "C" fn(r0: usize, r1: usize, r2: extern "C" fn(usize, usize), r3: *mut u8) */ +.cfi_startproc + stp x29, x30, [sp, #-16]! + .cfi_def_cfa sp, 16 + mov x29, sp + .cfi_def_cfa x29, 16 + .cfi_offset x29, -16 + .cfi_offset x30, -8 + mov sp, x3 + blr x2 + mov sp, x29 + .cfi_def_cfa sp, 16 + ldp x29, x30, [sp], #16 + .cfi_def_cfa sp, 0 + .cfi_restore x29 + .cfi_restore x30 + ret +.rust_psm_on_stack_end: +SIZE(rust_psm_on_stack,.rust_psm_on_stack_end) +.cfi_endproc diff --git a/vendor/psm/src/arch/arm_aapcs.s b/vendor/psm/src/arch/arm_aapcs.s new file mode 100644 index 000000000..c2fa9d81d --- /dev/null +++ b/vendor/psm/src/arch/arm_aapcs.s @@ -0,0 +1,106 @@ +#include "psm.h" + +.text +.syntax unified + +#if CFG_TARGET_OS_darwin || CFG_TARGET_OS_macos || CFG_TARGET_OS_ios + +#define GLOBL(fnname) .globl _##fnname +#define THUMBTYPE(fnname) .thumb_func _##fnname +#define FUNCTION(fnname) _##fnname +#define THUMBFN .code 16 +#define SIZE(fnname,endlabel) +#define FNSTART +#define CANTUNWIND +#define FNEND + +#else + +#define GLOBL(fnname) .globl fnname +#define THUMBTYPE(fnname) .type fnname,%function +#define FUNCTION(fnname) fnname +#define THUMBFN .code 16 +#define SIZE(fnname,endlabel) .size fnname,endlabel-fnname +#define FNSTART .fnstart +#define CANTUNWIND .cantunwind +#define FNEND .fnend + +#endif + + +GLOBL(rust_psm_stack_direction) +.p2align 2 +THUMBTYPE(rust_psm_stack_direction) +THUMBFN +FUNCTION(rust_psm_stack_direction): +/* extern "C" fn() -> u8 */ +FNSTART +.cfi_startproc + /* movs to support Thumb-1 */ + movs r0, #STACK_DIRECTION_DESCENDING + bx lr +.rust_psm_stack_direction_end: +SIZE(rust_psm_stack_direction,.rust_psm_stack_direction_end) +.cfi_endproc +CANTUNWIND +FNEND + +GLOBL(rust_psm_stack_pointer) +.p2align 2 +THUMBTYPE(rust_psm_stack_pointer) +THUMBFN +FUNCTION(rust_psm_stack_pointer): +/* extern "C" fn() -> *mut u8 */ +FNSTART +.cfi_startproc + mov r0, sp + bx lr +.rust_psm_stack_pointer_end: +SIZE(rust_psm_stack_pointer,.rust_psm_stack_pointer_end) +.cfi_endproc +CANTUNWIND +FNEND + + +GLOBL(rust_psm_replace_stack) +.p2align 2 +THUMBTYPE(rust_psm_replace_stack) +THUMBFN +FUNCTION(rust_psm_replace_stack): +/* extern "C" fn(r0: usize, r1: extern "C" fn(usize), r2: *mut u8) */ +FNSTART +.cfi_startproc +/* All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi */ + mov sp, r2 + bx r1 +.rust_psm_replace_stack_end: +SIZE(rust_psm_replace_stack,.rust_psm_replace_stack_end) +.cfi_endproc +CANTUNWIND +FNEND + + +GLOBL(rust_psm_on_stack) +.p2align 2 +THUMBTYPE(rust_psm_on_stack) +THUMBFN +FUNCTION(rust_psm_on_stack): +/* extern "C" fn(r0: usize, r1: usize, r2: extern "C" fn(usize, usize), r3: *mut u8) */ +FNSTART +.cfi_startproc + push {r4, lr} + .cfi_def_cfa_offset 8 + mov r4, sp + .cfi_def_cfa_register r4 + .cfi_offset lr, -4 + .cfi_offset r4, -8 + mov sp, r3 + blx r2 + mov sp, r4 + .cfi_restore sp + pop {r4, pc} +.rust_psm_on_stack_end: +SIZE(rust_psm_on_stack,.rust_psm_on_stack_end) +.cfi_endproc +CANTUNWIND +FNEND diff --git a/vendor/psm/src/arch/arm_armasm.asm b/vendor/psm/src/arch/arm_armasm.asm new file mode 100644 index 000000000..ab8a5bcf0 --- /dev/null +++ b/vendor/psm/src/arch/arm_armasm.asm @@ -0,0 +1,39 @@ + THUMB + AREA |.text|, CODE, READONLY + + + GLOBAL |rust_psm_stack_direction| + ALIGN 4 +|rust_psm_stack_direction| PROC + movs r0, #2 + bx lr + ENDP + + GLOBAL |rust_psm_stack_pointer| + ALIGN 4 +|rust_psm_stack_pointer| PROC + mov r0, sp + bx lr + ENDP + + + GLOBAL |rust_psm_replace_stack| + ALIGN 4 +|rust_psm_replace_stack| PROC + mov sp, r2 + bx r1 + ENDP + + + GLOBAL |rust_psm_on_stack| + ALIGN 4 +|rust_psm_on_stack| PROC + push {r4, lr} + mov r4, sp + mov sp, r3 + blx r2 + mov sp, r4 + pop {r4, pc} + ENDP + + END diff --git a/vendor/psm/src/arch/mips64_eabi.s b/vendor/psm/src/arch/mips64_eabi.s new file mode 100644 index 000000000..72bc01eb7 --- /dev/null +++ b/vendor/psm/src/arch/mips64_eabi.s @@ -0,0 +1,87 @@ +/* +Not only MIPS has 20 different ABIs... nobody tells anybody what specific variant of which ABI is +used where. + +This is an "EABI" implementation based on the following page: + +http://www.cygwin.com/ml/binutils/2003-06/msg00436.html +*/ + +#include "psm.h" + +.set noreorder /* we’ll manage the delay slots on our own, thanks! */ + +.text +.globl rust_psm_stack_direction +.p2align 3 +.type rust_psm_stack_direction,@function +.ent rust_psm_stack_direction +/* extern "C" fn() -> u8 */ +rust_psm_stack_direction: +.cfi_startproc + jr $31 + addiu $2, $zero, STACK_DIRECTION_DESCENDING +.end rust_psm_stack_direction +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 3 +.type rust_psm_stack_pointer,@function +.ent rust_psm_stack_pointer +/* extern "C" fn() -> *mut u8 */ +rust_psm_stack_pointer: +.cfi_startproc + jr $31 + move $2, $29 +.end rust_psm_stack_pointer +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + + +.globl rust_psm_replace_stack +.p2align 3 +.type rust_psm_replace_stack,@function +.ent rust_psm_replace_stack +/* extern "C" fn(r4: usize, r5: extern "C" fn(usize), r6: *mut u8) */ +rust_psm_replace_stack: +.cfi_startproc + move $25, $5 + jr $5 + move $29, $6 +.end rust_psm_replace_stack +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 3 +.type rust_psm_on_stack,@function +.ent rust_psm_on_stack +/* extern "C" fn(r4: usize, r5: usize, r6: extern "C" fn(usize), r7: *mut u8) */ +rust_psm_on_stack: +.cfi_startproc + sd $29, -8($7) + sd $31, -16($7) + .cfi_def_cfa 7, 0 + .cfi_offset 31, -16 + .cfi_offset 29, -8 + move $25, $6 + jalr $31, $6 + daddiu $29, $7, -16 + .cfi_def_cfa 29, 16 + ld $31, 0($29) + .cfi_restore 31 + ld $29, 8($29) + .cfi_restore 29 + jr $31 + nop +.end rust_psm_on_stack +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/mips_eabi.s b/vendor/psm/src/arch/mips_eabi.s new file mode 100644 index 000000000..e08ed278a --- /dev/null +++ b/vendor/psm/src/arch/mips_eabi.s @@ -0,0 +1,88 @@ +/* +Not only MIPS has 20 different ABIs... nobody tells anybody what specific variant of which ABI is +used where. + +This is an "EABI" implementation based on the following page: + +http://www.cygwin.com/ml/binutils/2003-06/msg00436.html +*/ + +#include "psm.h" + +.set noreorder /* we’ll manage the delay slots on our own, thanks! */ + +.text +.abicalls +.globl rust_psm_stack_direction +.p2align 2 +.type rust_psm_stack_direction,@function +.ent rust_psm_stack_direction +/* extern "C" fn() -> u8 */ +rust_psm_stack_direction: +.cfi_startproc + jr $31 + addiu $2, $zero, STACK_DIRECTION_DESCENDING +.end rust_psm_stack_direction +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 2 +.type rust_psm_stack_pointer,@function +.ent rust_psm_stack_pointer +/* extern "C" fn() -> *mut u8 */ +rust_psm_stack_pointer: +.cfi_startproc + jr $31 + move $2, $29 +.end rust_psm_stack_pointer +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + + +.globl rust_psm_replace_stack +.p2align 2 +.type rust_psm_replace_stack,@function +.ent rust_psm_replace_stack +/* extern "C" fn(r4: usize, r5: extern "C" fn(usize), r6: *mut u8) */ +rust_psm_replace_stack: +.cfi_startproc + move $25, $5 + jr $5 + move $29, $6 +.end rust_psm_replace_stack +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 2 +.type rust_psm_on_stack,@function +.ent rust_psm_on_stack +/* extern "C" fn(r4: usize, r5: usize, r6: extern "C" fn(usize), r7: *mut u8) */ +rust_psm_on_stack: +.cfi_startproc + sw $29, -4($7) + sw $31, -8($7) + .cfi_def_cfa 7, 0 + .cfi_offset 31, -8 + .cfi_offset 29, -4 + move $25, $6 + jalr $31, $6 + addiu $29, $7, -8 + .cfi_def_cfa 29, 8 + lw $31, 0($29) + .cfi_restore 31 + lw $29, 4($29) + .cfi_restore 29 + jr $31 + nop +.end rust_psm_on_stack +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/powerpc32.s b/vendor/psm/src/arch/powerpc32.s new file mode 100644 index 000000000..1f7a08619 --- /dev/null +++ b/vendor/psm/src/arch/powerpc32.s @@ -0,0 +1,76 @@ +#include "psm.h" +/* FIXME: this probably does not cover all ABIs? Tested with sysv only, possibly works for AIX as + well? +*/ + +.text +.globl rust_psm_stack_direction +.p2align 2 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + li 3, STACK_DIRECTION_DESCENDING + blr +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 2 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + mr 3, 1 + blr +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 2 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(3: usize, 4: extern "C" fn(usize), 5: *mut u8) */ +.cfi_startproc +/* NOTE: perhaps add a debug-assertion for stack alignment? */ + addi 5, 5, -16 + mr 1, 5 + mtctr 4 + bctr +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 2 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(3: usize, 4: usize, 5: extern "C" fn(usize, usize), 6: *mut u8) */ +.cfi_startproc + mflr 0 + stw 0, -24(6) + sub 6, 6, 1 + addi 6, 6, -32 + stwux 1, 1, 6 + .cfi_def_cfa r1, 32 + .cfi_offset r1, -32 + .cfi_offset lr, -24 + mtctr 5 + bctrl + lwz 0, 8(1) + mtlr 0 + .cfi_restore lr + /* FIXME: after this instruction backtrace breaks until control returns to the caller + That being said compiler-generated code has the same issue, so I guess that is fine for now? + */ + lwz 1, 0(1) + .cfi_restore r1 + blr +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/powerpc64.s b/vendor/psm/src/arch/powerpc64.s new file mode 100644 index 000000000..1504a8c01 --- /dev/null +++ b/vendor/psm/src/arch/powerpc64.s @@ -0,0 +1,90 @@ +/* Implementation of the AIX-like PowerPC ABI. Seems to be used by the big-endian PowerPC targets. + The following references were used during the implementation of this code: + + https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.alangref/idalangref_rntime_stack.htm + https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.alangref/idalangref_reg_use_conv.htm + https://www.ibm.com/developerworks/library/l-powasm4/index.html +*/ + +#include "psm.h" + +.text +.globl rust_psm_stack_direction +.p2align 2 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + li 3, STACK_DIRECTION_DESCENDING + blr +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 2 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + mr 3, 1 + blr +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 2 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(3: usize, 4: extern "C" fn(usize), 5: *mut u8) */ +.cfi_startproc + ld 2, 8(4) + ld 4, 0(4) + /* do not allocate the whole 112-byte sized frame, we know wont be used */ + addi 5, 5, -48 + mr 1, 5 + mtctr 4 + bctr +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 2 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(3: usize, 4: usize, 5: extern "C" fn(usize, usize), 6: *mut u8) */ +.cfi_startproc + mflr 0 + std 2, -72(6) + std 0, -8(6) + sub 6, 6, 1 + addi 6, 6, -112 + stdux 1, 1, 6 + .cfi_def_cfa r1, 112 + .cfi_offset r1, -112 + .cfi_offset r2, -72 + .cfi_offset lr, -8 + /* load the function pointer from TOC and make the call */ + ld 2, 8(5) + ld 5, 0(5) + mtctr 5 + bctrl + ld 2, 40(1) + .cfi_restore r2 + ld 0, 104(1) + mtlr 0 + .cfi_restore lr + /* FIXME: after this instruction backtrace breaks until control returns to the caller. + That being said compiler-generated code has the same issue, so I guess that is fine for now? + */ + ld 1, 0(1) + .cfi_restore r1 + blr +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/powerpc64_openpower.s b/vendor/psm/src/arch/powerpc64_openpower.s new file mode 100644 index 000000000..eb3c1c174 --- /dev/null +++ b/vendor/psm/src/arch/powerpc64_openpower.s @@ -0,0 +1,86 @@ +/* Implementation of stack swtiching routines for OpenPOWER 64-bit ELF ABI + The specification can be found at + http://openpowerfoundation.org/wp-content/uploads/resources/leabi/content/ch_preface.html + + This ABI is usually used by the ppc64le targets. +*/ + +#include "psm.h" + +.text +.abiversion 2 + + +.globl rust_psm_stack_direction +.p2align 4 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + li 3, STACK_DIRECTION_DESCENDING + blr +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 4 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + mr 3, 1 + blr +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 4 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(3: usize, 4: extern "C" fn(usize), 5: *mut u8) */ +.cfi_startproc + addi 5, 5, -32 + mtctr 4 + mr 12, 4 + mr 1, 5 + bctr +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + + +.globl rust_psm_on_stack +.p2align 4 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(3: usize, 4: usize, 5: extern "C" fn(usize, usize), 6: *mut u8) */ +.cfi_startproc + mflr 0 + std 0, -8(6) + std 2, -24(6) + sub 6, 6, 1 + addi 6, 6, -48 + stdux 1, 1, 6 + .cfi_def_cfa r1, 48 + .cfi_offset r1, -48 + .cfi_offset r2, -24 + .cfi_offset lr, -8 + mr 12, 5 + mtctr 5 + bctrl + ld 2, 24(1) + .cfi_restore r2 + ld 0, 40(1) + mtlr 0 + .cfi_restore lr + /* FIXME: after this instructin backtrace breaks until control returns to the caller */ + ld 1, 0(1) + blr +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/psm.h b/vendor/psm/src/arch/psm.h new file mode 100644 index 000000000..c1137f984 --- /dev/null +++ b/vendor/psm/src/arch/psm.h @@ -0,0 +1,10 @@ +#define STACK_DIRECTION_ASCENDING 1 +#define STACK_DIRECTION_DESCENDING 2 + + +/* +Various defines for values produced by `-DCFG_TARGET_*` flags. Only needs to be mutually unique +*/ +#define darwin 1 +#define macos 2 +#define ios 3 diff --git a/vendor/psm/src/arch/riscv.s b/vendor/psm/src/arch/riscv.s new file mode 100644 index 000000000..4972993c9 --- /dev/null +++ b/vendor/psm/src/arch/riscv.s @@ -0,0 +1,64 @@ +#include "psm.h" + +.text +.globl rust_psm_stack_direction +.p2align 2 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + li x10, STACK_DIRECTION_DESCENDING + jr x1 +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 2 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + add x10, x2, x0 + jr x1 +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 2 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(x10: usize, x11: extern "C" fn(usize), x12: *mut u8) */ +.cfi_startproc + add x2, x12, x0 + jr x11 +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 2 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(x10: usize, x11: usize, x12: extern "C" fn(usize, usize), x13: *mut u8) */ +.cfi_startproc + sw x1, -12(x13) + sw x2, -16(x13) + .cfi_def_cfa x13, 0 + .cfi_offset x1, -12 + .cfi_offset x2, -16 + addi x2, x13, -16 + .cfi_def_cfa x2, -16 + jalr x1, x12, 0 + lw x1, 4(x2) + .cfi_restore x1 + lw x2, 0(x2) + .cfi_restore x2 + jr x1 +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/riscv64.s b/vendor/psm/src/arch/riscv64.s new file mode 100644 index 000000000..1b275ec27 --- /dev/null +++ b/vendor/psm/src/arch/riscv64.s @@ -0,0 +1,64 @@ +#include "psm.h" + +.text +.globl rust_psm_stack_direction +.p2align 2 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + li x10, STACK_DIRECTION_DESCENDING + jr x1 +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 2 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + add x10, x2, x0 + jr x1 +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 2 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(x10: usize, x11: extern "C" fn(usize), x12: *mut u8) */ +.cfi_startproc + add x2, x12, x0 + jr x11 +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 2 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(x10: usize, x11: usize, x12: extern "C" fn(usize, usize), x13: *mut u8) */ +.cfi_startproc + sd x1, -8(x13) + sd x2, -16(x13) + .cfi_def_cfa x13, 0 + .cfi_offset x1, -8 + .cfi_offset x2, -16 + addi x2, x13, -16 + .cfi_def_cfa x2, -16 + jalr x1, x12, 0 + ld x1, 8(x2) + .cfi_restore x1 + ld x2, 0(x2) + .cfi_restore x2 + jr x1 +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/sparc64.s b/vendor/psm/src/arch/sparc64.s new file mode 100644 index 000000000..a0db27dde --- /dev/null +++ b/vendor/psm/src/arch/sparc64.s @@ -0,0 +1,67 @@ +#include "psm.h" + +.text +.globl rust_psm_stack_direction +.p2align 2 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + jmpl %o7 + 8, %g0 + mov STACK_DIRECTION_DESCENDING, %o0 +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 2 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + jmpl %o7 + 8, %g0 + mov %o6, %o0 +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 2 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(%i0: usize, %i1: extern "C" fn(usize), %i2: *mut u8) */ +.cfi_startproc + .cfi_def_cfa 0, 0 + .cfi_return_column 0 + jmpl %o1, %g0 + /* WEIRD: Why is the LSB set for the %sp and %fp on SPARC?? */ + add %o2, -0x7ff, %o6 +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 2 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(%i0: usize, %i1: usize, %i2: extern "C" fn(usize, usize), %i3: *mut u8) */ +.cfi_startproc + /* The fact that locals and saved register windows are offset by 2kB is + very nasty property of SPARC architecture and ABI. In this case it forces us to slice off + 2kB of the stack space outright for no good reason other than adapting to a botched design. + */ + save %o3, -0x87f, %o6 + .cfi_def_cfa_register %fp + .cfi_window_save + .cfi_register %r15, %r31 + mov %i1, %o1 + jmpl %i2, %o7 + mov %i0, %o0 + ret + restore +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/sparc_sysv.s b/vendor/psm/src/arch/sparc_sysv.s new file mode 100644 index 000000000..27d95e933 --- /dev/null +++ b/vendor/psm/src/arch/sparc_sysv.s @@ -0,0 +1,65 @@ +#include "psm.h" + +/* FIXME: this ABI has definitely not been verified at all */ + +.text +.globl rust_psm_stack_direction +.p2align 2 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + jmpl %o7 + 8, %g0 + mov STACK_DIRECTION_DESCENDING, %o0 +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 2 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + jmpl %o7 + 8, %g0 + mov %o6, %o0 +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 2 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(%i0: usize, %i1: extern "C" fn(usize), %i2: *mut u8) */ +.cfi_startproc + .cfi_def_cfa 0, 0 + .cfi_return_column 0 + jmpl %o1, %g0 + /* WEIRD: Why is the LSB set for the %sp and %fp on SPARC?? */ + add %o2, -0x3ff, %o6 +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 2 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(%i0: usize, %i1: usize, %i2: extern "C" fn(usize, usize), %i3: *mut u8) */ +.cfi_startproc + save %o3, -0x43f, %o6 + .cfi_def_cfa_register %fp + .cfi_window_save + .cfi_register %r15, %r31 + mov %i1, %o1 + jmpl %i2, %o7 + mov %i0, %o0 + ret + restore +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc diff --git a/vendor/psm/src/arch/wasm32.s b/vendor/psm/src/arch/wasm32.s new file mode 100644 index 000000000..e3364e7af --- /dev/null +++ b/vendor/psm/src/arch/wasm32.s @@ -0,0 +1,60 @@ +#include "psm.h" + +# Note that this function is not compiled when this package is uploaded to +# crates.io, this source is only here as a reference for how the corresponding +# wasm32.o was generated. This file can be compiled with: +# +# cpp psm/src/arch/wasm32.s | llvm-mc -o psm/src/arch/wasm32.o --arch=wasm32 -filetype=obj +# +# where you'll want to ensure that `llvm-mc` is from a relatively recent +# version of LLVM. + +.globaltype __stack_pointer, i32 + +.globl rust_psm_stack_direction +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +.functype rust_psm_stack_direction () -> (i32) + i32.const STACK_DIRECTION_DESCENDING + end_function + +.globl rust_psm_stack_pointer +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +.functype rust_psm_stack_pointer () -> (i32) + global.get __stack_pointer + end_function + +.globl rust_psm_on_stack +.type rust_psm_on_stack,@function +rust_psm_on_stack: +.functype rust_psm_on_stack (i32, i32, i32, i32) -> () + # get our new stack argument, then save the old stack + # pointer into that local + local.get 3 + global.get __stack_pointer + local.set 3 + global.set __stack_pointer + + # Call our indirect function specified + local.get 0 + local.get 1 + local.get 2 + call_indirect (i32, i32) -> () + + # restore the stack pointer before returning + local.get 3 + global.set __stack_pointer + end_function + +.globl rust_psm_replace_stack +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +.functype rust_psm_replace_stack (i32, i32, i32) -> () + local.get 2 + global.set __stack_pointer + local.get 0 + local.get 1 + call_indirect (i32) -> () + unreachable + end_function diff --git a/vendor/psm/src/arch/x86.s b/vendor/psm/src/arch/x86.s new file mode 100644 index 000000000..2e388760d --- /dev/null +++ b/vendor/psm/src/arch/x86.s @@ -0,0 +1,91 @@ +#include "psm.h" +/* NOTE: fastcall calling convention used on all x86 targets */ + +.text + +#if CFG_TARGET_OS_darwin || CFG_TARGET_OS_macos || CFG_TARGET_OS_ios + +#define GLOBL(fnname) .globl _##fnname +#define TYPE(fnname) +#define FUNCTION(fnname) _##fnname +#define SIZE(fnname,endlabel) + +#else + +#define GLOBL(fnname) .globl fnname +#define TYPE(fnname) .type fnname,@function +#define FUNCTION(fnname) fnname +#define SIZE(fnname,endlabel) .size fnname,endlabel-fnname + +#endif + + +GLOBL(rust_psm_stack_direction) +.p2align 4 +TYPE(rust_psm_stack_direction) +FUNCTION(rust_psm_stack_direction): +/* extern "fastcall" fn() -> u8 (%al) */ +.cfi_startproc + movb $STACK_DIRECTION_DESCENDING, %al # always descending on x86_64 + retl +.rust_psm_stack_direction_end: +SIZE(rust_psm_stack_direction,.rust_psm_stack_direction_end) +.cfi_endproc + + +GLOBL(rust_psm_stack_pointer) +.p2align 4 +TYPE(rust_psm_stack_pointer) +FUNCTION(rust_psm_stack_pointer): +/* extern "fastcall" fn() -> *mut u8 (%rax) */ +.cfi_startproc + leal 4(%esp), %eax + retl +.rust_psm_stack_pointer_end: +SIZE(rust_psm_stack_pointer,.rust_psm_stack_pointer_end) +.cfi_endproc + + +GLOBL(rust_psm_replace_stack) +.p2align 4 +TYPE(rust_psm_replace_stack) +FUNCTION(rust_psm_replace_stack): +/* extern "fastcall" fn(%ecx: usize, %edx: extern "fastcall" fn(usize), 4(%esp): *mut u8) */ +.cfi_startproc +/* + All we gotta do is set the stack pointer to 4(%esp) & tail-call the callback in %edx + + Note, that the callee expects the stack to be offset by 4 bytes (normally, a return address + would be store there) off the required stack alignment on entry. To offset the stack in such a + way we use the `calll` instruction, however it would also be possible to to use plain `jmpl` but + would require to adjust the stack manually, which cannot be easily done, because the stack + pointer argument is already stored in memory. + */ + movl 4(%esp), %esp + calll *%edx + ud2 +.rust_psm_replace_stack_end: +SIZE(rust_psm_replace_stack,.rust_psm_replace_stack_end) +.cfi_endproc + + +GLOBL(rust_psm_on_stack) +.p2align 4 +TYPE(rust_psm_on_stack) +FUNCTION(rust_psm_on_stack): +/* extern "fastcall" fn(%ecx: usize, %edx: usize, 4(%esp): extern "fastcall" fn(usize, usize), 8(%esp): *mut u8) */ +.cfi_startproc + pushl %ebp + .cfi_def_cfa %esp, 8 + .cfi_offset %ebp, -8 + movl %esp, %ebp + .cfi_def_cfa_register %ebp + movl 12(%ebp), %esp + calll *8(%ebp) + movl %ebp, %esp + popl %ebp + .cfi_def_cfa %esp, 4 + retl $8 +.rust_psm_on_stack_end: +SIZE(rust_psm_on_stack,.rust_psm_on_stack_end) +.cfi_endproc diff --git a/vendor/psm/src/arch/x86_64.s b/vendor/psm/src/arch/x86_64.s new file mode 100644 index 000000000..5f5ece5b1 --- /dev/null +++ b/vendor/psm/src/arch/x86_64.s @@ -0,0 +1,87 @@ +#include "psm.h" +/* NOTE: sysv64 calling convention is used on all x86_64 targets, including Windows! */ + +.text + +#if CFG_TARGET_OS_darwin || CFG_TARGET_OS_macos || CFG_TARGET_OS_ios + +#define GLOBL(fnname) .globl _##fnname +#define TYPE(fnname) +#define FUNCTION(fnname) _##fnname +#define SIZE(fnname,endlabel) + +#else + +#define GLOBL(fnname) .globl fnname +#define TYPE(fnname) .type fnname,@function +#define FUNCTION(fnname) fnname +#define SIZE(fnname,endlabel) .size fnname,endlabel-fnname + +#endif + + +GLOBL(rust_psm_stack_direction) +.p2align 4 +TYPE(rust_psm_stack_direction) +FUNCTION(rust_psm_stack_direction): +/* extern "sysv64" fn() -> u8 (%al) */ +.cfi_startproc + movb $STACK_DIRECTION_DESCENDING, %al # always descending on x86_64 + retq +.rust_psm_stack_direction_end: +SIZE(rust_psm_stack_direction,.rust_psm_stack_direction_end) +.cfi_endproc + + +GLOBL(rust_psm_stack_pointer) +.p2align 4 +TYPE(rust_psm_stack_pointer) +FUNCTION(rust_psm_stack_pointer): +/* extern "sysv64" fn() -> *mut u8 (%rax) */ +.cfi_startproc + leaq 8(%rsp), %rax + retq +.rust_psm_stack_pointer_end: +SIZE(rust_psm_stack_pointer,.rust_psm_stack_pointer_end) +.cfi_endproc + + +GLOBL(rust_psm_replace_stack) +.p2align 4 +TYPE(rust_psm_replace_stack) +FUNCTION(rust_psm_replace_stack): +/* extern "sysv64" fn(%rdi: usize, %rsi: extern "sysv64" fn(usize), %rdx: *mut u8) */ +.cfi_startproc +/* + All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi. + + 8-byte offset necessary to account for the "return" pointer that would otherwise be placed onto + stack with a regular call +*/ + leaq -8(%rdx), %rsp + jmpq *%rsi +.rust_psm_replace_stack_end: +SIZE(rust_psm_replace_stack,.rust_psm_replace_stack_end) +.cfi_endproc + + +GLOBL(rust_psm_on_stack) +.p2align 4 +TYPE(rust_psm_on_stack) +FUNCTION(rust_psm_on_stack): +/* extern "sysv64" fn(%rdi: usize, %rsi: usize, %rdx: extern "sysv64" fn(usize, usize), %rcx: *mut u8) */ +.cfi_startproc + pushq %rbp + .cfi_def_cfa %rsp, 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movq %rcx, %rsp + callq *%rdx + movq %rbp, %rsp + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.rust_psm_on_stack_end: +SIZE(rust_psm_on_stack,.rust_psm_on_stack_end) +.cfi_endproc diff --git a/vendor/psm/src/arch/x86_64_msvc.asm b/vendor/psm/src/arch/x86_64_msvc.asm new file mode 100644 index 000000000..67d72832f --- /dev/null +++ b/vendor/psm/src/arch/x86_64_msvc.asm @@ -0,0 +1,61 @@ +PUBLIC rust_psm_stack_direction +PUBLIC rust_psm_stack_pointer +PUBLIC rust_psm_replace_stack +PUBLIC rust_psm_on_stack + +_TEXT SEGMENT + +; extern "sysv64" fn() -> u8 (%al) +rust_psm_stack_direction PROC + mov al, 2 + ret +rust_psm_stack_direction ENDP + +; extern "sysv64" fn() -> *mut u8 (%rax) +rust_psm_stack_pointer PROC + lea rax, [rsp + 8] + ret +rust_psm_stack_pointer ENDP + +; extern "sysv64" fn(%rdi: usize, %rsi: extern "sysv64" fn(usize), %rdx: *mut u8, %rcx: *mut u8) +rust_psm_replace_stack PROC + mov gs:[08h], rdx + mov gs:[10h], rcx + lea rsp, [rdx - 8] + jmp rsi +rust_psm_replace_stack ENDP + +; extern "sysv64" fn(%rdi: usize, %rsi: usize, +; %rdx: extern "sysv64" fn(usize, usize), %rcx: *mut u8, %r8: *mut u8) +; +; NB: on Windows for SEH to work at all, the pointers in TIB, thread information block, need to be +; fixed up. Otherwise, it seems that exception mechanism on Windows will not bother looking for +; exception handlers at *all* if they happen to fall outside the are specified in TIB. +; +; This necessitates an API difference from the usual 4-argument signature used elsewhere. +; +; FIXME: this needs a catch-all exception handler that aborts in case somebody unwinds into here. +rust_psm_on_stack PROC FRAME + push rbp + .pushreg rbp + mov rbp, rsp + .setframe rbp, 0 + .endprolog + + push gs:[08h] + mov gs:[08h], rcx + push gs:[10h] + mov gs:[10h], r8 + mov rsp, rcx + call rdx + lea rsp, [rbp - 010h] + pop gs:[10h] + pop gs:[08h] + + pop rbp + ret +rust_psm_on_stack ENDP + +_TEXT ENDS + +END diff --git a/vendor/psm/src/arch/x86_64_windows_gnu.s b/vendor/psm/src/arch/x86_64_windows_gnu.s new file mode 100644 index 000000000..8f1258356 --- /dev/null +++ b/vendor/psm/src/arch/x86_64_windows_gnu.s @@ -0,0 +1,95 @@ +.text + +.def rust_psm_stack_direction +.scl 2 +.type 32 +.endef +.globl rust_psm_stack_direction +.p2align 4 +rust_psm_stack_direction: +/* extern "sysv64" fn() -> u8 (%al) */ +.cfi_startproc + movb $2, %al # always descending on x86_64 + retq +.cfi_endproc + +.def rust_psm_stack_pointer +.scl 2 +.type 32 +.endef +.globl rust_psm_stack_pointer +.p2align 4 +rust_psm_stack_pointer: +/* extern "sysv64" fn() -> *mut u8 (%rax) */ +.cfi_startproc + leaq 8(%rsp), %rax + retq +.cfi_endproc + + +.def rust_psm_replace_stack +.scl 2 +.type 32 +.endef +.globl rust_psm_replace_stack +.p2align 4 +rust_psm_replace_stack: +/* extern "sysv64" fn(%rdi: usize, %rsi: extern "sysv64" fn(usize), %rdx: *mut u8, %rcx: *mut u8) */ +.cfi_startproc +/* + All we gotta do is set the stack pointer to %rdx & tail-call the callback in %rsi. + + 8-byte offset necessary to account for the "return" pointer that would otherwise be placed onto + stack with a regular call +*/ + movq %gs:0x08, %rdx + movq %gs:0x10, %rcx + leaq -8(%rdx), %rsp + jmpq *%rsi +.cfi_endproc + + +.def rust_psm_on_stack +.scl 2 +.type 32 +.endef +.globl rust_psm_on_stack +.p2align 4 +rust_psm_on_stack: +/* +extern "sysv64" fn(%rdi: usize, %rsi: usize, + %rdx: extern "sysv64" fn(usize, usize), %rcx: *mut u8, %r8: *mut u8) + +NB: on Windows for SEH to work at all, the pointers in TIB, thread information block, need to be +fixed up. Otherwise, it seems that exception mechanism on Windows will not bother looking for +exception handlers at *all* if they happen to fall outside the are specified in TIB. + +This necessitates an API difference from the usual 4-argument signature used elsewhere. + +FIXME: this needs a catch-all exception handler that aborts in case somebody unwinds into here. +*/ +.cfi_startproc + pushq %rbp + .cfi_def_cfa %rsp, 16 + .cfi_offset %rbp, -16 + pushq %gs:0x08 + .cfi_def_cfa %rsp, 24 + pushq %gs:0x10 + .cfi_def_cfa %rsp, 32 + + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movq %rcx, %gs:0x08 + movq %r8, %gs:0x10 + movq %rcx, %rsp + callq *%rdx + movq %rbp, %rsp + + popq %gs:0x10 + .cfi_def_cfa %rsp, 24 + popq %gs:0x08 + .cfi_def_cfa %rsp, 16 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.cfi_endproc diff --git a/vendor/psm/src/arch/x86_msvc.asm b/vendor/psm/src/arch/x86_msvc.asm new file mode 100644 index 000000000..3838759f7 --- /dev/null +++ b/vendor/psm/src/arch/x86_msvc.asm @@ -0,0 +1,70 @@ +; FIXME: this is weird, this works locally but not on appveyor?!??! + +.386 +.model flat + +ASSUME FS:NOTHING + +; WTF: PUBLIC conflicts with "SYSCALL" but "SYSCALL" is the only way to stop MASM from manging the +; symbol names? +; +; PUBLIC @rust_psm_stack_direction@0 +; PUBLIC @rust_psm_stack_pointer@0 +; PUBLIC @rust_psm_replace_stack@12 +; PUBLIC @rust_psm_on_stack@16 + +_TEXT SEGMENT + +; extern "fastcall" fn() -> u8 (%al) +@rust_psm_stack_direction@0 PROC SYSCALL + mov al, 2 + ret +@rust_psm_stack_direction@0 ENDP + +; extern "fastcall" fn() -> *mut u8 (%rax) +@rust_psm_stack_pointer@0 PROC SYSCALL + lea eax, [esp + 4] + ret +@rust_psm_stack_pointer@0 ENDP + +; extern "fastcall" fn(%ecx: usize, %edx: extern "fastcall" fn(usize), +; 4(%esp): *mut u8, 8(%esp): *mut u8) +@rust_psm_replace_stack@16 PROC SYSCALL + mov eax, dword ptr [esp + 8] + mov fs:[08h], eax + mov esp, dword ptr [esp + 4] + mov fs:[04h], esp + jmp edx +@rust_psm_replace_stack@16 ENDP + +; extern "fastcall" fn(%ecx: usize, %edx: usize, 4(%esp): extern "fastcall" fn(usize, usize), +; 8(%esp): *mut u8, 12(%esp): *mut u8) +; +; NB: on Windows for SEH to work at all, the pointers in TIB, thread information block, need to be +; fixed up. Otherwise, it seems that exception mechanism on Windows will not bother looking for +; exception handlers at *all* if they happen to fall outside the are specified in TIB. +; +; This necessitates an API difference from the usual 4-argument signature used elsewhere. +@rust_psm_on_stack@20 PROC SYSCALL + push ebp + mov ebp, esp + + push fs:[0E0Ch] + push fs:[08h] + mov eax, dword ptr [ebp + 4 + 12] + mov dword ptr fs:[08h], eax + mov dword ptr fs:[0E0Ch], eax + push fs:[04h] + mov esp, dword ptr [ebp + 4 + 8] + mov dword ptr fs:[04h], esp + call dword ptr [ebp + 4 + 4] + + lea esp, [ebp - 12] + pop fs:[04h] + pop fs:[08h] + pop fs:[0E0Ch] + pop ebp + ret 12 +@rust_psm_on_stack@20 ENDP + +END diff --git a/vendor/psm/src/arch/x86_windows_gnu.s b/vendor/psm/src/arch/x86_windows_gnu.s new file mode 100644 index 000000000..474d4168a --- /dev/null +++ b/vendor/psm/src/arch/x86_windows_gnu.s @@ -0,0 +1,94 @@ +/* FIXME: this works locally but not on appveyor??!? */ +/* NOTE: fastcall calling convention used on all x86 targets */ +.text + +.def @rust_psm_stack_direction@0 +.scl 2 +.type 32 +.endef +.globl @rust_psm_stack_direction@0 +.p2align 4 +@rust_psm_stack_direction@0: +/* extern "fastcall" fn() -> u8 (%al) */ +.cfi_startproc + movb $2, %al # always descending on x86_64 + retl +.cfi_endproc + + +.def @rust_psm_stack_pointer@0 +.scl 2 +.type 32 +.endef +.globl @rust_psm_stack_pointer@0 +.p2align 4 +@rust_psm_stack_pointer@0: +/* extern "fastcall" fn() -> *mut u8 (%rax) */ +.cfi_startproc + leal 4(%esp), %eax + retl +.cfi_endproc + + +.def @rust_psm_replace_stack@16 +.scl 2 +.type 32 +.endef +.globl @rust_psm_replace_stack@16 +.p2align 4 +@rust_psm_replace_stack@16: +/* extern "fastcall" fn(%ecx: usize, %edx: extern "fastcall" fn(usize), 4(%esp): *mut u8) */ +.cfi_startproc +/* + All we gotta do is set the stack pointer to 4(%esp) & tail-call the callback in %edx + + Note, that the callee expects the stack to be offset by 4 bytes (normally, a return address + would be store there) off the required stack alignment on entry. To offset the stack in such a + way we use the `calll` instruction, however it would also be possible to to use plain `jmpl` but + would require to adjust the stack manually, which cannot be easily done, because the stack + pointer argument is already stored in memory. + */ + movl 8(%esp), %eax + mov %eax, %fs:0x08 + movl 4(%esp), %esp + mov %esp, %fs:0x04 + calll *%edx + ud2 +.cfi_endproc + + +.def @rust_psm_on_stack@16 +.scl 2 +.type 32 +.endef +.globl @rust_psm_on_stack@16 +.p2align 4 +@rust_psm_on_stack@16: +/* extern "fastcall" fn(%ecx: usize, %edx: usize, 4(%esp): extern "fastcall" fn(usize, usize), 8(%esp): *mut u8) */ +.cfi_startproc + pushl %ebp + .cfi_def_cfa %esp, 8 + .cfi_offset %ebp, -8 + pushl %fs:0x04 + .cfi_def_cfa %esp, 12 + pushl %fs:0x08 + .cfi_def_cfa %esp, 16 + movl %esp, %ebp + .cfi_def_cfa_register %ebp + + movl 24(%ebp), %eax + movl %eax, %fs:0x08 + movl 20(%ebp), %esp + movl %esp, %fs:0x04 + calll *16(%ebp) + + movl %ebp, %esp + popl %fs:0x08 + .cfi_def_cfa %esp, 12 + popl %fs:0x04 + .cfi_def_cfa %esp, 8 + popl %ebp + .cfi_def_cfa %esp, 4 + retl $12 +.cfi_endproc + diff --git a/vendor/psm/src/arch/zseries_linux.s b/vendor/psm/src/arch/zseries_linux.s new file mode 100644 index 000000000..e2536a1c9 --- /dev/null +++ b/vendor/psm/src/arch/zseries_linux.s @@ -0,0 +1,75 @@ +/* Implementation of stack swtiching routines for zSeries LINUX ABI. + + This ABI is used by the s390x-unknown-linux-gnu target. + + Documents used: + + * LINUX for zSeries: ELF Application Binary Interface Supplement (1st ed., 2001) (LNUX-1107-01) + * z/Architecture: Principles of Operation (4th ed., 2004) (SA22-7832-03) +*/ + +#include "psm.h" + +.text + + +.globl rust_psm_stack_direction +.p2align 4 +.type rust_psm_stack_direction,@function +rust_psm_stack_direction: +/* extern "C" fn() -> u8 */ +.cfi_startproc + lghi %r2, STACK_DIRECTION_DESCENDING + br %r14 +.rust_psm_stack_direction_end: +.size rust_psm_stack_direction,.rust_psm_stack_direction_end-rust_psm_stack_direction +.cfi_endproc + + +.globl rust_psm_stack_pointer +.p2align 4 +.type rust_psm_stack_pointer,@function +rust_psm_stack_pointer: +/* extern "C" fn() -> *mut u8 */ +.cfi_startproc + la %r2, 0(%r15) + br %r14 +.rust_psm_stack_pointer_end: +.size rust_psm_stack_pointer,.rust_psm_stack_pointer_end-rust_psm_stack_pointer +.cfi_endproc + + +.globl rust_psm_replace_stack +.p2align 4 +.type rust_psm_replace_stack,@function +rust_psm_replace_stack: +/* extern "C" fn(r2: usize, r3: extern "C" fn(usize), r4: *mut u8) */ +.cfi_startproc + /* FIXME: backtrace does not terminate cleanly for some reason */ + lay %r15, -160(%r4) + /* FIXME: this is `basr` instead of `br` purely to remove the backtrace link to the caller */ + basr %r14, %r3 +.rust_psm_replace_stack_end: +.size rust_psm_replace_stack,.rust_psm_replace_stack_end-rust_psm_replace_stack +.cfi_endproc + + +.globl rust_psm_on_stack +.p2align 4 +.type rust_psm_on_stack,@function +rust_psm_on_stack: +/* extern "C" fn(r2: usize, r3: usize, r4: extern "C" fn(usize, usize), r5: *mut u8) */ +.cfi_startproc + stmg %r14, %r15, -16(%r5) + lay %r15, -176(%r5) + .cfi_def_cfa %r15, 176 + .cfi_offset %r14, -16 + .cfi_offset %r15, -8 + basr %r14, %r4 + lmg %r14, %r15, 160(%r15) + .cfi_restore %r14 + .cfi_restore %r15 + br %r14 +.rust_psm_on_stack_end: +.size rust_psm_on_stack,.rust_psm_on_stack_end-rust_psm_on_stack +.cfi_endproc |