VirtualBox

source: vbox/trunk/src/recompiler/VBoxREMWrapper.cpp@ 3393

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

InnoTek -> innotek: all the headers and comments.

  • Property svn:keywords set to Id
File size: 96.8 KB
Line 
1/* $Id: VBoxREMWrapper.cpp 2981 2007-06-01 16:01:28Z vboxsync $ */
2/** @file
3 *
4 * VBoxREM Win64 DLL Wrapper.
5 *
6 * innotek GmbH confidential
7 *
8 * Copyright (c) 2006 innotek 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_aArgsCPUMGetGuestCpl[] =
457{
458 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
459 { REMPARMDESC_FLAGS_INT, sizeof(PCPUMCTXCORE) },
460};
461
462static const REMPARMDESC g_aArgsCPUMGetGuestCpuId[] =
463{
464 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
465 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
466 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
467 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
468 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
469 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
470};
471static const REMPARMDESC g_aArgsCPUMQueryGuestCtxPtr[] =
472{
473 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
474 { REMPARMDESC_FLAGS_INT, sizeof(PCPUMCTX *) }
475};
476static const REMPARMDESC g_aArgsCSAMR3MonitorPage[] =
477{
478 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
479 { REMPARMDESC_FLAGS_INT, sizeof(RTGCPTR) },
480 { REMPARMDESC_FLAGS_INT, sizeof(CSAMTAG) }
481};
482static const REMPARMDESC g_aArgsDBGCRegisterCommands[] =
483{
484 { REMPARMDESC_FLAGS_INT, sizeof(PCDBGCCMD) },
485 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) }
486};
487static const REMPARMDESC g_aArgsDBGFR3DisasInstrEx[] =
488{
489 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
490 { REMPARMDESC_FLAGS_INT, sizeof(RTSEL) },
491 { REMPARMDESC_FLAGS_INT, sizeof(RTGCPTR) },
492 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
493 { REMPARMDESC_FLAGS_INT, sizeof(char *) },
494 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
495 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
496};
497static const REMPARMDESC g_aArgsDBGFR3Info[] =
498{
499 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
500 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
501 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
502 { REMPARMDESC_FLAGS_INT, sizeof(PCDBGFINFOHLP) }
503};
504static const REMPARMDESC g_aArgsDBGFR3SymbolByAddr[] =
505{
506 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
507 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINTPTR) },
508 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCINTPTR) },
509 { REMPARMDESC_FLAGS_INT, sizeof(PDBGFSYMBOL) }
510};
511static const REMPARMDESC g_aArgsDISInstr[] =
512{
513 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
514 { REMPARMDESC_FLAGS_INT, sizeof(RTUINTPTR) },
515 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
516 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
517 { REMPARMDESC_FLAGS_INT, sizeof(char *) }
518};
519static const REMPARMDESC g_aArgsEMR3FatalError[] =
520{
521 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
522 { REMPARMDESC_FLAGS_INT, sizeof(int) }
523};
524static const REMPARMDESC g_aArgsHWACCMR3CanExecuteGuest[] =
525{
526 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
527 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
528 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
529 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
530};
531static const REMPARMDESC g_aArgsIOMIOPortRead[] =
532{
533 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
534 { REMPARMDESC_FLAGS_INT, sizeof(RTIOPORT) },
535 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
536 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
537};
538static const REMPARMDESC g_aArgsIOMIOPortWrite[] =
539{
540 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
541 { REMPARMDESC_FLAGS_INT, sizeof(RTIOPORT) },
542 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
543 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
544};
545static const REMPARMDESC g_aArgsIOMMMIORead[] =
546{
547 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
548 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
549 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) },
550 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
551};
552static const REMPARMDESC g_aArgsIOMMMIOWrite[] =
553{
554 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
555 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
556 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
557 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
558};
559static const REMPARMDESC g_aArgsMMR3HeapAlloc[] =
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_aArgsMMR3HeapAllocZ[] =
566{
567 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
568 { REMPARMDESC_FLAGS_INT, sizeof(MMTAG) },
569 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
570};
571static const REMPARMDESC g_aArgsPATMIsPatchGCAddr[] =
572{
573 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
574 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) }
575};
576static const REMPARMDESC g_aArgsPATMR3QueryOpcode[] =
577{
578 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
579 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) },
580 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) }
581};
582static const REMPARMDESC g_aArgsPATMR3QueryPatchMem[] =
583{
584 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
585 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
586};
587static const REMPARMDESC g_aArgsPDMApicGetBase[] =
588{
589 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
590 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t *) }
591};
592static const REMPARMDESC g_aArgsPDMApicGetTPR[] =
593{
594 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
595 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) }
596};
597static const REMPARMDESC g_aArgsPDMApicSetBase[] =
598{
599 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
600 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t) }
601};
602static const REMPARMDESC g_aArgsPDMApicSetTPR[] =
603{
604 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
605 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) }
606};
607static const REMPARMDESC g_aArgsPDMGetInterrupt[] =
608{
609 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
610 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) }
611};
612static const REMPARMDESC g_aArgsPDMIsaSetIrq[] =
613{
614 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
615 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) },
616 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) }
617};
618static const REMPARMDESC g_aArgsPGMGstGetPage[] =
619{
620 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
621 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) },
622 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t *) },
623 { REMPARMDESC_FLAGS_INT, sizeof(PRTGCPHYS) }
624};
625static const REMPARMDESC g_aArgsPGMInvalidatePage[] =
626{
627 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
628 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) }
629};
630static const REMPARMDESC g_aArgsPGMPhysGCPhys2HCPtr[] =
631{
632 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
633 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
634 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) },
635 { REMPARMDESC_FLAGS_INT, sizeof(PRTHCPTR) }
636};
637static const REMPARMDESC g_aArgsPGMPhysGCPtr2HCPtrByGstCR3[] =
638{
639 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
640 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
641 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
642 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
643 { REMPARMDESC_FLAGS_INT, sizeof(PRTHCPTR) }
644};
645static const REMPARMDESC g_aArgsPGM3PhysGrowRange[] =
646{
647 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
648 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) }
649};
650static const REMPARMDESC g_aArgsPGMPhysIsGCPhysValid[] =
651{
652 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
653 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) }
654};
655static const REMPARMDESC g_aArgsPGMPhysRead[] =
656{
657 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
658 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
659 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
660 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
661};
662static const REMPARMDESC g_aArgsPGMPhysReadGCPtr[] =
663{
664 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
665 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
666 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) },
667 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
668};
669static const REMPARMDESC g_aArgsPGMPhysWrite[] =
670{
671 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
672 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
673 { REMPARMDESC_FLAGS_INT, sizeof(const void *) },
674 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
675};
676static const REMPARMDESC g_aArgsPGMChangeMode[] =
677{
678 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
679 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
680 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
681 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t) }
682};
683static const REMPARMDESC g_aArgsPGMFlushTLB[] =
684{
685 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
686 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
687 { REMPARMDESC_FLAGS_INT, sizeof(bool) }
688};
689static const REMPARMDESC g_aArgsPGMR3PhysReadUxx[] =
690{
691 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
692 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) }
693};
694static const REMPARMDESC g_aArgsPGMR3PhysWriteU8[] =
695{
696 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
697 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
698 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) }
699};
700static const REMPARMDESC g_aArgsPGMR3PhysWriteU16[] =
701{
702 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
703 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
704 { REMPARMDESC_FLAGS_INT, sizeof(uint16_t) }
705};
706static const REMPARMDESC g_aArgsPGMR3PhysWriteU32[] =
707{
708 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
709 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
710 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) }
711};
712static const REMPARMDESC g_aArgsPGMR3PhysWriteU64[] =
713{
714 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
715 { REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS) },
716 { REMPARMDESC_FLAGS_INT, sizeof(uint64_t) }
717};
718static const REMPARMDESC g_aArgsSSMR3GetGCPtr[] =
719{
720 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
721 { REMPARMDESC_FLAGS_INT, sizeof(PRTGCPTR) }
722};
723static const REMPARMDESC g_aArgsSSMR3GetMem[] =
724{
725 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
726 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
727 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
728};
729static const REMPARMDESC g_aArgsSSMR3GetU32[] =
730{
731 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
732 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *) }
733};
734static const REMPARMDESC g_aArgsSSMR3GetUInt[] =
735{
736 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
737 { REMPARMDESC_FLAGS_INT, sizeof(PRTUINT) }
738};
739static const REMPARMDESC g_aArgsSSMR3PutGCPtr[] =
740{
741 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
742 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCPTR) }
743};
744static const REMPARMDESC g_aArgsSSMR3PutMem[] =
745{
746 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
747 { REMPARMDESC_FLAGS_INT, sizeof(const void *) },
748 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
749};
750static const REMPARMDESC g_aArgsSSMR3PutU32[] =
751{
752 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
753 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
754};
755static const REMPARMDESC g_aArgsSSMR3PutUInt[] =
756{
757 { REMPARMDESC_FLAGS_INT, sizeof(PSSMHANDLE) },
758 { REMPARMDESC_FLAGS_INT, sizeof(RTUINT) },
759};
760static const REMPARMDESC g_aArgsSSMR3RegisterInternal[] =
761{
762 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
763 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
764 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
765 { REMPARMDESC_FLAGS_INT, sizeof(uint32_t) },
766 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
767 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTSAVEPREP) },
768 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTSAVEEXEC) },
769 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTSAVEDONE) },
770 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTLOADPREP) },
771 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTLOADEXEC) },
772 { REMPARMDESC_FLAGS_INT, sizeof(PFNSSMINTLOADDONE) },
773};
774static const REMPARMDESC g_aArgsSTAMR3Register[] =
775{
776 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
777 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
778 { REMPARMDESC_FLAGS_INT, sizeof(STAMTYPE) },
779 { REMPARMDESC_FLAGS_INT, sizeof(STAMVISIBILITY) },
780 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
781 { REMPARMDESC_FLAGS_INT, sizeof(STAMUNIT) },
782 { REMPARMDESC_FLAGS_INT, sizeof(const char *) }
783};
784static const REMPARMDESC g_aArgsTRPMAssertTrap[] =
785{
786 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
787 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t) },
788 { REMPARMDESC_FLAGS_INT, sizeof(TRPMEVENT) }
789};
790static const REMPARMDESC g_aArgsTRPMQueryTrap[] =
791{
792 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
793 { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *) },
794 { REMPARMDESC_FLAGS_INT, sizeof(TRPMEVENT *) }
795};
796static const REMPARMDESC g_aArgsTRPMSetErrorCode[] =
797{
798 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
799 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINT) }
800};
801static const REMPARMDESC g_aArgsTRPMSetFaultAddress[] =
802{
803 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
804 { REMPARMDESC_FLAGS_GCPTR, sizeof(RTGCUINT) }
805};
806static const REMPARMDESC g_aArgsVMR3ReqCall[] =
807{
808 { REMPARMDESC_FLAGS_INT, sizeof(PVM) },
809 { REMPARMDESC_FLAGS_INT, sizeof(PVMREQ *) },
810 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
811 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
812 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
813 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
814};
815static const REMPARMDESC g_aArgsVMR3ReqFree[] =
816{
817 { REMPARMDESC_FLAGS_INT, sizeof(PVMREQ) }
818};
819
820
821/* IPRT args */
822static const REMPARMDESC g_aArgsAssertMsg1[] =
823{
824 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
825 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
826 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
827 { REMPARMDESC_FLAGS_INT, sizeof(const char *) }
828};
829static const REMPARMDESC g_aArgsAssertMsg2[] =
830{
831 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
832 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
833};
834static const REMPARMDESC g_aArgsRTLogFlags[] =
835{
836 { REMPARMDESC_FLAGS_INT, sizeof(PRTLOGGER) },
837 { REMPARMDESC_FLAGS_INT, sizeof(const char *) }
838};
839static const REMPARMDESC g_aArgsRTLogLoggerEx[] =
840{
841 { REMPARMDESC_FLAGS_INT, sizeof(PRTLOGGER) },
842 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
843 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
844 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
845 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
846};
847static const REMPARMDESC g_aArgsRTLogLoggerExV[] =
848{
849 { REMPARMDESC_FLAGS_INT, sizeof(PRTLOGGER) },
850 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
851 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) },
852 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
853 { REMPARMDESC_FLAGS_VALIST, 0 }
854};
855static const REMPARMDESC g_aArgsRTLogPrintf[] =
856{
857 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
858 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
859};
860static const REMPARMDESC g_aArgsRTMemProtect[] =
861{
862 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
863 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
864 { REMPARMDESC_FLAGS_INT, sizeof(unsigned) }
865};
866static const REMPARMDESC g_aArgsRTStrPrintf[] =
867{
868 { REMPARMDESC_FLAGS_INT, sizeof(char *) },
869 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
870 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
871 { REMPARMDESC_FLAGS_ELLIPSIS, 0 }
872};
873static const REMPARMDESC g_aArgsRTStrPrintfV[] =
874{
875 { REMPARMDESC_FLAGS_INT, sizeof(char *) },
876 { REMPARMDESC_FLAGS_INT, sizeof(size_t) },
877 { REMPARMDESC_FLAGS_INT, sizeof(const char *) },
878 { REMPARMDESC_FLAGS_VALIST, 0 }
879};
880
881
882/* CRT args */
883static const REMPARMDESC g_aArgsmemcpy[] =
884{
885 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
886 { REMPARMDESC_FLAGS_INT, sizeof(const void *) },
887 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
888};
889static const REMPARMDESC g_aArgsmemset[] =
890{
891 { REMPARMDESC_FLAGS_INT, sizeof(void *) },
892 { REMPARMDESC_FLAGS_INT, sizeof(int) },
893 { REMPARMDESC_FLAGS_INT, sizeof(size_t) }
894};
895
896
897/** @} */
898
899/**
900 * Descriptors for the exported functions.
901 */
902static const REMFNDESC g_aExports[] =
903{ /* pszName, (void *)pv, pParams, cParams, fFlags, cb, pvWrapper. */
904 { "REMR3Init", (void *)&pfnREMR3Init, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
905 { "REMR3Term", (void *)&pfnREMR3Term, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
906 { "REMR3Reset", (void *)&pfnREMR3Reset, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
907 { "REMR3Step", (void *)&pfnREMR3Step, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
908 { "REMR3BreakpointSet", (void *)&pfnREMR3BreakpointSet, &g_aArgsBreakpoint[0], ELEMENTS(g_aArgsBreakpoint), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
909 { "REMR3BreakpointClear", (void *)&pfnREMR3BreakpointClear, &g_aArgsBreakpoint[0], ELEMENTS(g_aArgsBreakpoint), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
910 { "REMR3EmulateInstruction", (void *)&pfnREMR3EmulateInstruction, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
911 { "REMR3Run", (void *)&pfnREMR3Run, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
912 { "REMR3State", (void *)&pfnREMR3State, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
913 { "REMR3StateBack", (void *)&pfnREMR3StateBack, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
914 { "REMR3StateUpdate", (void *)&pfnREMR3StateUpdate, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
915 { "REMR3A20Set", (void *)&pfnREMR3A20Set, &g_aArgsA20Set[0], ELEMENTS(g_aArgsA20Set), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
916 { "REMR3ReplayInvalidatedPages", (void *)&pfnREMR3ReplayInvalidatedPages, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
917 { "REMR3ReplayHandlerNotifications", (void *)&pfnREMR3ReplayHandlerNotifications, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
918 { "REMR3NotifyPhysRamRegister", (void *)&pfnREMR3NotifyPhysRamRegister, &g_aArgsNotifyPhysRamRegister[0], ELEMENTS(g_aArgsNotifyPhysRamRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
919 { "REMR3NotifyPhysRamChunkRegister", (void *)&pfnREMR3NotifyPhysRamChunkRegister, &g_aArgsNotifyPhysRamChunkRegister[0], ELEMENTS(g_aArgsNotifyPhysRamChunkRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
920 { "REMR3NotifyPhysReserve", (void *)&pfnREMR3NotifyPhysReserve, &g_aArgsNotifyPhysReserve[0], ELEMENTS(g_aArgsNotifyPhysReserve), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
921 { "REMR3NotifyPhysRomRegister", (void *)&pfnREMR3NotifyPhysRomRegister, &g_aArgsNotifyPhysRomRegister[0], ELEMENTS(g_aArgsNotifyPhysRomRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
922 { "REMR3NotifyHandlerPhysicalModify", (void *)&pfnREMR3NotifyHandlerPhysicalModify, &g_aArgsNotifyHandlerPhysicalModify[0], ELEMENTS(g_aArgsNotifyHandlerPhysicalModify), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
923 { "REMR3NotifyHandlerPhysicalRegister", (void *)&pfnREMR3NotifyHandlerPhysicalRegister, &g_aArgsNotifyHandlerPhysicalRegister[0], ELEMENTS(g_aArgsNotifyHandlerPhysicalRegister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
924 { "REMR3NotifyHandlerPhysicalDeregister", (void *)&pfnREMR3NotifyHandlerPhysicalDeregister, &g_aArgsNotifyHandlerPhysicalDeregister[0], ELEMENTS(g_aArgsNotifyHandlerPhysicalDeregister), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
925 { "REMR3NotifyInterruptSet", (void *)&pfnREMR3NotifyInterruptSet, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
926 { "REMR3NotifyInterruptClear", (void *)&pfnREMR3NotifyInterruptClear, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
927 { "REMR3NotifyTimerPending", (void *)&pfnREMR3NotifyTimerPending, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
928 { "REMR3NotifyDmaPending", (void *)&pfnREMR3NotifyDmaPending, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
929 { "REMR3NotifyQueuePending", (void *)&pfnREMR3NotifyQueuePending, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
930 { "REMR3NotifyFF", (void *)&pfnREMR3NotifyFF, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
931 { "REMR3NotifyCodePageChanged", (void *)&pfnREMR3NotifyCodePageChanged, &g_aArgsNotifyCodePageChanged[0], ELEMENTS(g_aArgsNotifyCodePageChanged), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
932 { "REMR3NotifyPendingInterrupt", (void *)&pfnREMR3NotifyPendingInterrupt, &g_aArgsNotifyPendingInterrupt[0], ELEMENTS(g_aArgsNotifyPendingInterrupt), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
933 { "REMR3QueryPendingInterrupt", (void *)&pfnREMR3QueryPendingInterrupt, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
934 { "REMR3DisasEnableStepping", (void *)&pfnREMR3DisasEnableStepping, &g_aArgsDisasEnableStepping[0], ELEMENTS(g_aArgsDisasEnableStepping), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
935 { "REMR3IsPageAccessHandled", (void *)&pfnREMR3IsPageAccessHandled, &g_aArgsIsPageAccessHandled[0], ELEMENTS(g_aArgsIsPageAccessHandled), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL }
936};
937
938
939/**
940 * Descriptors for the functions imported from VBoxVMM.
941 */
942static REMFNDESC g_aVMMImports[] =
943{
944 { "CPUMAreHiddenSelRegsValid", (void *)(uintptr_t)&CPUMAreHiddenSelRegsValid, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
945 { "CPUMGetAndClearChangedFlagsREM", (void *)(uintptr_t)&CPUMGetAndClearChangedFlagsREM, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(unsigned), NULL },
946 { "CPUMGetGuestCPL", (void *)(uintptr_t)&CPUMGetGuestCPL, &g_aArgsCPUMGetGuestCpl[0], ELEMENTS(g_aArgsCPUMGetGuestCpl), REMFNDESC_FLAGS_RET_INT, sizeof(unsigned), NULL },
947 { "CPUMGetGuestCpuId", (void *)(uintptr_t)&CPUMGetGuestCpuId, &g_aArgsCPUMGetGuestCpuId[0], ELEMENTS(g_aArgsCPUMGetGuestCpuId), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
948 { "CPUMGetGuestEAX", (void *)(uintptr_t)&CPUMGetGuestEAX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
949 { "CPUMGetGuestEBP", (void *)(uintptr_t)&CPUMGetGuestEBP, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
950 { "CPUMGetGuestEBX", (void *)(uintptr_t)&CPUMGetGuestEBX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
951 { "CPUMGetGuestECX", (void *)(uintptr_t)&CPUMGetGuestECX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
952 { "CPUMGetGuestEDI", (void *)(uintptr_t)&CPUMGetGuestEDI, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
953 { "CPUMGetGuestEDX", (void *)(uintptr_t)&CPUMGetGuestEDX, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
954 { "CPUMGetGuestEIP", (void *)(uintptr_t)&CPUMGetGuestEIP, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
955 { "CPUMGetGuestESI", (void *)(uintptr_t)&CPUMGetGuestESI, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
956 { "CPUMGetGuestESP", (void *)(uintptr_t)&CPUMGetGuestESP, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
957 { "CPUMQueryGuestCtxPtr", (void *)(uintptr_t)&CPUMQueryGuestCtxPtr, &g_aArgsCPUMQueryGuestCtxPtr[0], ELEMENTS(g_aArgsCPUMQueryGuestCtxPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
958 { "CSAMR3MonitorPage", (void *)(uintptr_t)&CSAMR3MonitorPage, &g_aArgsCSAMR3MonitorPage[0], ELEMENTS(g_aArgsCSAMR3MonitorPage), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
959 { "DBGCRegisterCommands", (void *)(uintptr_t)&DBGCRegisterCommands, &g_aArgsDBGCRegisterCommands[0], ELEMENTS(g_aArgsDBGCRegisterCommands), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
960 { "DBGFR3DisasInstrEx", (void *)(uintptr_t)&DBGFR3DisasInstrEx, &g_aArgsDBGFR3DisasInstrEx[0], ELEMENTS(g_aArgsDBGFR3DisasInstrEx), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
961 { "DBGFR3Info", (void *)(uintptr_t)&DBGFR3Info, &g_aArgsDBGFR3Info[0], ELEMENTS(g_aArgsDBGFR3Info), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
962 { "DBGFR3InfoLogRelHlp", (void *)(uintptr_t)&DBGFR3InfoLogRelHlp, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
963 { "DBGFR3SymbolByAddr", (void *)(uintptr_t)&DBGFR3SymbolByAddr, &g_aArgsDBGFR3SymbolByAddr[0], ELEMENTS(g_aArgsDBGFR3SymbolByAddr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
964 { "DISInstr", (void *)(uintptr_t)&DISInstr, &g_aArgsDISInstr[0], ELEMENTS(g_aArgsDISInstr), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
965 { "EMR3FatalError", (void *)(uintptr_t)&EMR3FatalError, &g_aArgsEMR3FatalError[0], ELEMENTS(g_aArgsEMR3FatalError), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
966 { "HWACCMR3CanExecuteGuest", (void *)(uintptr_t)&HWACCMR3CanExecuteGuest, &g_aArgsHWACCMR3CanExecuteGuest[0], ELEMENTS(g_aArgsHWACCMR3CanExecuteGuest), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
967 { "IOMIOPortRead", (void *)(uintptr_t)&IOMIOPortRead, &g_aArgsIOMIOPortRead[0], ELEMENTS(g_aArgsIOMIOPortRead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
968 { "IOMIOPortWrite", (void *)(uintptr_t)&IOMIOPortWrite, &g_aArgsIOMIOPortWrite[0], ELEMENTS(g_aArgsIOMIOPortWrite), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
969 { "IOMMMIORead", (void *)(uintptr_t)&IOMMMIORead, &g_aArgsIOMMMIORead[0], ELEMENTS(g_aArgsIOMMMIORead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
970 { "IOMMMIOWrite", (void *)(uintptr_t)&IOMMMIOWrite, &g_aArgsIOMMMIOWrite[0], ELEMENTS(g_aArgsIOMMMIOWrite), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
971 { "MMR3HeapAlloc", (void *)(uintptr_t)&MMR3HeapAlloc, &g_aArgsMMR3HeapAlloc[0], ELEMENTS(g_aArgsMMR3HeapAlloc), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
972 { "MMR3HeapAllocZ", (void *)(uintptr_t)&MMR3HeapAllocZ, &g_aArgsMMR3HeapAllocZ[0], ELEMENTS(g_aArgsMMR3HeapAllocZ), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
973 { "MMR3PhysGetRamSize", (void *)(uintptr_t)&MMR3PhysGetRamSize, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL },
974 { "PATMIsPatchGCAddr", (void *)(uintptr_t)&PATMIsPatchGCAddr, &g_aArgsPATMIsPatchGCAddr[0], ELEMENTS(g_aArgsPATMIsPatchGCAddr), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
975 { "PATMR3QueryOpcode", (void *)(uintptr_t)&PATMR3QueryOpcode, &g_aArgsPATMR3QueryOpcode[0], ELEMENTS(g_aArgsPATMR3QueryOpcode), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
976 { "PATMR3QueryPatchMemGC", (void *)(uintptr_t)&PATMR3QueryPatchMemGC, &g_aArgsPATMR3QueryPatchMem[0], ELEMENTS(g_aArgsPATMR3QueryPatchMem), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCPTR), NULL },
977 { "PATMR3QueryPatchMemHC", (void *)(uintptr_t)&PATMR3QueryPatchMemHC, &g_aArgsPATMR3QueryPatchMem[0], ELEMENTS(g_aArgsPATMR3QueryPatchMem), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
978 { "PDMApicGetBase", (void *)(uintptr_t)&PDMApicGetBase, &g_aArgsPDMApicGetBase[0], ELEMENTS(g_aArgsPDMApicGetBase), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
979 { "PDMApicGetTPR", (void *)(uintptr_t)&PDMApicGetTPR, &g_aArgsPDMApicGetTPR[0], ELEMENTS(g_aArgsPDMApicGetTPR), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
980 { "PDMApicSetBase", (void *)(uintptr_t)&PDMApicSetBase, &g_aArgsPDMApicSetBase[0], ELEMENTS(g_aArgsPDMApicSetBase), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
981 { "PDMApicSetTPR", (void *)(uintptr_t)&PDMApicSetTPR, &g_aArgsPDMApicSetTPR[0], ELEMENTS(g_aArgsPDMApicSetTPR), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
982 { "PDMR3DmaRun", (void *)(uintptr_t)&PDMR3DmaRun, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
983 { "PDMGetInterrupt", (void *)(uintptr_t)&PDMGetInterrupt, &g_aArgsPDMGetInterrupt[0], ELEMENTS(g_aArgsPDMGetInterrupt), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
984 { "PDMIsaSetIrq", (void *)(uintptr_t)&PDMIsaSetIrq, &g_aArgsPDMIsaSetIrq[0], ELEMENTS(g_aArgsPDMIsaSetIrq), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
985 { "PGMGstGetPage", (void *)(uintptr_t)&PGMGstGetPage, &g_aArgsPGMGstGetPage[0], ELEMENTS(g_aArgsPGMGstGetPage), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
986 { "PGMInvalidatePage", (void *)(uintptr_t)&PGMInvalidatePage, &g_aArgsPGMInvalidatePage[0], ELEMENTS(g_aArgsPGMInvalidatePage), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
987 { "PGMPhysGCPhys2HCPtr", (void *)(uintptr_t)&PGMPhysGCPhys2HCPtr, &g_aArgsPGMPhysGCPhys2HCPtr[0], ELEMENTS(g_aArgsPGMPhysGCPhys2HCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
988 { "PGMPhysGCPtr2HCPtrByGstCR3", (void *)(uintptr_t)&PGMPhysGCPtr2HCPtrByGstCR3, &g_aArgsPGMPhysGCPtr2HCPtrByGstCR3[0], ELEMENTS(g_aArgsPGMPhysGCPtr2HCPtrByGstCR3), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
989 { "PGM3PhysGrowRange", (void *)(uintptr_t)&PGM3PhysGrowRange, &g_aArgsPGM3PhysGrowRange[0], ELEMENTS(g_aArgsPGM3PhysGrowRange), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
990 { "PGMPhysIsGCPhysValid", (void *)(uintptr_t)&PGMPhysIsGCPhysValid, &g_aArgsPGMPhysIsGCPhysValid[0], ELEMENTS(g_aArgsPGMPhysIsGCPhysValid), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
991 { "PGMPhysIsA20Enabled", (void *)(uintptr_t)&PGMPhysIsA20Enabled, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
992 { "PGMPhysRead", (void *)(uintptr_t)&PGMPhysRead, &g_aArgsPGMPhysRead[0], ELEMENTS(g_aArgsPGMPhysRead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
993 { "PGMPhysReadGCPtr", (void *)(uintptr_t)&PGMPhysReadGCPtr, &g_aArgsPGMPhysReadGCPtr[0], ELEMENTS(g_aArgsPGMPhysReadGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
994 { "PGMPhysReadGCPtr", (void *)(uintptr_t)&PGMPhysReadGCPtr, &g_aArgsPGMPhysReadGCPtr[0], ELEMENTS(g_aArgsPGMPhysReadGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
995 { "PGMPhysWrite", (void *)(uintptr_t)&PGMPhysWrite, &g_aArgsPGMPhysWrite[0], ELEMENTS(g_aArgsPGMPhysWrite), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
996 { "PGMChangeMode", (void *)(uintptr_t)&PGMChangeMode, &g_aArgsPGMChangeMode[0], ELEMENTS(g_aArgsPGMChangeMode), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
997 { "PGMFlushTLB", (void *)(uintptr_t)&PGMFlushTLB, &g_aArgsPGMFlushTLB[0], ELEMENTS(g_aArgsPGMFlushTLB), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
998 { "PGMR3PhysReadByte", (void *)(uintptr_t)&PGMR3PhysReadByte, &g_aArgsPGMR3PhysReadUxx[0], ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint8_t), NULL },
999 { "PGMR3PhysReadDword", (void *)(uintptr_t)&PGMR3PhysReadDword, &g_aArgsPGMR3PhysReadUxx[0], ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
1000 { "PGMR3PhysReadWord", (void *)(uintptr_t)&PGMR3PhysReadWord, &g_aArgsPGMR3PhysReadUxx[0], ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint16_t), NULL },
1001 { "PGMR3PhysWriteByte", (void *)(uintptr_t)&PGMR3PhysWriteByte, &g_aArgsPGMR3PhysWriteU8[0], ELEMENTS(g_aArgsPGMR3PhysWriteU8), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1002 { "PGMR3PhysWriteDword", (void *)(uintptr_t)&PGMR3PhysWriteDword, &g_aArgsPGMR3PhysWriteU32[0], ELEMENTS(g_aArgsPGMR3PhysWriteU32), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1003 { "PGMR3PhysWriteWord", (void *)(uintptr_t)&PGMR3PhysWriteWord, &g_aArgsPGMR3PhysWriteU16[0], ELEMENTS(g_aArgsPGMR3PhysWriteU16), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1004 { "SSMR3GetGCPtr", (void *)(uintptr_t)&SSMR3GetGCPtr, &g_aArgsSSMR3GetGCPtr[0], ELEMENTS(g_aArgsSSMR3GetGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1005 { "SSMR3GetMem", (void *)(uintptr_t)&SSMR3GetMem, &g_aArgsSSMR3GetMem[0], ELEMENTS(g_aArgsSSMR3GetMem), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1006 { "SSMR3GetU32", (void *)(uintptr_t)&SSMR3GetU32, &g_aArgsSSMR3GetU32[0], ELEMENTS(g_aArgsSSMR3GetU32), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1007 { "SSMR3GetUInt", (void *)(uintptr_t)&SSMR3GetUInt, &g_aArgsSSMR3GetUInt[0], ELEMENTS(g_aArgsSSMR3GetUInt), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1008 { "SSMR3PutGCPtr", (void *)(uintptr_t)&SSMR3PutGCPtr, &g_aArgsSSMR3PutGCPtr[0], ELEMENTS(g_aArgsSSMR3PutGCPtr), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1009 { "SSMR3PutMem", (void *)(uintptr_t)&SSMR3PutMem, &g_aArgsSSMR3PutMem[0], ELEMENTS(g_aArgsSSMR3PutMem), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1010 { "SSMR3PutU32", (void *)(uintptr_t)&SSMR3PutU32, &g_aArgsSSMR3PutU32[0], ELEMENTS(g_aArgsSSMR3PutU32), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1011 { "SSMR3PutUInt", (void *)(uintptr_t)&SSMR3PutUInt, &g_aArgsSSMR3PutUInt[0], ELEMENTS(g_aArgsSSMR3PutUInt), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1012 { "SSMR3RegisterInternal", (void *)(uintptr_t)&SSMR3RegisterInternal, &g_aArgsSSMR3RegisterInternal[0], ELEMENTS(g_aArgsSSMR3RegisterInternal), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1013 { "STAMR3Register", (void *)(uintptr_t)&STAMR3Register, &g_aArgsSTAMR3Register[0], ELEMENTS(g_aArgsSTAMR3Register), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1014 { "TMCpuTickGet", (void *)(uintptr_t)&TMCpuTickGet, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL },
1015 { "TMCpuTickPause", (void *)(uintptr_t)&TMCpuTickPause, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1016 { "TMCpuTickResume", (void *)(uintptr_t)&TMCpuTickResume, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1017 { "TMTimerPoll", (void *)(uintptr_t)&TMTimerPoll, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL },
1018 { "TMR3TimerQueuesDo", (void *)(uintptr_t)&TMR3TimerQueuesDo, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1019 { "TMVirtualPause", (void *)(uintptr_t)&TMVirtualPause, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1020 { "TMVirtualResume", (void *)(uintptr_t)&TMVirtualResume, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1021 { "TRPMAssertTrap", (void *)(uintptr_t)&TRPMAssertTrap, &g_aArgsTRPMAssertTrap[0], ELEMENTS(g_aArgsTRPMAssertTrap), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1022 { "TRPMGetErrorCode", (void *)(uintptr_t)&TRPMGetErrorCode, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCUINT), NULL },
1023 { "TRPMGetFaultAddress", (void *)(uintptr_t)&TRPMGetFaultAddress, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCUINTPTR),NULL },
1024 { "TRPMQueryTrap", (void *)(uintptr_t)&TRPMQueryTrap, &g_aArgsTRPMQueryTrap[0], ELEMENTS(g_aArgsTRPMQueryTrap), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1025 { "TRPMResetTrap", (void *)(uintptr_t)&TRPMResetTrap, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1026 { "TRPMSetErrorCode", (void *)(uintptr_t)&TRPMSetErrorCode, &g_aArgsTRPMSetErrorCode[0], ELEMENTS(g_aArgsTRPMSetErrorCode), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1027 { "TRPMSetFaultAddress", (void *)(uintptr_t)&TRPMSetFaultAddress, &g_aArgsTRPMSetFaultAddress[0], ELEMENTS(g_aArgsTRPMSetFaultAddress), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1028 { "VMMR3Lock", (void *)(uintptr_t)&VMMR3Lock, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1029 { "VMMR3Unlock", (void *)(uintptr_t)&VMMR3Unlock, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1030 { "VMR3ReqCall", (void *)(uintptr_t)&VMR3ReqCall, &g_aArgsVMR3ReqCall[0], ELEMENTS(g_aArgsVMR3ReqCall), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1031 { "VMR3ReqFree", (void *)(uintptr_t)&VMR3ReqFree, &g_aArgsVMR3ReqFree[0], ELEMENTS(g_aArgsVMR3ReqFree), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_ELLIPSIS, sizeof(int), NULL },
1032// { "", (void *)(uintptr_t)&, &g_aArgsVM[0], ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1033};
1034
1035
1036/**
1037 * Descriptors for the functions imported from VBoxRT.
1038 */
1039static REMFNDESC g_aRTImports[] =
1040{
1041 { "AssertMsg1", (void *)(uintptr_t)&AssertMsg1, &g_aArgsAssertMsg1[0], ELEMENTS(g_aArgsAssertMsg1), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1042 { "AssertMsg2", (void *)(uintptr_t)&AssertMsg2, &g_aArgsAssertMsg2[0], ELEMENTS(g_aArgsAssertMsg2), REMFNDESC_FLAGS_RET_VOID | REMFNDESC_FLAGS_ELLIPSIS, 0, NULL },
1043 { "RTAssertDoBreakpoint", (void *)(uintptr_t)&RTAssertDoBreakpoint, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
1044 { "RTLogDefaultInstance", (void *)(uintptr_t)&RTLogDefaultInstance, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(PRTLOGGER), NULL },
1045 { "RTLogRelDefaultInstance", (void *)(uintptr_t)&RTLogRelDefaultInstance, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(PRTLOGGER), NULL },
1046 { "RTLogFlags", (void *)(uintptr_t)&RTLogFlags, &g_aArgsRTLogFlags[0], ELEMENTS(g_aArgsRTLogFlags), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1047 { "RTLogLoggerEx", (void *)(uintptr_t)&RTLogLoggerEx, &g_aArgsRTLogLoggerEx[0], ELEMENTS(g_aArgsRTLogLoggerEx), REMFNDESC_FLAGS_RET_VOID | REMFNDESC_FLAGS_ELLIPSIS, 0, NULL },
1048 { "RTLogLoggerExV", (void *)(uintptr_t)&RTLogLoggerExV, &g_aArgsRTLogLoggerExV[0], ELEMENTS(g_aArgsRTLogLoggerExV), REMFNDESC_FLAGS_RET_VOID | REMFNDESC_FLAGS_VALIST, 0, NULL },
1049 { "RTLogPrintf", (void *)(uintptr_t)&RTLogPrintf, &g_aArgsRTLogPrintf[0], ELEMENTS(g_aArgsRTLogPrintf), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1050 { "RTMemAlloc", (void *)(uintptr_t)&RTMemAlloc, &g_aArgsSIZE_T[0], ELEMENTS(g_aArgsSIZE_T), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1051 { "RTMemExecAlloc", (void *)(uintptr_t)&RTMemExecAlloc, &g_aArgsSIZE_T[0], ELEMENTS(g_aArgsSIZE_T), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1052 { "RTMemExecFree", (void *)(uintptr_t)&RTMemExecFree, &g_aArgsPTR[0], ELEMENTS(g_aArgsPTR), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1053 { "RTMemFree", (void *)(uintptr_t)&RTMemFree, &g_aArgsPTR[0], ELEMENTS(g_aArgsPTR), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1054 { "RTMemPageAlloc", (void *)(uintptr_t)&RTMemPageAlloc, &g_aArgsSIZE_T[0], ELEMENTS(g_aArgsSIZE_T), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1055 { "RTMemPageFree", (void *)(uintptr_t)&RTMemPageFree, &g_aArgsPTR[0], ELEMENTS(g_aArgsPTR), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
1056 { "RTMemProtect", (void *)(uintptr_t)&RTMemProtect, &g_aArgsRTMemProtect[0], ELEMENTS(g_aArgsRTMemProtect), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
1057 { "RTStrPrintf", (void *)(uintptr_t)&RTStrPrintf, &g_aArgsRTStrPrintf[0], ELEMENTS(g_aArgsRTStrPrintf), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_ELLIPSIS, sizeof(size_t), NULL },
1058 { "RTStrPrintfV", (void *)(uintptr_t)&RTStrPrintfV, &g_aArgsRTStrPrintfV[0], ELEMENTS(g_aArgsRTStrPrintfV), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_VALIST, sizeof(size_t), NULL },
1059 { "RTThreadNativeSelf", (void *)(uintptr_t)&RTThreadNativeSelf, NULL, 0, REMFNDESC_FLAGS_RET_INT, sizeof(RTNATIVETHREAD), NULL },
1060};
1061
1062
1063/**
1064 * Descriptors for the functions imported from VBoxRT.
1065 */
1066static REMFNDESC g_aCRTImports[] =
1067{
1068 { "memcpy", (void *)(uintptr_t)&memcpy, &g_aArgsmemcpy[0], ELEMENTS(g_aArgsmemcpy), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
1069 { "memset", (void *)(uintptr_t)&memset, &g_aArgsmemset[0], ELEMENTS(g_aArgsmemset), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL }
1070/*
1071floor floor
1072memcpy memcpy
1073sqrt sqrt
1074sqrtf sqrtf
1075*/
1076};
1077
1078
1079# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1080/** LIFO of read-write-executable memory chunks used for wrappers. */
1081static PREMEXECMEM g_pExecMemHead;
1082# endif
1083
1084
1085/*******************************************************************************
1086* Internal Functions *
1087*******************************************************************************/
1088# ifdef USE_REM_CALLING_CONVENTION_GLUE
1089DECLASM(int) WrapGCC2MSC0Int(void); DECLASM(int) WrapGCC2MSC0Int_EndProc(void);
1090DECLASM(int) WrapGCC2MSC1Int(void); DECLASM(int) WrapGCC2MSC1Int_EndProc(void);
1091DECLASM(int) WrapGCC2MSC2Int(void); DECLASM(int) WrapGCC2MSC2Int_EndProc(void);
1092DECLASM(int) WrapGCC2MSC3Int(void); DECLASM(int) WrapGCC2MSC3Int_EndProc(void);
1093DECLASM(int) WrapGCC2MSC4Int(void); DECLASM(int) WrapGCC2MSC4Int_EndProc(void);
1094DECLASM(int) WrapGCC2MSC5Int(void); DECLASM(int) WrapGCC2MSC5Int_EndProc(void);
1095DECLASM(int) WrapGCC2MSC6Int(void); DECLASM(int) WrapGCC2MSC6Int_EndProc(void);
1096DECLASM(int) WrapGCC2MSC7Int(void); DECLASM(int) WrapGCC2MSC7Int_EndProc(void);
1097DECLASM(int) WrapGCC2MSC8Int(void); DECLASM(int) WrapGCC2MSC8Int_EndProc(void);
1098DECLASM(int) WrapGCC2MSC9Int(void); DECLASM(int) WrapGCC2MSC9Int_EndProc(void);
1099DECLASM(int) WrapGCC2MSC10Int(void); DECLASM(int) WrapGCC2MSC10Int_EndProc(void);
1100DECLASM(int) WrapGCC2MSC11Int(void); DECLASM(int) WrapGCC2MSC11Int_EndProc(void);
1101DECLASM(int) WrapGCC2MSC12Int(void); DECLASM(int) WrapGCC2MSC12Int_EndProc(void);
1102DECLASM(int) WrapGCC2MSCVariadictInt(void); DECLASM(int) WrapGCC2MSCVariadictInt_EndProc(void);
1103
1104DECLASM(int) WrapMSC2GCC0Int(void); DECLASM(int) WrapMSC2GCC0Int_EndProc(void);
1105DECLASM(int) WrapMSC2GCC1Int(void); DECLASM(int) WrapMSC2GCC1Int_EndProc(void);
1106DECLASM(int) WrapMSC2GCC2Int(void); DECLASM(int) WrapMSC2GCC2Int_EndProc(void);
1107DECLASM(int) WrapMSC2GCC3Int(void); DECLASM(int) WrapMSC2GCC3Int_EndProc(void);
1108DECLASM(int) WrapMSC2GCC4Int(void); DECLASM(int) WrapMSC2GCC4Int_EndProc(void);
1109DECLASM(int) WrapMSC2GCC5Int(void); DECLASM(int) WrapMSC2GCC5Int_EndProc(void);
1110DECLASM(int) WrapMSC2GCC6Int(void); DECLASM(int) WrapMSC2GCC6Int_EndProc(void);
1111DECLASM(int) WrapMSC2GCC7Int(void); DECLASM(int) WrapMSC2GCC7Int_EndProc(void);
1112DECLASM(int) WrapMSC2GCC8Int(void); DECLASM(int) WrapMSC2GCC8Int_EndProc(void);
1113DECLASM(int) WrapMSC2GCC9Int(void); DECLASM(int) WrapMSC2GCC9Int_EndProc(void);
1114# endif
1115
1116
1117# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1118/**
1119 * Allocates a block of memory for glue code.
1120 *
1121 * The returned memory is padded with INT3s.
1122 *
1123 * @returns Pointer to the allocated memory.
1124 * @param The amount of memory to allocate.
1125 */
1126static void *remAllocGlue(size_t cb)
1127{
1128 PREMEXECMEM pCur = g_pExecMemHead;
1129 uint32_t cbAligned = (uint32_t)RT_ALIGN_32(cb, 32);
1130 while (pCur)
1131 {
1132 if (pCur->cb - pCur->off >= cbAligned)
1133 {
1134 void *pv = (uint8_t *)pCur + pCur->off;
1135 pCur->off += cbAligned;
1136 return memset(pv, 0xcc, cbAligned);
1137 }
1138 pCur = pCur->pNext;
1139 }
1140
1141 /* add a new chunk */
1142 AssertReturn(_64K - RT_ALIGN_Z(sizeof(*pCur), 32) > cbAligned, NULL);
1143 pCur = (PREMEXECMEM)RTMemExecAlloc(_64K);
1144 AssertReturn(pCur, NULL);
1145 pCur->cb = _64K;
1146 pCur->off = RT_ALIGN_32(sizeof(*pCur), 32) + cbAligned;
1147 pCur->pNext = g_pExecMemHead;
1148 g_pExecMemHead = pCur;
1149 return memset((uint8_t *)pCur + RT_ALIGN_Z(sizeof(*pCur), 32), 0xcc, cbAligned);
1150}
1151# endif /* USE_REM_CALLING_CONVENTION_GLUE || USE_REM_IMPORT_JUMP_GLUE */
1152
1153
1154# ifdef USE_REM_CALLING_CONVENTION_GLUE
1155/**
1156 * Checks if a function is all straight forward integers.
1157 *
1158 * @returns True if it's simple, false if it's bothersome.
1159 * @param pDesc The function descriptor.
1160 */
1161static bool remIsFunctionAllInts(PCREMFNDESC pDesc)
1162{
1163 if ( ( (pDesc->fFlags & REMFNDESC_FLAGS_RET_TYPE_MASK) != REMFNDESC_FLAGS_RET_INT
1164 || pDesc->cbReturn > sizeof(uint64_t))
1165 && (pDesc->fFlags & REMFNDESC_FLAGS_RET_TYPE_MASK) != REMFNDESC_FLAGS_RET_VOID)
1166 return false;
1167 unsigned i = pDesc->cParams;
1168 while (i-- > 0)
1169 switch (pDesc->paParams[i].fFlags & REMPARMDESC_FLAGS_TYPE_MASK)
1170 {
1171 case REMPARMDESC_FLAGS_INT:
1172 case REMPARMDESC_FLAGS_GCPTR:
1173 case REMPARMDESC_FLAGS_GCPHYS:
1174 case REMPARMDESC_FLAGS_HCPHYS:
1175 break;
1176
1177 default:
1178 AssertReleaseMsgFailed(("Invalid param flags %#x for #%d of %s!\n", pDesc->paParams[i].fFlags, i, pDesc->pszName));
1179 case REMPARMDESC_FLAGS_VALIST:
1180 case REMPARMDESC_FLAGS_ELLIPSIS:
1181 case REMPARMDESC_FLAGS_FLOAT:
1182 case REMPARMDESC_FLAGS_STRUCT:
1183 return false;
1184 }
1185 return true;
1186}
1187
1188
1189/**
1190 * Checks if the function has an ellipsis (...) argument.
1191 *
1192 * @returns true if it has an ellipsis, otherwise false.
1193 * @param pDesc The function descriptor.
1194 */
1195static bool remHasFunctionEllipsis(PCREMFNDESC pDesc)
1196{
1197 unsigned i = pDesc->cParams;
1198 while (i-- > 0)
1199 if ((pDesc->paParams[i].fFlags & REMPARMDESC_FLAGS_TYPE_MASK) == REMPARMDESC_FLAGS_ELLIPSIS)
1200 return true;
1201 return false;
1202}
1203
1204
1205/**
1206 * Checks if the function uses floating point (FP) arguments or return value.
1207 *
1208 * @returns true if it uses floating point, otherwise false.
1209 * @param pDesc The function descriptor.
1210 */
1211static bool remIsFunctionUsingFP(PCREMFNDESC pDesc)
1212{
1213 if ((pDesc->fFlags & REMFNDESC_FLAGS_RET_TYPE_MASK) == REMFNDESC_FLAGS_RET_FLOAT)
1214 return true;
1215 unsigned i = pDesc->cParams;
1216 while (i-- > 0)
1217 if ((pDesc->paParams[i].fFlags & REMPARMDESC_FLAGS_TYPE_MASK) == REMPARMDESC_FLAGS_FLOAT)
1218 return true;
1219 return false;
1220}
1221
1222
1223/**
1224 * Fixes export glue.
1225 *
1226 * @param pvGlue The glue code.
1227 * @param cb The size of the glue code.
1228 * @param pvExport The address of the export we're wrapping.
1229 * @param pDesc The export descriptor.
1230 */
1231static void remGenerateExportGlueFixup(void *pvGlue, size_t cb, uintptr_t uExport, PCREMFNDESC pDesc)
1232{
1233 union
1234 {
1235 uint8_t *pu8;
1236 int32_t *pi32;
1237 uint32_t *pu32;
1238 uint64_t *pu64;
1239 void *pv;
1240 } u;
1241 u.pv = pvGlue;
1242
1243 while (cb >= 4)
1244 {
1245 if (*u.pu32 == 0xdeadbeef)
1246 {
1247 /* 32-bit rel jmp/call to real export. */
1248 *u.pi32 = uExport - (uintptr_t)(u.pi32 + 1);
1249 Assert((uintptr_t)(u.pi32 + 1) + *u.pi32 == uExport);
1250 u.pi32++;
1251 cb -= 4;
1252 continue;
1253 }
1254 if (cb >= 8 && *u.pu64 == UINT64_C(0xdeadf00df00ddead))
1255 {
1256 /* 64-bit address to the real export. */
1257 *u.pu64++ = uExport;
1258 cb -= 8;
1259 continue;
1260 }
1261
1262 /* move on. */
1263 u.pu8++;
1264 cb--;
1265 }
1266}
1267
1268
1269/**
1270 * Fixes import glue.
1271 *
1272 * @param pvGlue The glue code.
1273 * @param cb The size of the glue code.
1274 * @param pDesc The import descriptor.
1275 */
1276static void remGenerateImportGlueFixup(void *pvGlue, size_t cb, PCREMFNDESC pDesc)
1277{
1278 union
1279 {
1280 uint8_t *pu8;
1281 int32_t *pi32;
1282 uint32_t *pu32;
1283 uint64_t *pu64;
1284 void *pv;
1285 } u;
1286 u.pv = pvGlue;
1287
1288 while (cb >= 4)
1289 {
1290 if (*u.pu32 == 0xdeadbeef)
1291 {
1292 /* 32-bit rel jmp/call to real function. */
1293 *u.pi32 = (uintptr_t)pDesc->pv - (uintptr_t)(u.pi32 + 1);
1294 Assert((uintptr_t)(u.pi32 + 1) + *u.pi32 == (uintptr_t)pDesc->pv);
1295 u.pi32++;
1296 cb -= 4;
1297 continue;
1298 }
1299 if (cb >= 8 && *u.pu64 == UINT64_C(0xdeadf00df00ddead))
1300 {
1301 /* 64-bit address to the real function. */
1302 *u.pu64++ = (uintptr_t)pDesc->pv;
1303 cb -= 8;
1304 continue;
1305 }
1306
1307 /* move on. */
1308 u.pu8++;
1309 cb--;
1310 }
1311}
1312
1313# endif /* USE_REM_CALLING_CONVENTION_GLUE */
1314
1315
1316/**
1317 * Generate wrapper glue code for an export.
1318 *
1319 * This is only used on win64 when loading a 64-bit linux module. So, on other
1320 * platforms it will not do anything.
1321 *
1322 * @returns VBox status code.
1323 * @param pValue IN: Where to get the address of the function to wrap.
1324 * OUT: Where to store the glue address.
1325 * @param pDesc The export descriptor.
1326 */
1327static int remGenerateExportGlue(PRTUINTPTR pValue, PCREMFNDESC pDesc)
1328{
1329# ifdef USE_REM_CALLING_CONVENTION_GLUE
1330 uintptr_t *ppfn = (uintptr_t *)pDesc->pv;
1331 if (!*ppfn)
1332 {
1333 if (remIsFunctionAllInts(pDesc))
1334 {
1335 static const struct { void *pvStart, *pvEnd; } s_aTemplates[] =
1336 {
1337 { (void *)&WrapMSC2GCC0Int, (void *)&WrapMSC2GCC0Int_EndProc },
1338 { (void *)&WrapMSC2GCC1Int, (void *)&WrapMSC2GCC1Int_EndProc },
1339 { (void *)&WrapMSC2GCC2Int, (void *)&WrapMSC2GCC2Int_EndProc },
1340 { (void *)&WrapMSC2GCC3Int, (void *)&WrapMSC2GCC3Int_EndProc },
1341 { (void *)&WrapMSC2GCC4Int, (void *)&WrapMSC2GCC4Int_EndProc },
1342 { (void *)&WrapMSC2GCC5Int, (void *)&WrapMSC2GCC5Int_EndProc },
1343 { (void *)&WrapMSC2GCC6Int, (void *)&WrapMSC2GCC6Int_EndProc },
1344 { (void *)&WrapMSC2GCC7Int, (void *)&WrapMSC2GCC7Int_EndProc },
1345 { (void *)&WrapMSC2GCC8Int, (void *)&WrapMSC2GCC8Int_EndProc },
1346 { (void *)&WrapMSC2GCC9Int, (void *)&WrapMSC2GCC9Int_EndProc },
1347 };
1348 const unsigned i = pDesc->cParams;
1349 AssertReleaseMsg(i < ELEMENTS(s_aTemplates), ("%d (%s)\n", i, pDesc->pszName));
1350
1351 /* duplicate the patch. */
1352 const size_t cb = (uintptr_t)s_aTemplates[i].pvEnd - (uintptr_t)s_aTemplates[i].pvStart;
1353 uint8_t *pb = (uint8_t *)remAllocGlue(cb);
1354 AssertReturn(pb, VERR_NO_MEMORY);
1355 memcpy(pb, s_aTemplates[i].pvStart, cb);
1356
1357 /* fix it up. */
1358 remGenerateExportGlueFixup(pb, cb, *pValue, pDesc);
1359 *ppfn = (uintptr_t)pb;
1360 }
1361 else
1362 {
1363 /* annoying stuff, later. */
1364#if 1
1365 AssertReleaseMsgFailed(("Not implemented! %s\n", pDesc->pszName));
1366 return VERR_NOT_IMPLEMENTED;
1367#else
1368 AssertMsg2("annoying: %s\n", pDesc->pszName);
1369 uint8_t *pb;
1370 pb = (uint8_t *)remAllocGlue(3);
1371 AssertReturn(pb, VERR_NO_MEMORY);
1372 *pb++ = 0xcc;
1373 *pb++ = 0x90;
1374 *pb++ = 0xc3;
1375 *ppfn = (uintptr_t)pb;
1376#endif
1377 }
1378 }
1379 *pValue = *ppfn;
1380 return VINF_SUCCESS;
1381# else /* !USE_REM_CALLING_CONVENTION_GLUE */
1382 return VINF_SUCCESS;
1383# endif /* !USE_REM_CALLING_CONVENTION_GLUE */
1384}
1385
1386
1387/**
1388 * Generate wrapper glue code for an import.
1389 *
1390 * This is only used on win64 when loading a 64-bit linux module. So, on other
1391 * platforms it will simply return the address of the imported function
1392 * without generating any glue code.
1393 *
1394 * @returns VBox status code.
1395 * @param pValue Where to store the glue address.
1396 * @param pDesc The export descriptor.
1397 */
1398static int remGenerateImportGlue(PRTUINTPTR pValue, PREMFNDESC pDesc)
1399{
1400# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1401 if (!pDesc->pvWrapper)
1402 {
1403# ifdef USE_REM_CALLING_CONVENTION_GLUE
1404 if (remIsFunctionAllInts(pDesc))
1405 {
1406 static const struct { void *pvStart, *pvEnd; } s_aTemplates[] =
1407 {
1408 { (void *)&WrapGCC2MSC0Int, (void *)&WrapGCC2MSC0Int_EndProc },
1409 { (void *)&WrapGCC2MSC1Int, (void *)&WrapGCC2MSC1Int_EndProc },
1410 { (void *)&WrapGCC2MSC2Int, (void *)&WrapGCC2MSC2Int_EndProc },
1411 { (void *)&WrapGCC2MSC3Int, (void *)&WrapGCC2MSC3Int_EndProc },
1412 { (void *)&WrapGCC2MSC4Int, (void *)&WrapGCC2MSC4Int_EndProc },
1413 { (void *)&WrapGCC2MSC5Int, (void *)&WrapGCC2MSC5Int_EndProc },
1414 { (void *)&WrapGCC2MSC6Int, (void *)&WrapGCC2MSC6Int_EndProc },
1415 { (void *)&WrapGCC2MSC7Int, (void *)&WrapGCC2MSC7Int_EndProc },
1416 { (void *)&WrapGCC2MSC8Int, (void *)&WrapGCC2MSC8Int_EndProc },
1417 { (void *)&WrapGCC2MSC9Int, (void *)&WrapGCC2MSC9Int_EndProc },
1418 { (void *)&WrapGCC2MSC10Int, (void *)&WrapGCC2MSC10Int_EndProc },
1419 { (void *)&WrapGCC2MSC11Int, (void *)&WrapGCC2MSC11Int_EndProc },
1420 { (void *)&WrapGCC2MSC12Int, (void *)&WrapGCC2MSC12Int_EndProc }
1421 };
1422 const unsigned i = pDesc->cParams;
1423 AssertReleaseMsg(i < ELEMENTS(s_aTemplates), ("%d (%s)\n", i, pDesc->pszName));
1424
1425 /* duplicate the patch. */
1426 const size_t cb = (uintptr_t)s_aTemplates[i].pvEnd - (uintptr_t)s_aTemplates[i].pvStart;
1427 pDesc->pvWrapper = remAllocGlue(cb);
1428 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1429 memcpy(pDesc->pvWrapper, s_aTemplates[i].pvStart, cb);
1430
1431 /* fix it up. */
1432 remGenerateImportGlueFixup((uint8_t *)pDesc->pvWrapper, cb, pDesc);
1433 }
1434 else if ( remHasFunctionEllipsis(pDesc)
1435 && !remIsFunctionUsingFP(pDesc))
1436 {
1437 /* duplicate the patch. */
1438 const size_t cb = (uintptr_t)&WrapGCC2MSCVariadictInt_EndProc - (uintptr_t)&WrapGCC2MSCVariadictInt;
1439 pDesc->pvWrapper = remAllocGlue(cb);
1440 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1441 memcpy(pDesc->pvWrapper, (void *)&WrapGCC2MSCVariadictInt, cb);
1442
1443 /* fix it up. */
1444 remGenerateImportGlueFixup((uint8_t *)pDesc->pvWrapper, cb, pDesc);
1445 }
1446 else
1447 {
1448 /* annoying stuff, later. */
1449#if 0
1450 AssertReleaseMsgFailed(("Not implemented! %s\n", pDesc->pszName));
1451 return VERR_NOT_IMPLEMENTED;
1452#else
1453 AssertMsg2("annoying: %s\n", pDesc->pszName);
1454 uint8_t *pb;
1455 pDesc->pvWrapper = pb = (uint8_t *)remAllocGlue(3);
1456 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1457 *pb++ = 0xcc;
1458 *pb++ = 0x90;
1459 *pb++ = 0xc3;
1460#endif
1461 }
1462# else /* !USE_REM_CALLING_CONVENTION_GLUE */
1463
1464 /*
1465 * Generate a jump patch.
1466 */
1467 uint8_t *pb;
1468# ifdef __AMD64__
1469 pDesc->pvWrapper = pb = (uint8_t *)remAllocGlue(32);
1470 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1471 /**pb++ = 0xcc;*/
1472 *pb++ = 0xff;
1473 *pb++ = 0x24;
1474 *pb++ = 0x25;
1475 *(uint32_t *)pb = (uintptr_t)pb + 5;
1476 pb += 5;
1477 *(uint64_t *)pb = (uint64_t)pDesc->pv;
1478# else
1479 pDesc->pvWrapper = pb = (uint8_t *)remAllocGlue(8);
1480 AssertReturn(pDesc->pvWrapper, VERR_NO_MEMORY);
1481 *pb++ = 0xea;
1482 *(uint32_t *)pb = (uint32_t)pDesc->pv;
1483# endif
1484# endif /* !USE_REM_CALLING_CONVENTION_GLUE */
1485 }
1486 *pValue = (uintptr_t)pDesc->pvWrapper;
1487# else /* !USE_REM_CALLING_CONVENTION_GLUE */
1488 *pValue = (uintptr_t)pDesc->pv;
1489# endif /* !USE_REM_CALLING_CONVENTION_GLUE */
1490 return VINF_SUCCESS;
1491}
1492
1493
1494/**
1495 * Resolve an external symbol during RTLdrGetBits().
1496 *
1497 * @returns iprt status code.
1498 * @param hLdrMod The loader module handle.
1499 * @param pszModule Module name.
1500 * @param pszSymbol Symbol name, NULL if uSymbol should be used.
1501 * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used.
1502 * @param pValue Where to store the symbol value (address).
1503 * @param pvUser User argument.
1504 */
1505static DECLCALLBACK(int) remGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
1506{
1507 unsigned i;
1508 for (i = 0; i < ELEMENTS(g_aVMMImports); i++)
1509 if (!strcmp(g_aVMMImports[i].pszName, pszSymbol))
1510 return remGenerateImportGlue(pValue, &g_aVMMImports[i]);
1511 for (i = 0; i < ELEMENTS(g_aRTImports); i++)
1512 if (!strcmp(g_aRTImports[i].pszName, pszSymbol))
1513 return remGenerateImportGlue(pValue, &g_aRTImports[i]);
1514 for (i = 0; i < ELEMENTS(g_aCRTImports); i++)
1515 if (!strcmp(g_aCRTImports[i].pszName, pszSymbol))
1516 return remGenerateImportGlue(pValue, &g_aCRTImports[i]);
1517 LogRel(("Missing REM Import: %s\n", pszSymbol));
1518#if 1
1519 *pValue = 0;
1520 AssertMsgFailed(("%s.%s\n", pszModule, pszSymbol));
1521 return VERR_SYMBOL_NOT_FOUND;
1522#else
1523 return remGenerateImportGlue(pValue, &g_aCRTImports[0]);
1524#endif
1525}
1526
1527/**
1528 * Loads the linux object, resolves all imports and exports.
1529 *
1530 * @returns VBox status code.
1531 */
1532static int remLoadLinuxObj(void)
1533{
1534 size_t offFilename;
1535 char szPath[RTPATH_MAX];
1536 int rc = RTPathProgram(szPath, sizeof(szPath) - 32);
1537 AssertRCReturn(rc, rc);
1538 offFilename = strlen(szPath);
1539
1540 /*
1541 * Load the VBoxREM2.rel object/DLL.
1542 */
1543 strcpy(&szPath[offFilename], "/VBoxREM2.rel");
1544 rc = RTLdrOpen(szPath, &g_ModREM2);
1545 if (VBOX_SUCCESS(rc))
1546 {
1547 g_pvREM2 = RTMemExecAlloc(RTLdrSize(g_ModREM2));
1548 if (g_pvREM2)
1549 {
1550#ifdef DEBUG /* How to load the VBoxREM2.rel symbols into the GNU debugger. */
1551 RTPrintf("VBoxREMWrapper: (gdb) add-symbol-file %s 0x%p\n", szPath, g_pvREM2);
1552#endif
1553 LogRel(("REM: Loading %s at 0x%p (%d bytes)\n"
1554 "REM: (gdb) add-symbol-file %s 0x%p\n",
1555 szPath, g_pvREM2, RTLdrSize(g_ModREM2), szPath, g_pvREM2));
1556 rc = RTLdrGetBits(g_ModREM2, g_pvREM2, (RTUINTPTR)g_pvREM2, remGetImport, NULL);
1557 if (VBOX_SUCCESS(rc))
1558 {
1559 /*
1560 * Resolve exports.
1561 */
1562 unsigned i;
1563 for (i = 0; i < ELEMENTS(g_aExports); i++)
1564 {
1565 RTUINTPTR Value;
1566 rc = RTLdrGetSymbolEx(g_ModREM2, g_pvREM2, (RTUINTPTR)g_pvREM2, g_aExports[i].pszName, &Value);
1567 AssertMsgRC(rc, ("%s rc=%VRc\n", g_aExports[i].pszName, rc));
1568 if (VBOX_FAILURE(rc))
1569 break;
1570 rc = remGenerateExportGlue(&Value, &g_aExports[i]);
1571 if (VBOX_FAILURE(rc))
1572 break;
1573 *(void **)g_aExports[i].pv = (void *)(uintptr_t)Value;
1574 }
1575 return rc;
1576 }
1577 RTMemExecFree(g_pvREM2);
1578 }
1579 RTLdrClose(g_ModREM2);
1580 g_ModREM2 = NIL_RTLDRMOD;
1581 }
1582 return rc;
1583}
1584
1585
1586/**
1587 * Unloads the linux object, freeing up all resources (dlls and
1588 * import glue) we allocated during remLoadLinuxObj().
1589 */
1590static void remUnloadLinuxObj(void)
1591{
1592 unsigned i;
1593
1594 /* close modules. */
1595 RTLdrClose(g_ModREM2);
1596 g_ModREM2 = NIL_RTLDRMOD;
1597 RTMemExecFree(g_pvREM2);
1598 g_pvREM2 = NULL;
1599
1600 /* clear the pointers. */
1601 for (i = 0; i < ELEMENTS(g_aExports); i++)
1602 *(void **)g_aExports[i].pv = NULL;
1603# if defined(USE_REM_CALLING_CONVENTION_GLUE) || defined(USE_REM_IMPORT_JUMP_GLUE)
1604 for (i = 0; i < ELEMENTS(g_aVMMImports); i++)
1605 g_aVMMImports[i].pvWrapper = NULL;
1606 for (i = 0; i < ELEMENTS(g_aRTImports); i++)
1607 g_aRTImports[i].pvWrapper = NULL;
1608 for (i = 0; i < ELEMENTS(g_aCRTImports); i++)
1609 g_aCRTImports[i].pvWrapper = NULL;
1610
1611 /* free wrapper memory. */
1612 while (g_pExecMemHead)
1613 {
1614 PREMEXECMEM pCur = g_pExecMemHead;
1615 g_pExecMemHead = pCur->pNext;
1616 memset(pCur, 0xcc, pCur->cb);
1617 RTMemExecFree(pCur);
1618 }
1619# endif
1620}
1621#endif
1622
1623
1624REMR3DECL(int) REMR3Init(PVM pVM)
1625{
1626#ifdef USE_REM_STUBS
1627 return VINF_SUCCESS;
1628#else
1629 if (!pfnREMR3Init)
1630 {
1631 int rc = remLoadLinuxObj();
1632 if (VBOX_FAILURE(rc))
1633 return rc;
1634 }
1635 return pfnREMR3Init(pVM);
1636#endif
1637}
1638
1639REMR3DECL(int) REMR3Term(PVM pVM)
1640{
1641#ifdef USE_REM_STUBS
1642 return VINF_SUCCESS;
1643#else
1644 int rc;
1645 Assert(VALID_PTR(pfnREMR3Term));
1646 rc = pfnREMR3Term(pVM);
1647 remUnloadLinuxObj();
1648 return rc;
1649#endif
1650}
1651
1652REMR3DECL(void) REMR3Reset(PVM pVM)
1653{
1654#ifndef USE_REM_STUBS
1655 Assert(VALID_PTR(pfnREMR3Reset));
1656 pfnREMR3Reset(pVM);
1657#endif
1658}
1659
1660REMR3DECL(int) REMR3Step(PVM pVM)
1661{
1662#ifdef USE_REM_STUBS
1663 return VERR_NOT_IMPLEMENTED;
1664#else
1665 Assert(VALID_PTR(pfnREMR3Step));
1666 return pfnREMR3Step(pVM);
1667#endif
1668}
1669
1670REMR3DECL(int) REMR3BreakpointSet(PVM pVM, RTGCUINTPTR Address)
1671{
1672#ifdef USE_REM_STUBS
1673 return VERR_REM_NO_MORE_BP_SLOTS;
1674#else
1675 Assert(VALID_PTR(pfnREMR3BreakpointSet));
1676 return pfnREMR3BreakpointSet(pVM, Address);
1677#endif
1678}
1679
1680REMR3DECL(int) REMR3BreakpointClear(PVM pVM, RTGCUINTPTR Address)
1681{
1682#ifdef USE_REM_STUBS
1683 return VERR_NOT_IMPLEMENTED;
1684#else
1685 Assert(VALID_PTR(pfnREMR3BreakpointClear));
1686 return pfnREMR3BreakpointClear(pVM, Address);
1687#endif
1688}
1689
1690REMR3DECL(int) REMR3EmulateInstruction(PVM pVM)
1691{
1692#ifdef USE_REM_STUBS
1693 return VERR_NOT_IMPLEMENTED;
1694#else
1695 Assert(VALID_PTR(pfnREMR3EmulateInstruction));
1696 return pfnREMR3EmulateInstruction(pVM);
1697#endif
1698}
1699
1700REMR3DECL(int) REMR3Run(PVM pVM)
1701{
1702#ifdef USE_REM_STUBS
1703 return VERR_NOT_IMPLEMENTED;
1704#else
1705 Assert(VALID_PTR(pfnREMR3Run));
1706 return pfnREMR3Run(pVM);
1707#endif
1708}
1709
1710REMR3DECL(int) REMR3State(PVM pVM)
1711{
1712#ifdef USE_REM_STUBS
1713 return VERR_NOT_IMPLEMENTED;
1714#else
1715 Assert(VALID_PTR(pfnREMR3State));
1716 return pfnREMR3State(pVM);
1717#endif
1718}
1719
1720REMR3DECL(int) REMR3StateBack(PVM pVM)
1721{
1722#ifdef USE_REM_STUBS
1723 return VERR_NOT_IMPLEMENTED;
1724#else
1725 Assert(VALID_PTR(pfnREMR3StateBack));
1726 return pfnREMR3StateBack(pVM);
1727#endif
1728}
1729
1730REMR3DECL(void) REMR3StateUpdate(PVM pVM)
1731{
1732#ifndef USE_REM_STUBS
1733 Assert(VALID_PTR(pfnREMR3StateUpdate));
1734 pfnREMR3StateUpdate(pVM);
1735#endif
1736}
1737
1738REMR3DECL(void) REMR3A20Set(PVM pVM, bool fEnable)
1739{
1740#ifndef USE_REM_STUBS
1741 Assert(VALID_PTR(pfnREMR3A20Set));
1742 pfnREMR3A20Set(pVM, fEnable);
1743#endif
1744}
1745
1746REMR3DECL(void) REMR3ReplayInvalidatedPages(PVM pVM)
1747{
1748#ifndef USE_REM_STUBS
1749 Assert(VALID_PTR(pfnREMR3ReplayInvalidatedPages));
1750 pfnREMR3ReplayInvalidatedPages(pVM);
1751#endif
1752}
1753
1754REMR3DECL(void) REMR3ReplayHandlerNotifications(PVM pVM)
1755{
1756#ifndef USE_REM_STUBS
1757 Assert(VALID_PTR(pfnREMR3ReplayHandlerNotifications));
1758 pfnREMR3ReplayHandlerNotifications(pVM);
1759#endif
1760}
1761
1762REMR3DECL(int) REMR3NotifyCodePageChanged(PVM pVM, RTGCPTR pvCodePage)
1763{
1764#ifdef USE_REM_STUBS
1765 return VINF_SUCCESS;
1766#else
1767 Assert(VALID_PTR(pfnREMR3NotifyCodePageChanged));
1768 return pfnREMR3NotifyCodePageChanged(pVM, pvCodePage);
1769#endif
1770}
1771
1772REMR3DECL(void) REMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvRam, unsigned fFlags)
1773{
1774#ifndef USE_REM_STUBS
1775 Assert(VALID_PTR(pfnREMR3NotifyPhysRamRegister));
1776 pfnREMR3NotifyPhysRamRegister(pVM, GCPhys, cb, pvRam, fFlags);
1777#endif
1778}
1779
1780REMR3DECL(void) REMR3NotifyPhysRamChunkRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, RTHCUINTPTR pvRam, unsigned fFlags)
1781{
1782#ifndef USE_REM_STUBS
1783 Assert(VALID_PTR(pfnREMR3NotifyPhysRamChunkRegister));
1784 pfnREMR3NotifyPhysRamChunkRegister(pVM, GCPhys, cb, pvRam, fFlags);
1785#endif
1786}
1787
1788REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy)
1789{
1790#ifndef USE_REM_STUBS
1791 Assert(VALID_PTR(pfnREMR3NotifyPhysRomRegister));
1792 pfnREMR3NotifyPhysRomRegister(pVM, GCPhys, cb, pvCopy);
1793#endif
1794}
1795
1796REMR3DECL(void) REMR3NotifyPhysReserve(PVM pVM, RTGCPHYS GCPhys, RTUINT cb)
1797{
1798#ifndef USE_REM_STUBS
1799 Assert(VALID_PTR(pfnREMR3NotifyPhysReserve));
1800 pfnREMR3NotifyPhysReserve(pVM, GCPhys, cb);
1801#endif
1802}
1803
1804REMR3DECL(void) REMR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)
1805{
1806#ifndef USE_REM_STUBS
1807 Assert(VALID_PTR(pfnREMR3NotifyHandlerPhysicalRegister));
1808 pfnREMR3NotifyHandlerPhysicalRegister(pVM, enmType, GCPhys, cb, fHasHCHandler);
1809#endif
1810}
1811
1812REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, void *pvHCPtr)
1813{
1814#ifndef USE_REM_STUBS
1815 Assert(VALID_PTR(pfnREMR3NotifyHandlerPhysicalDeregister));
1816 pfnREMR3NotifyHandlerPhysicalDeregister(pVM, enmType, GCPhys, cb, fHasHCHandler, pvHCPtr);
1817#endif
1818}
1819
1820REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, void *pvHCPtr)
1821{
1822#ifndef USE_REM_STUBS
1823 Assert(VALID_PTR(pfnREMR3NotifyHandlerPhysicalModify));
1824 pfnREMR3NotifyHandlerPhysicalModify(pVM, enmType, GCPhysOld, GCPhysNew, cb, fHasHCHandler, pvHCPtr);
1825#endif
1826}
1827
1828REMDECL(bool) REMR3IsPageAccessHandled(PVM pVM, RTGCPHYS GCPhys)
1829{
1830#ifdef USE_REM_STUBS
1831 return false;
1832#else
1833 Assert(VALID_PTR(pfnREMR3IsPageAccessHandled));
1834 return pfnREMR3IsPageAccessHandled(pVM, GCPhys);
1835#endif
1836}
1837
1838REMR3DECL(int) REMR3DisasEnableStepping(PVM pVM, bool fEnable)
1839{
1840#ifdef USE_REM_STUBS
1841 return VERR_NOT_IMPLEMENTED;
1842#else
1843 Assert(VALID_PTR(pfnREMR3DisasEnableStepping));
1844 return pfnREMR3DisasEnableStepping(pVM, fEnable);
1845#endif
1846}
1847
1848REMR3DECL(void) REMR3NotifyPendingInterrupt(PVM pVM, uint8_t u8Interrupt)
1849{
1850#ifndef USE_REM_STUBS
1851 Assert(VALID_PTR(pfnREMR3NotifyPendingInterrupt));
1852 pfnREMR3NotifyPendingInterrupt(pVM, u8Interrupt);
1853#endif
1854}
1855
1856REMR3DECL(uint32_t) REMR3QueryPendingInterrupt(PVM pVM)
1857{
1858#ifdef USE_REM_STUBS
1859 return REM_NO_PENDING_IRQ;
1860#else
1861 Assert(VALID_PTR(pfnREMR3QueryPendingInterrupt));
1862 return pfnREMR3QueryPendingInterrupt(pVM);
1863#endif
1864}
1865
1866REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM)
1867{
1868#ifndef USE_REM_STUBS
1869 Assert(VALID_PTR(pfnREMR3NotifyInterruptSet));
1870 pfnREMR3NotifyInterruptSet(pVM);
1871#endif
1872}
1873
1874REMR3DECL(void) REMR3NotifyInterruptClear(PVM pVM)
1875{
1876#ifndef USE_REM_STUBS
1877 Assert(VALID_PTR(pfnREMR3NotifyInterruptClear));
1878 pfnREMR3NotifyInterruptClear(pVM);
1879#endif
1880}
1881
1882REMR3DECL(void) REMR3NotifyTimerPending(PVM pVM)
1883{
1884#ifndef USE_REM_STUBS
1885 Assert(VALID_PTR(pfnREMR3NotifyTimerPending));
1886 pfnREMR3NotifyTimerPending(pVM);
1887#endif
1888}
1889
1890REMR3DECL(void) REMR3NotifyDmaPending(PVM pVM)
1891{
1892#ifndef USE_REM_STUBS
1893 Assert(VALID_PTR(pfnREMR3NotifyDmaPending));
1894 pfnREMR3NotifyDmaPending(pVM);
1895#endif
1896}
1897
1898REMR3DECL(void) REMR3NotifyQueuePending(PVM pVM)
1899{
1900#ifndef USE_REM_STUBS
1901 Assert(VALID_PTR(pfnREMR3NotifyQueuePending));
1902 pfnREMR3NotifyQueuePending(pVM);
1903#endif
1904}
1905
1906REMR3DECL(void) REMR3NotifyFF(PVM pVM)
1907{
1908#ifndef USE_REM_STUBS
1909 /* the timer can call this early on, so don't be picky. */
1910 if (pfnREMR3NotifyFF)
1911 pfnREMR3NotifyFF(pVM);
1912#endif
1913}
1914
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