summaryrefslogtreecommitdiff
path: root/libs/context/src/asm/fcontext_x86_64_ms_pe_masm.asm
blob: f1f8ca12a7c81fd18b8dc057f9c47808017db2a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

;           Copyright Oliver Kowalke 2009.
;  Distributed under the Boost Software License, Version 1.0.
;     (See accompanying file LICENSE_1_0.txt or copy at
;           http://www.boost.org/LICENSE_1_0.txt)

;  ----------------------------------------------------------------------------------
;  |    0    |    1    |    2    |    3    |    4     |    5    |    6    |    7    |
;  ----------------------------------------------------------------------------------
;  |   0x0   |   0x4   |   0x8   |   0xc   |   0x10   |   0x14  |   0x18  |   0x1c  |
;  ----------------------------------------------------------------------------------
;  |        R12        |         R13       |         R14        |        R15        |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |    8    |    9    |   10    |   11    |    12    |    13   |    14   |    15   |
;  ----------------------------------------------------------------------------------
;  |   0x20  |   0x24  |   0x28  |  0x2c   |   0x30   |   0x34  |   0x38  |   0x3c  |
;  ----------------------------------------------------------------------------------
;  |        RDI        |        RSI        |         RBX        |        RBP        |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |    16   |    17   |    18   |    19   |                                        |
;  ----------------------------------------------------------------------------------
;  |   0x40  |   0x44  |   0x48  |   0x4c  |                                        |
;  ----------------------------------------------------------------------------------
;  |        RSP        |       RIP         |                                        |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |    20   |    21   |    22   |    23   |                                        |
;  ----------------------------------------------------------------------------------
;  |   0x50  |   0x54  |   0x58  |   0x5c  |                                        |
;  ----------------------------------------------------------------------------------
;  |       sbase       |       slimit      |                                        |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |    24   |   25    |                                                            |
;  ----------------------------------------------------------------------------------
;  |   0x60  |   0x64  |                                                            |
;  ----------------------------------------------------------------------------------
;  |      fbr_strg     |                                                            |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |    26   |   27    |    28   |    29   |                                        |
;  ----------------------------------------------------------------------------------
;  |   0x68  |   0x6c  |   0x70  |   0x74  |                                        |
;  ----------------------------------------------------------------------------------
;  | fc_mxcsr|fc_x87_cw|       fc_xmm      |                                        |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |   30    |   31    |    32    |   33   |   34    |   35    |   36     |   37    |
;  ----------------------------------------------------------------------------------
;  |  0x78   |  0x7c   |   0x80   |  0x84  |  0x88   |  0x8c   |   0x90   |   0x94  |
;  ----------------------------------------------------------------------------------
;  |                  XMM6                 |                   XMM7                 |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |   38    |   39    |    40    |   41   |   42    |   43    |    44    |   45    |
;  ----------------------------------------------------------------------------------
;  |  0x98   |  0x9c   |  0x100  |  0x104  |  0x108  |  0x10c  |   0x110  |  0x114  |
;  ----------------------------------------------------------------------------------
;  |                  XMM8                 |                   XMM9                 |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |   46    |   47    |    48    |   49   |   50    |   51    |    52    |   53    |
;  ----------------------------------------------------------------------------------
;  |  0x118  |  0x11c  |  0x120  |  0x124  |  0x128  |  0x12c  |   0x130  |  0x134  |
;  ----------------------------------------------------------------------------------
;  |                 XMM10                 |                  XMM11                 |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |   54    |   55    |    56    |   57   |   58    |   59    |    60    |   61    |
;  ----------------------------------------------------------------------------------
;  |  0x138  |  0x13c  |  0x140  |  0x144  |  0x148  |  0x14c  |   0x150  |  0x154  |
;  ----------------------------------------------------------------------------------
;  |                 XMM12                 |                  XMM13                 |
;  ----------------------------------------------------------------------------------
;  ----------------------------------------------------------------------------------
;  |   62    |   63    |    64    |   65   |   66    |   67    |    68    |   69    |
;  ----------------------------------------------------------------------------------
;  |  0x158  |  0x15c  |  0x160  |  0x164  |  0x168  |  0x16c  |   0x170  |  0x174  |
;  ----------------------------------------------------------------------------------
;  |                 XMM14                 |                  XMM15                 |
;  ----------------------------------------------------------------------------------

EXTERN  _exit:PROC            ; standard C library function
EXTERN  align_stack:PROC      ; stack alignment
EXTERN  seh_fcontext:PROC     ; exception handler
.code

jump_fcontext PROC EXPORT FRAME:seh_fcontext
    .endprolog

    mov     [rcx],       r12        ; save R12
    mov     [rcx+08h],   r13        ; save R13
    mov     [rcx+010h],  r14        ; save R14
    mov     [rcx+018h],  r15        ; save R15
    mov     [rcx+020h],  rdi        ; save RDI
    mov     [rcx+028h],  rsi        ; save RSI
    mov     [rcx+030h],  rbx        ; save RBX
    mov     [rcx+038h],  rbp        ; save RBP

    mov     r10,         gs:[030h]  ; load NT_TIB
    mov     rax,         [r10+08h]  ; load current stack base
    mov     [rcx+050h],  rax        ; save current stack base
    mov     rax,         [r10+010h] ; load current stack limit
    mov     [rcx+058h],  rax        ; save current stack limit
    mov     rax,         [r10+018h] ; load fiber local storage
    mov     [rcx+060h],  rax        ; save fiber local storage

    test    r9,          r9
    je      nxt

    stmxcsr [rcx+068h]              ; save MMX control and status word
    fnstcw  [rcx+06ch]              ; save x87 control word
    mov     r10,         [rcx+070h] ; address of aligned XMM storage
    movaps  [r10],       xmm6
    movaps  [r10+010h],  xmm7
    movaps  [r10+020h],  xmm8
    movaps  [r10+030h],  xmm9
    movaps  [r10+040h],  xmm10
    movaps  [r10+050h],  xmm11
    movaps  [r10+060h],  xmm12
    movaps  [r10+070h],  xmm13
    movaps  [r10+080h],  xmm14
    movaps  [r10+090h],  xmm15

    ldmxcsr [rdx+068h]              ; restore MMX control and status word
    fldcw   [rdx+06ch]              ; restore x87 control word
    mov     r10,         [rdx+070h] ; address of aligned XMM storage
    movaps  xmm6,        [r10]
    movaps  xmm7,        [r10+010h]
    movaps  xmm8,        [r10+020h]
    movaps  xmm9,        [r10+030h]
    movaps  xmm10,       [r10+040h]
    movaps  xmm11,       [r10+050h]
    movaps  xmm12,       [r10+060h]
    movaps  xmm13,       [r10+070h]
    movaps  xmm14,       [r10+080h]
    movaps  xmm15,       [r10+090h]
nxt:

    lea     rax,         [rsp+08h]  ; exclude the return address
    mov     [rcx+040h],  rax        ; save as stack pointer
    mov     rax,         [rsp]      ; load return address
    mov     [rcx+048h],  rax        ; save return address

    mov     r12,        [rdx]       ; restore R12
    mov     r13,        [rdx+08h]   ; restore R13
    mov     r14,        [rdx+010h]  ; restore R14
    mov     r15,        [rdx+018h]  ; restore R15
    mov     rdi,        [rdx+020h]  ; restore RDI
    mov     rsi,        [rdx+028h]  ; restore RSI
    mov     rbx,        [rdx+030h]  ; restore RBX
    mov     rbp,        [rdx+038h]  ; restore RBP

    mov     r10,        gs:[030h]   ; load NT_TIB
    mov     rax,        [rdx+050h]  ; load stack base
    mov     [r10+08h],  rax         ; restore stack base
    mov     rax,        [rdx+058h]  ; load stack limit
    mov     [r10+010h], rax         ; restore stack limit
    mov     rax,        [rdx+060h]  ; load fiber local storage
    mov     [r10+018h], rax         ; restore fiber local storage

    mov     rsp,        [rdx+040h]  ; restore RSP
    mov     r10,        [rdx+048h]  ; fetch the address to returned to

    mov     rax,        r8          ; use third arg as return value after jump
    mov     rcx,        r8          ; use third arg as first arg in context function

    jmp     r10                     ; indirect jump to caller
jump_fcontext ENDP

make_fcontext PROC EXPORT FRAME  ; generate function table entry in .pdata and unwind information in    E
    .endprolog                   ; .xdata for a function's structured exception handling unwind behavior

    mov  [rcx],      rcx         ; store the address of current context
    mov  [rcx+048h], rdx         ; save the address of the function supposed to run
    mov  rdx,        [rcx+050h]  ; load the address where the context stack beginns

    push  rcx                    ; save pointer to fcontext_t
    sub   rsp,       028h        ; reserve shadow space for align_stack
    mov   rcx,       rdx         ; stack pointer as arg for align_stack
    mov   [rsp+8],   rcx
    call  align_stack   ; align stack
    mov   rdx,       rax         ; begin of aligned stack
    add   rsp,       028h
    pop   rcx                    ; restore pointer to fcontext_t

    lea  rdx,        [rdx-028h]  ; reserve 32byte shadow space + return address on stack, (RSP + 8) % 16 == 0
    mov  [rcx+040h], rdx         ; save the address where the context stack beginns

    stmxcsr [rcx+068h]           ; save MMX control and status word
    fnstcw  [rcx+06ch]           ; save x87 control word

    lea  rax,       finish       ; helper code executed after fn() returns
    mov  [rdx],     rax          ; store address off the helper function as return address

    xor  rax,       rax          ; set RAX to zero
    ret

finish:
    xor   rcx,        rcx
    mov   [rsp+08h],  rcx
    call  _exit                  ; exit application
    hlt
make_fcontext ENDP
END