VirtualBox

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

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

Corrected the wrapper for RTLogLoggerExV.

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