os/kernelhwsrv/kerneltest/e32test/dll/d_ldrtst.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32test\loader\d_ldrtst.cpp
    15 // LDD for testing loader
    16 // 
    17 //
    18 
    19 #include <kernel/kern_priv.h>
    20 #include "d_ldrtst.h"
    21 
    22 const TInt KMajorVersionNumber=0;
    23 const TInt KMinorVersionNumber=1;
    24 const TInt KBuildVersionNumber=1;
    25 
    26 class DLdrTest;
    27 class DLdrTestFactory : public DLogicalDevice
    28 //
    29 // Test LDD factory
    30 //
    31 	{
    32 public:
    33 	DLdrTestFactory();
    34 	virtual TInt Install();
    35 	virtual void GetCaps(TDes8& aDes) const;
    36 	virtual TInt Create(DLogicalChannelBase*& aChannel);
    37 	};
    38 
    39 class DLdrTest : public DLogicalChannelBase
    40 //
    41 // Test logical channel
    42 //
    43 	{
    44 public:
    45 	virtual ~DLdrTest();
    46 protected:
    47 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    48 	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
    49 public:
    50 	TInt GetCodeSegInfo(TAny* aHandle, TAny* aDest);
    51 	TAny* ModuleCodeSeg(TModuleHandle aModuleHandle);
    52 	TAny* ProcessCodeSeg(TInt aProcessHandle);
    53 	TAny* LibraryCodeSeg(TInt aLibraryHandle);
    54 	TInt GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax);
    55 	TAny* CodeSegFromAddr(TLinAddr aAddr);
    56 	TModuleHandle ModuleHandleFromAddr(TLinAddr aAddr);
    57 	TInt ProcessSMPUnsafeCount(TInt aProcessHandle);
    58 private:
    59 	SDblQueLink* FindCodeSegQueueAnchor();
    60 	};
    61 
    62 DECLARE_STANDARD_LDD()
    63 	{
    64 	return new DLdrTestFactory;
    65 	}
    66 
    67 DLdrTestFactory::DLdrTestFactory()
    68 //
    69 // Constructor
    70 //
    71 	{
    72 	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
    73 	}
    74 
    75 TInt DLdrTestFactory::Create(DLogicalChannelBase*& aChannel)
    76 //
    77 // Create a new DLdrTest on this logical device
    78 //
    79 	{
    80 	aChannel=new DLdrTest;
    81 	return aChannel?KErrNone:KErrNoMemory;
    82 	}
    83 
    84 TInt DLdrTestFactory::Install()
    85 //
    86 // Install the LDD - overriding pure virtual
    87 //
    88 	{
    89 	return SetName(&KLdrTestLddName);
    90 	}
    91 
    92 void DLdrTestFactory::GetCaps(TDes8& aDes) const
    93 //
    94 // Get capabilities - overriding pure virtual
    95 //
    96 	{
    97 	TCapsTestV01 b;
    98 	b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
    99     Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
   100 	}
   101 
   102 TInt DLdrTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
   103 //
   104 // Create channel
   105 //
   106 	{
   107 
   108 	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
   109 		return KErrNotSupported;
   110 	return KErrNone;
   111 	}
   112 
   113 DLdrTest::~DLdrTest()
   114 //
   115 // Destructor
   116 //
   117 	{
   118 	}
   119 
   120 TInt DLdrTest::GetCodeSegInfo(TAny* aHandle, TAny* aDest)
   121 	{
   122 	TCodeSegCreateInfo info;
   123 	DCodeSeg* pS=DCodeSeg::VerifyHandle(aHandle);
   124 	if (pS)
   125 		{
   126 		Kern::AccessCode();
   127 		pS->Info(info);
   128 		Kern::EndAccessCode();
   129 		kumemput32(aDest, &info, sizeof(info));
   130 		return KErrNone;
   131 		}
   132 	return KErrArgument;
   133 	}
   134 
   135 TAny* DLdrTest::ModuleCodeSeg(TModuleHandle aModuleHandle)
   136 	{
   137 	DCodeSeg* pS=DCodeSeg::VerifyHandle(aModuleHandle);
   138 	if(!pS)
   139 		{
   140 		Kern::AccessCode();
   141 		DCodeSeg::CodeSegFromEntryPoint((TLinAddr)aModuleHandle);  // ignore returned DCodeSeg*
   142 		Kern::EndAccessCode();
   143 		}
   144 	return pS;
   145 	}
   146 
   147 TAny* DLdrTest::CodeSegFromAddr(TLinAddr aAddr)
   148 	{
   149 	Kern::AccessCode();
   150 	DCodeSeg* s = Kern::CodeSegFromAddress(aAddr, Kern::CurrentThread().iOwningProcess);
   151 	Kern::EndAccessCode();
   152 	return s;
   153 	}
   154 
   155 TModuleHandle DLdrTest::ModuleHandleFromAddr(TLinAddr aAddr)
   156 	{
   157 	TModuleHandle h = (TModuleHandle)CodeSegFromAddr(aAddr);
   158 	if(!h)
   159 		h = (TModuleHandle)aAddr;
   160 	return h;
   161 	}
   162 
   163 TAny* DLdrTest::ProcessCodeSeg(TInt aProcessHandle)
   164 	{
   165 	DCodeSeg* pS=NULL;
   166 	DThread& t=Kern::CurrentThread();
   167 	NKern::LockSystem();
   168 	DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess);
   169 	if (pP)
   170 		{
   171 		pS=pP->iCodeSeg;
   172 		if (!pS)
   173 			pS=pP->iTempCodeSeg;
   174 		}
   175 	NKern::UnlockSystem();
   176 	return pS;
   177 	}
   178 
   179 TAny* DLdrTest::LibraryCodeSeg(TInt aLibraryHandle)
   180 	{
   181 	DCodeSeg* pS=NULL;
   182 	DThread& t=Kern::CurrentThread();
   183 	NKern::LockSystem();
   184 	DLibrary* pL=(DLibrary*)t.ObjectFromHandle(aLibraryHandle, ELibrary);
   185 	if (pL)
   186 		pS=pL->iCodeSeg;
   187 	NKern::UnlockSystem();
   188 	return pS;
   189 	}
   190 
   191 SDblQueLink* DLdrTest::FindCodeSegQueueAnchor()
   192 	{
   193 	SDblQueLink* p=&iDevice->iCodeSeg->iLink;	// this device driver's code segment
   194 	for (;;)
   195 		{
   196 		p=p->iPrev;
   197 		DCodeSeg* s=_LOFF(p, DCodeSeg, iLink);
   198 		if (s->iExeCodeSeg==s && (s->iAttr & ECodeSegAttKernel))
   199 			{
   200 			// s is the kernel's code segment, which is the first one to be created
   201 			return s->iLink.iPrev;
   202 			}
   203 		}
   204 	}
   205 
   206 TInt DLdrTest::GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax)
   207 	{
   208 	if (aMax<=0)
   209 		return KErrArgument;
   210 	RLdrTest::SEntry list[128];
   211 	Kern::AccessCode();
   212 	SDblQueLink* anchor=FindCodeSegQueueAnchor();
   213 	SDblQueLink* p=anchor->iNext;
   214 	if (aMax>128)
   215 		aMax=128;
   216 	TInt n=0;
   217 	for(; p!=anchor && n<aMax; p=p->iNext, ++n)
   218 		{
   219 		DCodeSeg* s=_LOFF(p, DCodeSeg, iLink);
   220 		list[n].iHandle=s;
   221 		list[n].iUid3=(TUint32)s->iUids.iUid[2].iUid;
   222 		}
   223 	Kern::EndAccessCode();
   224 	if (n>0)
   225 		kumemput32(aList, list, n*sizeof(RLdrTest::SEntry));
   226 	return n;
   227 	}
   228 
   229 TInt DLdrTest::ProcessSMPUnsafeCount(TInt aProcessHandle)
   230 	{
   231 	TInt count=KErrNotFound;
   232 	DThread& t=Kern::CurrentThread();
   233 	NKern::LockSystem();
   234 	DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess);
   235 	if (pP)
   236 		count=pP->iSMPUnsafeCount;
   237 	NKern::UnlockSystem();
   238 	return count;
   239 	}
   240 
   241 TInt DLdrTest::Request(TInt aFunction, TAny* a1, TAny* a2)
   242 	{
   243 	TInt r=KErrNone;
   244 	switch (aFunction)
   245 		{
   246 		case RLdrTest::EControlGetCodeSegInfo:
   247 			r=GetCodeSegInfo(a1,a2);
   248  			break;
   249 		case RLdrTest::EControlProcessCodeSeg:
   250 			r=(TInt)ProcessCodeSeg((TInt)a1);
   251  			break;
   252 		case RLdrTest::EControlLibraryCodeSeg:
   253 			r=(TInt)LibraryCodeSeg((TInt)a1);
   254  			break;
   255 		case RLdrTest::EControlModuleCodeSeg:
   256 			r=(TInt)ModuleCodeSeg((TModuleHandle)a1);
   257  			break;
   258 		case RLdrTest::EControlGetCodeSegList:
   259 			r=GetCodeSegList( (RLdrTest::SEntry*)a1, (TInt)a2 );
   260 			break;
   261 		case RLdrTest::EControlCodeSegFromAddr:
   262 			r=(TInt)CodeSegFromAddr((TLinAddr)a1);
   263  			break;
   264 		case RLdrTest::EControlModuleHandleFromAddr:
   265 			r=(TInt)ModuleHandleFromAddr((TLinAddr)a1);
   266  			break;
   267 		case RLdrTest::EControlProcessSMPUnsafeCount:
   268 			r=ProcessSMPUnsafeCount((TInt)a1);
   269 			break;
   270 		default:
   271 			r=KErrNotSupported;
   272 			break;
   273 		}
   274 	return r;
   275 	}
   276