coverity appeasement
[minix.git] / lib / libvassert / vassert.c
blob695c5b10cc03486b140dc4e28b9d953dc2c7d704
1 #include <string.h>
2 #include <stdarg.h>
3 #include <signal.h>
4 #include <setjmp.h>
5 #include <minix/config.h>
6 #include <minix/const.h>
7 #include <minix/ipc.h>
8 #include <minix/com.h>
9 #include <minix/syslib.h>
10 #include "vassert.h"
12 VAssert_StateWrapper vassert_state ALIGNED(VASSERT_PAGE_SIZE);
14 #define TRUE 1
15 #define FALSE 0
17 #define MAGIC_CMD 0x564d5868
18 #define MAGIC_PORT 0x5658
19 #define HIGH_BAND_PORT 0x5659
21 #define BACKDOOR_PORT 51
22 #define BACKDOOR_HB_PORT 1
23 #define CMD_SET_ADDRESS BACKDOOR_PORT|(1<<16)
24 #define CMD_RETURN_REPLAY BACKDOOR_PORT|(2<<16)
25 #define CMD_GO_LIVE BACKDOOR_PORT|(3<<16)
26 #define CMD_LOG BACKDOOR_HB_PORT|(4<<16)
27 #define CMD_SET_RECORD 47
29 #define LOG_MAX 512
31 typedef char Bool;
32 typedef unsigned int uint32;
33 typedef unsigned long long uint64;
35 #ifdef VM_X86_64
36 typedef uint64 VA;
37 #else
38 typedef uint32 VA;
39 #endif
41 static sigjmp_buf segv_jmp;
43 void libvassert_process_backdoor(uint32, uint32, uint32, reg_t *, reg_t *,
44 reg_t *, reg_t *);
47 *---------------------------------------------------------------------
49 * sig_segv --
51 * Customed SEGV signal handler for VAssert_IsInVM.
53 * Results:
55 * None.
57 * Side effects:
58 * None.
60 *---------------------------------------------------------------------
63 static void
64 sig_segv(int sig_no)
66 /* jumping to error handling in VAssert_IsInVM. */
67 siglongjmp(segv_jmp, 1);
72 *---------------------------------------------------------------------
74 * VAssert_IsInVM --
76 * Check if we are in virtual world.
78 * Results:
80 * Return TRUE on success, or FALSE on failure.
82 * Side effects:
83 * None.
85 *---------------------------------------------------------------------
88 static Bool
89 VAssert_IsInVM(void)
91 uint32 eax, ebx, ecx, edx;
92 static Bool inVM = FALSE;
93 static Bool tested = FALSE;
94 if (!tested) {
95 /* Error handling. */
96 if (sigsetjmp(segv_jmp, 0) != 0) {
97 signal(SIGSEGV, SIG_DFL);
98 inVM = FALSE;
99 return inVM;
101 tested = TRUE;
102 /* Install custom handler. */
103 signal(SIGSEGV, sig_segv);
104 /* Test if we are in a VM. */
105 libvassert_process_backdoor(0x0a, 0, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
106 signal(SIGSEGV, SIG_DFL);
107 inVM = TRUE;
109 return inVM;
114 *---------------------------------------------------------------------
116 * VAssert_Init --
118 * Tell vmx that vassert is inited.
120 * Results:
122 * Return 0 on success, or -1 on failure.
124 * Side effects:
125 * None
127 *---------------------------------------------------------------------
130 char
131 VAssert_Init(void)
133 uint32 eax, ebx, ecx, edx;
134 VA page_address = (VA) &vassert_state.inReplay;
135 if (!VAssert_IsInVM()) {
136 return -1;
138 bzero((char*) &vassert_state, sizeof vassert_state);
139 #ifndef __minix
140 /* Lock the page. */
141 if (mlock(&vassert_state, sizeof vassert_state)) {
142 return -1;
144 #endif
146 libvassert_process_backdoor(CMD_SET_ADDRESS, page_address,
147 MAGIC_PORT|(1<<16), &eax, &ebx, &ecx, &edx);
149 return (eax != -1) ? 0 : -1;
154 *---------------------------------------------------------------------
156 * VAssert_Uninit --
158 * Tell vmx that vassert is finalized.
160 * Results:
162 * Return 0 on success, or -1 on failure.
164 * Side effects:
165 * None
167 *---------------------------------------------------------------------
170 char
171 VAssert_Uninit(void)
173 unsigned int eax, ebx, ecx, edx;
174 if (!VAssert_IsInVM()) {
175 return -1;
177 libvassert_process_backdoor(CMD_SET_ADDRESS, 0, MAGIC_PORT|(0<<16), &eax, &ebx, &ecx, &edx);
178 return (eax != -1) ? 0 : 1;
183 *---------------------------------------------------------------------
185 * VAssert_LogMain --
187 * Print message to a text file on host side.
189 * Results:
190 * None
192 * Side effects:
193 * Write to a text file with fixed name.
194 * If the file exists, host UI will ask for append/replace/ignore
196 *---------------------------------------------------------------------
199 void
200 VAssert_LogMain(const char *format, ...)
202 unsigned int eax, ebx, ecx, edx;
203 char buf[LOG_MAX];
204 unsigned int len = 0;
205 va_list ap;
206 va_start(ap, format);
207 len = vsnprintf(buf, LOG_MAX, format, ap);
208 va_end(ap);
209 __asm__ __volatile__("cld; rep outsb;"
210 : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
211 : "0"(MAGIC_CMD), "1"(CMD_LOG), "2"(len), "d"(HIGH_BAND_PORT), "S"(buf)
212 : "memory"
218 *---------------------------------------------------------------------
220 * VAssert_GoLiveMain --
222 * Make the vm which is in replay exit replay.
224 * Results:
225 * None
227 * Side effects:
228 * Replay is stopped.
230 *---------------------------------------------------------------------
233 void
234 VAssert_GoLiveMain()
236 unsigned int eax, ebx, ecx, edx;
237 vassert_state.inReplay = 0;
238 libvassert_process_backdoor(CMD_GO_LIVE, 0, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
243 *---------------------------------------------------------------------
245 * VAssert_ReturnToReplayMain --
247 * Called after the custom work is done, and replay is to continue.
249 * Results:
250 * None
252 * Side effects:
253 * Replay is continued from pause.
255 *---------------------------------------------------------------------
258 void
259 VAssert_ReturnToReplayMain()
261 unsigned int eax, ebx, ecx, edx;
262 libvassert_process_backdoor(CMD_RETURN_REPLAY, 0, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
267 *---------------------------------------------------------------------
269 * VAssert_SetRecordingMain --
271 * Ask vmx for starting or stopping recording.
273 * Results:
275 * Return TRUE on success, or FALSE on failure.
277 * Side effects:
278 * Recording is started or stopped.
280 *---------------------------------------------------------------------
283 char
284 VAssert_SetRecordingMain(char start)
286 uint32 eax, ebx, ecx, edx;
287 if (!VAssert_IsInVM()) {
288 return FALSE;
290 libvassert_process_backdoor(CMD_SET_RECORD, start ? 1 : 2, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
291 return (eax == 1) ? TRUE : FALSE;