VirtualBox

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

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

REMR3ReplayHandlerNotifications

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