source: trunk/src/kash/shforkA-win.asm@ 2292

Last change on this file since 2292 was 2292, checked in by bird, 16 years ago

kash: forking on widnows.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.8 KB
Line 
1; $Id: shforkA-win.asm 2292 2009-02-28 04:46:25Z bird $
2;; @file
3; shforkA-win.asm - assembly routines used when forking on Windows.
4;
5
6;
7; Copyright (c) 2009 knut st. osmundsen <bird-kBuild-spamix@anduin.net>
8;
9; This file is part of kBuild.
10;
11; kBuild is free software; you can redistribute it and/or modify
12; it under the terms of the GNU General Public License as published by
13; the Free Software Foundation; either version 3 of the License, or
14; (at your option) any later version.
15;
16; kBuild is distributed in the hope that it will be useful,
17; but WITHOUT ANY WARRANTY; without even the implied warranty of
18; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19; GNU General Public License for more details.
20;
21; You should have received a copy of the GNU General Public License
22; along with kBuild. If not, see <http://www.gnu.org/licenses/>
23;
24;
25
26;*******************************************************************************
27;* Defined Constants And Macros *
28;*******************************************************************************
29%ifdef KBUILD_ARCH_AMD64
30 %define NAME(name) name
31%else
32 %define NAME(name) _ %+ name
33%endif
34
35
36;*******************************************************************************
37;* External Symbols *
38;*******************************************************************************
39extern NAME(real_main)
40extern NAME(shfork_maybe_forked)
41extern NAME(shfork_body)
42
43
44[section .text]
45
46;;
47; C main() wrapper.
48;
49NAME(main):
50global NAME(main)
51%ifdef KBUILD_ARCH_AMD64
52[proc_frame main]
53%endif
54
55 ;
56 ; Prolog, spilling parameters from registers.
57 ;
58%ifdef KBUILD_ARCH_AMD64
59 [pushreg rbp]
60 push rbp
61 [setframe rbp, 0]
62 mov rbp, rsp
63 [allocstack 0x40]
64 sub rsp, 40h
65 and rsp, ~1fh
66 mov [rsp ], rcx ; argc
67 mov [rsp+ 8h], rdx ; argv
68 mov [rsp+10h], r8 ; envp
69 [endprolog]
70%else
71 push ebp
72 mov ebp, esp
73 sub esp, 40h
74 and esp, ~1fh
75%endif
76
77 ;
78 ; Call shfork_maybe_forked. This will not return if we're forking.
79 ;
80%ifndef KBUILD_ARCH_AMD64
81 mov ecx, [ebp + 8h] ; argc
82 mov edx, [ebp + 0ch] ; argv
83 mov eax, [ebp + 10h] ; envp
84 mov [esp ], ecx
85 mov [esp + 4h], edx
86 mov [esp + 8h], eax
87%endif
88 call NAME(shfork_maybe_forked)
89
90 ;
91 ; Ok, it returned which means we're not forking.
92 ;
93 ; The accumulator register is now pointing to the top of the
94 ; stack we're going to call real_main on. Switch and call it.
95 ;
96 ; The TIB adjustments is required or we'll crash in longjmp/unwind.
97 ;
98%ifdef KBUILD_ARCH_AMD64
99 mov [rsp + 18h], rax
100 mov [rax - 8h], rsp
101
102 mov r10, [gs:08h] ; StackBase (the higher value)
103 mov r11, [gs:10h] ; StackLimit (the lower value)
104 mov [rax - 10h], r10
105 mov [rax - 18h], r11
106 cmp rax, r10
107 jb .below
108 mov [gs:08h], rax
109.below:
110 lea r9, [rax - 1*1024*1024]
111 cmp r9, r11
112 ja .above
113 mov [gs:10h], r9
114.above:
115
116 mov rcx, [rsp ] ; argc
117 mov rdx, [rsp + 08h] ; argv
118 mov r8, [rsp + 10h] ; envp
119
120 lea rsp, [eax - 40h] ; Switch!
121%else
122 mov [esp + 18h], eax
123 mov [eax - 4], esp
124 lea esp, [eax - 40h] ; Switch!
125
126 mov edx, [fs:04h] ; StackBase (the higher value)
127 mov ecx, [fs:08h] ; StackLimit (the lower value)
128 mov [eax - 10h], edx
129 mov [eax - 18h], ecx
130 cmp rax, edx
131 jb .below
132 mov [fs:04h], rax
133.below:
134 lea edx, [eax - 1*1024*1024]
135 cmp edx, ecx
136 ja .above
137 mov [fs:08h], edx
138.above:
139
140 mov ecx, [ebp + 8h] ; argc
141 mov edx, [ebp + 0ch] ; argv
142 mov eax, [ebp + 10h] ; envp
143
144 mov [esp ], ecx
145 mov [esp + 4h], edx
146 mov [esp + 8h], eax
147%endif
148 call NAME(real_main)
149
150 ;
151 ; Switch back the stack, restore the TIB fields and we're done.
152 ;
153%ifdef KBUILD_ARCH_AMD64
154 lea r11, [rsp + 40h]
155 mov rsp, [rsp + 38h]
156 mov r8, [r11 - 10h]
157 mov r9, [r11 - 18h]
158 mov [gs:08h], r8
159 mov [gs:10h], r9
160%else
161 lea edx, [esp + 40h]
162 mov esp, [esp + 2ch]
163 mov ecx, [edx - 10h]
164 mov edx, [edx - 18h]
165 mov [fs:04h], ecx
166 mov [fs:08h], edx
167%endif
168 leave
169 ret
170%ifdef KBUILD_ARCH_AMD64
171[endproc_frame main]
172%endif
173
174
175;;
176; sh_fork() worker
177;
178NAME(shfork_do_it):
179global NAME(shfork_do_it)
180%ifdef KBUILD_ARCH_AMD64
181 [proc_frame shfork_do_it]
182 [pushreg rbp]
183 push rbp
184 [setframe rbp, 0]
185 mov rbp, rsp
186 [allocstack 0x400]
187 sub rsp, 400h
188 and rsp, ~1ffh
189[endprolog]
190%else
191 push ebp
192 mov ebp, esp
193 sub esp, 400h
194 and esp, ~1ffh
195%endif
196
197 ;
198 ; Save most registers so they can be restored in the child.
199 ;
200%ifdef KBUILD_ARCH_AMD64
201 fxsave [rsp]
202 mov [rsp + 200h], rbp
203 mov [rsp + 208h], rax
204 mov [rsp + 210h], rbx
205 mov [rsp + 218h], rcx
206 mov [rsp + 220h], rdx
207 mov [rsp + 228h], rsi
208 mov [rsp + 230h], rdi
209 mov [rsp + 238h], r8
210 mov [rsp + 240h], r9
211 mov [rsp + 248h], r10
212 mov [rsp + 250h], r11
213 mov [rsp + 258h], r12
214 mov [rsp + 260h], r13
215 mov [rsp + 268h], r14
216 mov [rsp + 270h], r15
217%else
218 fxsave [esp]
219 mov [esp + 200h], ebp
220 mov [esp + 208h], eax
221 mov [esp + 210h], ebx
222 mov [esp + 218h], ecx
223 mov [esp + 220h], edx
224 mov [esp + 228h], esi
225 mov [esp + 230h], edi
226%endif
227
228 ;
229 ; Call the shfork_body that will spawn the child and all that.
230 ;
231%ifdef KBUILD_ARCH_AMD64
232 mov rcx, rsp
233%else
234 mov ecx, esp
235 sub esp, 20h
236 mov [esp], ecx
237%endif
238 call NAME(shfork_body)
239%ifdef KBUILD_ARCH_AMD64
240 lea esp, [esp + 20h]
241%endif
242
243 ;
244 ; Just leave the function, no need to restore things.
245 ;
246 leave
247 ret
248%ifdef KBUILD_ARCH_AMD64
249[endproc_frame shfork_do_it]
250%endif
251
252
253;;
254; Switch the stack, restore the register and leave as if we'd called shfork_do_it.
255;
256; @param cur Current stack pointer.
257; @param base The stack base (higher value).
258; @param limit The stack limit (lower value).
259;
260NAME(shfork_resume):
261global NAME(shfork_resume)
262%ifdef KBUILD_ARCH_AMD64
263 mov rsp, rcx
264%else
265 mov ecx, [esp + 4]
266 mov edx, [esp + 8]
267 mov eax, [esp + 12]
268 mov esp, ecx
269%endif
270
271 ;
272 ; Adjust stack stuff in the TIB (longjmp/unwind).
273 ;
274%ifdef KBUILD_ARCH_AMD64
275 cmp rdx, [gs:08h] ; StackBase (the higher value)
276 jb .below
277 mov [gs:08h], rdx
278.below:
279 cmp r8, [gs:10h] ; StackLimit
280 ja .above
281 mov [gs:10h], r8
282.above:
283%else
284 cmp edx, [fs:04h] ; StackBase (the higher value)
285 jb .below
286 mov [fs:04h], edx
287.below:
288 cmp eax, [fs:08h] ; StackLimit
289 ja .above
290 mov [fs:08h], eax
291.above:
292%endif
293
294 ;
295 ; Restore most of the registers.
296 ;
297 ;; @todo xmm registers may require explicit saving/restoring...
298%ifdef KBUILD_ARCH_AMD64
299 frstor [rsp]
300 mov rbp, [rsp + 200h]
301 mov rax, [rsp + 208h]
302 mov rbx, [rsp + 210h]
303 mov rcx, [rsp + 218h]
304 mov rdx, [rsp + 220h]
305 mov rsi, [rsp + 228h]
306 mov rdi, [rsp + 230h]
307 mov r8, [rsp + 238h]
308 mov r9, [rsp + 240h]
309 mov r10, [rsp + 248h]
310 mov r11, [rsp + 250h]
311 mov r12, [rsp + 258h]
312 mov r13, [rsp + 260h]
313 mov r14, [rsp + 268h]
314 mov r15, [rsp + 270h]
315%else
316 frstor [esp]
317 mov ebp, [esp + 200h]
318 mov eax, [esp + 208h]
319 mov ebx, [esp + 210h]
320 mov ecx, [esp + 218h]
321 mov edx, [esp + 220h]
322 mov esi, [esp + 228h]
323 mov edi, [esp + 230h]
324%endif
325 xor eax, eax ; the child returns 0.
326 leave
327 ret
328
Note: See TracBrowser for help on using the repository browser.