summaryrefslogtreecommitdiffhomepage
path: root/src/signal
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-10-24 20:49:52 -0400
committermidipix <writeonce@midipix.org>2015-10-24 20:49:52 -0400
commit66b804e22d6b78416acf3d29fadfd3cf691ebc45 (patch)
tree1dbafcbd7226e20f8730d181de5aa296b707a361 /src/signal
parent7d14e0bf3f303c3cd2b3732dc78f8cee77411339 (diff)
downloadmmglue-66b804e22d6b78416acf3d29fadfd3cf691ebc45.tar.bz2
mmglue-66b804e22d6b78416acf3d29fadfd3cf691ebc45.tar.xz
sigsetjmp: nt64: initial implementation.
Diffstat (limited to 'src/signal')
-rw-r--r--src/signal/nt64/sigsetjmp.s43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/signal/nt64/sigsetjmp.s b/src/signal/nt64/sigsetjmp.s
new file mode 100644
index 0000000..77ce4f6
--- /dev/null
+++ b/src/signal/nt64/sigsetjmp.s
@@ -0,0 +1,43 @@
+.text
+.globl __sigsetjmp
+.globl sigsetjmp
+
+.def __sigsetjmp; .scl 2; .type 32; .endef
+.def sigsetjmp; .scl 2; .type 32; .endef
+
+__sigsetjmp:
+sigsetjmp:
+ test %rdx,%rdx # save signal mask?
+ jnz 1f # yes: save mask
+ jmp setjmp # no: setjmp
+
+1:
+ # typedef unsigned long __jmp_buf[10];
+ #
+ # typedef struct __jmp_buf_tag {
+ # __jmp_buf __jb;
+ # unsigned long __fl;
+ # unsigned long __ss[16];
+ # }
+ #
+
+ popq 0x68(%rcx) # save return address to .__ss[2]
+ movq %rbx,0x70(%rcx) # save rbx (arbitrary choice) to .__ss[3]
+ movq %rcx,%rbx # save pointer to __jmp_buf to rbx
+
+ call __setjmp
+
+ pushq 0x68(%rbx) # push previously saved return address
+ movq %rbx,%rcx # save pointer to __jmp_buf to rcx (arg 0)
+ movl %eax,%edx # save setjmp return value to rdx (arg 1)
+ movq 0x70(%rcx),%rbx # restore rbx from .__ss[3]
+
+
+ jmp __sigsetjmp_tail # defer to __sigsetjmp_tail
+
+
+ .section .got$sigsetjmp,"r"
+ .global __imp_sigsetjmp
+__imp_sigsetjmp:
+ .quad sigsetjmp
+ .linkonce discard