VirtualBox

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

Last change on this file since 12519 was 12299, checked in by vboxsync, 16 years ago

Add option to REMR3State to flush all TBs. (currently not yet active)

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