VirtualBox

root/trunk/src/recompiler/VBoxREMWrapper.cpp

Revision 15520, 113.6 kB (checked in by vboxsync, 3 weeks ago)

partial dual-REM support in old recompiler

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 /* $Id$ */
2 /** @file
3  *
4  * VBoxREM Win64 DLL Wrapper.
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  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18  * Clara, CA 95054 USA or visit http://www.sun.com if you need
19  * additional information or have any questions.
20  */
21
22
23 /** @page pg_vboxrem_amd64      VBoxREM Hacks on AMD64
24  *
25  * There are problems with building BoxREM both on WIN64 and 64-bit linux.
26  *
27  * On linux binutils refuses to link shared objects without -fPIC compiled code
28  * (bitches about some fixup types). But when trying to build with -fPIC dyngen
29  * doesn't like the code anymore. Sweet. The current solution is to build the
30  * VBoxREM code as a relocatable module and use our ELF loader to load it.
31  *
32  * On WIN64 we're not aware of any GCC port which can emit code using the MSC
33  * calling convention. So, we're in for some real fun here. The choice is between
34  * porting GCC to AMD64 WIN64 and comming up with some kind of wrapper around
35  * either the win32 build or the 64-bit linux build.
36  *
37  *  -# Porting GCC will be a lot of work. For one thing the calling convention differs
38  *     and messing with such stuff can easily create ugly bugs. We would also have to
39  *     do some binutils changes, but I think those are rather small compared to GCC.
40  *     (That said, the MSC calling convention is far simpler than the linux one, it
41  *     reminds me of _Optlink which we have working already.)
42  *  -# Wrapping win32 code will work, but addresses outside the first 4GB are
43  *     inaccessible and we will have to create 32-64 thunks for all imported functions.
44  *     (To switch between 32-bit and 64-bit is load the right CS using far jmps (32->64)
45  *     or far returns (both).)
46  *  -# Wrapping 64-bit linux code might be the easier solution. The requirements here
47  *     are:
48  *       - Remove all CRT references we possibly, either by using intrinsics or using
49  *         IPRT. Part of IPRT will be linked into VBoxREM2.rel, this will be yet another
50  *         IPRT mode which I've dubbed 'no-crt'. The no-crt mode provide basic non-system
51  *         dependent stuff.
52  *       - Compile and link it into a relocatable object (include the gcc intrinsics
53  *         in libgcc). Call this VBoxREM2.rel.
54  *       - Write a wrapper dll, VBoxREM.dll, for which during REMR3Init() will load
55  *         VBoxREM2.rel (using IPRT) and generate calling convention wrappers
56  *         for all IPRT functions and VBoxVMM functions that it uses. All exports
57  *         will be wrapped vice versa.
58  *       - For building on windows hosts, we will use a mingw32 hosted cross compiler.
59  *         and add a 'no-crt' mode to IPRT where it provides the necessary CRT headers
60  *         and function implementations.
61  *
62  * The 3rd solution will be tried out first since it requires the least effort and
63  * will let us make use of the full 64-bit register set.
64  *
65  *
66  *
67  * @section sec_vboxrem_amd64_compare   Comparing the GCC and MSC calling conventions
68  *
69  * GCC expects the following (cut & past from page 20 in the ABI draft 0.96):
70  *
71  * @verbatim
72     %rax     temporary register; with variable arguments passes information about the
73              number of SSE registers used; 1st return register.
74              [Not preserved]
75     %rbx     callee-saved register; optionally used as base pointer.
76              [Preserved]
77     %rcx     used to pass 4th integer argument to functions.
78              [Not preserved]
79     %rdx     used to pass 3rd argument to functions; 2nd return register
80              [Not preserved]
81     %rsp     stack pointer
82              [Preserved]
83     %rbp     callee-saved register; optionally used as frame pointer
84              [Preserved]
85     %rsi     used to pass 2nd argument to functions
86              [Not preserved]
87     %rdi     used to pass 1st argument to functions
88              [Not preserved]
89     %r8      used to pass 5th argument to functions
90              [Not preserved]
91     %r9      used to pass 6th argument to functions
92              [Not preserved]
93     %r10     temporary register, used for passing a function's static chain
94              pointer [Not preserved]
95     %r11     temporary register
96              [Not preserved]
97     %r12-r15 callee-saved registers
98              [Preserved]
99     %xmm0-%xmm1  used to pass and return floating point arguments
100              [Not preserved]
101     %xmm2-%xmm7  used to pass floating point arguments
102              [Not preserved]
103     %xmm8-%xmm15 temporary registers
104              [Not preserved]
105     %mmx0-%mmx7  temporary registers
106              [Not preserved]
107     %st0     temporary register; used to return long double arguments
108              [Not preserved]
109     %st1     temporary registers; used to return long double arguments
110              [Not preserved]
111     %st2-%st7 temporary registers
112              [Not preserved]
113     %fs      Reserved for system use (as thread specific data register)
114              [Not preserved]
115    @endverbatim
116  *
117  * Direction flag is preserved as cleared.
118  * The stack must be aligned on a 16-byte boundrary before the 'call/jmp' instruction.
119  *
120  *
121  *
122  * MSC expects the following:
123  * @verbatim
124     rax      return value, not preserved.
125     rbx      preserved.
126     rcx      1st argument, integer, not preserved.
127     rdx      2nd argument, integer, not preserved.
128     rbp      preserved.
129     rsp      preserved.
130     rsi      preserved.
131     rdi      preserved.
132     r8       3rd argument, integer, not preserved.
133     r9       4th argument, integer, not preserved.
134     r10      scratch register, not preserved.
135     r11      scratch register, not preserved.
136     r12-r15  preserved.
137     xmm0     1st argument, fp, return value, not preserved.
138     xmm1     2st argument, fp, not preserved.
139     xmm2     3st argument, fp, not preserved.
140     xmm3     4st argument, fp, not preserved.
141     xmm4-xmm5    scratch, not preserved.
142     xmm6-xmm15   preserved.
143    @endverbatim
144  *
145  * Dunno what the direction flag is...
146  * The stack must be aligned on a 16-byte boundrary before the 'call/jmp' instruction.
147  *
148  *
149  * Thus, When GCC code is calling MSC code we don't really have to preserve
150  * anything. But but MSC code is calling GCC code, we'll have to save esi and edi.
151  *
152  */
153
154
155 /*******************************************************************************
156 *   Defined Constants And Macros                                               *
157 *******************************************************************************/
158 /** @def USE_REM_STUBS
159  * Define USE_REM_STUBS to stub the entire REM stuff. This is useful during
160  * early porting (before we start running stuff).
161  */
162 #if defined(__DOXYGEN__)
163 # define USE_REM_STUBS
164 #endif
165
166 /** @def USE_REM_CALLING_CONVENTION_GLUE
167  * Define USE_REM_CALLING_CONVENTION_GLUE for platforms where it's necessary to
168  * use calling convention wrappers.
169  */
170 #if (defined(RT_ARCH_AMD64) && defined(RT_OS_WINDOWS)) || defined(__DOXYGEN__)
171 # define USE_REM_CALLING_CONVENTION_GLUE
172 #endif
173
174 /** @def USE_REM_IMPORT_JUMP_GLUE
175  * Define USE_REM_IMPORT_JUMP_GLUE for platforms where we need to
176  * emit some jump glue to deal with big addresses.
177  */
178 #if (defined(RT_ARCH_AMD64) && !defined(USE_REM_CALLING_CONVENTION_GLUE) && !defined(RT_OS_DARWIN)) || defined(__DOXYGEN__)
179 # define USE_REM_IMPORT_JUMP_GLUE
180 #endif
181
182
183 /*******************************************************************************
184 *   Header Files                                                               *
185 *******************************************************************************/
186 #define LOG_GROUP LOG_GROUP_REM
187 #include <VBox/rem.h>
188 #include <VBox/vmm.h>
189 #include <VBox/dbgf.h>
190 #include <VBox/dbg.h>
191 #include <VBox/csam.h>
192 #include <VBox/mm.h>
193 #include <VBox/em.h>
194 #include <VBox/ssm.h>
195 #include <VBox/hwaccm.h>
196 #include <VBox/patm.h>
197 #ifdef VBOX_WITH_VMI
198 # include <VBox/parav.h>
199 #endif
200 #include <VBox/pdm.h>
201 #include <VBox/pgm.h>
202 #include <VBox/iom.h>
203 #include <VBox/vm.h>
204 #include <VBox/err.h>
205 #include <VBox/log.h>
206 #include <VBox/dis.h>
207
208 #include <iprt/alloc.h>
209 #include <iprt/assert.h>
210 #include <iprt/ldr.h>
211 #include <iprt/param.h>
212 #include <iprt/path.h>
213 #include <iprt/string.h>
214 #include <iprt/stream.h>
215
216
217 /*******************************************************************************
218 *   Structures and Typedefs                                                    *
219 *******************************************************************************/
220 /**
221  * Parameter descriptor.
222  */
223 typedef struct REMPARMDESC
224 {
225     /** Parameter flags (REMPARMDESC_FLAGS_*). */
226     uint8_t     fFlags;
227     /** The parameter size if REMPARMDESC_FLAGS_SIZE is set. */
228     uint8_t     cb;
229     /** Pointer to additional data.
230      * For REMPARMDESC_FLAGS_PFN this is a PREMFNDESC. */
231     void       *pvExtra;
232
233 } REMPARMDESC, *PREMPARMDESC;
234 /** Pointer to a constant parameter descriptor. */
235 typedef const REMPARMDESC *PCREMPARMDESC;
236
237 /** @name Parameter descriptor flags.
238  * @{ */
239 /** The parameter type is a kind of integer which could fit in a register. This includes pointers. */
240 #define REMPARMDESC_FLAGS_INT           0
241 /** The parameter is a GC pointer. */
242 #define REMPARMDESC_FLAGS_GCPTR         1
243 /** The parameter is a GC physical address. */
244 #define REMPARMDESC_FLAGS_GCPHYS        2
245 /** The parameter is a HC physical address. */
246 #define REMPARMDESC_FLAGS_HCPHYS        3
247 /** The parameter type is a kind of floating point. */
248 #define REMPARMDESC_FLAGS_FLOAT         4
249 /** The parameter value is a struct. This type takes a size. */
250 #define REMPARMDESC_FLAGS_STRUCT        5
251 /** The parameter is an elipsis. */
252 #define REMPARMDESC_FLAGS_ELLIPSIS      6
253 /** The parameter is a va_list. */
254 #define REMPARMDESC_FLAGS_VALIST        7
255 /** The parameter is a function pointer. pvExtra is a PREMFNDESC. */
256 #define REMPARMDESC_FLAGS_PFN           8
257 /** The parameter type mask. */
258 #define REMPARMDESC_FLAGS_TYPE_MASK     15
259 /** The parameter size field is valid. */
260 #define REMPARMDESC_FLAGS_SIZE          RT_BIT(7)
261 /** @} */
262
263 /**
264  * Function descriptor.
265  */
266 typedef struct REMFNDESC
267 {
268     /** The function name. */
269     const char         *pszName;
270     /** Exports: Pointer to the function pointer.
271      * Imports: Pointer to the function. */
272     void               *pv;
273     /** Array of parameter descriptors. */
274     PCREMPARMDESC       paParams;
275     /** The number of parameter descriptors pointed to by paParams. */
276     uint8_t             cParams;
277     /** Function flags (REMFNDESC_FLAGS_*). */
278     uint8_t             fFlags;
279     /** The size of the return value. */
280     uint8_t             cbReturn;
281     /** Pointer to the wrapper code for imports. */
282     void               *pvWrapper;
283 } REMFNDESC, *PREMFNDESC;
284 /** Pointer to a constant function descriptor. */
285 typedef const REMFNDESC *PCREMFNDESC;
286
287 /** @name Function descriptor flags.
288  * @{ */
289 /** The return type is void. */
290 #define REMFNDESC_FLAGS_RET_VOID        0
291 /** The return type is a kind of integer passed in rax/eax. This includes pointers. */
292 #define REMFNDESC_FLAGS_RET_INT         1
293 /** The return type is a kind of floating point. */
294 #define REMFNDESC_FLAGS_RET_FLOAT       2
295 /** The return value is a struct. This type take a size. */
296 #define REMFNDESC_FLAGS_RET_STRUCT      3
297 /** The return type mask. */
298 #define REMFNDESC_FLAGS_RET_TYPE_MASK   7
299 /** The argument list contains one or more va_list arguments (i.e. problems). */
300 #define REMFNDESC_FLAGS_VALIST          RT_BIT(6)
301 /** The function has an ellipsis (i.e. a problem). */
302 #define REMFNDESC_FLAGS_ELLIPSIS        RT_BIT(7)
303 /** @} */
304
305 /**
306  * Chunk of read-write-executable memory.
307  */
308 typedef struct REMEXECMEM
309 {
310     /** The number of bytes left. */
311     struct REMEXECMEM  *pNext;
312     /** The size of this chunk. */
313     uint32_t            cb;
314     /** The offset of the next code block. */
315     uint32_t            off;
316 #if ARCH_BITS == 32
317     uint32_t            padding;
318 #endif
319 } REMEXECMEM, *PREMEXECMEM;
320
321
322 /*******************************************************************************
323 *   Global Variables                                                           *
324 *******************************************************************************/
325 #ifndef USE_REM_STUBS
326 /** Loader handle of the REM object/DLL. */
327 static RTLDRMOD g_ModREM2;
328 /** Pointer to the memory containing the loaded REM2 object/DLL. */
329 static void    *g_pvREM2;
330
331 /** Linux object export addresses.
332  * These are references from the assembly wrapper code.
333  * @{ */
334 static DECLCALLBACKPTR(int, pfnREMR3Init)(PVM);
335 static DECLCALLBACKPTR(int, pfnREMR3Term)(PVM);
336 static DECLCALLBACKPTR(void, pfnREMR3Reset)(PVM);
337 static DECLCALLBACKPTR(int, pfnREMR3Step)(PVM);
338 static DECLCALLBACKPTR(int, pfnREMR3BreakpointSet)(PVM, RTGCUINTPTR);
339 static DECLCALLBACKPTR(int, pfnREMR3BreakpointClear)(PVM, RTGCUINTPTR);
340 static DECLCALLBACKPTR(int, pfnREMR3EmulateInstruction)(PVM);
341 static DECLCALLBACKPTR(int, pfnREMR3Run)(PVM);
342 static DECLCALLBACKPTR(int, pfnREMR3State)(PVM);
343 static DECLCALLBACKPTR(int, pfnREMR3StateBack)(PVM);
344 static DECLCALLBACKPTR(void, pfnREMR3StateUpdate)(PVM);
345 static DECLCALLBACKPTR(void, pfnREMR3A20Set)(PVM, bool);
346 static DECLCALLBACKPTR(void, pfnREMR3ReplayInvalidatedPages)(PVM);
347 static DECLCALLBACKPTR(void, pfnREMR3ReplayHandlerNotifications)(PVM pVM);
348 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRamRegister)(PVM, RTGCPHYS, RTUINT, unsigned);
349 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRamChunkRegister)(PVM, RTGCPHYS, RTUINT, RTHCUINTPTR, unsigned);
350 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysReserve)(PVM, RTGCPHYS, RTUINT);
351 static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRomRegister)(PVM, RTGCPHYS, RTUINT, void *, bool);
352 static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalModify)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, RTGCPHYS, bool, bool);
353 static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalRegister)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, bool);
354 static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalDeregister)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, bool, bool);
355 static DECLCALLBACKPTR(void, pfnREMR3NotifyInterruptSet)(PVM);
356 static DECLCALLBACKPTR(void, pfnREMR3NotifyInterruptClear)(PVM);
357 static DECLCALLBACKPTR(void, pfnREMR3NotifyTimerPending)(PVM);
358 static DECLCALLBACKPTR(void, pfnREMR3NotifyDmaPending)(PVM);
359 static DECLCALLBACKPTR(void, pfnREMR3NotifyQueuePending)(PVM);
360 static DECLCALLBACKPTR(void, pfnREMR3NotifyFF)(PVM);
361 static DECLCALLBACKPTR(int, pfnREMR3NotifyCodePageChanged)(PVM, RTGCPTR);
362 static DECLCALLBACKPTR(void, pfnREMR3NotifyPendingInterrupt)(PVM, uint8_t);
363 static DECLCALLBACKPTR(uint32_t, pfnREMR3QueryPendingInterrupt)(PVM);
364 static DECLCALLBACKPTR(int, pfnREMR3DisasEnableStepping)(PVM, bool);
365 static DECLCALLBACKPTR(bool, pfnREMR3IsPageAccessHandled)(PVM, RTGCPHYS);
366 /** @} */
367
368 /** Export and import parameter descriptors.
369  * @{
370  */
371 /* Common args. */
372 static const REMPARMDESC g_aArgsSIZE_T[] =
373 {
374     { REMPARMDESC_FLAGS_INT,        sizeof(size_t) }
375 };
376 static const REMPARMDESC g_aArgsPTR[] =
377 {
378     { REMPARMDESC_FLAGS_INT,        sizeof(void *) }
379 };
380 static const REMPARMDESC g_aArgsVM[] =
381 {
382     { REMPARMDESC_FLAGS_INT,        sizeof(PVM) }
383 };
384
385 /* REM args */
386 static const REMPARMDESC g_aArgsBreakpoint[] =
387 {
388     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
389     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCUINTPTR), NULL }
390 };
391 static const REMPARMDESC g_aArgsA20Set[] =
392 {
393     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
394     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL }
395 };
396 static const REMPARMDESC g_aArgsNotifyPhysRamRegister[] =
397 {
398     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
399     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
400     { REMPARMDESC_FLAGS_INT,        sizeof(RTUINT), NULL },
401     { REMPARMDESC_FLAGS_INT,        sizeof(void *), NULL },
402     { REMPARMDESC_FLAGS_INT,        sizeof(unsigned), NULL }
403 };
404 static const REMPARMDESC g_aArgsNotifyPhysRamChunkRegister[] =
405 {
406     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
407     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
408     { REMPARMDESC_FLAGS_INT,        sizeof(RTUINT), NULL },
409     { REMPARMDESC_FLAGS_INT,        sizeof(RTHCUINTPTR), NULL },
410     { REMPARMDESC_FLAGS_INT,        sizeof(unsigned), NULL }
411 };
412 static const REMPARMDESC g_aArgsNotifyPhysReserve[] =
413 {
414     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
415     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
416     { REMPARMDESC_FLAGS_INT,        sizeof(RTUINT), NULL }
417 };
418 static const REMPARMDESC g_aArgsNotifyPhysRomRegister[] =
419 {
420     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
421     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
422     { REMPARMDESC_FLAGS_INT,        sizeof(RTUINT), NULL },
423     { REMPARMDESC_FLAGS_INT,        sizeof(void *), NULL },
424     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL }
425 };
426 static const REMPARMDESC g_aArgsNotifyHandlerPhysicalModify[] =
427 {
428     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
429     { REMPARMDESC_FLAGS_INT,        sizeof(PGMPHYSHANDLERTYPE), NULL },
430     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
431     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
432     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
433     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL },
434     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL }
435 };
436 static const REMPARMDESC g_aArgsNotifyHandlerPhysicalRegister[] =
437 {
438     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
439     { REMPARMDESC_FLAGS_INT,        sizeof(PGMPHYSHANDLERTYPE), NULL },
440     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
441     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
442     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL }
443 };
444 static const REMPARMDESC g_aArgsNotifyHandlerPhysicalDeregister[] =
445 {
446     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
447     { REMPARMDESC_FLAGS_INT,        sizeof(PGMPHYSHANDLERTYPE), NULL },
448     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
449     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
450     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL },
451     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL }
452 };
453 static const REMPARMDESC g_aArgsNotifyCodePageChanged[] =
454 {
455     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
456     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCUINTPTR), NULL }
457 };
458 static const REMPARMDESC g_aArgsNotifyPendingInterrupt[] =
459 {
460     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
461     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t), NULL }
462 };
463 static const REMPARMDESC g_aArgsDisasEnableStepping[] =
464 {
465     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
466     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL }
467 };
468 static const REMPARMDESC g_aArgsIsPageAccessHandled[] =
469 {
470     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
471     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL }
472 };
473
474
475 /* VMM args */
476 static const REMPARMDESC g_aArgsCPUMGetGuestCpl[] =
477 {
478     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
479     { REMPARMDESC_FLAGS_INT,        sizeof(PCPUMCTXCORE), NULL },
480 };
481
482 /* CPUMGetGuestMsr args */
483 static const REMPARMDESC g_aArgsCPUMGetGuestMsr[] =
484 {
485     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
486     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
487 };
488
489 /* CPUMGetGuestMsr args */
490 static const REMPARMDESC g_aArgsCPUMSetGuestMsr[] =
491 {
492     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
493     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
494     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL },
495 };
496
497 static const REMPARMDESC g_aArgsCPUMGetGuestCpuId[] =
498 {
499     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
500     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
501     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL },
502     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL },
503     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL },
504     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL }
505 };
506
507 static const REMPARMDESC g_aArgsCPUMSetChangedFlags[] =
508 {
509     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
510     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
511 };
512
513 static const REMPARMDESC g_aArgsCPUMQueryGuestCtxPtr[] =
514 {
515     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL }
516 };
517 static const REMPARMDESC g_aArgsCSAMR3MonitorPage[] =
518 {
519     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
520     { REMPARMDESC_FLAGS_INT,        sizeof(RTRCPTR), NULL },
521     { REMPARMDESC_FLAGS_INT,        sizeof(CSAMTAG), NULL }
522 };
523 static const REMPARMDESC g_aArgsCSAMR3UnmonitorPage[] =
524 {
525     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
526     { REMPARMDESC_FLAGS_INT,        sizeof(RTRCPTR), NULL },
527     { REMPARMDESC_FLAGS_INT,        sizeof(CSAMTAG), NULL }
528 };
529
530 static const REMPARMDESC g_aArgsCSAMR3RecordCallAddress[] =
531 {
532     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
533     { REMPARMDESC_FLAGS_INT,        sizeof(RTRCPTR), NULL }
534 };
535
536 #if defined(VBOX_WITH_DEBUGGER) && !(defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)) /* the callbacks are problematic */
537 static const REMPARMDESC g_aArgsDBGCRegisterCommands[] =
538 {
539     { REMPARMDESC_FLAGS_INT,        sizeof(PCDBGCCMD), NULL },
540     { REMPARMDESC_FLAGS_INT,        sizeof(unsigned), NULL }
541 };
542 #endif
543 static const REMPARMDESC g_aArgsDBGFR3DisasInstrEx[] =
544 {
545     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
546     { REMPARMDESC_FLAGS_INT,        sizeof(RTSEL), NULL },
547     { REMPARMDESC_FLAGS_INT,        sizeof(RTGCPTR), NULL },
548     { REMPARMDESC_FLAGS_INT,        sizeof(unsigned), NULL },
549     { REMPARMDESC_FLAGS_INT,        sizeof(char *), NULL },
550     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
551     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL }
552 };
553 static const REMPARMDESC g_aArgsDBGFR3Info[] =
554 {
555     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
556     { REMPARMDESC_FLAGS_INT,        sizeof(const char *), NULL },
557     { REMPARMDESC_FLAGS_INT,        sizeof(const char *), NULL },
558     { REMPARMDESC_FLAGS_INT,        sizeof(PCDBGFINFOHLP), NULL }
559 };
560 static const REMPARMDESC g_aArgsDBGFR3SymbolByAddr[] =
561 {
562     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
563     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCUINTPTR), NULL },
564     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCINTPTR), NULL },
565     { REMPARMDESC_FLAGS_INT,        sizeof(PDBGFSYMBOL), NULL }
566 };
567 static const REMPARMDESC g_aArgsDISInstr[] =
568 {
569     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
570     { REMPARMDESC_FLAGS_INT,        sizeof(RTUINTPTR), NULL },
571     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
572     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL },
573     { REMPARMDESC_FLAGS_INT,        sizeof(char *), NULL }
574 };
575 static const REMPARMDESC g_aArgsEMR3FatalError[] =
576 {
577     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
578     { REMPARMDESC_FLAGS_INT,        sizeof(int), NULL }
579 };
580 static const REMPARMDESC g_aArgsHWACCMR3CanExecuteGuest[] =
581 {
582     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
583     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
584     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
585     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
586 };
587 static const REMPARMDESC g_aArgsIOMIOPortRead[] =
588 {
589     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
590     { REMPARMDESC_FLAGS_INT,        sizeof(RTIOPORT), NULL },
591     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL },
592     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
593 };
594 static const REMPARMDESC g_aArgsIOMIOPortWrite[] =
595 {
596     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
597     { REMPARMDESC_FLAGS_INT,        sizeof(RTIOPORT), NULL },
598     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
599     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
600 };
601 static const REMPARMDESC g_aArgsIOMMMIORead[] =
602 {
603     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
604     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
605     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL },
606     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
607 };
608 static const REMPARMDESC g_aArgsIOMMMIOWrite[] =
609 {
610     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
611     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
612     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
613     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
614 };
615 static const REMPARMDESC g_aArgsMMR3HeapAlloc[] =
616 {
617     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
618     { REMPARMDESC_FLAGS_INT,        sizeof(MMTAG), NULL },
619     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
620 };
621 static const REMPARMDESC g_aArgsMMR3HeapAllocZ[] =
622 {
623     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
624     { REMPARMDESC_FLAGS_INT,        sizeof(MMTAG), NULL },
625     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
626 };
627 static const REMPARMDESC g_aArgsPATMIsPatchGCAddr[] =
628 {
629     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
630     { REMPARMDESC_FLAGS_INT,        sizeof(RTRCPTR), NULL }
631 };
632 static const REMPARMDESC g_aArgsPATMR3QueryOpcode[] =
633 {
634     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
635     { REMPARMDESC_FLAGS_INT,        sizeof(RTRCPTR), NULL },
636     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *), NULL }
637 };
638 static const REMPARMDESC g_aArgsPATMR3QueryPatchMem[] =
639 {
640     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
641     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t *), NULL }
642 };
643 #ifdef VBOX_WITH_VMI
644 static const REMPARMDESC g_aArgsPARAVIsBiosCall[] =
645 {
646     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
647     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCPTR), NULL },
648     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
649 };
650 #endif
651 static const REMPARMDESC g_aArgsPDMApicGetBase[] =
652 {
653     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
654     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t *), NULL }
655 };
656 static const REMPARMDESC g_aArgsPDMApicGetTPR[] =
657 {
658     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
659     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *), NULL },
660     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *), NULL }
661 };
662 static const REMPARMDESC g_aArgsPDMApicSetBase[] =
663 {
664     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
665     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL }
666 };
667 static const REMPARMDESC g_aArgsPDMApicSetTPR[] =
668 {
669     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
670     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t), NULL }
671 };
672 static const REMPARMDESC g_aArgsPDMApicWriteMSR[] =
673 {
674     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
675     { REMPARMDESC_FLAGS_INT,        sizeof(VMCPUID), NULL },
676     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
677     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL }
678 };
679 static const REMPARMDESC g_aArgsPDMApicReadMSR[] =
680 {
681     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
682     { REMPARMDESC_FLAGS_INT,        sizeof(VMCPUID), NULL },
683     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
684     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t *), NULL }
685 };
686 static const REMPARMDESC g_aArgsPDMGetInterrupt[] =
687 {
688     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
689     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *), NULL }
690 };
691 static const REMPARMDESC g_aArgsPDMIsaSetIrq[] =
692 {
693     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
694     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t), NULL },
695     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t), NULL }
696 };
697 static const REMPARMDESC g_aArgsPGMGetGuestMode[] =
698 {
699     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
700 };
701 static const REMPARMDESC g_aArgsPGMGstGetPage[] =
702 {
703     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
704     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCPTR), NULL },
705     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t *), NULL },
706     { REMPARMDESC_FLAGS_INT,        sizeof(PRTGCPHYS), NULL }
707 };
708 static const REMPARMDESC g_aArgsPGMInvalidatePage[] =
709 {
710     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
711     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCPTR), NULL }
712 };
713 static const REMPARMDESC g_aArgsPGMPhysGCPhys2R3Ptr[] =
714 {
715     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
716     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
717     { REMPARMDESC_FLAGS_INT,        sizeof(RTUINT), NULL },
718     { REMPARMDESC_FLAGS_INT,        sizeof(PRTR3PTR), NULL }
719 };
720 static const REMPARMDESC g_aArgsPGMPhysGCPtr2R3PtrByGstCR3[] =
721 {
722     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
723     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
724     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL },
725     { REMPARMDESC_FLAGS_INT,        sizeof(unsigned), NULL },
726     { REMPARMDESC_FLAGS_INT,        sizeof(PRTR3PTR), NULL }
727 };
728 static const REMPARMDESC g_aArgsPGM3PhysGrowRange[] =
729 {
730     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
731     { REMPARMDESC_FLAGS_INT,        sizeof(PCRTGCPHYS), NULL }
732 };
733 static const REMPARMDESC g_aArgsPGMPhysIsGCPhysValid[] =
734 {
735     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
736     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL }
737 };
738 static const REMPARMDESC g_aArgsPGMPhysRead[] =
739 {
740     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
741     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
742     { REMPARMDESC_FLAGS_INT,        sizeof(void *), NULL },
743     { REMPARMDESC_FLAGS_INT,        sizeof(size_t), NULL }
744 };
745 static const REMPARMDESC g_aArgsPGMPhysSimpleReadGCPtr[] =
746 {
747     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
748     { REMPARMDESC_FLAGS_INT,        sizeof(void *), NULL },
749     { REMPARMDESC_FLAGS_GCPTR,      sizeof(RTGCPTR), NULL },
750     { REMPARMDESC_FLAGS_INT,        sizeof(size_t), NULL }
751 };
752 static const REMPARMDESC g_aArgsPGMPhysWrite[] =
753 {
754     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
755     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
756     { REMPARMDESC_FLAGS_INT,        sizeof(const void *), NULL },
757     { REMPARMDESC_FLAGS_INT,        sizeof(size_t), NULL }
758 };
759 static const REMPARMDESC g_aArgsPGMChangeMode[] =
760 {
761     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
762     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL },
763     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL },
764     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL }
765 };
766 static const REMPARMDESC g_aArgsPGMFlushTLB[] =
767 {
768     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
769     { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL },
770     { REMPARMDESC_FLAGS_INT,        sizeof(bool), NULL }
771 };
772 static const REMPARMDESC g_aArgsPGMR3PhysReadUxx[] =
773 {
774     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
775     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL }
776 };
777 static const REMPARMDESC g_aArgsPGMR3PhysWriteU8[] =
778 {
779     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
780     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
781     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t), NULL }
782 };
783 static const REMPARMDESC g_aArgsPGMR3PhysWriteU16[] =
784 {
785     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
786     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
787     { REMPARMDESC_FLAGS_INT,        sizeof(uint16_t), NULL }
788 };
789 static const REMPARMDESC g_aArgsPGMR3PhysWriteU32[] =
790 {
791     { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
792     { REMPARMDESC_FLAGS_GCPHYS,     sizeof(RTGCPHYS), NULL },
793     { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL }
794 };
795 static const REMP