os/kernelhwsrv/kerneltest/f32test/loader/t_ldrtst2.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1999-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\t_ldrtst2.cpp
    15 // 
    16 //
    17 
    18 #include "t_ldrtst.h"
    19 
    20 extern TInt GetModuleFlags(TInt);
    21 
    22 inline TBool AlwaysLoaded(TInt aModule)
    23 	{
    24 #ifdef __EPOC32__
    25 	TUint32 f=GetModuleFlags(aModule);
    26 	return ( (f&(KModuleFlagExe|KModuleFlagDataInTree|KModuleFlagXIP)) == (TUint32)KModuleFlagXIP );
    27 #else
    28 	TUint32 f=GetModuleFlags(aModule);
    29 	return ( (f&(KModuleFlagExe|KModuleFlagDataInTree)) == 0 );
    30 #endif
    31 	}
    32 
    33 TInt Order(const SModuleInstance& m1, const SModuleInstance& m2)
    34 	{
    35 	return TInt(m1.iCodeSeg)-TInt(m2.iCodeSeg);
    36 	}
    37 
    38 CGlobalModuleList::CGlobalModuleList()
    39 	:	 iModules(KNumModules)
    40 	{
    41 	}
    42 
    43 CGlobalModuleList::~CGlobalModuleList()
    44 	{
    45 	iModules.Close();
    46 	User::Free(iModuleAlloc);
    47 	TInt i;
    48 	for (i=0; i<KNumModules; ++i)
    49 		{
    50 		delete iPPInfo[i];
    51 		}
    52 	}
    53 
    54 void CGlobalModuleList::Init()
    55 	{
    56 	TBool proc_sym=(iMemModelAtt & (EMemModelAttrSameVA|EMemModelAttrSupportFixed))==EMemModelAttrSameVA;
    57 	TInt i;
    58 	for (i=0; i<KNumModules; ++i)
    59 		{
    60 		TUint32 f=GetModuleFlags(i);
    61 		if (f&KModuleFlagExe)
    62 			{
    63 			++iNumExes;
    64 			if (!proc_sym && (f&KModuleFlagFixed))
    65 				++iFixedExes;
    66 			}
    67 		}
    68 	iMaxModules=(1+iFixedExes)*(KNumModules-iNumExes)+iNumExes;
    69 	test.Printf(_L("iNumExes=%d iFixedExes=%d iMaxModules=%d\n"),iNumExes,iFixedExes,iMaxModules);
    70 	SModuleInstance* mi=(SModuleInstance*)User::Alloc(iMaxModules*sizeof(SModuleInstance));
    71 	test(mi!=NULL);
    72 	iFreeModules=mi;
    73 	iModuleAlloc=mi;
    74 	SModuleInstance* miE=mi+iMaxModules;
    75 	for (; mi<miE; ++mi)
    76 		{
    77 		SModuleInstance* miN=mi+1;
    78 		mi->iCodeSeg=(miN<miE)?miN:NULL;
    79 		}
    80 	for (i=0; i<KNumModules; ++i)
    81 		{
    82 		TUint32 f=GetModuleFlags(i);
    83 		if (f&KModuleFlagExe)
    84 			{
    85 			CPerProcessInfo* p=CPerProcessInfo::New(i,*this);
    86 			iPPInfo[i]=p;
    87 			}
    88 		}
    89 	}
    90 
    91 CGlobalModuleList* CGlobalModuleList::New(const LoaderTest& a)
    92 	{
    93 	CGlobalModuleList* p=new CGlobalModuleList;
    94 	test(p!=NULL);
    95 	test.Printf(_L("CGlobalModuleList at %08x\n"),p);
    96 	p->iDev=a.iDev;
    97 	p->iMemModelAtt=a.iMemModelAtt;
    98 	p->Init();
    99 	return p;
   100 	}
   101 
   102 void CGlobalModuleList::Free(SModuleInstance* a)
   103 	{
   104 	a->iCodeSeg=iFreeModules;
   105 	iFreeModules=a;
   106 	}
   107 
   108 SModuleInstance* CGlobalModuleList::GetMI()
   109 	{
   110 	SModuleInstance* p=iFreeModules;
   111 	test(p!=NULL);
   112 	iFreeModules=(SModuleInstance*)p->iCodeSeg;
   113 	return p;
   114 	}
   115 
   116 TAny* CGlobalModuleList::CodeSegFromHandle(TModuleHandle aModHandle)
   117 	{
   118 	return iDev.ModuleCodeSeg(aModHandle);
   119 	}
   120 
   121 void CGlobalModuleList::Close(SModuleInstance* a)
   122 	{
   123 	test.Printf(_L("Module %d@%08x Close(%d)\n"),a->iModNum,a->iCodeSeg,a->iAccessCount);
   124 	if (!--a->iAccessCount)
   125 		{
   126 		TCodeSegCreateInfo codeSeg;
   127 		TInt r=iDev.GetCodeSegInfo(a->iCodeSeg, codeSeg);
   128 		test(r==KErrArgument);
   129 		r=iModules.FindInOrder(a, Order);
   130 		test(r>=0);
   131 		iModules.Remove(r);
   132 		Free(a);
   133 		}
   134 	}
   135 
   136 
   137 void CGlobalModuleList::CheckAll()
   138 	{
   139 	TInt i;
   140 	for (i=0; i<KNumModules; ++i)
   141 		{
   142 		if (iPPInfo[i])
   143 			iPPInfo[i]->Check();
   144 		}
   145 	}
   146 
   147 TInt CGlobalModuleList::Load(TInt aExeNum, TInt aDllNum)
   148 	{
   149 	return iPPInfo[aExeNum]->Load(aDllNum);
   150 	}
   151 
   152 TInt CGlobalModuleList::CloseHandle(TInt aExeNum, TInt aDllNum)
   153 	{
   154 	CPerProcessInfo* p=iPPInfo[aExeNum];
   155 	TInt i;
   156 	for (i=0; i<KMaxHandles && p->iModuleNum[i]!=aDllNum; ++i) {}
   157 	if (i==KMaxHandles)
   158 		return KErrNotFound;
   159 	return p->CloseHandle(i);
   160 	}
   161 
   162 CPerProcessInfo::CPerProcessInfo()
   163 	{
   164 	Mem::Fill(iModuleNum, sizeof(iModuleNum), 0xff);
   165 	}
   166 
   167 CPerProcessInfo::~CPerProcessInfo()
   168 	{
   169 	if (iSession.Handle())
   170 		{
   171 		iSession.Exit();
   172 		iSession.Close();
   173 		User::WaitForRequest(iStatus);
   174 		test(iProcess.ExitType()==EExitKill);
   175 		test(iProcess.ExitReason()==KErrNone);
   176 		}
   177 	iProcess.Close();
   178 	}
   179 
   180 CPerProcessInfo* CPerProcessInfo::New(TInt aExeNum, CGlobalModuleList& aG)
   181 	{
   182 	CPerProcessInfo* p=new CPerProcessInfo;
   183 	test(p!=NULL);
   184 	test.Printf(_L("CPerProcessInfo for %d at %08x\n"),aExeNum,p);
   185 	p->iExeNum=aExeNum;
   186 	p->iDev=aG.iDev;
   187 	p->iGlobalList=&aG;
   188 	TInt r = p->Init();
   189 	if (r==KErrNone)
   190 		return p;
   191 	delete p;
   192 	return NULL;
   193 	}
   194 
   195 TInt CPerProcessInfo::Init()
   196 	{
   197 	TUint32 tt;
   198 	TInt r=LoadExe(iExeNum, 0, iProcess, tt);
   199 	test.Printf(_L("LoadExe(%d)->%d\n"),iExeNum,r);
   200 #ifdef __EPOC32__
   201 	test(r==KErrNone);
   202 	test.Printf(_L("BENCHMARK: LoadExe(%d)->%dms\n"),iExeNum,tt);
   203 #else
   204 	test(r==KErrNone || r==KErrNotSupported);
   205 	if (r!=KErrNone)
   206 		return r;
   207 #endif
   208 	iProcess.Logon(iStatus);
   209 	test(iStatus==KRequestPending);
   210 	r=iSession.Connect(iExeNum);
   211 	test.Printf(_L("Connect(%d)->%d\n"),iExeNum,r);
   212 	test(r==KErrNone);
   213 	TModuleList exe_info;
   214 	r=iSession.GetExeDepList(exe_info.iInfo);
   215 	exe_info.SetCount();
   216 	test.Printf(_L("GetExeDepList(%d)->%d count %d\n"),iExeNum,r,exe_info.iCount);
   217 	test(r==KErrNone);
   218 	r=AddModules(iExeNum, NULL, &exe_info);
   219 	test.Printf(_L("AddModules->%d\n"),r);
   220 	test(r==KErrNone);
   221 	return KErrNone;
   222 	}
   223 
   224 void CPerProcessInfo::GetModuleSet(TModuleSet& aSet)
   225 	{
   226 	TInt m;
   227 	for (m=0; m<KNumModules; ++m)
   228 		{
   229 		if (iHandleCount[m]==0 && m!=iExeNum)
   230 			continue;
   231 		aSet.Add(m);
   232 		const TInt* deps=ModuleDependencies[m];
   233 		TInt ndeps=*deps++;
   234 		TInt i;
   235 		for (i=0; i<ndeps; ++i)
   236 			{
   237 			TInt dm=*deps++;
   238 #ifndef __EPOC32__
   239 			// Emulator doesn't register subtrees without data
   240 			TInt f = GetModuleFlags(dm);
   241 			if (f & KModuleFlagDataInTree)
   242 #endif
   243 			aSet.Add(dm);
   244 			}
   245 		}
   246 	}
   247 
   248 void CPerProcessInfo::Check()
   249 	{
   250 	test.Printf(_L("%d:Check\n"),iExeNum);
   251 	TBool code_prot=iGlobalList->iMemModelAtt&EMemModelAttrRamCodeProt;
   252 	TBool data_prot=iGlobalList->iMemModelAtt&EMemModelAttrProcessProt;
   253 	TInt mmtype=iGlobalList->iMemModelAtt&EMemModelTypeMask;
   254 	TModuleSet set;
   255 	GetModuleSet(set);
   256 	TInt m;
   257 	for (m=0; m<KNumModules; ++m)
   258 		{
   259 		TUint32 f=GetModuleFlags(m);
   260 		if (set.Present(m))
   261 			{
   262 			test.Printf(_L("%d "),m);
   263 			SModuleInstance* pM=iModules[m];
   264 			test(pM!=NULL);
   265 			test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrNone);
   266 			if (f&KModuleFlagData)
   267 				test(iSession.CheckReadable(pM->iData)==KErrNone);
   268 			}
   269 		else
   270 			{
   271 			SModuleInstance* pM=iModules[m];
   272 			test(pM==NULL);
   273 			}
   274 		}
   275 	TInt ix;
   276 	TInt c=iGlobalList->iModules.Count();
   277 	test.Printf(_L("\n%d:CheckNP\n"),iExeNum);
   278 	for (ix=0; ix<c; ++ix)
   279 		{
   280 		const SModuleInstance* pM=iGlobalList->iModules[ix];
   281 		if (set.Present(pM->iModNum))
   282 			continue;
   283 		test.Printf(_L("%d "),pM->iModNum);
   284 		TUint32 f=GetModuleFlags(pM->iModNum);
   285 		if (!(f&KModuleFlagXIP) && code_prot)
   286 			{
   287 			if(mmtype==EMemModelTypeFlexible && (f&KModuleFlagExe))
   288 				{
   289 				// don't test EXEs on FlexibleMM because they don't live at unique addresses
   290 				}
   291 			else
   292 				{
   293 				// check code not loaded into this porcess....
   294 				test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrGeneral);
   295 				}
   296 			}
   297 		TBool check_data=(f&(KModuleFlagData|KModuleFlagExe))==(TUint32)KModuleFlagData;
   298 		if (check_data && mmtype==EMemModelTypeMoving)
   299 			{
   300 			if (f&KModuleFlagXIP)
   301 				{
   302 				const TInt* exeinfo=ModuleExeInfo[pM->iModNum];
   303 				TInt attp=exeinfo[0];
   304 				if (attp>=0 && (GetModuleFlags(attp)&KModuleFlagFixed))
   305 					check_data=EFalse;
   306 				}
   307 			}
   308 		if (check_data && data_prot)
   309 			test(iSession.CheckReadable(pM->iData)==KErrGeneral);
   310 		}
   311 	TInt h;
   312 	for (h=0; h<KMaxHandles; ++h)
   313 		{
   314 		m=iModuleNum[h];
   315 		if (m<0)
   316 			continue;
   317 		test(set.Present(m));
   318 		TInt y=++iGlobalList->iParam;
   319 		TInt r=iSession.CallRBlkI(h,y);
   320 		r-=y;
   321 		r/=INC_BLOCK_SZ;
   322 		test.Printf(_L("DLL %d RBlkI->%d\n"),m,r);
   323 		y=ModuleRBlkIParams[m][1]+ModuleRBlkIParams[m][0]*DLLNUMOFFSET;
   324 		test(r==y);
   325 		}
   326 	}
   327 
   328 void CPerProcessInfo::Unlink(const SDllInfo& a, TModuleList& aList)
   329 	{
   330 	test.Printf(_L("%d:Unlink %d %08x\n"),iExeNum,a.iDllNum,a.iModuleHandle);
   331 	test(iHandleCount[a.iDllNum]==0);
   332 	TBool code_prot=iGlobalList->iMemModelAtt&EMemModelAttrRamCodeProt;
   333 	TBool data_prot=iGlobalList->iMemModelAtt&EMemModelAttrProcessProt;
   334 	TInt mmtype=iGlobalList->iMemModelAtt&EMemModelTypeMask;
   335 	TModuleSet set;
   336 	GetModuleSet(set);
   337 	set.Display(_L("set: "));
   338 	TInt m;
   339 	for (m=0; m<KNumModules; ++m)
   340 		{
   341 		if (set.Present(m))
   342 			continue;
   343 		SModuleInstance* pM=iModules[m];
   344 		if (!pM)
   345 			continue;
   346 		iModules[m]=NULL;
   347 		TUint32 f=GetModuleFlags(m);
   348 		SDllInfo info;
   349 		info.iDllNum=m;
   350 		info.iEntryPointAddress=pM->iEntryPointAddress;
   351 		info.iModuleHandle=pM->iModuleHandle;
   352 		aList.Add(info);
   353 		test(pM->iModNum==m);
   354 		if (!(f&KModuleFlagXIP) && code_prot)
   355 			test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrGeneral);
   356 		TBool check_data=f&KModuleFlagData;
   357 		if (check_data && mmtype==EMemModelTypeMoving)
   358 			{
   359 			if (f&KModuleFlagXIP)
   360 				{
   361 				const TInt* exeinfo=ModuleExeInfo[pM->iModNum];
   362 				TInt attp=exeinfo[0];
   363 				if (attp>=0 && (GetModuleFlags(attp)&KModuleFlagFixed))
   364 					check_data=EFalse;
   365 				}
   366 			}
   367 		if (check_data && data_prot)
   368 			test(iSession.CheckReadable(pM->iData)==KErrGeneral);
   369 		iGlobalList->Close(pM);
   370 		}
   371 	}
   372 
   373 TInt CPerProcessInfo::CloseHandle(TInt aHandle)
   374 	{
   375 	TInt m=iModuleNum[aHandle];
   376 	test(m>=0);
   377 	iModuleNum[aHandle]=-1;
   378 	SModuleInstance* pM=iModules[m];
   379 	test(pM!=NULL);
   380 	SDllInfo dll_info;
   381 	dll_info.iDllNum=m;
   382 	dll_info.iEntryPointAddress=pM->iEntryPointAddress;
   383 	dll_info.iModuleHandle=pM->iModuleHandle;
   384 	TModuleList d_list;
   385 	TInt r=iSession.CloseDll(aHandle);
   386 	test(r==KErrNone);
   387 	r=iSession.GetCDList(d_list.iInfo);
   388 	test(r==KErrNone);
   389 	d_list.SetCount();
   390 	if (--iHandleCount[m])
   391 		{
   392 		test(d_list.iCount==0);
   393 		return KErrNone;
   394 		}
   395 	TModuleList xd_list;
   396 	if (!AlwaysLoaded(m))
   397 		Unlink(dll_info, xd_list);
   398 	TInt i;
   399 	TInt dcount=0;
   400 	for (i=0; i<xd_list.iCount; ++i)
   401 		{
   402 		TInt mn=xd_list.iInfo[i].iDllNum;
   403 		TUint32 f=GetModuleFlags(mn);
   404 		if (f&KModuleFlagData)
   405 			{
   406 			++dcount;
   407 			test(d_list.IsPresent(mn));
   408 			}
   409 		}
   410 	d_list.Display(_L("d_list:  "));
   411 	xd_list.Display(_L("xd_list: "));
   412 	test(dcount==d_list.iCount);
   413 	return KErrNone;
   414 	}
   415 
   416 TInt CPerProcessInfo::Load(TInt aDllNum)
   417 	{
   418 	TModuleList init_list;
   419 	TModuleList c_list;
   420 	TInt h=iSession.LoadDll(aDllNum, init_list.iInfo);
   421 	init_list.SetCount();
   422 	test.Printf(_L("%d:Load(%d)->%d Icount %d\n"),iExeNum,aDllNum,h,init_list.iCount);
   423 	if (h<0)
   424 		{
   425 		return h;
   426 		}
   427 	test(iSession.GetCDList(c_list.iInfo)==KErrNone);
   428 	c_list.SetCount();
   429 	iModuleNum[h]=aDllNum;
   430 	return AddModules(aDllNum, &c_list, &init_list);
   431 	}
   432 
   433 TInt CPerProcessInfo::AddModules(TInt aDllNum, TModuleList* aCList, TModuleList* aIList)
   434 	{
   435 	TInt r=0;
   436 	if (++iHandleCount[aDllNum]>1)
   437 		{
   438 		if (aCList)
   439 			test(aCList->iCount==0);
   440 		return KErrNone;
   441 		}
   442 	TModuleSet set;
   443 	if (!iModules[aDllNum] && !AlwaysLoaded(aDllNum))
   444 		set.Add(aDllNum);
   445 	const TInt* deps=ModuleDependencies[aDllNum];
   446 	TInt ndeps=*deps++;
   447 	TInt i;
   448 	TInt ccount=0;
   449 	for (i=0; i<ndeps; ++i)
   450 		{
   451 		TInt dm=*deps++;
   452 		if (!iModules[dm] && !AlwaysLoaded(dm))
   453 			{
   454 			set.Add(dm);
   455 			if (GetModuleFlags(dm)&KModuleFlagData)
   456 				++ccount;
   457 			}
   458 		}
   459 	if (aCList)
   460 		test(ccount==aCList->iCount);
   461 	for (i=0; i<KNumModules; ++i)
   462 		{
   463 		if (!set.Present(i))
   464 			continue;
   465 		SModuleInstance mi;
   466 		mi.iAccessCount=1;
   467 		mi.iModNum=i;
   468 		if (GetModuleFlags(i)&KModuleFlagData)
   469 			{
   470 			if (aCList)
   471 				test(aCList->Find(i)>=0);
   472 			}
   473 		TInt j=aIList->Find(i);
   474 		test(j>=0);
   475 		mi.iEntryPointAddress=aIList->iInfo[j].iEntryPointAddress;
   476 		mi.iModuleHandle=aIList->iInfo[j].iModuleHandle;
   477 		mi.iCodeSeg=iGlobalList->CodeSegFromHandle(mi.iModuleHandle);
   478 		test(mi.iCodeSeg!=NULL);
   479 		if (GetModuleFlags(i)&KModuleFlagData)
   480 			{
   481 			TCodeSegCreateInfo cs_info;
   482 			r=iDev.GetCodeSegInfo(mi.iCodeSeg, cs_info);
   483 			test(r==KErrNone);
   484 			mi.iData=cs_info.iDataRunAddress;
   485 			}
   486 		else
   487 			{
   488 			mi.iData=0;
   489 			}
   490 
   491 		r=iGlobalList->iModules.FindInOrder(&mi, Order);
   492 		if (r>=0)
   493 			{
   494 			test.Printf(_L("Module %d@%08x already exists\n"),mi.iModNum,mi.iCodeSeg);
   495 			SModuleInstance& mi0=*iGlobalList->iModules[r];
   496 			++mi0.iAccessCount;
   497 			test(mi.iEntryPointAddress==mi0.iEntryPointAddress);
   498 			test(mi.iModuleHandle==mi0.iModuleHandle);
   499 			test(mi.iData==mi0.iData);
   500 			test(mi.iModNum==mi0.iModNum);
   501 			iModules[i]=&mi0;
   502 			}
   503 		else
   504 			{
   505 			test.Printf(_L("Module %d@%08x new\n"),mi.iModNum,mi.iCodeSeg);
   506 			SModuleInstance* pM=iGlobalList->GetMI();
   507 			test(pM!=NULL);
   508 			*pM=mi;
   509 			iModules[i]=pM;
   510 			r=iGlobalList->iModules.InsertInOrder(pM, Order);
   511 			test(r==KErrNone);
   512 			}
   513 		}
   514 	return KErrNone;
   515 	}
   516 
   517 void LoaderTest::TestMultipleLoads()
   518 	{
   519 	CGlobalModuleList* p=CGlobalModuleList::New(*this);
   520 	p->CheckAll();
   521 
   522 #ifdef __WINS__
   523 	const TInt* multiLoad[] = {TC_MultLoad,0};
   524 #else
   525 	const TInt* multiLoad[] = {TC_MultLoad,TC_MultLoadTargetOnly,0};
   526 #endif
   527 	const TInt** multiLoadLists = multiLoad;
   528 	const TInt* tests;
   529 	while((tests=*multiLoadLists++)!=0)
   530 		{
   531 		TInt ntests=*tests++;
   532 		while(ntests>=4)
   533 			{
   534 			ntests-=4;
   535 			TInt exe1=*tests++;
   536 			TInt dll1=*tests++;
   537 			TInt exe2=*tests++;
   538 			TInt dll2=*tests++;
   539 			TUint32 xf1=GetModuleFlags(exe1);
   540 			TUint32 xf2=GetModuleFlags(exe2);
   541 			if (xf1&KModuleFlagExe)
   542 				{
   543 				TInt r=p->Load(exe1, dll1);
   544 				test.Printf(_L("%d:Load %d->%d"),exe1,dll1,r);
   545 				p->CheckAll();
   546 				}
   547 			if (xf2&KModuleFlagExe)
   548 				{
   549 				TInt r=p->CloseHandle(exe2, dll2);
   550 				test.Printf(_L("%d:Close %d->%d"),exe2,dll2,r);
   551 				p->CheckAll();
   552 				}
   553 			}
   554 		}
   555 
   556 	delete p;
   557 	}
   558