tstLdr.cpp revision 7258e84ec2fa7ecaf94e1a244bd6d2cf6b3a40a4
/* $Id$ */
/** @file
* InnoTek Portable Runtime - Testcase for parts of RTLdr*.
*/
/*
* Copyright (C) 2006 InnoTek Systemberatung GmbH
*
* 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 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.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/** If set, don't bitch when failing to resolve symbols. */
static bool g_fDontBitchOnResolveFailure = false;
/**
* 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 */
*pValue = 0xabcdef0f;
return VINF_SUCCESS;
}
/**
* One test iteration with one file.
*
* The test is very simple, we load the 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.
*/
{
int rc;
else
if (RT_FAILURE(rc))
{
rcRet++;
break;
}
/* size it */
{
rcRet++;
break;
}
/* Allocate bits. */
{
rcRet++;
break;
}
/* Get the bits. */
if (RT_FAILURE(rc))
{
rcRet++;
break;
}
}
/*
* Continue with the relocations and symbol resolving.
*/
if (!rcRet)
{
{
0xefefef00, /* same. */
0x40404040, /* the other. */
0xefefef00, /* back. */
0x40404040, /* the other. */
0xefefef00, /* back again. */
0x77773420, /* somewhere entirely else. */
0xf0000000, /* somewhere entirely else. */
0x40404040, /* the other. */
0xefefef00 /* back again. */
};
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 (;;)
{
/* Compare all which are at the same address. */
{
{
{
{
rcRet++;
}
}
}
}
/* compare symbols. */
{
{
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, NULL);
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.
*/
{
{
if (RT_FAILURE(rc))
{
rcRet++;
}
}
}
return rcRet;
}
{
RTR3Init();
int rcRet = 0;
if (argc <= 1)
{
return 1;
}
/*
* Iterate the files.
*/
{
g_fDontBitchOnResolveFailure = true;
else
{
}
}
/*
* Test result summary.
*/
if (!rcRet)
RTPrintf("tstLdr: SUCCESS\n");
else
return !!rcRet;
}