5 #include <minix/config.h>
6 #include <minix/const.h>
9 #include <minix/syslib.h>
10 #include <machine/stackframe.h>
13 VAssert_StateWrapper vassert_state
ALIGNED(VASSERT_PAGE_SIZE
);
18 #define MAGIC_CMD 0x564d5868
19 #define MAGIC_PORT 0x5658
20 #define HIGH_BAND_PORT 0x5659
22 #define BACKDOOR_PORT 51
23 #define BACKDOOR_HB_PORT 1
24 #define CMD_SET_ADDRESS BACKDOOR_PORT|(1<<16)
25 #define CMD_RETURN_REPLAY BACKDOOR_PORT|(2<<16)
26 #define CMD_GO_LIVE BACKDOOR_PORT|(3<<16)
27 #define CMD_LOG BACKDOOR_HB_PORT|(4<<16)
28 #define CMD_SET_RECORD 47
33 typedef unsigned int uint32
;
34 typedef unsigned long long uint64
;
42 static sigjmp_buf segv_jmp
;
44 void libvassert_process_backdoor(uint32
, uint32
, uint32
, reg_t
*, reg_t
*,
48 *---------------------------------------------------------------------
52 * Customed SEGV signal handler for VAssert_IsInVM.
61 *---------------------------------------------------------------------
64 static void sig_segv(int sig_no
)
66 /* jumping to error handling in VAssert_IsInVM. */
67 siglongjmp(segv_jmp
, 1);
72 *---------------------------------------------------------------------
76 * Check if we are in virtual world.
80 * Return TRUE on success, or FALSE on failure.
85 *---------------------------------------------------------------------
88 static Bool
VAssert_IsInVM(void)
90 uint32 eax
, ebx
, ecx
, edx
;
91 static Bool inVM
= FALSE
;
92 static Bool tested
= FALSE
;
95 if (sigsetjmp(segv_jmp
, 0) != 0) {
96 signal(SIGSEGV
, SIG_DFL
);
101 /* Install custom handler. */
102 signal(SIGSEGV
, sig_segv
);
103 /* Test if we are in a VM. */
104 libvassert_process_backdoor(0x0a, 0, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
105 signal(SIGSEGV
, SIG_DFL
);
113 *---------------------------------------------------------------------
117 * Tell vmx that vassert is inited.
121 * Return 0 on success, or -1 on failure.
126 *---------------------------------------------------------------------
129 char VAssert_Init(void)
131 uint32 eax
, ebx
, ecx
, edx
;
132 VA page_address
= (VA
) &vassert_state
.inReplay
;
133 if (!VAssert_IsInVM()) {
136 bzero((char*) &vassert_state
, sizeof vassert_state
);
139 if (mlock(&vassert_state
, sizeof vassert_state
)) {
144 libvassert_process_backdoor(CMD_SET_ADDRESS
, page_address
,
145 MAGIC_PORT
|(1<<16), &eax
, &ebx
, &ecx
, &edx
);
147 return (eax
!= -1) ? 0 : -1;
152 *---------------------------------------------------------------------
156 * Tell vmx that vassert is finalized.
160 * Return 0 on success, or -1 on failure.
165 *---------------------------------------------------------------------
168 char VAssert_Uninit(void)
170 unsigned int eax
, ebx
, ecx
, edx
;
171 if (!VAssert_IsInVM()) {
174 libvassert_process_backdoor(CMD_SET_ADDRESS
, 0, MAGIC_PORT
|(0<<16), &eax
, &ebx
, &ecx
, &edx
);
175 return (eax
!= -1) ? 0 : 1;
180 *---------------------------------------------------------------------
184 * Print message to a text file on host side.
190 * Write to a text file with fixed name.
191 * If the file exists, host UI will ask for append/replace/ignore
193 *---------------------------------------------------------------------
196 void VAssert_LogMain(const char *format
, ...)
198 unsigned int eax
, ebx
, ecx
, edx
;
200 unsigned int len
= 0;
202 va_start(ap
, format
);
203 len
= vsnprintf(buf
, LOG_MAX
, format
, ap
);
205 __asm__
__volatile__("cld; rep outsb;"
206 : "=a"(eax
), "=b"(ebx
), "=c"(ecx
), "=d"(edx
)
207 : "0"(MAGIC_CMD
), "1"(CMD_LOG
), "2"(len
), "d"(HIGH_BAND_PORT
), "S"(buf
)
214 *---------------------------------------------------------------------
216 * VAssert_GoLiveMain --
218 * Make the vm which is in replay exit replay.
226 *---------------------------------------------------------------------
229 void VAssert_GoLiveMain(void)
231 unsigned int eax
, ebx
, ecx
, edx
;
232 vassert_state
.inReplay
= 0;
233 libvassert_process_backdoor(CMD_GO_LIVE
, 0, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
238 *---------------------------------------------------------------------
240 * VAssert_ReturnToReplayMain --
242 * Called after the custom work is done, and replay is to continue.
248 * Replay is continued from pause.
250 *---------------------------------------------------------------------
253 void VAssert_ReturnToReplayMain(void)
255 unsigned int eax
, ebx
, ecx
, edx
;
256 libvassert_process_backdoor(CMD_RETURN_REPLAY
, 0, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
261 *---------------------------------------------------------------------
263 * VAssert_SetRecordingMain --
265 * Ask vmx for starting or stopping recording.
269 * Return TRUE on success, or FALSE on failure.
272 * Recording is started or stopped.
274 *---------------------------------------------------------------------
277 char VAssert_SetRecordingMain(char start
)
279 uint32 eax
, ebx
, ecx
, edx
;
280 if (!VAssert_IsInVM()) {
283 libvassert_process_backdoor(CMD_SET_RECORD
, start
? 1 : 2, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
284 return (eax
== 1) ? TRUE
: FALSE
;