VirtualBox

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

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

kash: more fixes + pipe.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette