diff -r 000000000000 -r a41df078684a kerneltest/f32test/loader/t_ldrtst2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/loader/t_ldrtst2.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,558 @@ +// 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\t_ldrtst2.cpp +// +// + +#include "t_ldrtst.h" + +extern TInt GetModuleFlags(TInt); + +inline TBool AlwaysLoaded(TInt aModule) + { +#ifdef __EPOC32__ + TUint32 f=GetModuleFlags(aModule); + return ( (f&(KModuleFlagExe|KModuleFlagDataInTree|KModuleFlagXIP)) == (TUint32)KModuleFlagXIP ); +#else + TUint32 f=GetModuleFlags(aModule); + return ( (f&(KModuleFlagExe|KModuleFlagDataInTree)) == 0 ); +#endif + } + +TInt Order(const SModuleInstance& m1, const SModuleInstance& m2) + { + return TInt(m1.iCodeSeg)-TInt(m2.iCodeSeg); + } + +CGlobalModuleList::CGlobalModuleList() + : iModules(KNumModules) + { + } + +CGlobalModuleList::~CGlobalModuleList() + { + iModules.Close(); + User::Free(iModuleAlloc); + TInt i; + for (i=0; iiCodeSeg=(miNiDev=a.iDev; + p->iMemModelAtt=a.iMemModelAtt; + p->Init(); + return p; + } + +void CGlobalModuleList::Free(SModuleInstance* a) + { + a->iCodeSeg=iFreeModules; + iFreeModules=a; + } + +SModuleInstance* CGlobalModuleList::GetMI() + { + SModuleInstance* p=iFreeModules; + test(p!=NULL); + iFreeModules=(SModuleInstance*)p->iCodeSeg; + return p; + } + +TAny* CGlobalModuleList::CodeSegFromHandle(TModuleHandle aModHandle) + { + return iDev.ModuleCodeSeg(aModHandle); + } + +void CGlobalModuleList::Close(SModuleInstance* a) + { + test.Printf(_L("Module %d@%08x Close(%d)\n"),a->iModNum,a->iCodeSeg,a->iAccessCount); + if (!--a->iAccessCount) + { + TCodeSegCreateInfo codeSeg; + TInt r=iDev.GetCodeSegInfo(a->iCodeSeg, codeSeg); + test(r==KErrArgument); + r=iModules.FindInOrder(a, Order); + test(r>=0); + iModules.Remove(r); + Free(a); + } + } + + +void CGlobalModuleList::CheckAll() + { + TInt i; + for (i=0; iCheck(); + } + } + +TInt CGlobalModuleList::Load(TInt aExeNum, TInt aDllNum) + { + return iPPInfo[aExeNum]->Load(aDllNum); + } + +TInt CGlobalModuleList::CloseHandle(TInt aExeNum, TInt aDllNum) + { + CPerProcessInfo* p=iPPInfo[aExeNum]; + TInt i; + for (i=0; iiModuleNum[i]!=aDllNum; ++i) {} + if (i==KMaxHandles) + return KErrNotFound; + return p->CloseHandle(i); + } + +CPerProcessInfo::CPerProcessInfo() + { + Mem::Fill(iModuleNum, sizeof(iModuleNum), 0xff); + } + +CPerProcessInfo::~CPerProcessInfo() + { + if (iSession.Handle()) + { + iSession.Exit(); + iSession.Close(); + User::WaitForRequest(iStatus); + test(iProcess.ExitType()==EExitKill); + test(iProcess.ExitReason()==KErrNone); + } + iProcess.Close(); + } + +CPerProcessInfo* CPerProcessInfo::New(TInt aExeNum, CGlobalModuleList& aG) + { + CPerProcessInfo* p=new CPerProcessInfo; + test(p!=NULL); + test.Printf(_L("CPerProcessInfo for %d at %08x\n"),aExeNum,p); + p->iExeNum=aExeNum; + p->iDev=aG.iDev; + p->iGlobalList=&aG; + TInt r = p->Init(); + if (r==KErrNone) + return p; + delete p; + return NULL; + } + +TInt CPerProcessInfo::Init() + { + TUint32 tt; + TInt r=LoadExe(iExeNum, 0, iProcess, tt); + test.Printf(_L("LoadExe(%d)->%d\n"),iExeNum,r); +#ifdef __EPOC32__ + test(r==KErrNone); + test.Printf(_L("BENCHMARK: LoadExe(%d)->%dms\n"),iExeNum,tt); +#else + test(r==KErrNone || r==KErrNotSupported); + if (r!=KErrNone) + return r; +#endif + iProcess.Logon(iStatus); + test(iStatus==KRequestPending); + r=iSession.Connect(iExeNum); + test.Printf(_L("Connect(%d)->%d\n"),iExeNum,r); + test(r==KErrNone); + TModuleList exe_info; + r=iSession.GetExeDepList(exe_info.iInfo); + exe_info.SetCount(); + test.Printf(_L("GetExeDepList(%d)->%d count %d\n"),iExeNum,r,exe_info.iCount); + test(r==KErrNone); + r=AddModules(iExeNum, NULL, &exe_info); + test.Printf(_L("AddModules->%d\n"),r); + test(r==KErrNone); + return KErrNone; + } + +void CPerProcessInfo::GetModuleSet(TModuleSet& aSet) + { + TInt m; + for (m=0; miMemModelAtt&EMemModelAttrRamCodeProt; + TBool data_prot=iGlobalList->iMemModelAtt&EMemModelAttrProcessProt; + TInt mmtype=iGlobalList->iMemModelAtt&EMemModelTypeMask; + TModuleSet set; + GetModuleSet(set); + TInt m; + for (m=0; miEntryPointAddress)==KErrNone); + if (f&KModuleFlagData) + test(iSession.CheckReadable(pM->iData)==KErrNone); + } + else + { + SModuleInstance* pM=iModules[m]; + test(pM==NULL); + } + } + TInt ix; + TInt c=iGlobalList->iModules.Count(); + test.Printf(_L("\n%d:CheckNP\n"),iExeNum); + for (ix=0; ixiModules[ix]; + if (set.Present(pM->iModNum)) + continue; + test.Printf(_L("%d "),pM->iModNum); + TUint32 f=GetModuleFlags(pM->iModNum); + if (!(f&KModuleFlagXIP) && code_prot) + { + if(mmtype==EMemModelTypeFlexible && (f&KModuleFlagExe)) + { + // don't test EXEs on FlexibleMM because they don't live at unique addresses + } + else + { + // check code not loaded into this porcess.... + test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrGeneral); + } + } + TBool check_data=(f&(KModuleFlagData|KModuleFlagExe))==(TUint32)KModuleFlagData; + if (check_data && mmtype==EMemModelTypeMoving) + { + if (f&KModuleFlagXIP) + { + const TInt* exeinfo=ModuleExeInfo[pM->iModNum]; + TInt attp=exeinfo[0]; + if (attp>=0 && (GetModuleFlags(attp)&KModuleFlagFixed)) + check_data=EFalse; + } + } + if (check_data && data_prot) + test(iSession.CheckReadable(pM->iData)==KErrGeneral); + } + TInt h; + for (h=0; hiParam; + TInt r=iSession.CallRBlkI(h,y); + r-=y; + r/=INC_BLOCK_SZ; + test.Printf(_L("DLL %d RBlkI->%d\n"),m,r); + y=ModuleRBlkIParams[m][1]+ModuleRBlkIParams[m][0]*DLLNUMOFFSET; + test(r==y); + } + } + +void CPerProcessInfo::Unlink(const SDllInfo& a, TModuleList& aList) + { + test.Printf(_L("%d:Unlink %d %08x\n"),iExeNum,a.iDllNum,a.iModuleHandle); + test(iHandleCount[a.iDllNum]==0); + TBool code_prot=iGlobalList->iMemModelAtt&EMemModelAttrRamCodeProt; + TBool data_prot=iGlobalList->iMemModelAtt&EMemModelAttrProcessProt; + TInt mmtype=iGlobalList->iMemModelAtt&EMemModelTypeMask; + TModuleSet set; + GetModuleSet(set); + set.Display(_L("set: ")); + TInt m; + for (m=0; miEntryPointAddress; + info.iModuleHandle=pM->iModuleHandle; + aList.Add(info); + test(pM->iModNum==m); + if (!(f&KModuleFlagXIP) && code_prot) + test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrGeneral); + TBool check_data=f&KModuleFlagData; + if (check_data && mmtype==EMemModelTypeMoving) + { + if (f&KModuleFlagXIP) + { + const TInt* exeinfo=ModuleExeInfo[pM->iModNum]; + TInt attp=exeinfo[0]; + if (attp>=0 && (GetModuleFlags(attp)&KModuleFlagFixed)) + check_data=EFalse; + } + } + if (check_data && data_prot) + test(iSession.CheckReadable(pM->iData)==KErrGeneral); + iGlobalList->Close(pM); + } + } + +TInt CPerProcessInfo::CloseHandle(TInt aHandle) + { + TInt m=iModuleNum[aHandle]; + test(m>=0); + iModuleNum[aHandle]=-1; + SModuleInstance* pM=iModules[m]; + test(pM!=NULL); + SDllInfo dll_info; + dll_info.iDllNum=m; + dll_info.iEntryPointAddress=pM->iEntryPointAddress; + dll_info.iModuleHandle=pM->iModuleHandle; + TModuleList d_list; + TInt r=iSession.CloseDll(aHandle); + test(r==KErrNone); + r=iSession.GetCDList(d_list.iInfo); + test(r==KErrNone); + d_list.SetCount(); + if (--iHandleCount[m]) + { + test(d_list.iCount==0); + return KErrNone; + } + TModuleList xd_list; + if (!AlwaysLoaded(m)) + Unlink(dll_info, xd_list); + TInt i; + TInt dcount=0; + for (i=0; i%d Icount %d\n"),iExeNum,aDllNum,h,init_list.iCount); + if (h<0) + { + return h; + } + test(iSession.GetCDList(c_list.iInfo)==KErrNone); + c_list.SetCount(); + iModuleNum[h]=aDllNum; + return AddModules(aDllNum, &c_list, &init_list); + } + +TInt CPerProcessInfo::AddModules(TInt aDllNum, TModuleList* aCList, TModuleList* aIList) + { + TInt r=0; + if (++iHandleCount[aDllNum]>1) + { + if (aCList) + test(aCList->iCount==0); + return KErrNone; + } + TModuleSet set; + if (!iModules[aDllNum] && !AlwaysLoaded(aDllNum)) + set.Add(aDllNum); + const TInt* deps=ModuleDependencies[aDllNum]; + TInt ndeps=*deps++; + TInt i; + TInt ccount=0; + for (i=0; iiCount); + for (i=0; iFind(i)>=0); + } + TInt j=aIList->Find(i); + test(j>=0); + mi.iEntryPointAddress=aIList->iInfo[j].iEntryPointAddress; + mi.iModuleHandle=aIList->iInfo[j].iModuleHandle; + mi.iCodeSeg=iGlobalList->CodeSegFromHandle(mi.iModuleHandle); + test(mi.iCodeSeg!=NULL); + if (GetModuleFlags(i)&KModuleFlagData) + { + TCodeSegCreateInfo cs_info; + r=iDev.GetCodeSegInfo(mi.iCodeSeg, cs_info); + test(r==KErrNone); + mi.iData=cs_info.iDataRunAddress; + } + else + { + mi.iData=0; + } + + r=iGlobalList->iModules.FindInOrder(&mi, Order); + if (r>=0) + { + test.Printf(_L("Module %d@%08x already exists\n"),mi.iModNum,mi.iCodeSeg); + SModuleInstance& mi0=*iGlobalList->iModules[r]; + ++mi0.iAccessCount; + test(mi.iEntryPointAddress==mi0.iEntryPointAddress); + test(mi.iModuleHandle==mi0.iModuleHandle); + test(mi.iData==mi0.iData); + test(mi.iModNum==mi0.iModNum); + iModules[i]=&mi0; + } + else + { + test.Printf(_L("Module %d@%08x new\n"),mi.iModNum,mi.iCodeSeg); + SModuleInstance* pM=iGlobalList->GetMI(); + test(pM!=NULL); + *pM=mi; + iModules[i]=pM; + r=iGlobalList->iModules.InsertInOrder(pM, Order); + test(r==KErrNone); + } + } + return KErrNone; + } + +void LoaderTest::TestMultipleLoads() + { + CGlobalModuleList* p=CGlobalModuleList::New(*this); + p->CheckAll(); + +#ifdef __WINS__ + const TInt* multiLoad[] = {TC_MultLoad,0}; +#else + const TInt* multiLoad[] = {TC_MultLoad,TC_MultLoadTargetOnly,0}; +#endif + const TInt** multiLoadLists = multiLoad; + const TInt* tests; + while((tests=*multiLoadLists++)!=0) + { + TInt ntests=*tests++; + while(ntests>=4) + { + ntests-=4; + TInt exe1=*tests++; + TInt dll1=*tests++; + TInt exe2=*tests++; + TInt dll2=*tests++; + TUint32 xf1=GetModuleFlags(exe1); + TUint32 xf2=GetModuleFlags(exe2); + if (xf1&KModuleFlagExe) + { + TInt r=p->Load(exe1, dll1); + test.Printf(_L("%d:Load %d->%d"),exe1,dll1,r); + p->CheckAll(); + } + if (xf2&KModuleFlagExe) + { + TInt r=p->CloseHandle(exe2, dll2); + test.Printf(_L("%d:Close %d->%d"),exe2,dll2,r); + p->CheckAll(); + } + } + } + + delete p; + } +