kerneltest/f32test/loader/dllt.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 0 a41df078684a
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// f32test\loader\dllt.cpp
// 
//

#include <e32svr.h>
#include "dllt.h"
#include <d_ldrtst.h>

#ifdef __VC32__
#pragma warning(disable:4706)
#endif

extern "C" TInt _E32Dll(TInt);

extern "C" __MODULE_EXPORT TInt INITFUNC(MDllList&);
extern "C" __MODULE_EXPORT TInt CHKCFUNC();
extern "C" __MODULE_EXPORT TInt RBLKIFUNC(TInt, TInt);

extern "C" __MODULE_IMPORT TInt BLKIFUNC(TInt);

#ifdef __DLL_LINK_TO_EXE
extern "C" IMPORT_C void RegisterConstructorCall(TInt aDllNum);
extern "C" IMPORT_C void RegisterInitCall(TInt aDllNum);
extern "C" IMPORT_C void RegisterDestructorCall(TInt aDllNum);
#endif

void GetDllInfo(SDllInfo& aInfo)
	{
	aInfo.iDllNum=DLLNUM;
	aInfo.iEntryPointAddress=((TInt)&_E32Dll);
	RLdrTest ldd;
	ldd.Open();
	aInfo.iModuleHandle=ldd.ModuleHandleFromAddr((TInt)&_E32Dll);
	ldd.Close();
	}

#ifdef __MODULE_HAS_DATA
class TDllData
	{
public:
	TDllData();
	~TDllData();
public:
	TTime iStartTime;
	TTime iInitTime;
	TInt iTest1;
	TFileName iFileName;
	RLibrary iLib;
	};

class TDllData2
	{
public:
	TDllData2();
	~TDllData2();
public:
	TInt iTest2;
	};

TInt Bss[16];
TInt DllNum=DLLNUM;
TInt Generation=0;
TInt InitFlag=0;
TInt CDFlag=0;
TFullName StartThread=RThread().FullName();
TName StartProcess=RProcess().Name();
TDllData TheDllDataObject;
TDllData2 TheDllDataObject2;

void AddToCDList()
	{
	MDllList* pM=(MDllList*)UserSvr::DllTls(TLS_INDEX);
	if (pM)
		{
		SDllInfo di;
		GetDllInfo(di);
		pM->Add(di);
		}
	}

TDllData::TDllData()
	{
	CDFlag|=1;
	if (CDFlag==3)
		AddToCDList();
#ifndef __DLL_IN_CYCLE
	TInt r;
	CHKDEPS(r);		// Check our dependencies are initialised
	if (r!=KErrNone)
		User::Panic(_L("CHKDEPS"),r);
#endif
	iStartTime.HomeTime();
	iTest1=299792458;
	Dll::FileName(iFileName);
#ifdef __DLL_LINK_TO_EXE
	RegisterConstructorCall(DLLNUM);
#endif
	}

TDllData::~TDllData()
	{
	CDFlag|=4;
	if (CDFlag==15)
		AddToCDList();
#ifdef __DLL_LINK_TO_EXE
	RegisterDestructorCall(DLLNUM);
#endif
	iLib.Close();
	}

TDllData2::TDllData2()
	{
	CDFlag|=2;
	if (CDFlag==3)
		AddToCDList();
	iTest2=DLLNUM^0x3bb;
	iTest2*=iTest2;
	}

TDllData2::~TDllData2()
	{
	CDFlag|=8;
	if (CDFlag==15)
		AddToCDList();
	}
#endif

#ifdef __MODULE_HAS_DATA
void RecordInitCall()
	{
	TheDllDataObject.iInitTime.HomeTime();
	}
#endif

extern "C" __MODULE_EXPORT TInt INITFUNC(MDllList& aList)
	{
	TInt r=KErrNone;
	SDllInfo info;
	GetDllInfo(info);
	if (!aList.IsPresent(info))
		{
		TInt pos=aList.Add(info);
		INITDEPS(r,aList);		// Call Init on our dependencies
		aList.MoveToEnd(pos);
#ifdef __MODULE_HAS_DATA
		if (r==KErrNone)
			r=CHKCFUNC();		// Check initial values for .data/.bss and check constructors have been called
		if (r==KErrNone)
			RecordInitCall();
#endif
#ifdef __DLL_LINK_TO_EXE
		RegisterInitCall(DLLNUM);
#endif
		}
	return r;
	}

extern "C" __MODULE_EXPORT TInt CHKCFUNC()
	{
#ifdef __MODULE_HAS_DATA
	TInt i;
	TInt x=0;
	for (i=0; i<16; ++i) x|=Bss[i];
	if (x)
		return 0x425353;
	if (DllNum!=DLLNUM)
		return 0x44415441;
	if (TheDllDataObject.iTest1!=299792458)
		return 0x54455354;
	x=DLLNUM^0x3bb;
	x*=x;
	if (x!=TheDllDataObject2.iTest2)
		return 0x54535432;
	TInt init_mark=~((DLLNUM+DLLNUMOFFSET)*(DLLNUM+DLLNUMOFFSET));
	if (InitFlag==init_mark)
		return KErrNone;
	if (InitFlag!=0)
		return 0x494e4946;
	if (Generation!=0)
		return 0x47454e;
	if (StartProcess!=RProcess().Name())
		return 0x535450;
	TFileName fn;
	Dll::FileName(fn);
	if (fn!=TheDllDataObject.iFileName)
		return 0x464e414d;
	InitFlag=init_mark;
	RDebug::Print(_L("ChkC %S OK"),&fn);
#endif
	return KErrNone;
	}

extern "C" __MODULE_EXPORT TInt GetGeneration()
	{
#ifdef __MODULE_HAS_DATA
	return Generation;
#else
	return 0;
#endif
	}

extern "C" __MODULE_EXPORT TInt RBLKIFUNC(TInt aInput, TInt aGeneration)
	{
	(void)aGeneration;
#ifdef __MODULE_HAS_DATA
	TInt r=aInput;
	if (aGeneration!=Generation)
		{
		Generation=aGeneration;
		r=BLKIFUNC(aInput);
		RBLKIFUNC_DEPS(r,aGeneration);
		}
	return r;
#else
	return aInput;
#endif
	}

extern "C" __MODULE_EXPORT void SetCloseLib(TInt aLibHandle)
	{
	(void)aLibHandle;
#ifdef __MODULE_HAS_DATA
	TheDllDataObject.iLib.SetHandle(aLibHandle);
#endif
	}