summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-08-06 07:51:54 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-08-06 07:51:54 -0700
commit7d5fc582b3d811662ca0ff45157f596db2f8dc1a (patch)
tree4f9e33215f2e3b95267fa1beda6286dcb66e6f71
parent51c8f5575d6d95537a9eb112c8be6838a7f89e49 (diff)
downloadtxr-7d5fc582b3d811662ca0ff45157f596db2f8dc1a.tar.gz
txr-7d5fc582b3d811662ca0ff45157f596db2f8dc1a.tar.bz2
txr-7d5fc582b3d811662ca0ff45157f596db2f8dc1a.zip
Port exception handling to 64 bit Cygwin.
* jmp.S (DEFUN): Separate definition for 64 bit Cygwin, which doesn't use leading underscores and has an unusual prologue. (jmp_save, jmp_restore): Separately defined for 64 bit Cygwin, due to use of Microsoft 64 bit calling conventions. * signal.h (struct jmp): In x86-64 version, only on Cygwin, new members: rsi and rdi. These registers are considered nonvolatile and so are saved and restored by jmp_save and jmp_restore.
-rw-r--r--jmp.S57
-rw-r--r--signal.h4
2 files changed, 59 insertions, 2 deletions
diff --git a/jmp.S b/jmp.S
index fcb67ddd..346d5bda 100644
--- a/jmp.S
+++ b/jmp.S
@@ -24,7 +24,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#if __MINGW32__ || __CYGWIN__
+#if __MINGW32__ || (__CYGWIN__ && __i386__)
#define DEFUN(NAME) \
.global _ ## NAME ; \
_ ## NAME: ;
@@ -48,6 +48,11 @@ NAME: ;
.thumb_func ; \
.type NAME, %function ; \
NAME: ;
+#elif __CYGWIN__ && __x86_64__
+#define DEFUN(NAME) \
+.globl NAME ; \
+.def NAME; .scl 2; .type 32; .endef; \
+NAME: ;
#else
#define DEFUN(NAME) \
.global NAME ; \
@@ -99,7 +104,7 @@ DEFUN(jmp_restore)
mov JEIP(%edx),%ecx
jmp *%ecx
-#elif __x86_64__
+#elif __x86_64__ && !__CYGWIN__
#define JRIP 0
#define JRSP 8
@@ -140,6 +145,54 @@ DEFUN(jmp_restore)
mov %rsi, %rax
jmp *%rdx
+#elif __x86_64__ && __CYGWIN__
+
+#define JRIP 0
+#define JRSP 8
+#define JRBP 16
+#define JRBX 24
+#define JR12 32
+#define JR13 40
+#define JR14 48
+#define JR15 56
+#define JRSI 64
+#define JRDI 72
+
+#define RETA 0
+#define ARG2 8
+
+DEFUN(jmp_save)
+ mov RETA(%rsp), %rax
+ mov %rax, JRIP(%rcx)
+ lea ARG2(%rsp), %rax
+ mov %rax, JRSP(%rcx)
+ mov %rbp, JRBP(%rcx)
+ mov %rbx, JRBX(%rcx)
+ mov %r12, JR12(%rcx)
+ mov %r13, JR13(%rcx)
+ mov %r14, JR14(%rcx)
+ mov %r15, JR15(%rcx)
+ mov %rsi, JRSI(%rcx)
+ mov %rdi, JRDI(%rcx)
+ xor %rax, %rax
+ ret
+
+DEFUN(jmp_restore)
+ mov JRDI(%rcx), %rdi
+ mov JRSI(%rcx), %rsi
+ mov JR15(%rcx), %r15
+ mov JR14(%rcx), %r14
+ mov JR13(%rcx), %r13
+ mov JR12(%rcx), %r12
+ mov JRBX(%rcx), %rbx
+ mov JRBP(%rcx), %rbp
+ mov JRSP(%rcx), %rax
+ mov %rax, %rsp
+ mov JRIP(%rcx), %rcx
+ mov %rdx, %rax
+ jmp *%rcx
+
+
#elif __arm__ && !__thumb__
DEFUN(jmp_save)
diff --git a/signal.h b/signal.h
index e54a6c43..73ca1e24 100644
--- a/signal.h
+++ b/signal.h
@@ -62,6 +62,10 @@ struct jmp {
unsigned long r13;
unsigned long r14;
unsigned long r15;
+#if __CYGWIN__
+ unsigned long rsi;
+ unsigned long rdi;
+#endif
};
#elif __arm__ && !__thumb__