libvassert: vmware VAssert support.
- BSD-licensed Code gratefully taken from the project at http://en.sourceforge.jp/projects/sfnet_vassertlinuxsdk/ - For more information on vmware VAssert, a powerful debugging facility usable under vmware, see: www.vmware.com/pdf/ws65_vassert_programming.pdf
This commit is contained in:
		
							parent
							
								
									f614d0015a
								
							
						
					
					
						commit
						914d02825f
					
				@ -21,7 +21,7 @@ SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libdriver libnetdriver \
 | 
				
			|||||||
	libddekit
 | 
						libddekit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
 | 
					.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
 | 
				
			||||||
SUBDIR+= libelf libminc libcrypt libterminfo libcurses
 | 
					SUBDIR+= libelf libminc libcrypt libterminfo libcurses libvassert
 | 
				
			||||||
.endif
 | 
					.endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.if ${COMPILER_TYPE} == "ack"
 | 
					.if ${COMPILER_TYPE} == "ack"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								lib/libvassert/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								lib/libvassert/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					# Makefile for libvassert library
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LIB=    vassert
 | 
				
			||||||
 | 
					SRCS=	backdoor.S vassert.c
 | 
				
			||||||
 | 
					INCS+=	vassert.h
 | 
				
			||||||
 | 
					INCSDIR= /usr/include/minix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.include <bsd.lib.mk>
 | 
				
			||||||
							
								
								
									
										22
									
								
								lib/libvassert/backdoor.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								lib/libvassert/backdoor.S
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					.global libvassert_process_backdoor 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					libvassert_process_backdoor:
 | 
				
			||||||
 | 
						push   %ebx
 | 
				
			||||||
 | 
						push   %esi
 | 
				
			||||||
 | 
						mov    0xc(%esp),%ecx
 | 
				
			||||||
 | 
						mov    0x14(%esp),%edx
 | 
				
			||||||
 | 
						mov    0x10(%esp),%ebx
 | 
				
			||||||
 | 
						mov    $0x564d5868,%eax
 | 
				
			||||||
 | 
						out    %eax,(%dx)
 | 
				
			||||||
 | 
						mov    0x18(%esp),%esi
 | 
				
			||||||
 | 
						mov    %eax,(%esi)
 | 
				
			||||||
 | 
						mov    0x20(%esp),%eax
 | 
				
			||||||
 | 
						mov    %ecx,(%eax)
 | 
				
			||||||
 | 
						mov    0x24(%esp),%eax
 | 
				
			||||||
 | 
						mov    %edx,(%eax)
 | 
				
			||||||
 | 
						mov    0x1c(%esp),%eax
 | 
				
			||||||
 | 
						mov    %ebx,(%eax)
 | 
				
			||||||
 | 
						pop    %esi
 | 
				
			||||||
 | 
						pop    %ebx
 | 
				
			||||||
 | 
						ret
 | 
				
			||||||
							
								
								
									
										298
									
								
								lib/libvassert/vassert.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								lib/libvassert/vassert.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,298 @@
 | 
				
			|||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <setjmp.h>
 | 
				
			||||||
 | 
					#include <minix/config.h>
 | 
				
			||||||
 | 
					#include <minix/const.h>
 | 
				
			||||||
 | 
					#include <minix/ipc.h>
 | 
				
			||||||
 | 
					#include <minix/com.h>
 | 
				
			||||||
 | 
					#include "vassert.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VAssert_StateWrapper vassert_state ALIGNED(VASSERT_PAGE_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TRUE 1
 | 
				
			||||||
 | 
					#define FALSE 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAGIC_CMD  0x564d5868
 | 
				
			||||||
 | 
					#define MAGIC_PORT 0x5658
 | 
				
			||||||
 | 
					#define HIGH_BAND_PORT 0x5659
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BACKDOOR_PORT 		51
 | 
				
			||||||
 | 
					#define BACKDOOR_HB_PORT	1
 | 
				
			||||||
 | 
					#define CMD_SET_ADDRESS 	BACKDOOR_PORT|(1<<16)
 | 
				
			||||||
 | 
					#define CMD_RETURN_REPLAY 	BACKDOOR_PORT|(2<<16)
 | 
				
			||||||
 | 
					#define CMD_GO_LIVE		BACKDOOR_PORT|(3<<16)
 | 
				
			||||||
 | 
					#define CMD_LOG			BACKDOOR_HB_PORT|(4<<16)
 | 
				
			||||||
 | 
					#define CMD_SET_RECORD		47
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOG_MAX 512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef char Bool;
 | 
				
			||||||
 | 
					typedef unsigned int uint32;
 | 
				
			||||||
 | 
					typedef unsigned long long uint64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef VM_X86_64
 | 
				
			||||||
 | 
					typedef uint64 VA;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					typedef uint32 VA;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static sigjmp_buf segv_jmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * sig_segv --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Customed SEGV signal handler for VAssert_IsInVM.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *    None.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    None.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					sig_segv(int sig_no)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   /* jumping to error handling in VAssert_IsInVM. */
 | 
				
			||||||
 | 
					   siglongjmp(segv_jmp, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * VAssert_IsInVM --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Check if we are in virtual world.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *    Return TRUE on success, or FALSE on failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    None.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Bool
 | 
				
			||||||
 | 
					VAssert_IsInVM(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   uint32 eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					   static Bool inVM = FALSE;
 | 
				
			||||||
 | 
					   static Bool tested = FALSE;
 | 
				
			||||||
 | 
					   if (!tested) {
 | 
				
			||||||
 | 
					      /* Error handling. */
 | 
				
			||||||
 | 
					      if (sigsetjmp(segv_jmp, 0) != 0) {
 | 
				
			||||||
 | 
					         signal(SIGSEGV, SIG_DFL);
 | 
				
			||||||
 | 
					         inVM = FALSE;
 | 
				
			||||||
 | 
					         return inVM;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      tested = TRUE;
 | 
				
			||||||
 | 
					      /* Install custom handler. */
 | 
				
			||||||
 | 
					      signal(SIGSEGV, sig_segv);
 | 
				
			||||||
 | 
					      /* Test if we are in a VM. */
 | 
				
			||||||
 | 
					      libvassert_process_backdoor(0x0a, 0, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					      signal(SIGSEGV, SIG_DFL);
 | 
				
			||||||
 | 
					      inVM = TRUE;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   return inVM;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * VAssert_Init --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Tell vmx that vassert is inited.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *    Return 0 on success, or -1 on failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    None
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char
 | 
				
			||||||
 | 
					VAssert_Init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   uint32 eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					   VA page_address = (VA) &vassert_state.inReplay, ph;
 | 
				
			||||||
 | 
					   if (!VAssert_IsInVM()) {
 | 
				
			||||||
 | 
					      return -1;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   bzero((char*) &vassert_state, sizeof vassert_state);
 | 
				
			||||||
 | 
					#ifndef __minix
 | 
				
			||||||
 | 
					   /* Lock the page. */
 | 
				
			||||||
 | 
					   if (mlock(&vassert_state, sizeof vassert_state)) {
 | 
				
			||||||
 | 
					      return -1;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   /* vmware expects a linear address (or is simply forgetting
 | 
				
			||||||
 | 
					    * to adjust the given address for segments)
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   if(sys_umap(SELF, D, page_address, 1, &ph)) {
 | 
				
			||||||
 | 
					   	printf("VAssert_Init: sys_umap failed\n");
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   libvassert_process_backdoor(CMD_SET_ADDRESS, ph,
 | 
				
			||||||
 | 
					   	MAGIC_PORT|(1<<16), &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   return (eax != -1) ? 0 : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * VAssert_Uninit --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Tell vmx that vassert is finalized.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *    Return 0 on success, or -1 on failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    None
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char
 | 
				
			||||||
 | 
					VAssert_Uninit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   unsigned int eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					   if (!VAssert_IsInVM()) {
 | 
				
			||||||
 | 
					      return -1;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   libvassert_process_backdoor(CMD_SET_ADDRESS, 0, MAGIC_PORT|(0<<16), &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					   return (eax != -1) ? 0 : 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * VAssert_LogMain --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Print message to a text file on host side.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *    None
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    Write to a text file with fixed name.
 | 
				
			||||||
 | 
					 *    If the file exists, host UI will ask for append/replace/ignore
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					VAssert_LogMain(const char *format, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   unsigned int eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					   char buf[LOG_MAX];
 | 
				
			||||||
 | 
					   unsigned int len = 0;
 | 
				
			||||||
 | 
					   va_list ap;
 | 
				
			||||||
 | 
					   va_start(ap, format);
 | 
				
			||||||
 | 
					   len = vsnprintf(buf, LOG_MAX, format, ap);
 | 
				
			||||||
 | 
					   va_end(ap);
 | 
				
			||||||
 | 
					   __asm__ __volatile__("cld; rep outsb;"
 | 
				
			||||||
 | 
					                        : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) 
 | 
				
			||||||
 | 
					                        : "0"(MAGIC_CMD), "1"(CMD_LOG), "2"(len), "d"(HIGH_BAND_PORT), "S"(buf)
 | 
				
			||||||
 | 
					                        : "memory"
 | 
				
			||||||
 | 
					                       );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * VAssert_GoLiveMain --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Make the vm which is in replay exit replay.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *    None
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    Replay is stopped.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					VAssert_GoLiveMain()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   unsigned int eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					   vassert_state.inReplay = 0;
 | 
				
			||||||
 | 
					   libvassert_process_backdoor(CMD_GO_LIVE, 0, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * VAssert_ReturnToReplayMain --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Called after the custom work is done, and replay is to continue.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *    None
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    Replay is continued from pause.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					VAssert_ReturnToReplayMain()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   unsigned int eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					   libvassert_process_backdoor(CMD_RETURN_REPLAY, 0, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * VAssert_SetRecordingMain --
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 *    Ask vmx for starting or stopping recording.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Results:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *    Return TRUE on success, or FALSE on failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Side effects:
 | 
				
			||||||
 | 
					 *    Recording is started or stopped.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *---------------------------------------------------------------------
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char
 | 
				
			||||||
 | 
					VAssert_SetRecordingMain(char start)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   uint32 eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					   if (!VAssert_IsInVM()) {
 | 
				
			||||||
 | 
					      return FALSE;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   libvassert_process_backdoor(CMD_SET_RECORD, start ? 1 : 2, MAGIC_PORT, &eax, &ebx, &ecx, &edx);
 | 
				
			||||||
 | 
					   return (eax == 1) ? TRUE : FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										138
									
								
								lib/libvassert/vassert.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								lib/libvassert/vassert.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,138 @@
 | 
				
			|||||||
 | 
					#ifndef _VASSERT_H_
 | 
				
			||||||
 | 
					#define _VASSERT_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C"
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#endif /*__cplusplus*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIGNED(n) __attribute__((__aligned__(n)))
 | 
				
			||||||
 | 
					#define VASSERT_TRIGGER_OFFSET 1221
 | 
				
			||||||
 | 
					#define VASSERT_PAGE_SIZE      4096
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Need to align at 4K. */
 | 
				
			||||||
 | 
					/* Ensure the inReplay flag is on its own page. */
 | 
				
			||||||
 | 
					#pragma pack(1)
 | 
				
			||||||
 | 
					typedef struct VAssert_StateWrapper {
 | 
				
			||||||
 | 
					   char space1[VASSERT_TRIGGER_OFFSET];
 | 
				
			||||||
 | 
					   volatile char inReplay;
 | 
				
			||||||
 | 
					   char space[VASSERT_PAGE_SIZE - VASSERT_TRIGGER_OFFSET - sizeof(char)];
 | 
				
			||||||
 | 
					} VAssert_StateWrapper;
 | 
				
			||||||
 | 
					#pragma pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern VAssert_StateWrapper vassert_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * User-selectable standard functions.
 | 
				
			||||||
 | 
					 * XXX: Document these, in coordination with the SDK docs.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__KERNEL__)
 | 
				
			||||||
 | 
					#  define KERNEL_VASSERT
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef KERNEL_VASSERT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  ifndef VASSERT_CUSTOM_ASSERT
 | 
				
			||||||
 | 
					#     define VASSERT_CUSTOM_ASSERT(expr)
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  ifndef VASSERT_CUSTOM_ABORT
 | 
				
			||||||
 | 
					#     include <linux/kernel.h>
 | 
				
			||||||
 | 
					#     define VASSERT_CUSTOM_ABORT() ((void)0) // printk(KERN_ALERT"VAssert abort at %s: %d", __FILE__, __LINE__)
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  ifndef VASSERT_CUSTOM_LOG
 | 
				
			||||||
 | 
					#     include <linux/kernel.h>
 | 
				
			||||||
 | 
					#     define VASSERT_CUSTOM_LOG printk
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#  ifndef VASSERT_CUSTOM_ASSERT
 | 
				
			||||||
 | 
					#     include <assert.h>
 | 
				
			||||||
 | 
					#     define VASSERT_CUSTOM_ASSERT assert
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  ifndef VASSERT_CUSTOM_ABORT
 | 
				
			||||||
 | 
					#     include <stdlib.h>
 | 
				
			||||||
 | 
					#     define VASSERT_CUSTOM_ABORT abort
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#  ifndef VASSERT_CUSTOM_LOG
 | 
				
			||||||
 | 
					#     include <stdio.h>
 | 
				
			||||||
 | 
					#     define VASSERT_CUSTOM_LOG printf
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Results: 0 if successful, -1 if not. */
 | 
				
			||||||
 | 
					// XXX need to automatic de-register trigger page when the program quits
 | 
				
			||||||
 | 
					extern char VAssert_Init(void);
 | 
				
			||||||
 | 
					extern char VAssert_Uninit(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * These functions should not be called directly; they need to be wrapped.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					extern void VAssert_LogMain(const char *format, ...);
 | 
				
			||||||
 | 
					extern void VAssert_GoLiveMain(void);
 | 
				
			||||||
 | 
					extern void VAssert_ReturnToReplayMain(void);
 | 
				
			||||||
 | 
					extern char VAssert_Trace(size_t max_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef VASSERT_ALWAYS_EXECUTE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAssert_Assert(expr)              \
 | 
				
			||||||
 | 
					do {                                      \
 | 
				
			||||||
 | 
					   VASSERT_CUSTOM_ASSERT(expr);           \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAssert_Log(args)                 \
 | 
				
			||||||
 | 
					do {                                      \
 | 
				
			||||||
 | 
					   VASSERT_CUSTOM_LOG args;               \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAssert_BeginBlock
 | 
				
			||||||
 | 
					#define VAssert_EndBlock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else /* VASSERT_ALWAYS_EXECUTE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAssert_Assert(expr)              \
 | 
				
			||||||
 | 
					do {                                      \
 | 
				
			||||||
 | 
					   if (vassert_state.inReplay) {          \
 | 
				
			||||||
 | 
					      if (!(expr)) {                      \
 | 
				
			||||||
 | 
					         VAssert_GoLiveMain();            \
 | 
				
			||||||
 | 
					         VASSERT_CUSTOM_ABORT();          \
 | 
				
			||||||
 | 
					      } else {                            \
 | 
				
			||||||
 | 
					         VAssert_ReturnToReplayMain();    \
 | 
				
			||||||
 | 
					      }                                   \
 | 
				
			||||||
 | 
					   }                                      \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAssert_Log(args)                 \
 | 
				
			||||||
 | 
					do {                                      \
 | 
				
			||||||
 | 
					   if (vassert_state.inReplay) {          \
 | 
				
			||||||
 | 
					      VAssert_LogMain args;               \
 | 
				
			||||||
 | 
					      VAssert_ReturnToReplayMain();       \
 | 
				
			||||||
 | 
					   }                                      \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAssert_BeginBlock if (vassert_state.inReplay)
 | 
				
			||||||
 | 
					#define VAssert_EndBlock VAssert_ReturnToReplayMain()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* VASSERT_ALWAYS_EXECUTE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * Record/Replay functionality
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Results: True if successful, false if not.
 | 
				
			||||||
 | 
					 * Input: True to start recording, false to stop.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					extern char VAssert_SetRecordingMain(char start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAssert_StartRecording() VAssert_SetRecordingMain(1)
 | 
				
			||||||
 | 
					#define VAssert_StopRecording() VAssert_SetRecordingMain(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif /*__cplusplus*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /*_VASSERT_H_*/
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user