VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstX86-1.cpp@ 93905

Last change on this file since 93905 was 93555, checked in by vboxsync, 3 years ago

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. [build fix] bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1/* $Id: tstX86-1.cpp 93555 2022-02-02 23:07:34Z vboxsync $ */
2/** @file
3 * X86 instruction set exploration/testcase #1.
4 */
5
6/*
7 * Copyright (C) 2011-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/test.h>
23#include <VBox/param.h>
24#include <iprt/mem.h>
25#include <iprt/errcore.h>
26#include <iprt/assert.h>
27#include <iprt/x86.h>
28
29#ifdef RT_OS_WINDOWS
30# include <iprt/win/windows.h>
31#else
32# ifdef RT_OS_DARWIN
33# define _XOPEN_SOURCE
34# endif
35# include <signal.h>
36# include <ucontext.h>
37# define USE_SIGNAL
38#endif
39
40
41/*********************************************************************************************************************************
42* Structures and Typedefs *
43*********************************************************************************************************************************/
44typedef struct TRAPINFO
45{
46 uintptr_t uTrapPC;
47 uintptr_t uResumePC;
48 uint8_t u8Trap;
49 uint8_t cbInstr;
50 uint8_t auAlignment[sizeof(uintptr_t) * 2 - 2];
51} TRAPINFO;
52typedef TRAPINFO const *PCTRAPINFO;
53
54
55/*********************************************************************************************************************************
56* Global Variables *
57*********************************************************************************************************************************/
58RT_C_DECLS_BEGIN
59uint8_t *g_pbEfPage = NULL;
60uint8_t *g_pbEfExecPage = NULL;
61extern TRAPINFO g_aTrapInfo[];
62RT_C_DECLS_END
63
64
65/*********************************************************************************************************************************
66* Internal Functions *
67*********************************************************************************************************************************/
68DECLASM(int32_t) x861_Test1(void);
69DECLASM(int32_t) x861_Test2(void);
70DECLASM(int32_t) x861_Test3(void);
71DECLASM(int32_t) x861_Test4(void);
72DECLASM(int32_t) x861_Test5(void);
73DECLASM(int32_t) x861_Test6(void);
74DECLASM(int32_t) x861_Test7(void);
75DECLASM(int32_t) x861_TestFPUInstr1(void);
76
77
78
79static PCTRAPINFO findTrapInfo(uintptr_t uTrapPC, uintptr_t uTrapSP)
80{
81 /* Search by trap program counter. */
82 for (unsigned i = 0; g_aTrapInfo[i].uTrapPC; i++)
83 if (g_aTrapInfo[i].uTrapPC == uTrapPC)
84 return &g_aTrapInfo[i];
85
86 /* Search by return address. */
87 uintptr_t uReturn = *(uintptr_t *)uTrapSP;
88 for (unsigned i = 0; g_aTrapInfo[i].uTrapPC; i++)
89 if (g_aTrapInfo[i].uTrapPC + g_aTrapInfo[i].cbInstr == uReturn)
90 return &g_aTrapInfo[i];
91
92 return NULL;
93}
94
95#ifdef USE_SIGNAL
96static void sigHandler(int iSig, siginfo_t *pSigInfo, void *pvSigCtx)
97{
98 ucontext_t *pCtx = (ucontext_t *)pvSigCtx;
99 NOREF(pSigInfo);
100
101# if defined(RT_ARCH_AMD64) && defined(RT_OS_DARWIN)
102 uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext->__ss.__rip;
103 uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext->__ss.__rsp;
104 uintptr_t uTrapNo = pCtx->uc_mcontext->__es.__trapno;
105 uintptr_t uErr = pCtx->uc_mcontext->__es.__err;
106 uintptr_t uCr2 = pCtx->uc_mcontext->__es.__faultvaddr;
107
108# elif defined(RT_ARCH_AMD64) && defined(RT_OS_FREEBSD)
109 uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.mc_rip;
110 uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.mc_rsp;
111 uintptr_t uTrapNo = ~(uintptr_t)0;
112 uintptr_t uErr = ~(uintptr_t)0;
113 uintptr_t uCr2 = ~(uintptr_t)0;
114
115# elif defined(RT_ARCH_AMD64)
116 uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_RIP];
117 uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_RSP];
118 uintptr_t uTrapNo = pCtx->uc_mcontext.gregs[REG_TRAPNO];
119 uintptr_t uErr = pCtx->uc_mcontext.gregs[REG_ERR];
120 uintptr_t uCr2 = pCtx->uc_mcontext.gregs[REG_CR2];
121
122# elif defined(RT_ARCH_X86) && defined(RT_OS_DARWIN)
123 uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext->__ss.__eip;
124 uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext->__ss.__esp;
125 uintptr_t uTrapNo = pCtx->uc_mcontext->__es.__trapno;
126 uintptr_t uErr = pCtx->uc_mcontext->__es.__err;
127 uintptr_t uCr2 = pCtx->uc_mcontext->__es.__faultvaddr;
128
129# elif defined(RT_ARCH_X86) && defined(RT_OS_FREEBSD)
130 uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.mc_eip;
131 uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.mc_esp;
132 uintptr_t uTrapNo = ~(uintptr_t)0;
133 uintptr_t uErr = ~(uintptr_t)0;
134 uintptr_t uCr2 = ~(uintptr_t)0;
135
136# elif defined(RT_ARCH_X86)
137 uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_EIP];
138 uintptr_t *puSP = (uintptr_t *)&pCtx->uc_mcontext.gregs[REG_ESP];
139 uintptr_t uTrapNo = pCtx->uc_mcontext.gregs[REG_TRAPNO];
140 uintptr_t uErr = pCtx->uc_mcontext.gregs[REG_ERR];
141# ifdef REG_CR2 /** @todo ... */
142 uintptr_t uCr2 = pCtx->uc_mcontext.gregs[REG_CR2];
143# else
144 uintptr_t uCr2 = ~(uintptr_t)0;
145# endif
146
147# else
148 uintptr_t *puPC = NULL;
149 uintptr_t *puSP = NULL;
150 uintptr_t uTrapNo = ~(uintptr_t)0;
151 uintptr_t uErr = ~(uintptr_t)0;
152 uintptr_t uCr2 = ~(uintptr_t)0;
153# endif
154 if (uTrapNo == X86_XCPT_PF)
155 RTAssertMsg2("tstX86-1: Trap #%#04x err=%#06x at %p / %p\n", uTrapNo, uErr, *puPC, uCr2);
156 else
157 RTAssertMsg2("tstX86-1: Trap #%#04x err=%#06x at %p\n", uTrapNo, uErr, *puPC);
158
159 PCTRAPINFO pTrapInfo = findTrapInfo(*puPC, *puSP);
160 if (pTrapInfo)
161 {
162 if (pTrapInfo->u8Trap != uTrapNo && uTrapNo != ~(uintptr_t)0)
163 RTAssertMsg2("tstX86-1: Expected #%#04x, got #%#04x\n", pTrapInfo->u8Trap, uTrapNo);
164 else
165 {
166 if (*puPC != pTrapInfo->uTrapPC)
167 *puSP += sizeof(uintptr_t);
168 *puPC = pTrapInfo->uResumePC;
169 return;
170 }
171 }
172 else
173 RTAssertMsg2("tstX86-1: Unexpected trap!\n");
174
175 /* die */
176 signal(iSig, SIG_IGN);
177}
178#else
179
180#endif
181
182
183
184int main()
185{
186 /*
187 * Set up the test environment.
188 */
189 RTTEST hTest;
190 RTEXITCODE rcExit = RTTestInitAndCreate("tstX86-1", &hTest);
191 if (rcExit != RTEXITCODE_SUCCESS)
192 return rcExit;
193 RTTestBanner(hTest);
194
195 g_pbEfPage = (uint8_t *)RTTestGuardedAllocTail(hTest, HOST_PAGE_SIZE);
196 RTTESTI_CHECK(g_pbEfPage != NULL);
197
198 g_pbEfExecPage = (uint8_t *)RTMemExecAlloc(HOST_PAGE_SIZE*2);
199 RTTESTI_CHECK(g_pbEfExecPage != NULL);
200 RTTESTI_CHECK(!((uintptr_t)g_pbEfExecPage & HOST_PAGE_OFFSET_MASK));
201 RTTESTI_CHECK_RC(RTMemProtect(g_pbEfExecPage + HOST_PAGE_SIZE, HOST_PAGE_SIZE, RTMEM_PROT_NONE), VINF_SUCCESS);
202
203#ifdef USE_SIGNAL
204 static int const s_aiSigs[] = { SIGBUS, SIGSEGV, SIGFPE, SIGILL };
205 for (unsigned i = 0; i < RT_ELEMENTS(s_aiSigs); i++)
206 {
207 struct sigaction SigAct;
208 RTTESTI_CHECK_BREAK(sigaction(s_aiSigs[i], NULL, &SigAct) == 0);
209 SigAct.sa_sigaction = sigHandler;
210 SigAct.sa_flags |= SA_SIGINFO;
211 RTTESTI_CHECK(sigaction(s_aiSigs[i], &SigAct, NULL) == 0);
212 }
213#else
214 /** @todo implement me. */
215#endif
216
217
218 if (!RTTestErrorCount(hTest))
219 {
220 /*
221 * Do the testing.
222 */
223 int32_t rc;
224#if 0
225 RTTestSub(hTest, "Misc 1");
226 rc = x861_Test1();
227 if (rc != 0)
228 RTTestFailed(hTest, "x861_Test1 -> %d", rc);
229
230 RTTestSub(hTest, "Prefixes and groups");
231 rc = x861_Test2();
232 if (rc != 0)
233 RTTestFailed(hTest, "x861_Test2 -> %d", rc);
234
235 RTTestSub(hTest, "fxsave / fxrstor and #PFs");
236 rc = x861_Test3();
237 if (rc != 0)
238 RTTestFailed(hTest, "x861_Test3 -> %d", rc);
239
240 RTTestSub(hTest, "Multibyte NOPs");
241 rc = x861_Test4();
242 if (rc != 0)
243 RTTestFailed(hTest, "x861_Test4 -> %d", rc);
244//#endif
245
246 RTTestSub(hTest, "Odd encodings and odd ends");
247 rc = x861_Test5();
248 if (rc != 0)
249 RTTestFailed(hTest, "x861_Test5 -> %d", rc);
250
251//#if 0
252 RTTestSub(hTest, "Odd floating point encodings");
253 rc = x861_Test6();
254 if (rc != 0)
255 RTTestFailed(hTest, "x861_Test5 -> %d", rc);
256
257 RTTestSub(hTest, "Floating point exceptions ++");
258 rc = x861_Test7();
259 if (rc != 0)
260 RTTestFailed(hTest, "x861_Test6 -> %d", rc);
261#endif
262
263 rc = x861_TestFPUInstr1();
264 if (rc != 0)
265 RTTestFailed(hTest, "x861_TestFPUInstr1 -> %d", rc);
266 }
267
268 return RTTestSummaryAndDestroy(hTest);
269}
270
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette