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 *---------------------------------------------------------------------
67 /* jumping to error handling in VAssert_IsInVM. */
68 siglongjmp(segv_jmp
, 1);
73 *---------------------------------------------------------------------
77 * Check if we are in virtual world.
81 * Return TRUE on success, or FALSE on failure.
86 *---------------------------------------------------------------------
92 uint32 eax
, ebx
, ecx
, edx
;
93 static Bool inVM
= FALSE
;
94 static Bool tested
= FALSE
;
97 if (sigsetjmp(segv_jmp
, 0) != 0) {
98 signal(SIGSEGV
, SIG_DFL
);
103 /* Install custom handler. */
104 signal(SIGSEGV
, sig_segv
);
105 /* Test if we are in a VM. */
106 libvassert_process_backdoor(0x0a, 0, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
107 signal(SIGSEGV
, SIG_DFL
);
115 *---------------------------------------------------------------------
119 * Tell vmx that vassert is inited.
123 * Return 0 on success, or -1 on failure.
128 *---------------------------------------------------------------------
134 uint32 eax
, ebx
, ecx
, edx
;
135 VA page_address
= (VA
) &vassert_state
.inReplay
;
136 if (!VAssert_IsInVM()) {
139 bzero((char*) &vassert_state
, sizeof vassert_state
);
142 if (mlock(&vassert_state
, sizeof vassert_state
)) {
147 libvassert_process_backdoor(CMD_SET_ADDRESS
, page_address
,
148 MAGIC_PORT
|(1<<16), &eax
, &ebx
, &ecx
, &edx
);
150 return (eax
!= -1) ? 0 : -1;
155 *---------------------------------------------------------------------
159 * Tell vmx that vassert is finalized.
163 * Return 0 on success, or -1 on failure.
168 *---------------------------------------------------------------------
174 unsigned int eax
, ebx
, ecx
, edx
;
175 if (!VAssert_IsInVM()) {
178 libvassert_process_backdoor(CMD_SET_ADDRESS
, 0, MAGIC_PORT
|(0<<16), &eax
, &ebx
, &ecx
, &edx
);
179 return (eax
!= -1) ? 0 : 1;
184 *---------------------------------------------------------------------
188 * Print message to a text file on host side.
194 * Write to a text file with fixed name.
195 * If the file exists, host UI will ask for append/replace/ignore
197 *---------------------------------------------------------------------
201 VAssert_LogMain(const char *format
, ...)
203 unsigned int eax
, ebx
, ecx
, edx
;
205 unsigned int len
= 0;
207 va_start(ap
, format
);
208 len
= vsnprintf(buf
, LOG_MAX
, format
, ap
);
210 __asm__
__volatile__("cld; rep outsb;"
211 : "=a"(eax
), "=b"(ebx
), "=c"(ecx
), "=d"(edx
)
212 : "0"(MAGIC_CMD
), "1"(CMD_LOG
), "2"(len
), "d"(HIGH_BAND_PORT
), "S"(buf
)
219 *---------------------------------------------------------------------
221 * VAssert_GoLiveMain --
223 * Make the vm which is in replay exit replay.
231 *---------------------------------------------------------------------
237 unsigned int eax
, ebx
, ecx
, edx
;
238 vassert_state
.inReplay
= 0;
239 libvassert_process_backdoor(CMD_GO_LIVE
, 0, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
244 *---------------------------------------------------------------------
246 * VAssert_ReturnToReplayMain --
248 * Called after the custom work is done, and replay is to continue.
254 * Replay is continued from pause.
256 *---------------------------------------------------------------------
260 VAssert_ReturnToReplayMain()
262 unsigned int eax
, ebx
, ecx
, edx
;
263 libvassert_process_backdoor(CMD_RETURN_REPLAY
, 0, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
268 *---------------------------------------------------------------------
270 * VAssert_SetRecordingMain --
272 * Ask vmx for starting or stopping recording.
276 * Return TRUE on success, or FALSE on failure.
279 * Recording is started or stopped.
281 *---------------------------------------------------------------------
285 VAssert_SetRecordingMain(char start
)
287 uint32 eax
, ebx
, ecx
, edx
;
288 if (!VAssert_IsInVM()) {
291 libvassert_process_backdoor(CMD_SET_RECORD
, start
? 1 : 2, MAGIC_PORT
, &eax
, &ebx
, &ecx
, &edx
);
292 return (eax
== 1) ? TRUE
: FALSE
;