tstLdr.cpp revision 6c2750d8e30830bf114880ca33922b108ab3e942
/* $Id$ */
/** @file
* IPRT - Testcase for parts of RTLdr*.
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <iprt/initterm.h>
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/** If set, don't bitch when failing to resolve symbols. */
static bool g_fDontBitchOnResolveFailure = false;
/** Whether it's kernel model code or not.. */
static bool g_fKernel = true;
/** Module architectur bit count. */
/**
* Resolve an external symbol during RTLdrGetBits().
*
* @returns iprt status code.
* @param hLdrMod The loader module handle.
* @param pszModule Module name.
* @param pszSymbol Symbol name, NULL if uSymbol should be used.
* @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used.
* @param pValue Where to store the symbol value (address).
* @param pvUser User argument.
*/
static DECLCALLBACK(int) testGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
{
/* check the name format and only permit certain names... later, right? */
if (g_cBits == 32)
*pValue = 0xabcdef0f;
else
{
if (g_fKernel)
else
}
return VINF_SUCCESS;
}
/**
* 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 rcRet = 0;
struct Load
{
void *pvBits;
const char *pszName;
} aLoads[6] =
{
};
unsigned i;
/*
* Load them.
*/
for (i = 0; i < RT_ELEMENTS(aLoads); i++)
{
/* adjust load address and announce our intentions */
if (g_cBits == 32)
/* open it */
int rc;
else
if (RT_FAILURE(rc))
{
rcRet++;
break;
}
/* size it */
{
rcRet++;
break;
}
/* Allocate bits. */
{
rcRet++;
break;
}
/* Get the bits. */
rc = RTLdrGetBits(aLoads[i].hLdrMod, aLoads[i].pvBits, aLoads[i].Addr, testGetImport, &aLoads[i].Addr);
if (RT_FAILURE(rc))
{
rcRet++;
break;
}
}
/*
* Continue with the relocations and symbol resolving.
*/
if (!rcRet)
{
{
};
struct Symbols
{
/** The symbol offset. -1 indicates the first time. */
unsigned off;
/** The symbol name. */
const char *pszName;
} aSyms[] =
{
{ ~0, "Entrypoint" },
{ ~0, "SomeExportFunction1" },
{ ~0, "SomeExportFunction2" },
{ ~0, "SomeExportFunction3" },
{ ~0, "SomeExportFunction4" },
{ ~0, "SomeExportFunction5" },
{ ~0, "SomeExportFunction5" },
{ ~0, "DISCoreOne" }
};
unsigned iRel = 0;
for (;;)
{
/* adjust load address and announce our intentions */
if (g_cBits == 32)
/* Compare all which are at the same address. */
{
{
{
{
#if 1
#else
#endif
rcRet++;
break;
}
}
}
}
/* compare symbols. */
for (i = 0; i < RT_ELEMENTS(aLoads); i++)
{
{
int rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, aLoads[i].Addr, aSyms[iSym].pszName, &Value);
if (RT_SUCCESS(rc))
{
{
{
RTPrintf("tstLdr: Mismatching symbol '%s' in '%s'/%d. expected off=%d got %d\n",
rcRet++;
}
}
else
{
RTPrintf("tstLdr: Invalid value for symbol '%s' in '%s'/%d. off=%#x Value=%#x\n",
rcRet++;
}
}
else if (!g_fDontBitchOnResolveFailure)
{
RTPrintf("tstLdr: Failed to resolve symbol '%s' in '%s'/%d.\n", aSyms[iSym].pszName, pszFilename, i);
rcRet++;
}
}
}
break;
/* relocate it stuff. */
int rc = RTLdrRelocate(aLoads[2].hLdrMod, aLoads[2].pvBits, aRels[iRel], aLoads[2].Addr, testGetImport, &aRels[iRel]);
if (RT_FAILURE(rc))
{
RTPrintf("tstLdr: Relocate of '%s' from %#x to %#x failed, rc=%Rrc. Aborting test.\n",
rcRet++;
break;
}
/* next */
iRel++;
}
}
/*
* Clean up.
*/
for (i = 0; i < RT_ELEMENTS(aLoads); i++)
{
{
if (RT_FAILURE(rc))
{
rcRet++;
}
}
}
return rcRet;
}
{
RTR3Init();
int rcRet = 0;
if (argc <= 1)
{
return 1;
}
/*
* Iterate the files.
*/
{
g_fDontBitchOnResolveFailure = true;
g_cBits = 32;
g_cBits = 64;
g_fKernel = 64;
else
{
}
}
/*
* Test result summary.
*/
if (!rcRet)
RTPrintf("tstLdr: SUCCESS\n");
else
return !!rcRet;
}