VirtualBox

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

Last change on this file since 3903 was 3903, checked in by vboxsync, 17 years ago

fixed path of VBoxREM2.rel (amd64)

  • Property svn:keywords set to Id
File size: 105.4 KB
Line 
1/* $Id: VBoxREMWrapper.cpp 3903 2007-07-27 09:56:25Z 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(RT_ARCH_AMD64) && defined(RT_OS_WINDOWS)) || 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(RT_ARCH_AMD64) && !defined(USE_REM_CALLING_CONVENTION_GLUE) && !defined(RT_OS_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(RT_OS_WINDOWS) && defined(RT_ARCH_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(RT_OS_WINDOWS) && defined(RT_ARCH_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 RT_OS_WINDOWS
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 RT_ARCH_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 = RTPathAppPrivateArch(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