VirtualBox

source: vbox/trunk/src/recompiler/new/VBoxREMWrapper.cpp@ 1590

Last change on this file since 1590 was 1590, checked in by vboxsync, 18 years ago

Quick hack to only use physical addresses so we can dispense with the unnecessary address translation. It's all enabled by the DEFS += REM_PHYS_ADDR_IN_TLB statement in the Makefile.kmk. (Not tested with PGM_DYNAMIC_RAM_ALLOC yet, will do that tomorrow.)

  • Property svn:keywords set to Id
File size: 96.2 KB
Line 
1/* $Id: VBoxREMWrapper.cpp 1590 2007-03-21 02:58:53Z vboxsync $ */
2/** @file
3 *
4 * VBoxREM Win64 DLL Wrapper.
5 *
6 * InnoTek Systemberatung GmbH confidential
7 *
8 * Copyright (c) 2006 InnoTek Systemberatung GmbH
9 *
10 * Author: knut st. osmundsen <[email protected]>
11 *
12 * All Rights Reserved
13 *
14 */
15
16
17/** @page pg_vboxrem_amd64 VBoxREM Hacks on AMD64
18 *
19 * There are problems with building BoxREM both on WIN64 and 64-bit linux.
20 *
21 * On linux binutils refuses to link shared objects without -fPIC compiled code
22 * (bitches about some fixup types). But when trying to build with -fPIC dyngen
23 * doesn't like the code anymore. Sweet. The current solution is to build the
24 * VBoxREM code as a relocatable module and use our ELF loader to load it.
25 *
26 * On WIN64 we're not aware of any GCC port which can emit code using the MSC
27 * calling convention. So, we're in for some real fun here. The choice is between
28 * porting GCC to AMD64 WIN64 and comming up with some kind of wrapper around
29 * either the win32 build or the 64-bit linux build.
30 *
31 * -# Porting GCC will be a lot of work. For one thing the calling convention differs
32 * and messing with such stuff can easily create ugly bugs. We would also have to
33 * do some binutils changes, but I think those are rather small compared to GCC.
34 * (That said, the MSC calling convention is far simpler than the linux one, it
35 * reminds me of _Optlink which we have working already.)
36 * -# Wrapping win32 code will work, but addresses outside the first 4GB are
37 * inaccessible and we will have to create 32-64 thunks for all imported functions.
38 * (To switch between 32-bit and 64-bit is load the right CS using far jmps (32->64)
39 * or far returns (both).)
40 * -# Wrapping 64-bit linux code might be the easier solution. The requirements here
41 * are:
42 * - Remove all CRT references we possibly, either by using intrinsics or using
43 * IPRT. Part of IPRT will be linked into VBoxREM2.rel, this will be yet another
44 * IPRT mode which I've dubbed 'no-crt'. The no-crt mode provide basic non-system
45 * dependent stuff.
46 * - Compile and link it into a relocatable object (include the gcc intrinsics
47 * in libgcc). Call this VBoxREM2.rel.
48 * - Write a wrapper dll, VBoxREM.dll, for which during REMR3Init() will load
49 * VBoxREM2.rel (using IPRT) and generate calling convention wrappers
50 * for all IPRT functions and VBoxVMM functions that it uses. All exports
51 * will be wrapped vice versa.
52 * - For building on windows hosts, we will use a mingw32 hosted cross compiler.
53 * and add a 'no-crt' mode to IPRT where it provides the necessary CRT headers
54 * and function implementations.
55 *
56 * The 3rd solution will be tried out first since it requires the least effort and
57 * will let us make use of the full 64-bit register set.
58 *
59 *
60 *
61 * @section sec_vboxrem_amd64_compare Comparing the GCC and MSC calling conventions
62 *
63 * GCC expects the following (cut & past from page 20 in the ABI draft 0.96):
64 *
65 * %rax temporary register; with variable arguments passes information about the
66 * number of SSE registers used; 1st return register.
67 * [Not preserved]
68 * %rbx callee-saved register; optionally used as base pointer.
69 * [Preserved]
70 * %rcx used to pass 4th integer argument to functions.
71 * [Not preserved]
72 * %rdx used to pass 3rd argument to functions; 2nd return register
73 * [Not preserved]
74 * %rsp stack pointer
75 * [Preserved]
76 * %rbp callee-saved register; optionally used as frame pointer
77 * [Preserved]
78 * %rsi used to pass 2nd argument to functions
79 * [Not preserved]
80 * %rdi used to pass 1st argument to functions
81 * [Not preserved]
82 * %r8 used to pass 5th argument to functions
83 * [Not preserved]
84 * %r9 used to pass 6th argument to functions
85 * [Not preserved]
86 * %r10 temporary register, used for passing a function’s static chain pointer
87 * [Not preserved]
88 * %r11 temporary register
89 * [Not preserved]
90 * %r12-r15 callee-saved registers
91 * [Preserved]
92 * %xmm0–%xmm1 used to pass and return floating point arguments
93 * [Not preserved]
94 * %xmm2–%xmm7 used to pass floating point arguments
95 * [Not preserved]
96 * %xmm8–%xmm15 temporary registers
97 * [Not preserved]
98 * %mmx0–%mmx7 temporary registers
99 * [Not preserved]
100 * %st0 temporary register; used to return long double arguments
101 * [Not preserved]
102 * %st1 temporary registers; used to return long double arguments
103 * [Not preserved]
104 * %st2–%st7 temporary registers
105 * [Not preserved]
106 * %fs Reserved for system use (as thread specific data register)
107 * [Not preserved]
108 *
109 * Direction flag is preserved as cleared.
110 * The stack must be aligned on a 16-byte boundrary before the 'call/jmp' instruction.
111 *
112 *
113 *
114 * MSC expects the following:
115 * rax return value, not preserved.
116 * rbx preserved.
117 * rcx 1st argument, integer, not preserved.
118 * rdx 2nd argument, integer, not preserved.
119 * rbp preserved.
120 * rsp preserved.
121 * rsi preserved.
122 * rdi preserved.
123 * r8 3rd argument, integer, not preserved.
124 * r9 4th argument, integer, not preserved.
125 * r10 scratch register, not preserved.
126 * r11 scratch register, not preserved.
127 * r12-r15 preserved.
128 * xmm0 1st argument, fp, return value, not preserved.
129 * xmm1 2st argument, fp, not preserved.
130 * xmm2 3st argument, fp, not preserved.
131 * xmm3 4st argument, fp, not preserved.
132 * xmm4-xmm5 scratch, not preserved.
133 * xmm6-xmm15 preserved.
134 *
135 * Dunno what the direction flag is...
136 * The stack must be aligned on a 16-byte boundrary before the 'call/jmp' instruction.
137 *
138 *
139 * Thus, When GCC code is calling MSC code we don't really have to preserve
140 * anything. But but MSC code is calling GCC code, we'll have to save esi and edi.
141 *
142 */
143
144
145/*******************************************************************************
146* Defined Constants And Macros *
147*******************************************************************************/
148/** @def USE_REM_STUBS
149 * Define USE_REM_STUBS to stub the entire REM stuff. This is useful during
150 * early porting (before we start running stuff).
151 */
152#if defined(__DOXYGEN__)
153# define USE_REM_STUBS
154#endif
155
156/** @def USE_REM_CALLING_CONVENTION_GLUE
157 * Define USE_REM_CALLING_CONVENTION_GLUE for platforms where it's necessary to
158 * use calling convention wrappers.
159 */
160#if (defined(__AMD64__) && defined(__WIN__)) || defined(__DOXYGEN__)
161# define USE_REM_CALLING_CONVENTION_GLUE
162#endif
163
164/** @def USE_REM_IMPORT_JUMP_GLUE
165 * Define USE_REM_IMPORT_JUMP_GLUE for platforms where we need to
166 * emit some jump glue to deal with big addresses.
167 */
168#if (defined(__AMD64__) && !defined(USE_REM_CALLING_CONVENTION_GLUE) && !defined(__DARWIN__)) || defined(__DOXYGEN__)
169# define USE_REM_IMPORT_JUMP_GLUE
170#endif
171
172
173/*******************************************************************************
174* Header Files *
175*******************************************************************************/
176#define LOG_GROUP LOG_GROUP_REM
177#include <VBox/rem.h>
178#include <VBox/vmm.h>
179#include <VBox/dbgf.h>
180#include <VBox/dbg.h>
181#include <VBox/csam.h>
182#include <VBox/mm.h>
183#include <VBox/em.h>
184#include <VBox/ssm.h>
185#include <VBox/hwaccm.h>
186#include <VBox/patm.h>
187#include <VBox/pdm.h>
188#include <VBox/pgm.h>
189#include <VBox/iom.h>
190#include <VBox/vm.h>
191#include <VBox/err.h>
192#include <VBox/log.h>
193#include <VBox/dis.h>
194
195#include <iprt/alloc.h>
196#include <iprt/assert.h>
197#include <iprt/ldr.h>
198#include <iprt/param.h>
199#include <iprt/path.h>
200#include <iprt/string.h>
201#include <iprt/stream.h>
202
203
204/*******************************************************************************
205* Structures and Typedefs *
206*******************************************************************************/
207/**
208 * Parameter descriptor.
209 */
210typedef struct REMPARMDESC
211{
212 /** Parameter flags (REMPARMDESC_FLAGS_*). */
213 uint8_t fFlags;
214 /** The parameter size if REMPARMDESC_FLAGS_SIZE is set. */
215 uint8_t cb;
216} REMPARMDESC, *PREMPARMDESC;
217/** Pointer to a constant parameter descriptor. */
218typedef const REMPARMDESC *PCREMPARMDESC;
219
220/** @name Parameter descriptor flags.
221 * @{ */
222/** The parameter type is a kind of integer which could fit in a register. This includes pointers. */
223#define REMPARMDESC_FLAGS_INT 0
224/** The parameter is a GC pointer. */
225#define REMPARMDESC_FLAGS_GCPTR 1
226/** The parameter is a GC physical address. */
227#define REMPARMDESC_FLAGS_GCPHYS 2
228/** The parameter is a HC physical address. */
229#define REMPARMDESC_FLAGS_HCPHYS 3
230/** The parameter type is a kind of floating point. */
231#define REMPARMDESC_FLAGS_FLOAT 4
232/** The parameter value is a struct. This type takes a size. */
233#define REMPARMDESC_FLAGS_STRUCT 5
234/** The parameter is an elipsis. */
235#define REMPARMDESC_FLAGS_ELLIPSIS 6
236/** The parameter is a va_list. */
237#define REMPARMDESC_FLAGS_VALIST 7
238/** The parameter type mask. */
239#define REMPARMDESC_FLAGS_TYPE_MASK 7
240/** The parameter size field is valid. */
241#define REMPARMDESC_FLAGS_SIZE BIT(7)
242/** @} */
243
244/**
245 * Function descriptor.
246 */
247typedef struct REMFNDESC
248{
249 /** The function name. */
250 const char *pszName;
251 /** Exports: Pointer to the function pointer.
252 * Imports: Pointer to the function. */
253 void *pv;
254 /** Array of parameter descriptors. */
255 PCREMPARMDESC paParams;
256 /** The number of parameter descriptors pointed to by paParams. */
257 uint8_t cParams;
258 /** Function flags (REMFNDESC_FLAGS_*). */
259 uint8_t fFlags;
260 /** The size of the return value. */
261 uint8_t cbReturn;
262 /** Pointer to the wrapper code for imports. */
263 void *pvWrapper;
264} REMFNDESC, *PREMFNDESC;
265/** Pointer to a constant function descriptor. */
266typedef const REMFNDESC *PCREMFNDESC;
267
268/** @name Function descriptor flags.
269 * @{ */
270/** The return type is void. */
271#define REMFNDESC_FLAGS_RET_VOID 0
272/** The return type is a kind of integer passed in rax/eax. This includes pointers. */
273#define REMFNDESC_FLAGS_RET_INT 1
274/** The return type is a kind of floating point. */
275#define REMFNDESC_FLAGS_RET_FLOAT 2
276/** The return value is a struct. This type take a size. */
277#define REMFNDESC_FLAGS_RET_STRUCT 3
278/** The return type mask. */
279#define REMFNDESC_FLAGS_RET_TYPE_MASK 7
280/** The argument list contains one or more va_list arguments (i.e. problems). */
281#define REMFNDESC_FLAGS_VALIST BIT(6)
282/** The function has an ellipsis (i.e. a problem). */
283#define REMFNDESC_FLAGS_ELLIPSIS BIT(7)
284/** @} */
285
286/**
287 * Chunk of read-write-executable memory.
288 */
289typedef struct REMEXECMEM
290{
291 /** The number of bytes left. */
292 struct REMEXECMEM *pNext;
293 /** The size of this chunk. */
294 uint32_t cb;
295 /** The offset of the next code block. */
296 uint32_t off;
297#if ARCH_BITS == 32
298 uint32_t padding;
299#endif
300} REMEXECMEM, *PREMEXECMEM;
301
302
303/*******************************************************************************
304* Global Variables *
305*******************************************************************************/
306#ifndef USE_REM_STUBS
307/** Loader handle of the REM object/DLL. */
308static RTLDRMOD g_ModREM2;
309/** Pointer to the memory containing the loaded REM2 object/DLL. */
310static void *g_pvREM2;
311
312/** Linux object export addresses.
313 * These are references from the assembly wrapper code.
314 * @{ */
315static DECLCALLBACKPTR(int, pfnREMR3Init)(PVM);
316static DECLCALLBACKPTR(int, pfnREMR3Term)(PVM);
317static DECLCALLBACKPTR(void, pfnREMR3Reset)(PVM);
318static DECLCALLBACKPTR(int, pfnREMR3Step)(PVM);
319static DECLCALLBACKPTR(int, pfnREMR3BreakpointSet)(PVM, RTGCUINTPTR);
320static DECLCALLBACKPTR(int, pfnREMR3BreakpointClear)(PVM, RTGCUINTPTR);
321static DECLCALLBACKPTR(int, pfnREMR3EmulateInstruction)(PVM);
322static DECLCALLBACKPTR(int, pfnREMR3Run)(PVM);
323static DECLCALLBACKPTR(int, pfnREMR3State)(PVM);
324static DECLCALLBACKPTR(int, pfnREMR3StateBack)(PVM);
325static DECLCALLBACKPTR(void, pfnREMR3StateUpdate)(PVM);
326static DECLCALLBACKPTR(void, pfnREMR3A20Set)(PVM, bool);
327static DECLCALLBACKPTR(void, pfnREMR3ReplayInvalidatedPages)(PVM);
328static DECLCALLBACKPTR(void, pfnREMR3ReplayHandlerNotifications)(PVM pVM);
329static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRamRegister)(PVM, RTGCPHYS, RTUINT, void *, unsigned);
330static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRamChunkRegister)(PVM, RTGCPHYS, RTUINT, RTHCUINTPTR, unsigned);
331static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysReserve)(PVM, RTGCPHYS, RTUINT);
332static DECLCALLBACKPTR(void, pfnREMR3NotifyPhysRomRegister)(PVM, RTGCPHYS, RTUINT, void *);
333static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalModify)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, RTGCPHYS, bool, void *);
334static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalRegister)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, bool);
335static DECLCALLBACKPTR(void, pfnREMR3NotifyHandlerPhysicalDeregister)(PVM, PGMPHYSHANDLERTYPE, RTGCPHYS, RTGCPHYS, bool, void *);
336static DECLCALLBACKPTR(void, pfnREMR3NotifyInterruptSet)(PVM);
337static DECLCALLBACKPTR(void, pfnREMR3NotifyInterruptClear)(PVM);
338static DECLCALLBACKPTR(void, pfnREMR3NotifyTimerPending)(PVM);
339static DECLCALLBACKPTR(void, pfnREMR3NotifyDmaPending)(PVM);
340static DECLCALLBACKPTR(void, pfnREMR3NotifyQueuePending)(PVM);
341static DECLCALLBACKPTR(void, pfnREMR3NotifyFF)(PVM);
342static DECLCALLBACKPTR(int, pfnREMR3NotifyCodePageChanged)(PVM, RTGCPTR);
343static DECLCALLBACKPTR(void, pfnREMR3NotifyPendingInterrupt)(PVM, uint8_t);
344static DECLCALLBACKPTR(uint32_t, pfnREMR3QueryPendingInterrupt)(PVM);
345static DECLCALLBACKPTR(int, pfnREMR3DisasEnableStepping)(PVM, bool);
346static DECLCALLBACKPTR(bool, pfnREMR3IsPageAccessHandled)(PVM, RTGCPHYS);
347/** @} */
348
349/** Export and import parameter descriptors.
350 * @{
351 */
352/* Common args. */
353static const REMPARMDESC g_aArgsSIZE_T[] =
354{
355 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
356};
357static const REMPARMDESC g_aArgsPTR[] =
358{
359 { REMPARMDESC_FLAGS_INT, sizeof(void *) }
360};
361static const REMPARMDESC g_aArgsVM[] =
362{
363 { REMPARMDESC_FLAGS_INT, sizeof(PVM) }
364};
365
366/* REM args */
367static const REMPARMDESC g_aArgsBreakpoint[] =
368{
369 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
370 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINTPTR) }
371};
372static const REMPARMDESC g_aArgsA20Set[] =
373{
374 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
375 { REMPARMDESC_FLAGS_INT, sizeof(bool) }
376};
377static const REMPARMDESC g_aArgsNotifyPhysRamRegister[] =
378{
379 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
380 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
381 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) },
382 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
383 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) }
384};
385static const REMPARMDESC g_aArgsNotifyPhysRamChunkRegister[] =
386{
387 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
388 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
389 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) },
390 { REMPARMDESC_FLAGS_INT, sizeof(RTHCUINTPTR) },
391 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) }
392};
393static const REMPARMDESC g_aArgsNotifyPhysReserve[] =
394{
395 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
396 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
397 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) }
398};
399static const REMPARMDESC g_aArgsNotifyPhysRomRegister[] =
400{
401 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
402 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
403 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) },
404 { REMPARMDESC_FLAGS_INT, sizeof(void *) }
405};
406static const REMPARMDESC g_aArgsNotifyHandlerPhysicalModify[] =
407{
408 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
409 { REMPARMDESC_FLAGS_INT, sizeof(PGMPHYSHANDLERTYPE) },
410 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
411 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
412 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
413 { REMPARMDESC_FLAGS_INT, sizeof(bool) },
414 { REMPARMDESC_FLAGS_INT, sizeof(void *) }
415};
416static const REMPARMDESC g_aArgsNotifyHandlerPhysicalRegister[] =
417{
418 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
419 { REMPARMDESC_FLAGS_INT, sizeof(PGMPHYSHANDLERTYPE) },
420 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
421 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
422 { REMPARMDESC_FLAGS_INT, sizeof(bool) }
423};
424static const REMPARMDESC g_aArgsNotifyHandlerPhysicalDeregister[] =
425{
426 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
427 { REMPARMDESC_FLAGS_INT, sizeof(PGMPHYSHANDLERTYPE) },
428 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
429 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
430 { REMPARMDESC_FLAGS_INT, sizeof(bool) },
431 { REMPARMDESC_FLAGS_INT, sizeof(void *) }
432};
433static const REMPARMDESC g_aArgsNotifyCodePageChanged[] =
434{
435 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
436 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINTPTR) }
437};
438static const REMPARMDESC g_aArgsNotifyPendingInterrupt[] =
439{
440 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
441 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) }
442};
443static const REMPARMDESC g_aArgsDisasEnableStepping[] =
444{
445 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
446 { REMPARMDESC_FLAGS_INT, sizeof(bool) }
447};
448static const REMPARMDESC g_aArgsIsPageAccessHandled[] =
449{
450 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
451 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) }
452};
453
454
455/* VMM args */
456static const REMPARMDESC g_aArgsCPUMGetGuestCpuId[] =
457{
458 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
459 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
460 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
461 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
462 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
463 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
464};
465static const REMPARMDESC g_aArgsCPUMQueryGuestCtxPtr[] =
466{
467 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
468 { REMPARMDESC_FLAGS_INT, sizeof(PCPUMCTX *) }
469};
470static const REMPARMDESC g_aArgsCSAMR3MonitorPage[] =
471{
472 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
473 { REMPARMDESC_FLAGS_INT, sizeof(RTGCPTR) },
474 { REMPARMDESC_FLAGS_INT, sizeof(CSAMTAG) }
475};
476static const REMPARMDESC g_aArgsDBGCRegisterCommands[] =
477{
478 { REMPARMDESC_FLAGS_INT, sizeof(PCDBGCCMD) },
479 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) }
480};
481static const REMPARMDESC g_aArgsDBGFR3DisasInstrEx[] =
482{
483 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
484 { REMPARMDESC_FLAGS_INT, sizeof(RTSEL) },
485 { REMPARMDESC_FLAGS_INT, sizeof(RTGCPTR) },
486 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
487 { REMPARMDESC_FLAGS_INT, sizeof(char *) },
488 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
489 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
490};
491static const REMPARMDESC g_aArgsDBGFR3Info[] =
492{
493 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
494 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
495 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
496 { REMPARMDESC_FLAGS_INT, sizeof(PCDBGFINFOHLP) }
497};
498static const REMPARMDESC g_aArgsDBGFR3SymbolByAddr[] =
499{
500 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
501 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINTPTR) },
502 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCINTPTR) },
503 { REMPARMDESC_FLAGS_INT, sizeof(PDBGFSYMBOL) }
504};
505static const REMPARMDESC g_aArgsDISInstr[] =
506{
507 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
508 { REMPARMDESC_FLAGS_INT, sizeof(RTUINTPTR) },
509 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
510 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
511 { REMPARMDESC_FLAGS_INT, sizeof(char *) }
512};
513static const REMPARMDESC g_aArgsEMR3FatalError[] =
514{
515 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
516 { REMPARMDESC_FLAGS_INT, sizeof(int) }
517};
518static const REMPARMDESC g_aArgsHWACCMR3CanExecuteGuest[] =
519{
520 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
521 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
522 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
523 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
524};
525static const REMPARMDESC g_aArgsIOMIOPortRead[] =
526{
527 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
528 { REMPARMDESC_FLAGS_INT, sizeof(RTIOPORT) },
529 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
530 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
531};
532static const REMPARMDESC g_aArgsIOMIOPortWrite[] =
533{
534 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
535 { REMPARMDESC_FLAGS_INT, sizeof(RTIOPORT) },
536 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
537 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
538};
539static const REMPARMDESC g_aArgsIOMMMIORead[] =
540{
541 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
542 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
543 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
544 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
545};
546static const REMPARMDESC g_aArgsIOMMMIOWrite[] =
547{
548 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
549 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
550 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
551 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
552};
553static const REMPARMDESC g_aArgsMMR3HeapAlloc[] =
554{
555 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
556 { REMPARMDESC_FLAGS_INT, sizeof(MMTAG) },
557 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
558};
559static const REMPARMDESC g_aArgsMMR3HeapAllocZ[] =
560{
561 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
562 { REMPARMDESC_FLAGS_INT, sizeof(MMTAG) },
563 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
564};
565static const REMPARMDESC g_aArgsPATMIsPatchGCAddr[] =
566{
567 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
568 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) }
569};
570static const REMPARMDESC g_aArgsPATMR3QueryOpcode[] =
571{
572 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
573 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) },
574 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) }
575};
576static const REMPARMDESC g_aArgsPATMR3QueryPatchMem[] =
577{
578 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
579 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
580};
581static const REMPARMDESC g_aArgsPDMApicGetBase[] =
582{
583 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
584 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t *) }
585};
586static const REMPARMDESC g_aArgsPDMApicGetTPR[] =
587{
588 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
589 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) }
590};
591static const REMPARMDESC g_aArgsPDMApicSetBase[] =
592{
593 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
594 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t) }
595};
596static const REMPARMDESC g_aArgsPDMApicSetTPR[] =
597{
598 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
599 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) }
600};
601static const REMPARMDESC g_aArgsPDMGetInterrupt[] =
602{
603 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
604 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) }
605};
606static const REMPARMDESC g_aArgsPDMIsaSetIrq[] =
607{
608 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
609 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) },
610 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) }
611};
612static const REMPARMDESC g_aArgsPGMGstGetPage[] =
613{
614 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
615 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) },
616 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t *) },
617 { REMPARMDESC_FLAGS_INT, sizeof(PRTGCPHYS) }
618};
619static const REMPARMDESC g_aArgsPGMInvalidatePage[] =
620{
621 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
622 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) }
623};
624static const REMPARMDESC g_aArgsPGMPhysGCPhys2HCPtr[] =
625{
626 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
627 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
628 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) },
629 { REMPARMDESC_FLAGS_INT, sizeof(PRTHCPTR) }
630};
631static const REMPARMDESC g_aArgsPGMPhysGCPtr2HCPtrByGstCR3[] =
632{
633 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
634 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
635 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
636 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
637 { REMPARMDESC_FLAGS_INT, sizeof(PRTHCPTR) }
638};
639static const REMPARMDESC g_aArgsPGM3PhysGrowRange[] =
640{
641 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
642 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) }
643};
644static const REMPARMDESC g_aArgsPGMPhysIsGCPhysValid[] =
645{
646 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
647 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) }
648};
649static const REMPARMDESC g_aArgsPGMPhysRead[] =
650{
651 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
652 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
653 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
654 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
655};
656static const REMPARMDESC g_aArgsPGMPhysReadGCPtr[] =
657{
658 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
659 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
660 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) },
661 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
662};
663static const REMPARMDESC g_aArgsPGMPhysWrite[] =
664{
665 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
666 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
667 { REMPARMDESC_FLAGS_INT, sizeof(const void *) },
668 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
669};
670static const REMPARMDESC g_aArgsPGMChangeMode[] =
671{
672 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
673 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
674 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
675 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t) }
676};
677static const REMPARMDESC g_aArgsPGMFlushTLB[] =
678{
679 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
680 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
681 { REMPARMDESC_FLAGS_INT, sizeof(bool) }
682};
683static const REMPARMDESC g_aArgsPGMR3PhysReadUxx[] =
684{
685 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
686 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) }
687};
688static const REMPARMDESC g_aArgsPGMR3PhysWriteU8[] =
689{
690 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
691 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
692 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) }
693};
694static const REMPARMDESC g_aArgsPGMR3PhysWriteU16[] =
695{
696 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
697 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
698 { REMPARMDESC_FLAGS_INT, sizeof(uint16_t) }
699};
700static const REMPARMDESC g_aArgsPGMR3PhysWriteU32[] =
701{
702 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
703 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
704 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
705};
706static const REMPARMDESC g_aArgsPGMR3PhysWriteU64[] =
707{
708 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
709 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
710 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t) }
711};
712static const REMPARMDESC g_aArgsSSMR3GetGCPtr[] =
713{
714 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
715 { REMPARMDESC_FLAGS_INT, sizeof(PRTGCPTR) }
716};
717static const REMPARMDESC g_aArgsSSMR3GetMem[] =
718{
719 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
720 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
721 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
722};
723static const REMPARMDESC g_aArgsSSMR3GetU32[] =
724{
725 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
726 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
727};
728static const REMPARMDESC g_aArgsSSMR3GetUInt[] =
729{
730 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
731 { REMPARMDESC_FLAGS_INT, sizeof(PRTUINT) }
732};
733static const REMPARMDESC g_aArgsSSMR3PutGCPtr[] =
734{
735 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
736 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) }
737};
738static const REMPARMDESC g_aArgsSSMR3PutMem[] =
739{
740 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
741 { REMPARMDESC_FLAGS_INT, sizeof(const void *) },
742 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
743};
744static const REMPARMDESC g_aArgsSSMR3PutU32[] =
745{
746 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
747 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
748};
749static const REMPARMDESC g_aArgsSSMR3PutUInt[] =
750{
751 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
752 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) },
753};
754static const REMPARMDESC g_aArgsSSMR3RegisterInternal[] =
755{
756 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
757 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
758 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
759 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
760 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
761 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTSAVEPREP) },
762 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTSAVEEXEC) },
763 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTSAVEDONE) },
764 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTLOADPREP) },
765 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTLOADEXEC) },
766 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTLOADDONE) },
767};
768static const REMPARMDESC g_aArgsSTAMR3Register[] =
769{
770 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
771 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
772 { REMPARMDESC_FLAGS_INT, sizeof(STAMTYPE) },
773 { REMPARMDESC_FLAGS_INT, sizeof(STAMVISIBILITY) },
774 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
775 { REMPARMDESC_FLAGS_INT, sizeof(STAMUNIT) },
776 { REMPARMDESC_FLAGS_INT, sizeof(const char *) }
777};
778static const REMPARMDESC g_aArgsTRPMAssertTrap[] =
779{
780 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
781 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) },
782 { REMPARMDESC_FLAGS_INT, sizeof(bool) }
783};
784static const REMPARMDESC g_aArgsTRPMQueryTrap[] =
785{
786 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
787 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) },
788 { REMPARMDESC_FLAGS_INT, sizeof(bool *) }
789};
790static const REMPARMDESC g_aArgsTRPMSetErrorCode[] =
791{
792 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
793 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINT) }
794};
795static const REMPARMDESC g_aArgsTRPMSetFaultAddress[] =
796{
797 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
798 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINT) }
799};
800static const REMPARMDESC g_aArgsVMR3ReqCall[] =
801{
802 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
803 { REMPARMDESC_FLAGS_INT, sizeof(PVMREQ *) },
804 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
805 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
806 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
807 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
808};
809static const REMPARMDESC g_aArgsVMR3ReqFree[] =
810{
811 { REMPARMDESC_FLAGS_INT, sizeof(PVMREQ) }
812};
813
814
815/* IPRT args */
816static const REMPARMDESC g_aArgsAssertMsg1[] =
817{
818 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
819 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
820 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
821 { REMPARMDESC_FLAGS_INT, sizeof(const char *) }
822};
823static const REMPARMDESC g_aArgsAssertMsg2[] =
824{
825 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
826 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
827};
828static const REMPARMDESC g_aArgsRTLogFlags[] =
829{
830 { REMPARMDESC_FLAGS_INT, sizeof(PRTLOGGER) },
831 { REMPARMDESC_FLAGS_INT, sizeof(const char *) }
832};
833static const REMPARMDESC g_aArgsRTLogLoggerEx[] =
834{
835 { REMPARMDESC_FLAGS_INT, sizeof(PRTLOGGER) },
836 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
837 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
838 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
839 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
840};
841static const REMPARMDESC g_aArgsRTLogLoggerExV[] =
842{
843 { REMPARMDESC_FLAGS_INT, sizeof(PRTLOGGER) },
844 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
845 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
846 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
847 { REMPARMDESC_FLAGS_VALIST, 0 }
848};
849static const REMPARMDESC g_aArgsRTLogPrintf[] =
850{
851 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
852 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
853};
854static const REMPARMDESC g_aArgsRTMemProtect[] =
855{
856 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
857 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
858 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) }
859};
860static const REMPARMDESC g_aArgsRTStrPrintf[] =
861{
862 { REMPARMDESC_FLAGS_INT, sizeof(char *) },
863 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
864 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
865 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
866};
867static const REMPARMDESC g_aArgsRTStrPrintfV[] =
868{
869 { REMPARMDESC_FLAGS_INT, sizeof(char *) },
870 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
871 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
872 { REMPARMDESC_FLAGS_VALIST, 0 }
873};
874
875
876/* CRT args */
877static const REMPARMDESC g_aArgsmemcpy[] =
878{
879 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
880 { REMPARMDESC_FLAGS_INT, sizeof(const void *) },
881 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
882};
883static const REMPARMDESC g_aArgsmemset[] =
884{
885 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
886 { REMPARMDESC_FLAGS_INT, sizeof(int) },
887 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
888};
889
890
891/** @} */
892
893/**
894 * Descriptors for the exported functions.
895 */
896static const REMFNDESC g_aExports[] =
897{ /* pszName, (void *)pv, pParams, cParams, fFlags, cb, pvWrapper. */
898 { "REMR3Init", (void *)&pfnREMR3Init, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
899 { "REMR3Term", (void *)&pfnREMR3Term, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
900 { "REMR3Reset", (void *)&pfnREMR3Reset, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
901 { "REMR3Step", (void *)&pfnREMR3Step, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
902 { "REMR3BreakpointSet", (void *)&pfnREMR3BreakpointSet, &g_aArgsBreakpoint[0], ELEMENTS(g_aArgsBreakpoint), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
903 { "REMR3BreakpointClear", (void *)&pfnREMR3BreakpointClear, &g_aArgsBreakpoint[0], ELEMENTS(g_aArgsBreakpoint), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
904 { "REMR3EmulateInstruction", (void *)&pfnREMR3EmulateInstruction, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
905 { "REMR3Run", (void *)&pfnREMR3Run, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
906 { "REMR3State", (void *)&pfnREMR3State, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
907 { "REMR3StateBack", (void *)&pfnREMR3StateBack, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
908 { "REMR3StateUpdate", (void *)&pfnREMR3StateUpdate, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
909 { "REMR3A20Set", (void *)&pfnREMR3A20Set, &g_aArgsA20Set[0], ELEMENTS(g_aArgsA20Set), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
910 { "REMR3ReplayInvalidatedPages", (void *)&pfnREMR3ReplayInvalidatedPages, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
911 { "REMR3ReplayHandlerNotifications", (void *)&pfnREMR3ReplayHandlerNotifications, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
912 { "REMR3NotifyPhysRamRegister", (void *)&pfnREMR3NotifyPhysRamRegister, &g_aArgsNotifyPhysRamRegister[0], ELEMENTS(g_aArgsNotifyPhysRamRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
913 { "REMR3NotifyPhysRamChunkRegister", (void *)&pfnREMR3NotifyPhysRamChunkRegister, &g_aArgsNotifyPhysRamChunkRegister[0], ELEMENTS(g_aArgsNotifyPhysRamChunkRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
914 { "REMR3NotifyPhysReserve", (void *)&pfnREMR3NotifyPhysReserve, &g_aArgsNotifyPhysReserve[0], ELEMENTS(g_aArgsNotifyPhysReserve), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
915 { "REMR3NotifyPhysRomRegister", (void *)&pfnREMR3NotifyPhysRomRegister, &g_aArgsNotifyPhysRomRegister[0], ELEMENTS(g_aArgsNotifyPhysRomRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
916 { "REMR3NotifyHandlerPhysicalModify", (void *)&pfnREMR3NotifyHandlerPhysicalModify, &g_aArgsNotifyHandlerPhysicalModify[0], ELEMENTS(g_aArgsNotifyHandlerPhysicalModify), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
917 { "REMR3NotifyHandlerPhysicalRegister", (void *)&pfnREMR3NotifyHandlerPhysicalRegister, &g_aArgsNotifyHandlerPhysicalRegister[0], ELEMENTS(g_aArgsNotifyHandlerPhysicalRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
918 { "REMR3NotifyHandlerPhysicalDeregister", (void *)&pfnREMR3NotifyHandlerPhysicalDeregister, &g_aArgsNotifyHandlerPhysicalDeregister[0], ELEMENTS(g_aArgsNotifyHandlerPhysicalDeregister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
919 { "REMR3NotifyInterruptSet", (void *)&pfnREMR3NotifyInterruptSet, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
920 { "REMR3NotifyInterruptClear", (void *)&pfnREMR3NotifyInterruptClear, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
921 { "REMR3NotifyTimerPending", (void *)&pfnREMR3NotifyTimerPending, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
922 { "REMR3NotifyDmaPending", (void *)&pfnREMR3NotifyDmaPending, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
923 { "REMR3NotifyQueuePending", (void *)&pfnREMR3NotifyQueuePending, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
924 { "REMR3NotifyFF", (void *)&pfnREMR3NotifyFF, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
925 { "REMR3NotifyCodePageChanged", (void *)&pfnREMR3NotifyCodePageChanged, &g_aArgsNotifyCodePageChanged[0], ELEMENTS(g_aArgsNotifyCodePageChanged), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
926 { "REMR3NotifyPendingInterrupt", (void *)&pfnREMR3NotifyPendingInterrupt, &g_aArgsNotifyPendingInterrupt[0], ELEMENTS(g_aArgsNotifyPendingInterrupt), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
927 { "REMR3QueryPendingInterrupt", (void *)&pfnREMR3QueryPendingInterrupt, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
928 { "REMR3DisasEnableStepping", (void *)&pfnREMR3DisasEnableStepping, &g_aArgsDisasEnableStepping[0], ELEMENTS(g_aArgsDisasEnableStepping), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
929 { "REMR3IsPageAccessHandled", (void *)&pfnREMR3IsPageAccessHandled, &g_aArgsIsPageAccessHandled[0], ELEMENTS(g_aArgsIsPageAccessHandled), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL }
930};
931
932
933/**
934 * Descriptors for the functions imported from VBoxVMM.
935 */
936static REMFNDESC g_aVMMImports[] =
937{
938 { "CPUMGetAndClearChangedFlagsREM", (void *)(uintptr_t)&CPUMGetAndClearChangedFlagsREM, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(unsigned), NULL },
939 { "CPUMGetGuestCpuId", (void *)(uintptr_t)&CPUMGetGuestCpuId, &g_aArgsCPUMGetGuestCpuId[0], ELEMENTS(g_aArgsCPUMGetGuestCpuId), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
940 { "CPUMGetGuestEAX", (void *)(uintptr_t)&CPUMGetGuestEAX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
941 { "CPUMGetGuestEBP", (void *)(uintptr_t)&CPUMGetGuestEBP, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
942 { "CPUMGetGuestEBX", (void *)(uintptr_t)&CPUMGetGuestEBX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
943 { "CPUMGetGuestECX", (void *)(uintptr_t)&CPUMGetGuestECX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
944 { "CPUMGetGuestEDI", (void *)(uintptr_t)&CPUMGetGuestEDI, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
945 { "CPUMGetGuestEDX", (void *)(uintptr_t)&CPUMGetGuestEDX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
946 { "CPUMGetGuestEIP", (void *)(uintptr_t)&CPUMGetGuestEIP, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
947 { "CPUMGetGuestESI", (void *)(uintptr_t)&CPUMGetGuestESI, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
948 { "CPUMGetGuestESP", (void *)(uintptr_t)&CPUMGetGuestESP, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
949 { "CPUMQueryGuestCtxPtr", (void *)(uintptr_t)&CPUMQueryGuestCtxPtr, &g_aArgsCPUMQueryGuestCtxPtr[0], ELEMENTS(g_aArgsCPUMQueryGuestCtxPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
950 { "CSAMR3MonitorPage", (void *)(uintptr_t)&CSAMR3MonitorPage, &g_aArgsCSAMR3MonitorPage[0], ELEMENTS(g_aArgsCSAMR3MonitorPage), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
951 { "DBGCRegisterCommands", (void *)(uintptr_t)&DBGCRegisterCommands, &g_aArgsDBGCRegisterCommands[0], ELEMENTS(g_aArgsDBGCRegisterCommands), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
952 { "DBGFR3DisasInstrEx", (void *)(uintptr_t)&DBGFR3DisasInstrEx, &g_aArgsDBGFR3DisasInstrEx[0], ELEMENTS(g_aArgsDBGFR3DisasInstrEx), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
953 { "DBGFR3Info", (void *)(uintptr_t)&DBGFR3Info, &g_aArgsDBGFR3Info[0], ELEMENTS(g_aArgsDBGFR3Info), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
954 { "DBGFR3InfoLogRelHlp", (void *)(uintptr_t)&DBGFR3InfoLogRelHlp, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
955 { "DBGFR3SymbolByAddr", (void *)(uintptr_t)&DBGFR3SymbolByAddr, &g_aArgsDBGFR3SymbolByAddr[0], ELEMENTS(g_aArgsDBGFR3SymbolByAddr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
956 { "DISInstr", (void *)(uintptr_t)&DISInstr, &g_aArgsDISInstr[0], ELEMENTS(g_aArgsDISInstr), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
957 { "EMR3FatalError", (void *)(uintptr_t)&EMR3FatalError, &g_aArgsEMR3FatalError[0], ELEMENTS(g_aArgsEMR3FatalError), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
958 { "HWACCMR3CanExecuteGuest", (void *)(uintptr_t)&HWACCMR3CanExecuteGuest, &g_aArgsHWACCMR3CanExecuteGuest[0], ELEMENTS(g_aArgsHWACCMR3CanExecuteGuest), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
959 { "IOMIOPortRead", (void *)(uintptr_t)&IOMIOPortRead, &g_aArgsIOMIOPortRead[0], ELEMENTS(g_aArgsIOMIOPortRead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
960 { "IOMIOPortWrite", (void *)(uintptr_t)&IOMIOPortWrite, &g_aArgsIOMIOPortWrite[0], ELEMENTS(g_aArgsIOMIOPortWrite), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
961 { "IOMMMIORead", (void *)(uintptr_t)&IOMMMIORead, &g_aArgsIOMMMIORead[0], ELEMENTS(g_aArgsIOMMMIORead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
962 { "IOMMMIOWrite", (void *)(uintptr_t)&IOMMMIOWrite, &g_aArgsIOMMMIOWrite[0], ELEMENTS(g_aArgsIOMMMIOWrite), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
963 { "MMR3HeapAlloc", (void *)(uintptr_t)&MMR3HeapAlloc, &g_aArgsMMR3HeapAlloc[0], ELEMENTS(g_aArgsMMR3HeapAlloc), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
964 { "MMR3HeapAllocZ", (void *)(uintptr_t)&MMR3HeapAllocZ, &g_aArgsMMR3HeapAllocZ[0], ELEMENTS(g_aArgsMMR3HeapAllocZ), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
965 { "MMR3PhysGetRamSize", (void *)(uintptr_t)&MMR3PhysGetRamSize, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL },
966 { "PATMIsPatchGCAddr", (void *)(uintptr_t)&PATMIsPatchGCAddr, &g_aArgsPATMIsPatchGCAddr[0], ELEMENTS(g_aArgsPATMIsPatchGCAddr), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
967 { "PATMR3QueryOpcode", (void *)(uintptr_t)&PATMR3QueryOpcode, &g_aArgsPATMR3QueryOpcode[0], ELEMENTS(g_aArgsPATMR3QueryOpcode), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
968 { "PATMR3QueryPatchMemGC", (void *)(uintptr_t)&PATMR3QueryPatchMemGC, &g_aArgsPATMR3QueryPatchMem[0], ELEMENTS(g_aArgsPATMR3QueryPatchMem), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCPTR), NULL },
969 { "PATMR3QueryPatchMemHC", (void *)(uintptr_t)&PATMR3QueryPatchMemHC, &g_aArgsPATMR3QueryPatchMem[0], ELEMENTS(g_aArgsPATMR3QueryPatchMem), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
970 { "PDMApicGetBase", (void *)(uintptr_t)&PDMApicGetBase, &g_aArgsPDMApicGetBase[0], ELEMENTS(g_aArgsPDMApicGetBase), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
971 { "PDMApicGetTPR", (void *)(uintptr_t)&PDMApicGetTPR, &g_aArgsPDMApicGetTPR[0], ELEMENTS(g_aArgsPDMApicGetTPR), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
972 { "PDMApicSetBase", (void *)(uintptr_t)&PDMApicSetBase, &g_aArgsPDMApicSetBase[0], ELEMENTS(g_aArgsPDMApicSetBase), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
973 { "PDMApicSetTPR", (void *)(uintptr_t)&PDMApicSetTPR, &g_aArgsPDMApicSetTPR[0], ELEMENTS(g_aArgsPDMApicSetTPR), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
974 { "PDMR3DmaRun", (void *)(uintptr_t)&PDMR3DmaRun, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
975 { "PDMGetInterrupt", (void *)(uintptr_t)&PDMGetInterrupt, &g_aArgsPDMGetInterrupt[0], ELEMENTS(g_aArgsPDMGetInterrupt), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
976 { "PDMIsaSetIrq", (void *)(uintptr_t)&PDMIsaSetIrq, &g_aArgsPDMIsaSetIrq[0], ELEMENTS(g_aArgsPDMIsaSetIrq), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
977 { "PGMGstGetPage", (void *)(uintptr_t)&PGMGstGetPage, &g_aArgsPGMGstGetPage[0], ELEMENTS(g_aArgsPGMGstGetPage), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
978 { "PGMInvalidatePage", (void *)(uintptr_t)&PGMInvalidatePage, &g_aArgsPGMInvalidatePage[0], ELEMENTS(g_aArgsPGMInvalidatePage), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
979 { "PGMPhysGCPhys2HCPtr", (void *)(uintptr_t)&PGMPhysGCPhys2HCPtr, &g_aArgsPGMPhysGCPhys2HCPtr[0], ELEMENTS(g_aArgsPGMPhysGCPhys2HCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
980 { "PGMPhysGCPtr2HCPtrByGstCR3", (void *)(uintptr_t)&PGMPhysGCPtr2HCPtrByGstCR3, &g_aArgsPGMPhysGCPtr2HCPtrByGstCR3[0], ELEMENTS(g_aArgsPGMPhysGCPtr2HCPtrByGstCR3), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
981 { "PGM3PhysGrowRange", (void *)(uintptr_t)&PGM3PhysGrowRange, &g_aArgsPGM3PhysGrowRange[0], ELEMENTS(g_aArgsPGM3PhysGrowRange), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
982 { "PGMPhysIsGCPhysValid", (void *)(uintptr_t)&PGMPhysIsGCPhysValid, &g_aArgsPGMPhysIsGCPhysValid[0], ELEMENTS(g_aArgsPGMPhysIsGCPhysValid), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
983 { "PGMPhysIsA20Enabled", (void *)(uintptr_t)&PGMPhysIsA20Enabled, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
984 { "PGMPhysRead", (void *)(uintptr_t)&PGMPhysRead, &g_aArgsPGMPhysRead[0], ELEMENTS(g_aArgsPGMPhysRead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
985 { "PGMPhysReadGCPtr", (void *)(uintptr_t)&PGMPhysReadGCPtr, &g_aArgsPGMPhysReadGCPtr[0], ELEMENTS(g_aArgsPGMPhysReadGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
986 { "PGMPhysReadGCPtr", (void *)(uintptr_t)&PGMPhysReadGCPtr, &g_aArgsPGMPhysReadGCPtr[0], ELEMENTS(g_aArgsPGMPhysReadGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
987 { "PGMPhysWrite", (void *)(uintptr_t)&PGMPhysWrite, &g_aArgsPGMPhysWrite[0], ELEMENTS(g_aArgsPGMPhysWrite), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
988 { "PGMChangeMode", (void *)(uintptr_t)&PGMChangeMode, &g_aArgsPGMChangeMode[0], ELEMENTS(g_aArgsPGMChangeMode), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
989 { "PGMFlushTLB", (void *)(uintptr_t)&PGMFlushTLB, &g_aArgsPGMFlushTLB[0], ELEMENTS(g_aArgsPGMFlushTLB), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
990 { "PGMR3PhysReadByte", (void *)(uintptr_t)&PGMR3PhysReadByte, &g_aArgsPGMR3PhysReadUxx[0], ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint8_t), NULL },
991 { "PGMR3PhysReadDword", (void *)(uintptr_t)&PGMR3PhysReadDword, &g_aArgsPGMR3PhysReadUxx[0], ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
992 { "PGMR3PhysReadWord", (void *)(uintptr_t)&PGMR3PhysReadWord, &g_aArgsPGMR3PhysReadUxx[0], ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint16_t), NULL },
993 { "PGMR3PhysWriteByte", (void *)(uintptr_t)&PGMR3PhysWriteByte, &g_aArgsPGMR3PhysWriteU8[0], ELEMENTS(g_aArgsPGMR3PhysWriteU8), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
994 { "PGMR3PhysWriteDword", (void *)(uintptr_t)&PGMR3PhysWriteDword, &g_aArgsPGMR3PhysWriteU32[0], ELEMENTS(g_aArgsPGMR3PhysWriteU32), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
995 { "PGMR3PhysWriteWord", (void *)(uintptr_t)&PGMR3PhysWriteWord, &g_aArgsPGMR3PhysWriteU16[0], ELEMENTS(g_aArgsPGMR3PhysWriteU16), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
996 { "SSMR3GetGCPtr", (void *)(uintptr_t)&SSMR3GetGCPtr, &g_aArgsSSMR3GetGCPtr[0], ELEMENTS(g_aArgsSSMR3GetGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
997 { "SSMR3GetMem", (void *)(uintptr_t)&SSMR3GetMem, &g_aArgsSSMR3GetMem[0], ELEMENTS(g_aArgsSSMR3GetMem), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
998 { "SSMR3GetU32", (void *)(uintptr_t)&SSMR3GetU32, &g_aArgsSSMR3GetU32[0], ELEMENTS(g_aArgsSSMR3GetU32), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
999 { "SSMR3GetUInt", (void *)(uintptr_t)&SSMR3GetUInt, &g_aArgsSSMR3GetUInt[0], ELEMENTS(g_aArgsSSMR3GetUInt), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1000 { "SSMR3PutGCPtr", (void *)(uintptr_t)&SSMR3PutGCPtr, &g_aArgsSSMR3PutGCPtr[0], ELEMENTS(g_aArgsSSMR3PutGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1001 { "SSMR3PutMem", (void *)(uintptr_t)&SSMR3PutMem, &g_aArgsSSMR3PutMem[0], ELEMENTS(g_aArgsSSMR3PutMem), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1002 { "SSMR3PutU32", (void *)(uintptr_t)&SSMR3PutU32, &g_aArgsSSMR3PutU32[0], ELEMENTS(g_aArgsSSMR3PutU32), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1003 { "SSMR3PutUInt", (void *)(uintptr_t)&SSMR3PutUInt, &g_aArgsSSMR3PutUInt[0], ELEMENTS(g_aArgsSSMR3PutUInt), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1004 { "SSMR3RegisterInternal", (void *)(uintptr_t)&SSMR3RegisterInternal, &g_aArgsSSMR3RegisterInternal[0], ELEMENTS(g_aArgsSSMR3RegisterInternal), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1005 { "STAMR3Register", (void *)(uintptr_t)&STAMR3Register, &g_aArgsSTAMR3Register[0], ELEMENTS(g_aArgsSTAMR3Register), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1006 { "TMCpuTickGet", (void *)(uintptr_t)&TMCpuTickGet, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL },
1007 { "TMCpuTickPause", (void *)(uintptr_t)&TMCpuTickPause, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1008 { "TMCpuTickResume", (void *)(uintptr_t)&TMCpuTickResume, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1009 { "TMTimerPoll", (void *)(uintptr_t)&TMTimerPoll, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL },
1010 { "TMR3TimerQueuesDo", (void *)(uintptr_t)&TMR3TimerQueuesDo, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1011 { "TMVirtualPause", (void *)(uintptr_t)&TMVirtualPause, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1012 { "TMVirtualResume", (void *)(uintptr_t)&TMVirtualResume, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1013 { "TRPMAssertTrap", (void *)(uintptr_t)&TRPMAssertTrap, &g_aArgsTRPMAssertTrap[0], ELEMENTS(g_aArgsTRPMAssertTrap), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1014 { "TRPMGetErrorCode", (void *)(uintptr_t)&TRPMGetErrorCode, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCUINT), NULL },
1015 { "TRPMGetFaultAddress", (void *)(uintptr_t)&TRPMGetFaultAddress, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCUINTPTR),NULL },
1016 { "TRPMQueryTrap", (void *)(uintptr_t)&TRPMQueryTrap, &g_aArgsTRPMQueryTrap[0], ELEMENTS(g_aArgsTRPMQueryTrap), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1017 { "TRPMResetTrap", (void *)(uintptr_t)&TRPMResetTrap, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1018 { "TRPMSetErrorCode", (void *)(uintptr_t)&TRPMSetErrorCode, &g_aArgsTRPMSetErrorCode[0], ELEMENTS(g_aArgsTRPMSetErrorCode), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1019 { "TRPMSetFaultAddress", (void *)(uintptr_t)&TRPMSetFaultAddress, &g_aArgsTRPMSetFaultAddress[0], ELEMENTS(g_aArgsTRPMSetFaultAddress), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1020 { "VMMR3Lock", (void *)(uintptr_t)&VMMR3Lock, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1021 { "VMMR3Unlock", (void *)(uintptr_t)&VMMR3Unlock, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1022 { "VMR3ReqCall", (void *)(uintptr_t)&VMR3ReqCall, &g_aArgsVMR3ReqCall[0], ELEMENTS(g_aArgsVMR3ReqCall), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1023 { "VMR3ReqFree", (void *)(uintptr_t)&VMR3ReqFree, &g_aArgsVMR3ReqFree[0], ELEMENTS(g_aArgsVMR3ReqFree), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_ELLIPSIS, sizeof(int), NULL },
1024// { "", (void *)(uintptr_t)&, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1025};
1026
1027
1028/**
1029 * Descriptors for the functions imported from VBoxRT.
1030 */
1031static REMFNDESC g_aRTImports[] =
1032{
1033 { "AssertMsg1", (void *)(uintptr_t)&AssertMsg1, &g_aArgsAssertMsg1[0], ELEMENTS(g_aArgsAssertMsg1), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1034 { "AssertMsg2", (void *)(uintptr_t)&AssertMsg2, &g_aArgsAssertMsg2[0], ELEMENTS(g_aArgsAssertMsg2), REMFNDESC_FLAGS_RET_VOID | REMFNDESC_FLAGS_ELLIPSIS, 0, NULL },
1035 { "RTAssertDoBreakpoint", (void *)(uintptr_t)&RTAssertDoBreakpoint, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
1036 { "RTLogDefaultInstance", (void *)(uintptr_t)&RTLogDefaultInstance, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(PRTLOGGER), NULL },
1037 { "RTLogRelDefaultInstance", (void *)(uintptr_t)&RTLogRelDefaultInstance, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(PRTLOGGER), NULL },
1038 { "RTLogFlags", (void *)(uintptr_t)&RTLogFlags, &g_aArgsRTLogFlags[0], ELEMENTS(g_aArgsRTLogFlags), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1039 { "RTLogLoggerEx", (void *)(uintptr_t)&RTLogLoggerEx, &g_aArgsRTLogLoggerEx[0], ELEMENTS(g_aArgsRTLogLoggerEx), REMFNDESC_FLAGS_RET_VOID | REMFNDESC_FLAGS_ELLIPSIS, 0, NULL },
1040 { "RTLogLoggerExV", (void *)(uintptr_t)&RTLogLoggerExV, &g_aArgsRTLogLoggerExV[0], ELEMENTS(g_aArgsRTLogLoggerExV), REMFNDESC_FLAGS_RET_VOID | REMFNDESC_FLAGS_VALIST, 0, NULL },
1041 { "RTLogPrintf", (void *)(uintptr_t)&RTLogPrintf, &g_aArgsRTLogPrintf[0], ELEMENTS(g_aArgsRTLogPrintf), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1042 { "RTMemAlloc", (void *)(uintptr_t)&RTMemAlloc, &g_aArgsSIZE_T[0], ELEMENTS(g_aArgsSIZE_T), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1043 { "RTMemExecAlloc", (void *)(uintptr_t)&RTMemExecAlloc, &g_aArgsSIZE_T[0], ELEMENTS(g_aArgsSIZE_T), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1044 { "RTMemExecFree", (void *)(uintptr_t)&RTMemExecFree, &g_aArgsPTR[0], ELEMENTS(g_aArgsPTR), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1045 { "RTMemFree", (void *)(uintptr_t)&RTMemFree, &g_aArgsPTR[0], ELEMENTS(g_aArgsPTR), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1046 { "RTMemPageAlloc", (void *)(uintptr_t)&RTMemPageAlloc, &g_aArgsSIZE_T[0], ELEMENTS(g_aArgsSIZE_T), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1047 { "RTMemPageFree", (void *)(uintptr_t)&RTMemPageFree, &g_aArgsPTR[0], ELEMENTS(g_aArgsPTR), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1048 { "RTMemProtect", (void *)(uintptr_t)&RTMemProtect, &g_aArgsRTMemProtect[0], ELEMENTS(g_aArgsRTMemProtect), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1049 { "RTStrPrintf", (void *)(uintptr_t)&RTStrPrintf, &g_aArgsRTStrPrintf[0], ELEMENTS(g_aArgsRTStrPrintf), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_ELLIPSIS, sizeof(size_t), NULL },
1050 { "RTStrPrintfV", (void *)(uintptr_t)&RTStrPrintfV, &g_aArgsRTStrPrintfV[0], ELEMENTS(g_aArgsRTStrPrintfV), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_VALIST, sizeof(size_t), NULL },
1051 { "RTThreadNativeSelf", (void *)(uintptr_t)&RTThreadNativeSelf, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(RTNATIVETHREAD), NULL },
1052};
1053
1054
1055/**
1056 * Descriptors for the functions imported from VBoxRT.
1057 */
1058static REMFNDESC g_aCRTImports[] =
1059{
1060 { "memcpy", (void *)(uintptr_t)&memcpy, &g_aArgsmemcpy[0], ELEMENTS(g_aArgsmemcpy), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1061 { "memset", (void *)(uintptr_t)&memset, &g_aArgsmemset[0], ELEMENTS(g_aArgsmemset), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL }
1062/*
1063floor floor
1064memcpy memcpy
1065sqrt sqrt
1066sqrtf sqrtf
1067*/
1068};
1069
1070
1071# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1072/** LIFO of read-write-executable memory chunks used for wrappers. */
1073static PREMEXECMEM g_pExecMemHead;
1074# endif
1075
1076
1077/*******************************************************************************
1078* Internal Functions *
1079*******************************************************************************/
1080# ifdef USE_REM_CALLING_CONVENTION_GLUE
1081DECLASM(int) WrapGCC2MSC0Int(void); DECLASM(int) WrapGCC2MSC0Int_EndProc(void);
1082DECLASM(int) WrapGCC2MSC1Int(void); DECLASM(int) WrapGCC2MSC1Int_EndProc(void);
1083DECLASM(int) WrapGCC2MSC2Int(void); DECLASM(int) WrapGCC2MSC2Int_EndProc(void);
1084DECLASM(int) WrapGCC2MSC3Int(void); DECLASM(int) WrapGCC2MSC3Int_EndProc(void);
1085DECLASM(int) WrapGCC2MSC4Int(void); DECLASM(int) WrapGCC2MSC4Int_EndProc(void);
1086DECLASM(int) WrapGCC2MSC5Int(void); DECLASM(int) WrapGCC2MSC5Int_EndProc(void);
1087DECLASM(int) WrapGCC2MSC6Int(void); DECLASM(int) WrapGCC2MSC6Int_EndProc(void);
1088DECLASM(int) WrapGCC2MSC7Int(void); DECLASM(int) WrapGCC2MSC7Int_EndProc(void);
1089DECLASM(int) WrapGCC2MSC8Int(void); DECLASM(int) WrapGCC2MSC8Int_EndProc(void);
1090DECLASM(int) WrapGCC2MSC9Int(void); DECLASM(int) WrapGCC2MSC9Int_EndProc(void);
1091DECLASM(int) WrapGCC2MSC10Int(void); DECLASM(int) WrapGCC2MSC10Int_EndProc(void);
1092DECLASM(int) WrapGCC2MSC11Int(void); DECLASM(int) WrapGCC2MSC11Int_EndProc(void);
1093DECLASM(int) WrapGCC2MSC12Int(void); DECLASM(int) WrapGCC2MSC12Int_EndProc(void);
1094DECLASM(int) WrapGCC2MSCVariadictInt(void); DECLASM(int) WrapGCC2MSCVariadictInt_EndProc(void);
1095
1096DECLASM(int) WrapMSC2GCC0Int(void); DECLASM(int) WrapMSC2GCC0Int_EndProc(void);
1097DECLASM(int) WrapMSC2GCC1Int(void); DECLASM(int) WrapMSC2GCC1Int_EndProc(void);
1098DECLASM(int) WrapMSC2GCC2Int(void); DECLASM(int) WrapMSC2GCC2Int_EndProc(void);
1099DECLASM(int) WrapMSC2GCC3Int(void); DECLASM(int) WrapMSC2GCC3Int_EndProc(void);
1100DECLASM(int) WrapMSC2GCC4Int(void); DECLASM(int) WrapMSC2GCC4Int_EndProc(void);
1101DECLASM(int) WrapMSC2GCC5Int(void); DECLASM(int) WrapMSC2GCC5Int_EndProc(void);
1102DECLASM(int) WrapMSC2GCC6Int(void); DECLASM(int) WrapMSC2GCC6Int_EndProc(void);
1103DECLASM(int) WrapMSC2GCC7Int(void); DECLASM(int) WrapMSC2GCC7Int_EndProc(void);
1104DECLASM(int) WrapMSC2GCC8Int(void); DECLASM(int) WrapMSC2GCC8Int_EndProc(void);
1105DECLASM(int) WrapMSC2GCC9Int(void); DECLASM(int) WrapMSC2GCC9Int_EndProc(void);
1106# endif
1107
1108
1109# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1110/**
1111 * Allocates a block of memory for glue code.
1112 *
1113 * The returned memory is padded with INT3s.
1114 *
1115 * @returns Pointer to the allocated memory.
1116 * @param The amount of memory to allocate.
1117 */
1118static void *remAllocGlue(size_t cb)
1119{
1120 PREMEXECMEM pCur = g_pExecMemHead;
1121 uint32_t cbAligned = (uint32_t)RT_ALIGN_32(cb, 32);
1122 while (pCur)
1123 {
1124 if (pCur->cb - pCur->off >= cbAligned)
1125 {
1126 void *pv = (uint8_t *)pCur + pCur->off;
1127 pCur->off += cbAligned;
1128 return memset(pv, 0xcc, cbAligned);
1129 }
1130 pCur = pCur->pNext;
1131 }
1132
1133 /* add a new chunk */
1134 AssertReturn(_64K - RT_ALIGN_Z(sizeof(*pCur), 32) > cbAligned, NULL);
1135 pCur = (PREMEXECMEM)RTMemExecAlloc(_64K);
1136 AssertReturn(pCur, NULL);
1137 pCur->cb = _64K;
1138 pCur->off = RT_ALIGN_32(sizeof(*pCur), 32) + cbAligned;
1139 pCur->pNext = g_pExecMemHead;
1140 g_pExecMemHead = pCur;
1141 return memset((uint8_t *)pCur + RT_ALIGN_Z(sizeof(*pCur), 32), 0xcc, cbAligned);
1142}
1143# endif /* USE_REM_CALLING_CONVENTION_GLUE || USE_REM_IMPORT_JUMP_GLUE */
1144
1145
1146# ifdef USE_REM_CALLING_CONVENTION_GLUE
1147/**
1148 * Checks if a function is all straight forward integers.
1149 *
1150 * @returns True if it's simple, false if it's bothersome.
1151 * @param pDesc The function descriptor.
1152 */
1153static bool remIsFunctionAllInts(PCREMFNDESC pDesc)
1154{
1155 if ( ( (pDesc->fFlags & REMFNDESC_FLAGS_RET_TYPE_MASK) != REMFNDESC_FLAGS_RET_INT
1156 || pDesc->cbReturn > sizeof(uint64_t))
1157 && (pDesc->fFlags & REMFNDESC_FLAGS_RET_TYPE_MASK) != REMFNDESC_FLAGS_RET_VOID)
1158 return false;
1159 unsigned i = pDesc->cParams;
1160 while (i-- > 0)
1161 switch (pDesc->paParams[i].fFlags & REMPARMDESC_FLAGS_TYPE_MASK)
1162 {
1163 case REMPARMDESC_FLAGS_INT:
1164 case REMPARMDESC_FLAGS_GCPTR:
1165 case REMPARMDESC_FLAGS_GCPHYS:
1166 case REMPARMDESC_FLAGS_HCPHYS:
1167 break;
1168
1169 default:
1170 AssertReleaseMsgFailed(("Invalid param flags %#x for #%d of %s!\n", pDesc->paParams[i].fFlags, i, pDesc->pszName));
1171 case REMPARMDESC_FLAGS_VALIST:
1172 case REMPARMDESC_FLAGS_ELLIPSIS:
1173 case REMPARMDESC_FLAGS_FLOAT:
1174 case REMPARMDESC_FLAGS_STRUCT:
1175 return false;
1176 }
1177 return true;
1178}
1179
1180
1181/**
1182 * Checks if the function has an ellipsis (...) argument.
1183 *
1184 * @returns true if it has an ellipsis, otherwise false.
1185 * @param pDesc The function descriptor.
1186 */
1187static bool remHasFunctionEllipsis(PCREMFNDESC pDesc)
1188{
1189 unsigned i = pDesc->cParams;
1190 while (i-- > 0)
1191 if ((pDesc->paParams[i].fFlags & REMPARMDESC_FLAGS_TYPE_MASK) == REMPARMDESC_FLAGS_ELLIPSIS)
1192 return true;
1193 return false;
1194}
1195
1196
1197/**
1198 * Checks if the function uses floating point (FP) arguments or return value.
1199 *
1200 * @returns true if it uses floating point, otherwise false.
1201 * @param pDesc The function descriptor.
1202 */
1203static bool remIsFunctionUsingFP(PCREMFNDESC pDesc)
1204{
1205 if ((pDesc->fFlags & REMFNDESC_FLAGS_RET_TYPE_MASK) == REMFNDESC_FLAGS_RET_FLOAT)
1206 return true;
1207 unsigned i = pDesc->cParams;
1208 while (i-- > 0)
1209 if ((pDesc->paParams[i].fFlags & REMPARMDESC_FLAGS_TYPE_MASK) == REMPARMDESC_FLAGS_FLOAT)
1210 return true;
1211 return false;
1212}
1213
1214
1215/**
1216 * Fixes export glue.
1217 *
1218 * @param pvGlue The glue code.
1219 * @param cb The size of the glue code.
1220 * @param pvExport The address of the export we're wrapping.
1221 * @param pDesc The export descriptor.
1222 */
1223static void remGenerateExportGlueFixup(void *pvGlue, size_t cb, uintptr_t uExport, PCREMFNDESC pDesc)
1224{
1225 union
1226 {
1227 uint8_t *pu8;
1228 int32_t *pi32;
1229 uint32_t *pu32;
1230 uint64_t *pu64;
1231 void *pv;
1232 } u;
1233 u.pv = pvGlue;
1234
1235 while (cb >= 4)
1236 {
1237 if (*u.pu32 == 0xdeadbeef)
1238 {
1239 /* 32-bit rel jmp/call to real export. */
1240 *u.pi32 = uExport - (uintptr_t)(u.pi32 + 1);
1241 Assert((uintptr_t)(u.pi32 + 1) + *u.pi32 == uExport);
1242 u.pi32++;
1243 cb -= 4;
1244 continue;
1245 }
1246 if (cb >= 8 && *u.pu64 == UINT64_C(0xdeadf00df00ddead))
1247 {
1248 /* 64-bit address to the real export. */
1249 *u.pu64++ = uExport;
1250 cb -= 8;
1251 continue;
1252 }
1253
1254 /* move on. */
1255 u.pu8++;
1256 cb--;
1257 }
1258}
1259
1260
1261/**
1262 * Fixes import glue.
1263 *
1264 * @param pvGlue The glue code.
1265 * @param cb The size of the glue code.
1266 * @param pDesc The import descriptor.
1267 */
1268static void remGenerateImportGlueFixup(void *pvGlue, size_t cb, PCREMFNDESC pDesc)
1269{
1270 union
1271 {
1272 uint8_t *pu8;
1273 int32_t *pi32;
1274 uint32_t *pu32;
1275 uint64_t *pu64;
1276 void *pv;
1277 } u;
1278 u.pv = pvGlue;
1279
1280 while (cb >= 4)
1281 {
1282 if (*u.pu32 == 0xdeadbeef)
1283 {
1284 /* 32-bit rel jmp/call to real function. */
1285 *u.pi32 = (uintptr_t)pDesc->pv - (uintptr_t)(u.pi32 + 1);
1286 Assert((uintptr_t)(u.pi32 + 1) + *u.pi32 == (uintptr_t)pDesc->pv);
1287 u.pi32++;
1288 cb -= 4;
1289 continue;
1290 }
1291 if (cb >= 8 && *u.pu64 == UINT64_C(0xdeadf00df00ddead))
1292 {
1293 /* 64-bit address to the real function. */
1294 *u.pu64++ = (uintptr_t)pDesc->pv;
1295 cb -= 8;
1296 continue;
1297 }
1298
1299 /* move on. */
1300 u.pu8++;
1301 cb--;
1302 }
1303}
1304
1305# endif /* USE_REM_CALLING_CONVENTION_GLUE */
1306
1307
1308/**
1309 * Generate wrapper glue code for an export.
1310 *
1311 * This is only used on win64 when loading a 64-bit linux module. So, on other
1312 * platforms it will not do anything.
1313 *
1314 * @returns VBox status code.
1315 * @param pValue IN: Where to get the address of the function to wrap.
1316 * OUT: Where to store the glue address.
1317 * @param pDesc The export descriptor.
1318 */
1319static int remGenerateExportGlue(PRTUINTPTR pValue, PCREMFNDESC pDesc)
1320{
1321# ifdef USE_REM_CALLING_CONVENTION_GLUE
1322 uintptr_t *ppfn = (uintptr_t *)pDesc->pv;
1323 if (!*ppfn)
1324 {
1325 if (remIsFunctionAllInts(pDesc))
1326 {
1327 static const struct { void *pvStart, *pvEnd; } s_aTemplates[] =
1328 {
1329 { (void *)&WrapMSC2GCC0Int, (void *)&WrapMSC2GCC0Int_EndProc },
1330 { (void *)&WrapMSC2GCC1Int, (void *)&WrapMSC2GCC1Int_EndProc },
1331 { (void *)&WrapMSC2GCC2Int, (void *)&WrapMSC2GCC2Int_EndProc },
1332 { (void *)&WrapMSC2GCC3Int, (void *)&WrapMSC2GCC3Int_EndProc },
1333 { (void *)&WrapMSC2GCC4Int, (void *)&WrapMSC2GCC4Int_EndProc },
1334 { (void *)&WrapMSC2GCC5Int, (void *)&WrapMSC2GCC5Int_EndProc },
1335 { (void *)&WrapMSC2GCC6Int, (void *)&WrapMSC2GCC6Int_EndProc },
1336 { (void *)&WrapMSC2GCC7Int, (void *)&WrapMSC2GCC7Int_EndProc },
1337 { (void *)&WrapMSC2GCC8Int, (void *)&WrapMSC2GCC8Int_EndProc },
1338 { (void *)&WrapMSC2GCC9Int, (void *)&WrapMSC2GCC9Int_EndProc },
1339 };
1340 const unsigned i = pDesc->cParams;
1341 AssertReleaseMsg(i < ELEMENTS(s_aTemplates), ("%d (%s)\n", i, pDesc->pszName));
1342
1343 /* duplicate the patch. */
1344 const size_t cb = (uintptr_t)s_aTemplates[i].pvEnd - (uintptr_t)s_aTemplates[i].pvStart;
1345 uint8_t *pb = (uint8_t *)remAllocGlue(cb);
1346 AssertReturn(pb, VERR_NO_MEMORY);
1347 memcpy(pb, s_aTemplates[i].pvStart, cb);
1348
1349 /* fix it up. */
1350 remGenerateExportGlueFixup(pb, cb, *pValue, pDesc);
1351 *ppfn = (uintptr_t)pb;
1352 }
1353 else
1354 {
1355 /* annoying stuff, later. */
1356#if 1
1357 AssertReleaseMsgFailed(("Not implemented! %s\n", pDesc->pszName));
1358 return VERR_NOT_IMPLEMENTED;
1359#else
1360 AssertMsg2("annoying: %s\n", pDesc->pszName);
1361 uint8_t *pb;
1362 pb = (uint8_t *)remAllocGlue(3);
1363 AssertReturn(pb, VERR_NO_MEMORY);
1364 *pb++ = 0xcc;
1365 *pb++ = 0x90;
1366 *pb++ = 0xc3;
1367 *ppfn = (uintptr_t)pb;
1368#endif
1369 }
1370 }
1371 *pValue = *ppfn;
1372 return VINF_SUCCESS;
1373# else /* !USE_REM_CALLING_CONVENTION_GLUE */
1374 return VINF_SUCCESS;
1375# endif /* !USE_REM_CALLING_CONVENTION_GLUE */
1376}
1377
1378
1379/**
1380 * Generate wrapper glue code for an import.
1381 *
1382 * This is only used on win64 when loading a 64-bit linux module. So, on other
1383 * platforms it will simply return the address of the imported function
1384 * without generating any glue code.
1385 *
1386 * @returns VBox status code.
1387 * @param pValue Where to store the glue address.
1388 * @param pDesc The export descriptor.
1389 */
1390static int remGenerateImportGlue(PRTUINTPTR pValue, PREMFNDESC pDesc)
1391{
1392# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1393 if (!pDesc->pvWrapper)
1394 {
1395# ifdef USE_REM_CALLING_CONVENTION_GLUE
1396 if (remIsFunctionAllInts(pDesc))
1397 {
1398 static const struct { void *pvStart, *pvEnd; } s_aTemplates[] =
1399 {
1400 { (void *)&WrapGCC2MSC0Int, (void *)&WrapGCC2MSC0Int_EndProc },
1401 { (void *)&WrapGCC2MSC1Int, (void *)&WrapGCC2MSC1Int_EndProc },
1402 { (void *)&WrapGCC2MSC2Int, (void *)&WrapGCC2MSC2Int_EndProc },
1403 { (void *)&WrapGCC2MSC3Int, (void *)&WrapGCC2MSC3Int_EndProc },
1404 { (void *)&WrapGCC2MSC4Int, (void *)&WrapGCC2MSC4Int_EndProc },
1405 { (void *)&WrapGCC2MSC5Int, (void *)&WrapGCC2MSC5Int_EndProc },
1406 { (void *)&WrapGCC2MSC6Int, (void *)&WrapGCC2MSC6Int_EndProc },
1407 { (void *)&WrapGCC2MSC7Int, (void *)&WrapGCC2MSC7Int_EndProc },
1408 { (void *)&WrapGCC2MSC8Int, (void *)&WrapGCC2MSC8Int_EndProc },
1409 { (void *)&WrapGCC2MSC9Int, (void *)&WrapGCC2MSC9Int_EndProc },
1410 { (void *)&WrapGCC2MSC10Int, (void *)&WrapGCC2MSC10Int_EndProc },
1411 { (void *)&WrapGCC2MSC11Int, (void *)&WrapGCC2MSC11Int_EndProc },
1412 { (void *)&WrapGCC2MSC12Int, (void *)&WrapGCC2MSC12Int_EndProc }
1413 };
1414 const unsigned i = pDesc->cParams;
1415 AssertReleaseMsg(i < ELEMENTS(s_aTemplates), ("%d (%s)\n", i, pDesc->pszName));
1416
1417 /* duplicate the patch. */
1418 const size_t cb = (uintptr_t)s_aTemplates[i].pvEnd - (uintptr_t)s_aTemplates[i].pvStart;
1419 pDesc->pvWrapper = remAllocGlue(cb);
1420 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1421 memcpy(pDesc->pvWrapper, s_aTemplates[i].pvStart, cb);
1422
1423 /* fix it up. */
1424 remGenerateImportGlueFixup((uint8_t *)pDesc->pvWrapper, cb, pDesc);
1425 }
1426 else if ( remHasFunctionEllipsis(pDesc)
1427 && !remIsFunctionUsingFP(pDesc))
1428 {
1429 /* duplicate the patch. */
1430 const size_t cb = (uintptr_t)&WrapGCC2MSCVariadictInt_EndProc - (uintptr_t)&WrapGCC2MSCVariadictInt;
1431 pDesc->pvWrapper = remAllocGlue(cb);
1432 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1433 memcpy(pDesc->pvWrapper, (void *)&WrapGCC2MSCVariadictInt, cb);
1434
1435 /* fix it up. */
1436 remGenerateImportGlueFixup((uint8_t *)pDesc->pvWrapper, cb, pDesc);
1437 }
1438 else
1439 {
1440 /* annoying stuff, later. */
1441#if 0
1442 AssertReleaseMsgFailed(("Not implemented! %s\n", pDesc->pszName));
1443 return VERR_NOT_IMPLEMENTED;
1444#else
1445 AssertMsg2("annoying: %s\n", pDesc->pszName);
1446 uint8_t *pb;
1447 pDesc->pvWrapper = pb = (uint8_t *)remAllocGlue(3);
1448 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1449 *pb++ = 0xcc;
1450 *pb++ = 0x90;
1451 *pb++ = 0xc3;
1452#endif
1453 }
1454# else /* !USE_REM_CALLING_CONVENTION_GLUE */
1455
1456 /*
1457 * Generate a jump patch.
1458 */
1459 uint8_t *pb;
1460# ifdef __AMD64__
1461 pDesc->pvWrapper = pb = (uint8_t *)remAllocGlue(32);
1462 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1463 /**pb++ = 0xcc;*/
1464 *pb++ = 0xff;
1465 *pb++ = 0x24;
1466 *pb++ = 0x25;
1467 *(uint32_t *)pb = (uintptr_t)pb + 5;
1468 pb += 5;
1469 *(uint64_t *)pb = (uint64_t)pDesc->pv;
1470# else
1471 pDesc->pvWrapper = pb = (uint8_t *)remAllocGlue(8);
1472 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1473 *pb++ = 0xea;
1474 *(uint32_t *)pb = (uint32_t)pDesc->pv;
1475# endif
1476# endif /* !USE_REM_CALLING_CONVENTION_GLUE */
1477 }
1478 *pValue = (uintptr_t)pDesc->pvWrapper;
1479# else /* !USE_REM_CALLING_CONVENTION_GLUE */
1480 *pValue = (uintptr_t)pDesc->pv;
1481# endif /* !USE_REM_CALLING_CONVENTION_GLUE */
1482 return VINF_SUCCESS;
1483}
1484
1485
1486/**
1487 * Resolve an external symbol during RTLdrGetBits().
1488 *
1489 * @returns iprt status code.
1490 * @param hLdrMod The loader module handle.
1491 * @param pszModule Module name.
1492 * @param pszSymbol Symbol name, NULL if uSymbol should be used.
1493 * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used.
1494 * @param pValue Where to store the symbol value (address).
1495 * @param pvUser User argument.
1496 */
1497static DECLCALLBACK(int) remGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
1498{
1499 unsigned i;
1500 for (i = 0; i < ELEMENTS(g_aVMMImports); i++)
1501 if (!strcmp(g_aVMMImports[i].pszName, pszSymbol))
1502 return remGenerateImportGlue(pValue, &g_aVMMImports[i]);
1503 for (i = 0; i < ELEMENTS(g_aRTImports); i++)
1504 if (!strcmp(g_aRTImports[i].pszName, pszSymbol))
1505 return remGenerateImportGlue(pValue, &g_aRTImports[i]);
1506 for (i = 0; i < ELEMENTS(g_aCRTImports); i++)
1507 if (!strcmp(g_aCRTImports[i].pszName, pszSymbol))
1508 return remGenerateImportGlue(pValue, &g_aCRTImports[i]);
1509#if 1
1510 AssertMsg2("missing: %s\n", pszSymbol);
1511 return remGenerateImportGlue(pValue, &g_aCRTImports[0]);
1512#else
1513 *pValue = 0;
1514 AssertMsgFailed(("%s.%s\n", pszModule, pszSymbol));
1515 return VERR_SYMBOL_NOT_FOUND;
1516#endif
1517}
1518
1519/**
1520 * Loads the linux object, resolves all imports and exports.
1521 *
1522 * @returns VBox status code.
1523 */
1524static int remLoadLinuxObj(void)
1525{
1526 size_t offFilename;
1527 char szPath[RTPATH_MAX];
1528 int rc = RTPathProgram(szPath, sizeof(szPath) - 32);
1529 AssertRCReturn(rc, rc);
1530 offFilename = strlen(szPath);
1531
1532 /*
1533 * Load the VBoxREM2.rel object/DLL.
1534 */
1535 strcpy(&szPath[offFilename], "/VBoxREM2.rel");
1536 rc = RTLdrOpen(szPath, &g_ModREM2);
1537 if (VBOX_SUCCESS(rc))
1538 {
1539 g_pvREM2 = RTMemExecAlloc(RTLdrSize(g_ModREM2));
1540 if (g_pvREM2)
1541 {
1542#ifdef DEBUG /* How to load the VBoxREM2.rel symbols into the GNU debugger. */
1543 RTPrintf("VBoxREMWrapper: (gdb) add-symbol-file %s 0x%p\n", szPath, g_pvREM2);
1544#endif
1545 Log(("Loading %s at 0x%p (%d bytes)\n"
1546 "(gdb) add-symbol-file %s 0x%p\n",
1547 szPath, g_pvREM2, RTLdrSize(g_ModREM2), szPath, g_pvREM2));
1548 rc = RTLdrGetBits(g_ModREM2, g_pvREM2, (RTUINTPTR)g_pvREM2, remGetImport, NULL);
1549 if (VBOX_SUCCESS(rc))
1550 {
1551 /*
1552 * Resolve exports.
1553 */
1554 unsigned i;
1555 for (i = 0; i < ELEMENTS(g_aExports); i++)
1556 {
1557 RTUINTPTR Value;
1558 rc = RTLdrGetSymbolEx(g_ModREM2, g_pvREM2, (RTUINTPTR)g_pvREM2, g_aExports[i].pszName, &Value);
1559 AssertMsgRC(rc, ("%s rc=%VRc\n", g_aExports[i].pszName, rc));
1560 if (VBOX_FAILURE(rc))
1561 break;
1562 rc = remGenerateExportGlue(&Value, &g_aExports[i]);
1563 if (VBOX_FAILURE(rc))
1564 break;
1565 *(void **)g_aExports[i].pv = (void *)(uintptr_t)Value;
1566 }
1567 return rc;
1568 }
1569 RTMemExecFree(g_pvREM2);
1570 }
1571 RTLdrClose(g_ModREM2);
1572 g_ModREM2 = NIL_RTLDRMOD;
1573 }
1574 return rc;
1575}
1576
1577
1578/**
1579 * Unloads the linux object, freeing up all resources (dlls and
1580 * import glue) we allocated during remLoadLinuxObj().
1581 */
1582static void remUnloadLinuxObj(void)
1583{
1584 unsigned i;
1585
1586 /* close modules. */
1587 RTLdrClose(g_ModREM2);
1588 g_ModREM2 = NIL_RTLDRMOD;
1589 RTMemExecFree(g_pvREM2);
1590 g_pvREM2 = NULL;
1591
1592 /* clear the pointers. */
1593 for (i = 0; i < ELEMENTS(g_aExports); i++)
1594 *(void **)g_aExports[i].pv = NULL;
1595# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1596 for (i = 0; i < ELEMENTS(g_aVMMImports); i++)
1597 g_aVMMImports[i].pvWrapper = NULL;
1598 for (i = 0; i < ELEMENTS(g_aRTImports); i++)
1599 g_aRTImports[i].pvWrapper = NULL;
1600 for (i = 0; i < ELEMENTS(g_aCRTImports); i++)
1601 g_aCRTImports[i].pvWrapper = NULL;
1602
1603 /* free wrapper memory. */
1604 while (g_pExecMemHead)
1605 {
1606 PREMEXECMEM pCur = g_pExecMemHead;
1607 g_pExecMemHead = pCur->pNext;
1608 memset(pCur, 0xcc, pCur->cb);
1609 RTMemExecFree(pCur);
1610 }
1611# endif
1612}
1613#endif
1614
1615
1616REMR3DECL(int) REMR3Init(PVM pVM)
1617{
1618#ifdef USE_REM_STUBS
1619 return VINF_SUCCESS;
1620#else
1621 if (!pfnREMR3Init)
1622 {
1623 int rc = remLoadLinuxObj();
1624 if (VBOX_FAILURE(rc))
1625 return rc;
1626 }
1627 return pfnREMR3Init(pVM);
1628#endif
1629}
1630
1631REMR3DECL(int) REMR3Term(PVM pVM)
1632{
1633#ifdef USE_REM_STUBS
1634 return VINF_SUCCESS;
1635#else
1636 int rc;
1637 Assert(VALID_PTR(pfnREMR3Term));
1638 rc = pfnREMR3Term(pVM);
1639 remUnloadLinuxObj();
1640 return rc;
1641#endif
1642}
1643
1644REMR3DECL(void) REMR3Reset(PVM pVM)
1645{
1646#ifndef USE_REM_STUBS
1647 Assert(VALID_PTR(pfnREMR3Reset));
1648 pfnREMR3Reset(pVM);
1649#endif
1650}
1651
1652REMR3DECL(int) REMR3Step(PVM pVM)
1653{
1654#ifdef USE_REM_STUBS
1655 return VERR_NOT_IMPLEMENTED;
1656#else
1657 Assert(VALID_PTR(pfnREMR3Step));
1658 return pfnREMR3Step(pVM);
1659#endif
1660}
1661
1662REMR3DECL(int) REMR3BreakpointSet(PVM pVM, RTGCUINTPTR Address)
1663{
1664#ifdef USE_REM_STUBS
1665 return VERR_REM_NO_MORE_BP_SLOTS;
1666#else
1667 Assert(VALID_PTR(pfnREMR3BreakpointSet));
1668 return pfnREMR3BreakpointSet(pVM, Address);
1669#endif
1670}
1671
1672REMR3DECL(int) REMR3BreakpointClear(PVM pVM, RTGCUINTPTR Address)
1673{
1674#ifdef USE_REM_STUBS
1675 return VERR_NOT_IMPLEMENTED;
1676#else
1677 Assert(VALID_PTR(pfnREMR3BreakpointClear));
1678 return pfnREMR3BreakpointClear(pVM, Address);
1679#endif
1680}
1681
1682REMR3DECL(int) REMR3EmulateInstruction(PVM pVM)
1683{
1684#ifdef USE_REM_STUBS
1685 return VERR_NOT_IMPLEMENTED;
1686#else
1687 Assert(VALID_PTR(pfnREMR3EmulateInstruction));
1688 return pfnREMR3EmulateInstruction(pVM);
1689#endif
1690}
1691
1692REMR3DECL(int) REMR3Run(PVM pVM)
1693{
1694#ifdef USE_REM_STUBS
1695 return VERR_NOT_IMPLEMENTED;
1696#else
1697 Assert(VALID_PTR(pfnREMR3Run));
1698 return pfnREMR3Run(pVM);
1699#endif
1700}
1701
1702REMR3DECL(int) REMR3State(PVM pVM)
1703{
1704#ifdef USE_REM_STUBS
1705 return VERR_NOT_IMPLEMENTED;
1706#else
1707 Assert(VALID_PTR(pfnREMR3State));
1708 return pfnREMR3State(pVM);
1709#endif
1710}
1711
1712REMR3DECL(int) REMR3StateBack(PVM pVM)
1713{
1714#ifdef USE_REM_STUBS
1715 return VERR_NOT_IMPLEMENTED;
1716#else
1717 Assert(VALID_PTR(pfnREMR3StateBack));
1718 return pfnREMR3StateBack(pVM);
1719#endif
1720}
1721
1722REMR3DECL(void) REMR3StateUpdate(PVM pVM)
1723{
1724#ifndef USE_REM_STUBS
1725 Assert(VALID_PTR(pfnREMR3StateUpdate));
1726 pfnREMR3StateUpdate(pVM);
1727#endif
1728}
1729
1730REMR3DECL(void) REMR3A20Set(PVM pVM, bool fEnable)
1731{
1732#ifndef USE_REM_STUBS
1733 Assert(VALID_PTR(pfnREMR3A20Set));
1734 pfnREMR3A20Set(pVM, fEnable);
1735#endif
1736}
1737
1738REMR3DECL(void) REMR3ReplayInvalidatedPages(PVM pVM)
1739{
1740#ifndef USE_REM_STUBS
1741 Assert(VALID_PTR(pfnREMR3ReplayInvalidatedPages));
1742 pfnREMR3ReplayInvalidatedPages(pVM);
1743#endif
1744}
1745
1746REMR3DECL(void) REMR3ReplayHandlerNotifications(PVM pVM)
1747{
1748#ifndef USE_REM_STUBS
1749 Assert(VALID_PTR(pfnREMR3ReplayHandlerNotifications));
1750 pfnREMR3ReplayHandlerNotifications(pVM);
1751#endif
1752}
1753
1754REMR3DECL(int) REMR3NotifyCodePageChanged(PVM pVM, RTGCPTR pvCodePage)
1755{
1756#ifdef USE_REM_STUBS
1757 return VINF_SUCCESS;
1758#else
1759 Assert(VALID_PTR(pfnREMR3NotifyCodePageChanged));
1760 return pfnREMR3NotifyCodePageChanged(pVM, pvCodePage);
1761#endif
1762}
1763
1764REMR3DECL(void) REMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvRam, unsigned fFlags)
1765{
1766#ifndef USE_REM_STUBS
1767 Assert(VALID_PTR(pfnREMR3NotifyPhysRamRegister));
1768 pfnREMR3NotifyPhysRamRegister(pVM, GCPhys, cb, pvRam, fFlags);
1769#endif
1770}
1771
1772REMR3DECL(void) REMR3NotifyPhysRamChunkRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, RTHCUINTPTR pvRam, unsigned fFlags)
1773{
1774#ifndef USE_REM_STUBS
1775 Assert(VALID_PTR(pfnREMR3NotifyPhysRamChunkRegister));
1776 pfnREMR3NotifyPhysRamChunkRegister(pVM, GCPhys, cb, pvRam, fFlags);
1777#endif
1778}
1779
1780REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy)
1781{
1782#ifndef USE_REM_STUBS
1783 Assert(VALID_PTR(pfnREMR3NotifyPhysRomRegister));
1784 pfnREMR3NotifyPhysRomRegister(pVM, GCPhys, cb, pvCopy);
1785#endif
1786}
1787
1788REMR3DECL(void) REMR3NotifyPhysReserve(PVM pVM, RTGCPHYS GCPhys, RTUINT cb)
1789{
1790#ifndef USE_REM_STUBS
1791 Assert(VALID_PTR(pfnREMR3NotifyPhysReserve));
1792 pfnREMR3NotifyPhysReserve(pVM, GCPhys, cb);
1793#endif
1794}
1795
1796REMR3DECL(void) REMR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)
1797{
1798#ifndef USE_REM_STUBS
1799 Assert(VALID_PTR(pfnREMR3NotifyHandlerPhysicalRegister));
1800 pfnREMR3NotifyHandlerPhysicalRegister(pVM, enmType, GCPhys, cb, fHasHCHandler);
1801#endif
1802}
1803
1804REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, void *pvHCPtr)
1805{
1806#ifndef USE_REM_STUBS
1807 Assert(VALID_PTR(pfnREMR3NotifyHandlerPhysicalDeregister));
1808 pfnREMR3NotifyHandlerPhysicalDeregister(pVM, enmType, GCPhys, cb, fHasHCHandler, pvHCPtr);
1809#endif
1810}
1811
1812REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, void *pvHCPtr)
1813{
1814#ifndef USE_REM_STUBS
1815 Assert(VALID_PTR(pfnREMR3NotifyHandlerPhysicalModify));
1816 pfnREMR3NotifyHandlerPhysicalModify(pVM, enmType, GCPhysOld, GCPhysNew, cb, fHasHCHandler, pvHCPtr);
1817#endif
1818}
1819
1820REMDECL(bool) REMR3IsPageAccessHandled(PVM pVM, RTGCPHYS GCPhys)
1821{
1822#ifdef USE_REM_STUBS
1823 return false;
1824#else
1825 Assert(VALID_PTR(pfnREMR3IsPageAccessHandled));
1826 return pfnREMR3IsPageAccessHandled(pVM, GCPhys);
1827#endif
1828}
1829
1830REMR3DECL(int) REMR3DisasEnableStepping(PVM pVM, bool fEnable)
1831{
1832#ifdef USE_REM_STUBS
1833 return VERR_NOT_IMPLEMENTED;
1834#else
1835 Assert(VALID_PTR(pfnREMR3DisasEnableStepping));
1836 return pfnREMR3DisasEnableStepping(pVM, fEnable);
1837#endif
1838}
1839
1840REMR3DECL(void) REMR3NotifyPendingInterrupt(PVM pVM, uint8_t u8Interrupt)
1841{
1842#ifndef USE_REM_STUBS
1843 Assert(VALID_PTR(pfnREMR3NotifyPendingInterrupt));
1844 pfnREMR3NotifyPendingInterrupt(pVM, u8Interrupt);
1845#endif
1846}
1847
1848REMR3DECL(uint32_t) REMR3QueryPendingInterrupt(PVM pVM)
1849{
1850#ifdef USE_REM_STUBS
1851 return REM_NO_PENDING_IRQ;
1852#else
1853 Assert(VALID_PTR(pfnREMR3QueryPendingInterrupt));
1854 return pfnREMR3QueryPendingInterrupt(pVM);
1855#endif
1856}
1857
1858REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM)
1859{
1860#ifndef USE_REM_STUBS
1861 Assert(VALID_PTR(pfnREMR3NotifyInterruptSet));
1862 pfnREMR3NotifyInterruptSet(pVM);
1863#endif
1864}
1865
1866REMR3DECL(void) REMR3NotifyInterruptClear(PVM pVM)
1867{
1868#ifndef USE_REM_STUBS
1869 Assert(VALID_PTR(pfnREMR3NotifyInterruptClear));
1870 pfnREMR3NotifyInterruptClear(pVM);
1871#endif
1872}
1873
1874REMR3DECL(void) REMR3NotifyTimerPending(PVM pVM)
1875{
1876#ifndef USE_REM_STUBS
1877 Assert(VALID_PTR(pfnREMR3NotifyTimerPending));
1878 pfnREMR3NotifyTimerPending(pVM);
1879#endif
1880}
1881
1882REMR3DECL(void) REMR3NotifyDmaPending(PVM pVM)
1883{
1884#ifndef USE_REM_STUBS
1885 Assert(VALID_PTR(pfnREMR3NotifyDmaPending));
1886 pfnREMR3NotifyDmaPending(pVM);
1887#endif
1888}
1889
1890REMR3DECL(void) REMR3NotifyQueuePending(PVM pVM)
1891{
1892#ifndef USE_REM_STUBS
1893 Assert(VALID_PTR(pfnREMR3NotifyQueuePending));
1894 pfnREMR3NotifyQueuePending(pVM);
1895#endif
1896}
1897
1898REMR3DECL(void) REMR3NotifyFF(PVM pVM)
1899{
1900#ifndef USE_REM_STUBS
1901 /* the timer can call this early on, so don't be picky. */
1902 if (pfnREMR3NotifyFF)
1903 pfnREMR3NotifyFF(pVM);
1904#endif
1905}
1906
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