VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/win/SUPDrvA-win.asm@ 12157

Last change on this file since 12157 was 12157, checked in by vboxsync, 17 years ago

VBoxDrv/win: Use the IPRT versions of AssertMsg[12].

File size: 19.6 KB
Line 
1; $Id$
2;; @file
3; VirtualBox Support Driver - Windows NT specific assembly parts.
4;
5
6;
7; Copyright (C) 2006-2007 Sun Microsystems, Inc.
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27; Clara, CA 95054 USA or visit http://www.sun.com if you need
28; additional information or have any questions.
29;
30
31;*******************************************************************************
32;* Header Files *
33;*******************************************************************************
34%include "iprt/asmdefs.mac"
35
36BEGINCODE
37%ifdef RT_ARCH_AMD64
38%define _DbgPrint DbgPrint
39%endif
40extern _DbgPrint
41
42;;
43; Kind of alias for DbgPrint
44BEGINPROC SUPR0Printf
45 jmp _DbgPrint
46ENDPROC SUPR0Printf
47
48
49%ifdef SUPDRV_WITH_UNWIND_HACK
50 %ifdef RT_ARCH_AMD64
51
52;;
53; Common prolog, take the proc name as argument.
54; This creates a 0x80 byte stack frame.
55;
56%macro NtWrapProlog 1
57[proc_frame %1]
58 push rbp
59 [pushreg rbp]
60 mov rbp, rsp
61 [setframe rbp, 0]
62 sub rsp, 0x80
63 [allocstack 0x80]
64
65 ; save rdi and load rbp into it
66 mov [rbp - 8h], rdi
67 [savereg rdi, 0x78]
68 mov rdi, rbp
69[endprolog]
70%endmacro
71
72;;
73; Common epilog, take the proc name as argument.
74%macro NtWrapEpilog 1
75 ; restore rbp and rdi then return.
76 mov rbp, rdi
77 mov rdi, [rdi - 8h]
78 leave
79 ret
80[endproc_frame %1]
81%endmacro
82
83;;
84; Create a stack marker with the rbp. The marker is 32 byte big.
85; This is 32-byte aligned and 32 byte in size.
86;
87; Trashes r10
88%macro NtWrapCreateMarker 0
89 lea r10, [rbp - 30h]
90 and r10, ~1fh ; 32-byte align it.
91 mov dword [r10 ], 0x20080901
92 mov dword [r10 + 04h], 0x20080902
93 mov qword [r10 + 08h], rbp
94 mov dword [r10 + 10h], 0x20080903
95 mov dword [r10 + 14h], 0x20080904
96 mov qword [r10 + 18h], rbp
97%endmacro
98
99;;
100; Destroys the stack marker.
101;
102; Trashes r10
103%macro NtWrapDestroyMarker 0
104 lea r10, [rbp - 30h]
105 and r10, ~1fh ; 32-byte align it.
106 mov [r10 ], rbp
107 mov [r10 + 08h], rbp
108 mov [r10 + 10h], rbp
109 mov [r10 + 18h], rbp
110%endmacro
111
112;;
113; Find the stack marker with the rbp of the entry frame.
114;
115; Search the current stack page inline, call a helper function
116; which does a safe search of any further stack pages.
117;
118; Trashes rax, r10 and r11.
119; Modifies rbp
120;
121%macro NtWrapLocateMarker 0
122 mov rax, rbp
123 and rax, ~1fh ; 32-byte align it.
124
125 ;
126 ; Calc remainig space in the current page. If we're on a
127 ; page boundrary, we'll search the entire previous page.
128 ;
129 mov r10, rax
130 neg r10
131 and r10, 0fffh
132 inc r10
133 shr r10, 5 ; /= 32 bytes
134 jz %%not_found ; If zero, take the slow path
135
136 ;
137 ; The search loop.
138 ;
139%%again:
140 dec r10
141 lea rax, [rax + 20h]
142 jz %%not_found
143 cmp dword [rax ], 0x20080901
144 je %%candidate
145 jmp %%again
146
147%%not_found:
148 call NAME(NtWrapLocateMarkerHelper)
149 jmp %%done
150
151%%candidate:
152 cmp dword [rax + 04h], 0x20080902
153 jne %%again
154 cmp dword [rax + 10h], 0x20080903
155 jne %%again
156 cmp dword [rax + 14h], 0x20080904
157 jne %%again
158 mov r11, [rax + 08h]
159 cmp r11, [rax + 18h]
160 jne %%again
161
162 ; found it, change rbp.
163 mov rbp, r11
164%%done:
165%endmacro
166
167;;
168; Wraps a function with 4 or less argument that will go into registers.
169%macro NtWrapFunctionWithAllRegParams 1
170extern NAME(%1)
171BEGINPROC supdrvNtWrap%1
172 NtWrapProlog supdrvNtWrap%1
173 NtWrapLocateMarker
174
175 call NAME(%1)
176
177 NtWrapEpilog supdrvNtWrap%1
178ENDPROC supdrvNtWrap%1
179%endmacro
180
181;;
182; Wraps a function with 5 argument, where the first 4 goes into registers.
183%macro NtWrapFunctionWith5Params 1
184extern NAME(%1)
185BEGINPROC supdrvNtWrap%1
186 NtWrapProlog supdrvNtWrap%1
187 NtWrapLocateMarker
188
189 mov r11, [rdi + 30h]
190 mov [rsp + 20h], r11
191 call NAME(%1)
192
193 NtWrapEpilog supdrvNtWrap%1
194ENDPROC supdrvNtWrap%1
195%endmacro
196
197;;
198; Wraps a function with 6 argument, where the first 4 goes into registers.
199%macro NtWrapFunctionWith6Params 1
200extern NAME(%1)
201BEGINPROC supdrvNtWrap%1
202 NtWrapProlog supdrvNtWrap%1
203 NtWrapLocateMarker
204
205 mov r11, [rdi + 30h]
206 mov [rsp + 20h], r11
207 mov r10, [rdi + 38h]
208 mov [rsp + 28h], r10
209 call NAME(%1)
210
211 NtWrapEpilog supdrvNtWrap%1
212ENDPROC supdrvNtWrap%1
213%endmacro
214
215;;
216; Wraps a function with 7 argument, where the first 4 goes into registers.
217%macro NtWrapFunctionWith7Params 1
218extern NAME(%1)
219BEGINPROC supdrvNtWrap%1
220 NtWrapProlog supdrvNtWrap%1
221 NtWrapLocateMarker
222
223 mov r11, [rdi + 30h]
224 mov [rsp + 20h], r11
225 mov r10, [rdi + 38h]
226 mov [rsp + 28h], r10
227 mov rax, [rdi + 40h]
228 mov [rsp + 30h], rax
229 call NAME(%1)
230
231 NtWrapEpilog supdrvNtWrap%1
232ENDPROC supdrvNtWrap%1
233%endmacro
234
235extern IoGetStackLimits
236
237;;
238; Helper that cautiously continues the stack marker search
239; NtWrapLocateMarker started.
240;
241; The stack layout at the time is something like this.
242; rbp+08h callers return address.
243; rbp-00h saved rbp
244; rbp-08h saved rdi
245; rbp-09h
246; thru unused.
247; rbp-80h
248; rbp-88h our return address.
249; rbp-89h
250; thru callee register dump zone.
251; rbp-a0h
252;
253; @param rax Current stack location.
254; @param rdi Parent stack frame pointer. (This should equal rbp on entry.)
255;
256; Trashes: rax, r10, r11.
257; Will use the callers stack frame for register saving ASSUMING that
258; rbp-80h thru rbp-09h is unused.
259;
260; Modifies: rbp
261;
262BEGINPROC NtWrapLocateMarkerHelper
263 ;
264 ; Prolog. Save volatile regs and reserve callee space.
265 ;
266 sub rsp, 20h ; For IoGetStackLimits().
267 mov [rdi - 80h], rax
268 mov [rdi - 78h], rcx
269 mov [rdi - 70h], rdx
270 mov [rdi - 68h], r8
271 mov [rdi - 60h], r9
272
273 ;
274 ; Call VOID IoGetStackLimits(OUT PULONG_PTR LowLimit, OUT PULONG_PTR HighLimit);
275 ;
276 ; Use rdi-40h for the high limit and rdi-50h for the low one, we're only
277 ; interested in the high one.
278 ;
279 lea rcx, [rdi - 40h] ; arg #1 LowLimit
280 lea rdx, [rdi - 50h] ; arg #2 HighLimit
281 mov [rdx], eax ; paranoia - init to end of current search.
282 call IoGetStackLimits
283
284 ;
285 ; Move the top address into r10, restore rax and continue
286 ; the search. Check that r10 is less than 3 pages from rax.
287 ;
288 mov rax, [rdi - 80h] ; Restore eax (see prolog)
289 mov r10, [rdi - 50h] ; HighLimit
290 and r10, ~1fh ; 32-byte align it (downwards)
291 sub r10, rax
292 jz .not_found ; If already at the top of the stack.
293 cmp r10, 3000h
294 jae .out_of_bounds ; If too far away, something is busted.
295 shr r10, 5 ; /= 32.
296
297 ; The loop body.
298.search_loop:
299 cmp dword [rax ], 0x20080901
300 je .candidate
301.continue_searching:
302 dec r10
303 jz .not_found
304 lea rax, [rax + 20h]
305 jmp .search_loop
306
307 ; Found the first marker, check for the rest.
308.candidate:
309 cmp dword [rax + 04h], 0x20080902
310 jne .continue_searching
311 cmp dword [rax + 10h], 0x20080903
312 jne .continue_searching
313 cmp dword [rax + 14h], 0x20080904
314 jne .continue_searching
315 mov r11, [rax + 08h]
316 cmp r11, [rax + 18h]
317 jne .continue_searching
318
319 ; found it, change rbp.
320 mov rbp, r11
321
322 ;
323 ; Restore registers and pop the stack frame.
324 ;
325.epilog:
326 mov r9, [rdi - 60h]
327 mov r8, [rdi - 68h]
328 mov rdx, [rdi - 70h]
329 mov rcx, [rdi - 78h]
330 ; mov rax, [rdi - 80h]
331 add rsp, 20h
332 ret
333
334 ;
335 ; Needless to say, this isn't supposed to happen. Thus the int3.
336 ; Note down r10 and rax.
337 ;
338.out_of_bounds:
339%ifdef DEBUG
340 int3
341%endif
342.not_found:
343%ifdef DEBUG
344 int3
345%endif
346 jmp .epilog
347ENDPROC NtWrapLocateMarkerHelper
348
349
350
351;
352; This has the same order as the list in SUPDrv.c
353;
354NtWrapFunctionWithAllRegParams SUPR0ComponentRegisterFactory
355NtWrapFunctionWithAllRegParams SUPR0ComponentDeregisterFactory
356NtWrapFunctionWithAllRegParams SUPR0ComponentQueryFactory
357NtWrapFunctionWith5Params SUPR0ObjRegister
358NtWrapFunctionWithAllRegParams SUPR0ObjAddRef
359NtWrapFunctionWithAllRegParams SUPR0ObjRelease
360NtWrapFunctionWithAllRegParams SUPR0ObjVerifyAccess
361NtWrapFunctionWithAllRegParams SUPR0LockMem
362NtWrapFunctionWithAllRegParams SUPR0UnlockMem
363NtWrapFunctionWith5Params SUPR0ContAlloc
364NtWrapFunctionWithAllRegParams SUPR0ContFree
365NtWrapFunctionWith5Params SUPR0LowAlloc
366NtWrapFunctionWithAllRegParams SUPR0LowFree
367NtWrapFunctionWithAllRegParams SUPR0MemAlloc
368NtWrapFunctionWithAllRegParams SUPR0MemGetPhys
369NtWrapFunctionWithAllRegParams SUPR0MemFree
370NtWrapFunctionWithAllRegParams SUPR0PageAlloc
371NtWrapFunctionWithAllRegParams SUPR0PageFree
372;NtWrapFunctionWithAllRegParams SUPR0Printf - cannot wrap this buster.
373NtWrapFunctionWithAllRegParams RTMemAlloc
374NtWrapFunctionWithAllRegParams RTMemAllocZ
375NtWrapFunctionWithAllRegParams RTMemFree
376NtWrapFunctionWithAllRegParams RTMemDup
377NtWrapFunctionWithAllRegParams RTMemDupEx
378NtWrapFunctionWithAllRegParams RTMemRealloc
379NtWrapFunctionWithAllRegParams RTR0MemObjAllocLow
380NtWrapFunctionWithAllRegParams RTR0MemObjAllocPage
381NtWrapFunctionWithAllRegParams RTR0MemObjAllocPhys
382NtWrapFunctionWithAllRegParams RTR0MemObjAllocPhysNC
383NtWrapFunctionWithAllRegParams RTR0MemObjAllocCont
384NtWrapFunctionWithAllRegParams RTR0MemObjLockUser
385NtWrapFunctionWith5Params RTR0MemObjMapKernel
386NtWrapFunctionWith6Params RTR0MemObjMapUser
387;NtWrapFunctionWithAllRegParams RTR0MemObjAddress - not necessary
388;NtWrapFunctionWithAllRegParams RTR0MemObjAddressR3 - not necessary
389;NtWrapFunctionWithAllRegParams RTR0MemObjSize - not necessary
390;NtWrapFunctionWithAllRegParams RTR0MemObjIsMapping - not necessary
391;NtWrapFunctionWithAllRegParams RTR0MemObjGetPagePhysAddr - not necessary
392NtWrapFunctionWithAllRegParams RTR0MemObjFree
393;NtWrapFunctionWithAllRegParams RTProcSelf - not necessary
394;NtWrapFunctionWithAllRegParams RTR0ProcHandleSelf - not necessary
395NtWrapFunctionWithAllRegParams RTSemFastMutexCreate
396NtWrapFunctionWithAllRegParams RTSemFastMutexDestroy
397NtWrapFunctionWithAllRegParams RTSemFastMutexRequest
398NtWrapFunctionWithAllRegParams RTSemFastMutexRelease
399NtWrapFunctionWithAllRegParams RTSemEventCreate
400NtWrapFunctionWithAllRegParams RTSemEventSignal
401NtWrapFunctionWithAllRegParams RTSemEventWait
402NtWrapFunctionWithAllRegParams RTSemEventWaitNoResume
403NtWrapFunctionWithAllRegParams RTSemEventDestroy
404NtWrapFunctionWithAllRegParams RTSemEventMultiCreate
405NtWrapFunctionWithAllRegParams RTSemEventMultiSignal
406NtWrapFunctionWithAllRegParams RTSemEventMultiReset
407NtWrapFunctionWithAllRegParams RTSemEventMultiWait
408NtWrapFunctionWithAllRegParams RTSemEventMultiWaitNoResume
409NtWrapFunctionWithAllRegParams RTSemEventMultiDestroy
410NtWrapFunctionWithAllRegParams RTSpinlockCreate
411NtWrapFunctionWithAllRegParams RTSpinlockDestroy
412NtWrapFunctionWithAllRegParams RTSpinlockAcquire
413NtWrapFunctionWithAllRegParams RTSpinlockRelease
414NtWrapFunctionWithAllRegParams RTSpinlockAcquireNoInts
415NtWrapFunctionWithAllRegParams RTSpinlockReleaseNoInts
416;NtWrapFunctionWithAllRegParams RTTimeNanoTS - not necessary
417;NtWrapFunctionWithAllRegParams RTTimeMilliTS - not necessary
418;NtWrapFunctionWithAllRegParams RTTimeSystemNanoTS - not necessary
419;NtWrapFunctionWithAllRegParams RTTimeSystemMilliTS - not necessary
420;NtWrapFunctionWithAllRegParams RTThreadNativeSelf - not necessary
421NtWrapFunctionWithAllRegParams RTThreadSleep
422NtWrapFunctionWithAllRegParams RTThreadYield
423%if 0 ; Thread APIs, Part 2
424;NtWrapFunctionWithAllRegParams RTThreadSelf
425NtWrapFunctionWith7Params RTThreadCreate
426NtWrapFunctionWithAllRegParams RTThreadGetNative
427NtWrapFunctionWithAllRegParams RTThreadWait
428NtWrapFunctionWithAllRegParams RTThreadWaitNoResume
429NtWrapFunctionWithAllRegParams RTThreadGetName
430NtWrapFunctionWithAllRegParams RTThreadSelfName
431NtWrapFunctionWithAllRegParams RTThreadGetType
432NtWrapFunctionWithAllRegParams RTThreadUserSignal
433NtWrapFunctionWithAllRegParams RTThreadUserReset
434NtWrapFunctionWithAllRegParams RTThreadUserWait
435NtWrapFunctionWithAllRegParams RTThreadUserWaitNoResume
436%endif
437;NtWrapFunctionWithAllRegParams RTLogDefaultInstance - a bit of a gamble, but we do not want the overhead!
438;NtWrapFunctionWithAllRegParams RTMpCpuId - not necessary
439;NtWrapFunctionWithAllRegParams RTMpCpuIdFromSetIndex - not necessary
440;NtWrapFunctionWithAllRegParams RTMpCpuIdToSetIndex - not necessary
441;NtWrapFunctionWithAllRegParams RTMpIsCpuPossible - not necessary
442;NtWrapFunctionWithAllRegParams RTMpGetCount - not necessary
443;NtWrapFunctionWithAllRegParams RTMpGetMaxCpuId - not necessary
444;NtWrapFunctionWithAllRegParams RTMpGetOnlineCount - not necessary
445;NtWrapFunctionWithAllRegParams RTMpGetOnlineSet - not necessary
446;NtWrapFunctionWithAllRegParams RTMpGetSet - not necessary
447;NtWrapFunctionWithAllRegParams RTMpIsCpuOnline - not necessary
448NtWrapFunctionWithAllRegParams RTMpOnAll
449NtWrapFunctionWithAllRegParams RTMpOnOthers
450NtWrapFunctionWithAllRegParams RTMpOnSpecific
451;NtWrapFunctionWithAllRegParams RTLogRelDefaultInstance - not necessary.
452NtWrapFunctionWithAllRegParams RTLogSetDefaultInstanceThread
453;NtWrapFunctionWithAllRegParams RTLogLogger - can't wrap this buster.
454;NtWrapFunctionWithAllRegParams RTLogLoggerEx - can't wrap this buster.
455NtWrapFunctionWith5Params RTLogLoggerExV
456;NtWrapFunctionWithAllRegParams RTLogPrintf - can't wrap this buster. ;; @todo provide va_list log wrappers in RuntimeR0.
457NtWrapFunctionWithAllRegParams RTLogPrintfV
458NtWrapFunctionWithAllRegParams AssertMsg1
459;NtWrapFunctionWithAllRegParams AssertMsg2 - can't wrap this buster.
460
461
462;;
463; @cproto DECLASM(int) supdrvNtWrapVMMR0EntryEx(PFNRT pfnVMMR0EntryEx, PVM pVM, unsigned uOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession);
464;
465; @param pfnVMMR0EntryEx rcx
466; @param pVM rdx
467; @param uOperation r8
468; @param pReq r9
469; @param u64Arg [rsp + 28h] / [rbp + 30h]
470; @param pSession [rsp + 30h] / [rbp + 38h]
471;
472BEGINPROC supdrvNtWrapVMMR0EntryEx
473 NtWrapProlog supdrvNtWrapVMMR0EntryEx
474 NtWrapCreateMarker
475
476 mov rax, rcx
477 mov rcx, rdx
478 mov rdx, r8
479 mov r8, r9
480 mov r9, [rbp + 30h]
481 mov r11, [rbp + 38h]
482 mov [rsp + 20h], r11
483 call rax
484
485 NtWrapDestroyMarker
486 NtWrapEpilog supdrvNtWrapVMMR0EntryEx
487ENDPROC supdrvNtWrapVMMR0EntryEx
488
489
490;;
491; @cproto DECLASM(int) supdrvNtWrapVMMR0EntryFast(PFNRT pfnVMMR0EntryFast, PVM pVM, unsigned uOperation);
492;
493; @param pfnVMMR0EntryFast rcx
494; @param pVM rdx
495; @param uOperation r8
496;
497BEGINPROC supdrvNtWrapVMMR0EntryFast
498 NtWrapProlog supdrvNtWrapVMMR0EntryFast
499 NtWrapCreateMarker
500
501 mov rax, rcx
502 mov rcx, rdx
503 mov rdx, r8
504 call rax
505
506 NtWrapDestroyMarker
507 NtWrapEpilog supdrvNtWrapVMMR0EntryFast
508ENDPROC supdrvNtWrapVMMR0EntryFast
509
510
511;;
512; @cproto DECLASM(void) supdrvNtWrapObjDestructor(PFNRT pfnDestruction, void *pvObj, void *pvUser1, void *pvUser2);
513;
514; @param pfnDestruction rcx
515; @param pvObj rdx
516; @param pvUser1 r8
517; @param pvUser2 r9
518;
519BEGINPROC supdrvNtWrapObjDestructor
520 NtWrapProlog supdrvNtWrapObjDestructor
521 NtWrapCreateMarker
522
523 mov rax, rcx
524 mov rcx, rdx
525 mov rdx, r8
526 mov r8, r9
527 call rax
528
529 NtWrapDestroyMarker
530 NtWrapEpilog supdrvNtWrapObjDestructor
531ENDPROC supdrvNtWrapObjDestructor
532
533
534;;
535; @cproto DECLASM(void *) supdrvNtWrapQueryFactoryInterface(PFNRT pfnQueryFactoryInterface, struct SUPDRVFACTORY const *pSupDrvFactory,
536; PSUPDRVSESSION pSession, const char *pszInterfaceUuid);
537;
538; @param pfnQueryFactoryInterface rcx
539; @param pSupDrvFactory rdx
540; @param pSession r8
541; @param pszInterfaceUuid r9
542;
543BEGINPROC supdrvNtWrapQueryFactoryInterface
544 NtWrapProlog supdrvNtWrapQueryFactoryInterface
545 NtWrapCreateMarker
546
547 mov rax, rcx
548 mov rcx, rdx
549 mov rdx, r8
550 mov r8, r9
551 call rax
552
553 NtWrapDestroyMarker
554 NtWrapEpilog supdrvNtWrapQueryFactoryInterface
555ENDPROC supdrvNtWrapQueryFactoryInterface
556
557
558;;
559; @cproto DECLASM(int) supdrvNtWrapModuleInit(PFNRT pfnModuleInit);
560;
561; @param pfnModuleInit rcx
562;
563BEGINPROC supdrvNtWrapModuleInit
564 NtWrapProlog supdrvNtWrapModuleInit
565 NtWrapCreateMarker
566
567 call rcx
568
569 NtWrapDestroyMarker
570 NtWrapEpilog supdrvNtWrapModuleInit
571ENDPROC supdrvNtWrapModuleInit
572
573
574;;
575; @cproto DECLASM(void) supdrvNtWrapModuleTerm(PFNRT pfnModuleTerm);
576;
577; @param pfnModuleInit rcx
578;
579BEGINPROC supdrvNtWrapModuleTerm
580 NtWrapProlog supdrvNtWrapModuleTerm
581 NtWrapCreateMarker
582
583 call rcx
584
585 NtWrapDestroyMarker
586 NtWrapEpilog supdrvNtWrapModuleTerm
587ENDPROC supdrvNtWrapModuleTerm
588
589
590
591 %endif ; RT_ARCH_AMD64
592%endif ; SUPDRV_WITH_UNWIND_HACK
593
Note: See TracBrowser for help on using the repository browser.

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