VirtualBox

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

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

Callback wrapping using custom assembly templates (too lazy to generate code). Disabled the problematic DBGC stuff on 64-bit windows.

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