VirtualBox

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

Last change on this file was 2416, checked in by bird, 14 years ago

kash: implemented opendir/readdir/closedir for windows (NT). Fixed windows forking.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.1 KB
Line 
1; $Id: shforkA-win.asm 2416 2010-09-14 00:30:30Z bird $
2;; @file
3; shforkA-win.asm - assembly routines used when forking on Windows.
4;
5
6;
7; Copyright (c) 2009-2010 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 [rbp-08h], rcx ; argc
70 mov [rbp-10h], rdx ; argv
71 mov [rbp-18h], 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
109 cmp rax, r10
110 jb .below
111 mov [gs:08h], rax
112.below:
113 lea r9, [rax - SHFORK_STACK_SIZE]
114 cmp r9, r11
115 ja .above
116 mov [gs:10h], r9
117.above:
118
119 mov rcx, [rbp - 08h] ; argc
120 mov rdx, [rbp - 10h] ; argv
121 mov r8, [rbp - 18h] ; envp
122
123 lea rsp, [rax - 40h] ; Switch!
124%else
125 mov [esp + 18h], eax
126 mov [eax - 4], esp
127 lea esp, [eax - 40h] ; Switch!
128
129 mov edx, [fs:04h] ; StackBase (the higher value)
130 mov ecx, [fs:08h] ; StackLimit (the lower value)
131 mov [eax - 10h], edx
132 mov [eax - 18h], ecx
133 cmp eax, edx
134 jb .below
135 mov [fs:04h], eax
136.below:
137 lea edx, [eax - SHFORK_STACK_SIZE]
138 cmp edx, ecx
139 ja .above
140 mov [fs:08h], edx
141.above:
142
143 mov ecx, [ebp + 8h] ; argc
144 mov edx, [ebp + 0ch] ; argv
145 mov eax, [ebp + 10h] ; envp
146
147 mov [esp ], ecx
148 mov [esp + 4h], edx
149 mov [esp + 8h], eax
150%endif
151 call NAME(real_main)
152
153 ;
154 ; Switch back the stack, restore the TIB fields and we're done.
155 ;
156%ifdef KBUILD_ARCH_AMD64
157 lea r11, [rsp + 40h]
158 mov rsp, [rsp + 38h]
159 mov r8, [r11 - 10h]
160 mov r9, [r11 - 18h]
161 mov [gs:08h], r8
162 mov [gs:10h], r9
163%else
164 lea edx, [esp + 40h]
165 mov esp, [esp + 2ch]
166 mov ecx, [edx - 10h]
167 mov edx, [edx - 18h]
168 mov [fs:04h], ecx
169 mov [fs:08h], edx
170%endif
171 leave
172 ret
173%ifdef KBUILD_ARCH_AMD64
174[endproc_frame main]
175%endif
176
177
178;;
179; sh_fork() worker
180;
181; @returns See fork().
182; @param psh
183;
184NAME(shfork_do_it):
185global NAME(shfork_do_it)
186%ifdef KBUILD_ARCH_AMD64
187 [proc_frame shfork_do_it]
188 [pushreg rbp]
189 push rbp
190 [setframe rbp, 0]
191 mov rbp, rsp
192 [allocstack 0x400]
193 sub rsp, 400h
194 and rsp, ~1ffh
195[endprolog]
196%else
197 push ebp
198 mov ebp, esp
199 sub esp, 400h
200 and esp, ~1ffh
201%endif
202
203 ;
204 ; Save most registers so they can be restored in the child.
205 ;
206%ifdef KBUILD_ARCH_AMD64
207 fxsave [rsp]
208 mov [rsp + 200h], rbp
209 mov [rsp + 208h], rax
210 mov [rsp + 210h], rbx
211 mov [rsp + 218h], rcx
212 mov [rsp + 220h], rdx
213 mov [rsp + 228h], rsi
214 mov [rsp + 230h], rdi
215 mov [rsp + 238h], r8
216 mov [rsp + 240h], r9
217 mov [rsp + 248h], r10
218 mov [rsp + 250h], r11
219 mov [rsp + 258h], r12
220 mov [rsp + 260h], r13
221 mov [rsp + 268h], r14
222 mov [rsp + 270h], r15
223%else
224 fxsave [esp]
225 mov [esp + 200h], ebp
226 mov [esp + 208h], eax
227 mov [esp + 210h], ebx
228 mov [esp + 218h], ecx
229 mov [esp + 220h], edx
230 mov [esp + 228h], esi
231 mov [esp + 230h], edi
232%endif
233
234 ;
235 ; Call the shfork_body that will spawn the child and all that.
236 ;
237%ifdef KBUILD_ARCH_AMD64
238 ;mov rcx, rcx ; psh
239 mov rdx, rsp ; stack_ptr
240 sub rsp, 20h
241 call NAME(shfork_body)
242 lea rsp, [rsp + 20h]
243%else
244 mov edx, esp
245 mov ecx, [ebp + 8h] ; psh
246 sub esp, 20h
247 mov [esp ], ecx
248 mov [esp + 4], edx ; stack_ptr
249 call NAME(shfork_body)
250 lea esp, [esp + 20h]
251%endif
252
253 ;
254 ; Just leave the function, no need to restore things.
255 ;
256 leave
257 ret
258%ifdef KBUILD_ARCH_AMD64
259[endproc_frame shfork_do_it]
260%endif
261
262
263;;
264; Switch the stack, restore the register and leave as if we'd called shfork_do_it.
265;
266; @param cur Current stack pointer.
267; @param base The stack base (higher value).
268; @param limit The stack limit (lower value).
269;
270NAME(shfork_resume):
271global NAME(shfork_resume)
272%ifdef KBUILD_ARCH_AMD64
273 mov rsp, rcx
274%else
275 mov ecx, [esp + 4]
276 mov edx, [esp + 8]
277 mov eax, [esp + 12]
278 mov esp, ecx
279%endif
280
281 ;
282 ; Adjust stack stuff in the TIB (longjmp/unwind).
283 ;
284%ifdef KBUILD_ARCH_AMD64
285 cmp rdx, [gs:08h] ; StackBase (the higher value)
286 jb .below
287 mov [gs:08h], rdx
288.below:
289 cmp r8, [gs:10h] ; StackLimit
290 ja .above
291 mov [gs:10h], r8
292.above:
293%else
294 cmp edx, [fs:04h] ; StackBase (the higher value)
295 jb .below
296 mov [fs:04h], edx
297.below:
298 cmp eax, [fs:08h] ; StackLimit
299 ja .above
300 mov [fs:08h], eax
301.above:
302%endif
303
304 ;
305 ; Restore most of the registers.
306 ;
307 ;; @todo xmm registers may require explicit saving/restoring...
308%ifdef KBUILD_ARCH_AMD64
309 frstor [rsp]
310 mov rbp, [rsp + 200h]
311 mov rax, [rsp + 208h]
312 mov rbx, [rsp + 210h]
313 mov rcx, [rsp + 218h]
314 mov rdx, [rsp + 220h]
315 mov rsi, [rsp + 228h]
316 mov rdi, [rsp + 230h]
317 mov r8, [rsp + 238h]
318 mov r9, [rsp + 240h]
319 mov r10, [rsp + 248h]
320 mov r11, [rsp + 250h]
321 mov r12, [rsp + 258h]
322 mov r13, [rsp + 260h]
323 mov r14, [rsp + 268h]
324 mov r15, [rsp + 270h]
325%else
326 frstor [esp]
327 mov ebp, [esp + 200h]
328 mov eax, [esp + 208h]
329 mov ebx, [esp + 210h]
330 mov ecx, [esp + 218h]
331 mov edx, [esp + 220h]
332 mov esi, [esp + 228h]
333 mov edi, [esp + 230h]
334%endif
335 xor eax, eax ; the child returns 0.
336 leave
337 ret
338
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