/** * One test iteration with one file. * * The test is very simple, we load the file three times * into two different regions. The first two into each of the * regions the for compare usage. The third is loaded into one * and then relocated between the two and other locations a few times. * * @returns number of errors. * @param pszFilename The file to load the mess with. */ static int testLdrOne(const char *pszFilename) { int cErrors = 0; size_t cbImage = 0; struct Load { RTLDRMOD hLdrMod; void *pvBits; size_t cbBits; const char *pszName; } aLoads[6] = { { NULL, NULL, 0, "foo" }, { NULL, NULL, 0, "bar" }, { NULL, NULL, 0, "foobar" }, { NULL, NULL, 0, "kLdr-foo" }, { NULL, NULL, 0, "kLdr-bar" }, { NULL, NULL, 0, "kLdr-foobar" } }; unsigned i; int rc; /* * Load them. */ for (i = 0; i < RT_ELEMENTS(aLoads); i++) { if (!strncmp(aLoads[i].pszName, RT_STR_TUPLE("kLdr-"))) rc = RTLdrOpenkLdr(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); else rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to open '%s'/%d, rc=%Rrc. aborting test.\n", pszFilename, i, rc); Assert(aLoads[i].hLdrMod == NIL_RTLDRMOD); cErrors++; break; } /* size it */ size_t cb = RTLdrSize(aLoads[i].hLdrMod); if (cbImage && cb != cbImage) { RTPrintf("tstLdr-4: Size mismatch '%s'/%d. aborting test.\n", pszFilename, i); cErrors++; break; } aLoads[i].cbBits = cbImage = cb; /* Allocate bits. */ aLoads[i].pvBits = RTMemExecAlloc(cb); if (!aLoads[i].pvBits) { RTPrintf("tstLdr-4: Out of memory '%s'/%d cbImage=%d. aborting test.\n", pszFilename, i, cbImage); cErrors++; break; } /* Get the bits. */ rc = RTLdrGetBits(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, testGetImport, NULL); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to get bits for '%s'/%d, rc=%Rrc. aborting test\n", pszFilename, i, rc); cErrors++; break; } } /* * Execute the code. */ if (!cErrors) { for (i = 0; i < RT_ELEMENTS(aLoads); i += 1) { /* get the pointer. */ RTUINTPTR Value; rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, UINT32_MAX, "DisasmTest1", &Value); if (rc == VERR_SYMBOL_NOT_FOUND) rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, UINT32_MAX, "_DisasmTest1", &Value); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to get symbol \"DisasmTest1\" from load #%d: %Rrc\n", i, rc); cErrors++; break; } DECLCALLBACKPTR(int, pfnDisasmTest1)(void) = (DECLCALLBACKPTR(int, RT_NOTHING)(void))(uintptr_t)Value; /* eeeh. */ RTPrintf("tstLdr-4: pfnDisasmTest1=%p / add-symbol-file %s %#x\n", pfnDisasmTest1, pszFilename, aLoads[i].pvBits); /* call the test function. */ rc = pfnDisasmTest1(); if (rc) { RTPrintf("tstLdr-4: load #%d Test1 -> %#x\n", i, rc); cErrors++; } } } /* * Clean up. */ for (i = 0; i < RT_ELEMENTS(aLoads); i++) { if (aLoads[i].pvBits) RTMemExecFree(aLoads[i].pvBits, aLoads[i].cbBits); if (aLoads[i].hLdrMod) { rc = RTLdrClose(aLoads[i].hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to close '%s' i=%d, rc=%Rrc.\n", pszFilename, i, rc); cErrors++; } } } return cErrors; }
int main() { /* * Set up the test environment. */ RTTEST hTest; RTEXITCODE rcExit = RTTestInitAndCreate("tstX86-1", &hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; RTTestBanner(hTest); g_pbEfPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE); RTTESTI_CHECK(g_pbEfPage != NULL); g_pbEfExecPage = (uint8_t *)RTMemExecAlloc(PAGE_SIZE*2); RTTESTI_CHECK(g_pbEfExecPage != NULL); RTTESTI_CHECK(!((uintptr_t)g_pbEfExecPage & PAGE_OFFSET_MASK)); RTTESTI_CHECK_RC(RTMemProtect(g_pbEfExecPage + PAGE_SIZE, PAGE_SIZE, RTMEM_PROT_NONE), VINF_SUCCESS); #ifdef USE_SIGNAL static int const s_aiSigs[] = { SIGBUS, SIGSEGV, SIGFPE, SIGILL }; for (unsigned i = 0; i < RT_ELEMENTS(s_aiSigs); i++) { struct sigaction SigAct; RTTESTI_CHECK_BREAK(sigaction(s_aiSigs[i], NULL, &SigAct) == 0); SigAct.sa_sigaction = sigHandler; SigAct.sa_flags |= SA_SIGINFO; RTTESTI_CHECK(sigaction(s_aiSigs[i], &SigAct, NULL) == 0); } #else /** @todo implement me. */ #endif if (!RTTestErrorCount(hTest)) { /* * Do the testing. */ int32_t rc; #if 0 RTTestSub(hTest, "Misc 1"); rc = x861_Test1(); if (rc != 0) RTTestFailed(hTest, "x861_Test1 -> %d", rc); RTTestSub(hTest, "Prefixes and groups"); rc = x861_Test2(); if (rc != 0) RTTestFailed(hTest, "x861_Test2 -> %d", rc); RTTestSub(hTest, "fxsave / fxrstor and #PFs"); rc = x861_Test3(); if (rc != 0) RTTestFailed(hTest, "x861_Test3 -> %d", rc); RTTestSub(hTest, "Multibyte NOPs"); rc = x861_Test4(); if (rc != 0) RTTestFailed(hTest, "x861_Test4 -> %d", rc); //#endif RTTestSub(hTest, "Odd encodings and odd ends"); rc = x861_Test5(); if (rc != 0) RTTestFailed(hTest, "x861_Test5 -> %d", rc); //#if 0 RTTestSub(hTest, "Odd floating point encodings"); rc = x861_Test6(); if (rc != 0) RTTestFailed(hTest, "x861_Test5 -> %d", rc); RTTestSub(hTest, "Floating point exceptions ++"); rc = x861_Test7(); if (rc != 0) RTTestFailed(hTest, "x861_Test6 -> %d", rc); #endif rc = x861_TestFPUInstr1(); if (rc != 0) RTTestFailed(hTest, "x861_TestFPUInstr1 -> %d", rc); } return RTTestSummaryAndDestroy(hTest); }