tstX86-1.cpp revision e39e9ca944f684a8b310c320b54aa43bbaa072da
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/* $Id$ */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/** @file
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * X86 instruction set exploration/testcase #1.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/*
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Copyright (C) 2011 Oracle Corporation
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * available from http://www.virtualbox.org. This file is free software;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * you can redistribute it and/or modify it under the terms of the GNU
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * General Public License (GPL) as published by the Free Software
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/*******************************************************************************
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync* Header Files *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync*******************************************************************************/
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#include <iprt/test.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#include <iprt/param.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#ifdef RT_OS_WINDOWS
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# include <Windows.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# ifdef RT_OS_DARWIN
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# define _XOPEN_SOURCE
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# endif
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# include <signal.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# include <ucontext.h>
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# define USE_SIGNAL
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#endif
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/*******************************************************************************
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync* Structures and Typedefs *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync*******************************************************************************/
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsynctypedef struct TRAPINFO
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uintptr_t uTrapPC;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uintptr_t uResumePC;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uint8_t u8Trap;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uint8_t cbInstr;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uint8_t auAlignment[sizeof(uintptr_t) * 2 - 2];
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync} TRAPINFO;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsynctypedef TRAPINFO const *PCTRAPINFO;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/*******************************************************************************
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync* Global Variables *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync*******************************************************************************/
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncRT_C_DECLS_BEGIN
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncuint8_t *g_pbEfPage = NULL;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncextern TRAPINFO g_aTrapInfo[];
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncRT_C_DECLS_END
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync/*******************************************************************************
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync* Internal Functions *
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync*******************************************************************************/
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncDECLASM(int32_t) x861_Test1(void);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncstatic PCTRAPINFO findTrapInfo(uintptr_t uTrapPC)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync for (unsigned i = 0; g_aTrapInfo[i].uTrapPC; i++)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (g_aTrapInfo[i].uTrapPC == uTrapPC)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return &g_aTrapInfo[i];
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return NULL;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#ifdef USE_SIGNAL
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncstatic void sigHandler(int iSig, siginfo_t *pSigInfo, void *pvSigCtx)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync ucontext_t *pCtx = (ucontext_t *)pvSigCtx;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# if defined(RT_ARCH_AMD64) && defined(RT_OS_DARWIN)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext->__ss.__rip;
e39e9ca944f684a8b310c320b54aa43bbaa072davboxsync# elif defined(RT_ARCH_AMD64) && defined(RT_OS_FREEBSD)
e39e9ca944f684a8b310c320b54aa43bbaa072davboxsync uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.mc_rip;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# elif defined(RT_ARCH_AMD64)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_RIP];
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# elif defined(RT_ARCH_X86) && defined(RT_OS_DARWIN)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext->__ss.__eip;
e39e9ca944f684a8b310c320b54aa43bbaa072davboxsync# elif defined(RT_ARCH_X86) && defined(RT_OS_FREEBSD)
e39e9ca944f684a8b310c320b54aa43bbaa072davboxsync uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.mc_eip;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# elif defined(RT_ARCH_X86)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_EIP];
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync uintptr_t *puPC = NULL;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync# endif
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync PCTRAPINFO pTrapInfo = findTrapInfo(*puPC);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (pTrapInfo)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /** @todo verify the kind of trap */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync *puPC = pTrapInfo->uResumePC;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /* die */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync signal(iSig, SIG_IGN);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#endif
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsyncint main()
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync{
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /*
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Set up the test environment.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTTEST hTest;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTEXITCODE rcExit = RTTestInitAndCreate("tstX86-1", &hTest);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (rcExit != RTEXITCODE_SUCCESS)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return rcExit;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync g_pbEfPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTTESTI_CHECK(g_pbEfPage != NULL);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#ifdef USE_SIGNAL
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync static int const s_aiSigs[] = { SIGBUS, SIGSEGV, SIGFPE };
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync for (unsigned i = 0; i < RT_ELEMENTS(s_aiSigs); i++)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync struct sigaction SigAct;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTTESTI_CHECK_BREAK(sigaction(s_aiSigs[i], NULL, &SigAct) == 0);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync SigAct.sa_sigaction = sigHandler;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync SigAct.sa_flags |= SA_SIGINFO;
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTTESTI_CHECK(sigaction(s_aiSigs[i], &SigAct, NULL) == 0);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#else
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /** @todo implement me. */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync#endif
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (!RTTestErrorCount(hTest))
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync {
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync /*
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync * Do the testing.
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync */
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTTestSub(hTest, "part 1");
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync int32_t rc = x861_Test1();
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync if (rc != 0)
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync RTTestFailed(hTest, "x861_Test1 -> %d", rc);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync }
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync return RTTestSummaryAndDestroy(hTest);
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync}
65c72795ab90d3daefa759b716fbb5c6352c7a56vboxsync