1;; Copyright 2019 The Android Open Source Project
2;;
3;; This software is licensed under the terms of the GNU General Public
4;; License version 2, as published by the Free Software Foundation, and
5;; may be copied, distributed, and modified under those terms.
6;;
7;; This program is distributed in the hope that it will be useful,
8;; but WITHOUT ANY WARRANTY; without even the implied warranty of
9;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10;; GNU General Public License for more details.
11
12;; This contains setjmp/longjmp implementation that we can use with qemu.
13
14;; This is the standard register usage in Win64
15;;
16;; RAX	        Volatile	Return value register
17;; RCX	        Volatile	First integer argument
18;; RDX  	Volatile	Second integer argument
19;; R8	        Volatile	Third integer argument
20;; R9	        Volatile	Fourth integer argument
21;; R10:R11	Volatile	Must be preserved as needed by caller; used in syscall/sysret instructions
22;; R12:R15	Nonvolatile	Must be preserved by callee
23;; RDI	        Nonvolatile	Must be preserved by callee
24;; RSI	        Nonvolatile	Must be preserved by callee
25;; RBX	        Nonvolatile	Must be preserved by callee
26;; RBP	        Nonvolatile	May be used as a frame pointer; must be preserved by callee
27;; RSP	        Nonvolatile	Stack pointer
28;; XMM0, YMM0	Volatile	First FP argument; first vector-type argument when __vectorcall is used
29;; XMM1, YMM1	Volatile	Second FP argument; second vector-type argument when __vectorcall is used
30;; XMM2, YMM2	Volatile	Third FP argument; third vector-type argument when __vectorcall is used
31;; XMM3, YMM3	Volatile	Fourth FP argument; fourth vector-type argument when __vectorcall is used
32;; XMM4, YMM4	Volatile	Must be preserved as needed by caller; fifth vector-type argument when __vectorcall is used
33;; XMM5, YMM5	Volatile	Must be preserved as needed by caller; sixth vector-type argument when __vectorcall is used
34;; XMM6:XMM15, YMM6:YMM15	Nonvolatile (XMM), Volatile (upper half of YMM)	Must be preserved by callee. YMM registers must be preserved as needed by caller.
35
36        section .text              ; Code section.
37        global  sigsetjmp_impl     ; Export functions, linker can now link against it.
38        global  siglongjmp_impl    ;
39
40sigsetjmp_impl:                 ; Function entry
41
42  ;; According to msdn:
43  ;;
44  ;; A call to setjmp preserves the current stack pointer, non-volatile registers, and
45  ;; MxCsr registers. Calls to longjmp return to the most recent setjmp call site and
46  ;; resets the stack pointer, non-volatile registers, and MxCsr registers,
47  ;; back to the state as preserved by the most recent setjmp call.
48  ;;
49  ;; We are only doing the bare minimum, and are not saving th mxcsr/xmm/ymm regs.
50  ;; We rely on jmp_buf having enough space for 16 64 bit registers.
51
52        mov [rcx]      , rdx      ; RDX	Volatile	Second integer argument
53        mov [rcx+0x8]  , r8       ; R8	Volatile	Third integer argument
54        mov [rcx+0x10] , r9       ; R9	Volatile	Fourth integer argument
55        mov [rcx+0x18] , r10      ; R10 Volatile	Must be preserved as needed by caller; used in syscall/sysret instructions
56        mov [rcx+0x20] , r11      ; R11 Volatile	Must be preserved as needed by caller; used in syscall/sysret instructions ;
57        mov [rcx+0x28] , r12      ; R12	Nonvolatile	Must be preserved by callee
58        mov [rcx+0x30] , r15      ; R15	Nonvolatile	Must be preserved by callee
59        mov [rcx+0x38] , rdi      ; RDI	Nonvolatile	Must be preserved by callee
60        mov [rcx+0x40] , rsi      ; RSI	Nonvolatile	Must be preserved by callee
61        mov [rcx+0x48] , rbx      ; RBX	Nonvolatile	Must be preserved by callee
62        mov [rcx+0x50] , rbp      ; RBP	Nonvolatile	May be used as a frame pointer; must be preserved by callee
63        mov [rcx+0x58] , rsp      ; RSP	Nonvolatile	Stack pointer, note this will automatically be adjusted by our return.
64        mov rax, [rsp];
65        mov [rcx+0x60] , rax      ; We need to save our return address.
66
67;; We are not doing any of these.
68;; XMM0, YMM0	Volatile	First FP argument; first vector-type argument when __vectorcall is used
69;; XMM1, YMM1	Volatile	Second FP argument; second vector-type argument when __vectorcall is used
70;; XMM2, YMM2	Volatile	Third FP argument; third vector-type argument when __vectorcall is used
71;; XMM3, YMM3	Volatile	Fourth FP argument; fourth vector-type argument when __vectorcall is used
72;; XMM4, YMM4	Volatile	Must be preserved as needed by caller; fifth vector-type argument when __vectorcall is used
73;; XMM5, YMM5	Volatile	Must be preserved as needed by caller; sixth vector-type argument when __vectorcall is used
74;; XMM6:XMM15, YMM6:YMM15	Nonvolatile (XMM), Volatile (upper half of YMM)	Must be preserved by callee. YMM registers must be preserved as needed by caller.
75        mov rax, 0              ; We came from a call to setjmp, so Woohoo
76        ret                     ; return
77
78siglongjmp_impl:
79
80        ;; First we reconstruct out stack, so when we call ret, we go back to sigjmp location
81        mov rsp, [rcx+0x58]       ; RSP	Nonvolatile	Stack pointer
82        mov rax, [rcx+0x60]
83        mov [rsp], rax            ; Set our return address on the stack.
84
85        ;; Next we restore the registers.
86        mov rax, rdx              ; Return value (param 2) from longjmp
87        mov rdx, [rcx]            ; RDX	Volatile	Second integer argument
88        mov r8,  [rcx+0x8]        ; R8	Volatile	Third integer argument
89        mov r9,  [rcx+0x10]       ; R9	Volatile	Fourth integer argument
90        mov r10, [rcx+0x18]       ; R10 Volatile	Must be preserved as needed by caller; used in syscall/sysret instructions
91        mov r11, [rcx+0x20]       ; R11 Volatile	Must be preserved as needed by caller; used in syscall/sysret instructions ;
92        mov r12, [rcx+0x28]       ; R12	Nonvolatile	Must be preserved by callee
93        mov r15, [rcx+0x30]       ; R15	Nonvolatile	Must be preserved by callee
94        mov rdi, [rcx+0x38]       ; RDI	Nonvolatile	Must be preserved by callee
95        mov rsi, [rcx+0x40]       ; RSI	Nonvolatile	Must be preserved by callee
96        mov rbx, [rcx+0x48]       ; RBX	Nonvolatile	Must be preserved by callee
97        mov rbp, [rcx+0x50]       ; RBP	Nonvolatile	May be used as a frame pointer; must be preserved by callee
98
99;; XMM0, YMM0	Volatile	First FP argument; first vector-type argument when __vectorcall is used
100;; XMM1, YMM1	Volatile	Second FP argument; second vector-type argument when __vectorcall is used
101;; XMM2, YMM2	Volatile	Third FP argument; third vector-type argument when __vectorcall is used
102;; XMM3, YMM3	Volatile	Fourth FP argument; fourth vector-type argument when __vectorcall is used
103;; XMM4, YMM4	Volatile	Must be preserved as needed by caller; fifth vector-type argument when __vectorcall is used
104;; XMM5, YMM5	Volatile	Must be preserved as needed by caller; sixth vector-type argument when __vectorcall is used
105;; XMM6:XMM15, YMM6:YMM15	Nonvolatile (XMM), Volatile (upper half of YMM)	Must be preserved by callee. YMM registers must be preserved as needed by caller.
106
107        ret                     ; return
108
109
110        section .data           ; Data section, initialized variables
111