kerneltest/e32test/dll/d_ldrtst.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/dll/d_ldrtst.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,276 @@
+// Copyright (c) 1998-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\d_ldrtst.cpp
+// LDD for testing loader
+// 
+//
+
+#include <kernel/kern_priv.h>
+#include "d_ldrtst.h"
+
+const TInt KMajorVersionNumber=0;
+const TInt KMinorVersionNumber=1;
+const TInt KBuildVersionNumber=1;
+
+class DLdrTest;
+class DLdrTestFactory : public DLogicalDevice
+//
+// Test LDD factory
+//
+	{
+public:
+	DLdrTestFactory();
+	virtual TInt Install();
+	virtual void GetCaps(TDes8& aDes) const;
+	virtual TInt Create(DLogicalChannelBase*& aChannel);
+	};
+
+class DLdrTest : public DLogicalChannelBase
+//
+// Test logical channel
+//
+	{
+public:
+	virtual ~DLdrTest();
+protected:
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
+public:
+	TInt GetCodeSegInfo(TAny* aHandle, TAny* aDest);
+	TAny* ModuleCodeSeg(TModuleHandle aModuleHandle);
+	TAny* ProcessCodeSeg(TInt aProcessHandle);
+	TAny* LibraryCodeSeg(TInt aLibraryHandle);
+	TInt GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax);
+	TAny* CodeSegFromAddr(TLinAddr aAddr);
+	TModuleHandle ModuleHandleFromAddr(TLinAddr aAddr);
+	TInt ProcessSMPUnsafeCount(TInt aProcessHandle);
+private:
+	SDblQueLink* FindCodeSegQueueAnchor();
+	};
+
+DECLARE_STANDARD_LDD()
+	{
+	return new DLdrTestFactory;
+	}
+
+DLdrTestFactory::DLdrTestFactory()
+//
+// Constructor
+//
+	{
+	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+	}
+
+TInt DLdrTestFactory::Create(DLogicalChannelBase*& aChannel)
+//
+// Create a new DLdrTest on this logical device
+//
+	{
+	aChannel=new DLdrTest;
+	return aChannel?KErrNone:KErrNoMemory;
+	}
+
+TInt DLdrTestFactory::Install()
+//
+// Install the LDD - overriding pure virtual
+//
+	{
+	return SetName(&KLdrTestLddName);
+	}
+
+void DLdrTestFactory::GetCaps(TDes8& aDes) const
+//
+// Get capabilities - overriding pure virtual
+//
+	{
+	TCapsTestV01 b;
+	b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+    Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
+	}
+
+TInt DLdrTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
+//
+// Create channel
+//
+	{
+
+	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
+		return KErrNotSupported;
+	return KErrNone;
+	}
+
+DLdrTest::~DLdrTest()
+//
+// Destructor
+//
+	{
+	}
+
+TInt DLdrTest::GetCodeSegInfo(TAny* aHandle, TAny* aDest)
+	{
+	TCodeSegCreateInfo info;
+	DCodeSeg* pS=DCodeSeg::VerifyHandle(aHandle);
+	if (pS)
+		{
+		Kern::AccessCode();
+		pS->Info(info);
+		Kern::EndAccessCode();
+		kumemput32(aDest, &info, sizeof(info));
+		return KErrNone;
+		}
+	return KErrArgument;
+	}
+
+TAny* DLdrTest::ModuleCodeSeg(TModuleHandle aModuleHandle)
+	{
+	DCodeSeg* pS=DCodeSeg::VerifyHandle(aModuleHandle);
+	if(!pS)
+		{
+		Kern::AccessCode();
+		DCodeSeg::CodeSegFromEntryPoint((TLinAddr)aModuleHandle);  // ignore returned DCodeSeg*
+		Kern::EndAccessCode();
+		}
+	return pS;
+	}
+
+TAny* DLdrTest::CodeSegFromAddr(TLinAddr aAddr)
+	{
+	Kern::AccessCode();
+	DCodeSeg* s = Kern::CodeSegFromAddress(aAddr, Kern::CurrentThread().iOwningProcess);
+	Kern::EndAccessCode();
+	return s;
+	}
+
+TModuleHandle DLdrTest::ModuleHandleFromAddr(TLinAddr aAddr)
+	{
+	TModuleHandle h = (TModuleHandle)CodeSegFromAddr(aAddr);
+	if(!h)
+		h = (TModuleHandle)aAddr;
+	return h;
+	}
+
+TAny* DLdrTest::ProcessCodeSeg(TInt aProcessHandle)
+	{
+	DCodeSeg* pS=NULL;
+	DThread& t=Kern::CurrentThread();
+	NKern::LockSystem();
+	DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess);
+	if (pP)
+		{
+		pS=pP->iCodeSeg;
+		if (!pS)
+			pS=pP->iTempCodeSeg;
+		}
+	NKern::UnlockSystem();
+	return pS;
+	}
+
+TAny* DLdrTest::LibraryCodeSeg(TInt aLibraryHandle)
+	{
+	DCodeSeg* pS=NULL;
+	DThread& t=Kern::CurrentThread();
+	NKern::LockSystem();
+	DLibrary* pL=(DLibrary*)t.ObjectFromHandle(aLibraryHandle, ELibrary);
+	if (pL)
+		pS=pL->iCodeSeg;
+	NKern::UnlockSystem();
+	return pS;
+	}
+
+SDblQueLink* DLdrTest::FindCodeSegQueueAnchor()
+	{
+	SDblQueLink* p=&iDevice->iCodeSeg->iLink;	// this device driver's code segment
+	for (;;)
+		{
+		p=p->iPrev;
+		DCodeSeg* s=_LOFF(p, DCodeSeg, iLink);
+		if (s->iExeCodeSeg==s && (s->iAttr & ECodeSegAttKernel))
+			{
+			// s is the kernel's code segment, which is the first one to be created
+			return s->iLink.iPrev;
+			}
+		}
+	}
+
+TInt DLdrTest::GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax)
+	{
+	if (aMax<=0)
+		return KErrArgument;
+	RLdrTest::SEntry list[128];
+	Kern::AccessCode();
+	SDblQueLink* anchor=FindCodeSegQueueAnchor();
+	SDblQueLink* p=anchor->iNext;
+	if (aMax>128)
+		aMax=128;
+	TInt n=0;
+	for(; p!=anchor && n<aMax; p=p->iNext, ++n)
+		{
+		DCodeSeg* s=_LOFF(p, DCodeSeg, iLink);
+		list[n].iHandle=s;
+		list[n].iUid3=(TUint32)s->iUids.iUid[2].iUid;
+		}
+	Kern::EndAccessCode();
+	if (n>0)
+		kumemput32(aList, list, n*sizeof(RLdrTest::SEntry));
+	return n;
+	}
+
+TInt DLdrTest::ProcessSMPUnsafeCount(TInt aProcessHandle)
+	{
+	TInt count=KErrNotFound;
+	DThread& t=Kern::CurrentThread();
+	NKern::LockSystem();
+	DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess);
+	if (pP)
+		count=pP->iSMPUnsafeCount;
+	NKern::UnlockSystem();
+	return count;
+	}
+
+TInt DLdrTest::Request(TInt aFunction, TAny* a1, TAny* a2)
+	{
+	TInt r=KErrNone;
+	switch (aFunction)
+		{
+		case RLdrTest::EControlGetCodeSegInfo:
+			r=GetCodeSegInfo(a1,a2);
+ 			break;
+		case RLdrTest::EControlProcessCodeSeg:
+			r=(TInt)ProcessCodeSeg((TInt)a1);
+ 			break;
+		case RLdrTest::EControlLibraryCodeSeg:
+			r=(TInt)LibraryCodeSeg((TInt)a1);
+ 			break;
+		case RLdrTest::EControlModuleCodeSeg:
+			r=(TInt)ModuleCodeSeg((TModuleHandle)a1);
+ 			break;
+		case RLdrTest::EControlGetCodeSegList:
+			r=GetCodeSegList( (RLdrTest::SEntry*)a1, (TInt)a2 );
+			break;
+		case RLdrTest::EControlCodeSegFromAddr:
+			r=(TInt)CodeSegFromAddr((TLinAddr)a1);
+ 			break;
+		case RLdrTest::EControlModuleHandleFromAddr:
+			r=(TInt)ModuleHandleFromAddr((TLinAddr)a1);
+ 			break;
+		case RLdrTest::EControlProcessSMPUnsafeCount:
+			r=ProcessSMPUnsafeCount((TInt)a1);
+			break;
+		default:
+			r=KErrNotSupported;
+			break;
+		}
+	return r;
+	}
+