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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32test\loader\exet.cpp
18 #define __INCLUDE_DEPENDENCY_GRAPH
26 #include "../mmu/d_memorytest.h"
29 #pragma warning(disable:4706)
32 const TInt KMaxHandlesPerDll=4;
33 const TInt KMaxHandles=KMaxHandlesPerDll*KNumModules;
35 extern "C" TInt _E32Startup();
37 extern "C" IMPORT_C void RegisterConstructorCall(TInt aDllNum);
38 extern "C" IMPORT_C void RegisterInitCall(TInt aDllNum);
39 extern "C" IMPORT_C void RegisterDestructorCall(TInt aDllNum);
41 #define PANIC() ExeTPanic(__LINE__)
42 #define EXET_ASSERT(c) ((void)((c)||(PANIC(),0)))
44 static TText GetSpecialDrive(TInt aSpecialDriveNum);
46 void ExeTPanic(TInt aLine)
48 User::Panic(_L("EXET"),aLine);
51 /******************************************************************************
53 ******************************************************************************/
55 NONSHARABLE_CLASS(TDllList) : public MDllList
59 virtual TBool IsPresent(const SDllInfo& aInfo);
60 virtual TInt Add(const SDllInfo& aInfo);
61 virtual void MoveToEnd(TInt aPos);
64 SDllInfo iInfo[KNumModules];
67 NONSHARABLE_CLASS(CTestServer) : public CServer2
71 virtual ~CTestServer();
72 virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
73 virtual TInt RunError(TInt aError);
78 NONSHARABLE_CLASS(CTestSession) : public CSession2
81 virtual ~CTestSession();
82 virtual void CreateL();
83 virtual void ServiceL(const RMessage2& aMessage);
85 TInt GetExeDepList(const RMessage2& aMessage);
86 TInt GetCDList(const RMessage2& aMessage);
87 TInt LoadDll(const RMessage2& aMessage);
88 TInt CloseDll(TInt aHandle);
89 TInt CallBlkI(TInt aHandle, TInt aIn);
90 TInt CallRBlkI(TInt aHandle, TInt aIn);
93 RMemoryTestLdd iTestLdd;
96 NONSHARABLE_CLASS(CDllInfo) : public CBase
102 TInt StoreHandle(TInt aHandle);
103 void RemoveHandle(TInt aIndex);
106 void RegisterConstructorCall(TInt aDllNum);
107 void RegisterInitCall(TInt aDllNum);
108 void RegisterDestructorCall(TInt aDllNum);
113 TInt iHandles[KMaxHandles];
114 TInt iModuleNum[KMaxHandles];
115 TDllList iExeDepList;
116 TDllList iDllConstructList;
119 /******************************************************************************
121 ******************************************************************************/
122 #ifdef __MODULE_HAS_DATA
138 TFullName StartThread=RThread().FullName();
139 TName StartProcess=RProcess().Name();
140 TExeData TheExeDataObject;
143 : iFileName(RProcess().FileName())
146 CHKDEPS(r); // Check our dependencies are initialised
148 User::Panic(_L("CHKDEPS"),r);
149 iStartTime.HomeTime();
151 RegisterConstructorCall(EXENUM);
155 /******************************************************************************
157 ******************************************************************************/
161 Mem::Fill(iInfo, KNumModules*sizeof(SDllInfo), 0xff);
164 TBool TDllList::IsPresent(const SDllInfo& aInfo)
167 for (i=0; i<iCount; ++i)
169 if (iInfo[i].iDllNum==aInfo.iDllNum)
175 TInt TDllList::Add(const SDllInfo& aInfo)
177 EXET_ASSERT(iCount<KNumModules);
179 iInfo[iCount++]=aInfo;
183 void TDllList::MoveToEnd(TInt aPos)
187 SDllInfo x(iInfo[aPos]);
188 Mem::Move(iInfo+aPos, iInfo+aPos+1, (iCount-aPos-1)*sizeof(SDllInfo));
193 /******************************************************************************
194 * Class CTestSession/CTestServer
195 ******************************************************************************/
197 CTestSession::~CTestSession()
201 void CTestSession::CreateL()
203 User::LeaveIfError(iTestLdd.Open());
206 void CTestSession::ServiceL(const RMessage2& aMessage)
208 TInt r=KErrNotSupported;
209 TInt mid=aMessage.Function();
212 case RLoaderTest::EMsgGetExeDepList:
213 r=GetExeDepList(aMessage);
215 case RLoaderTest::EMsgLoadDll:
218 case RLoaderTest::EMsgCallBlkI:
219 r=CallBlkI(aMessage.Int0(), aMessage.Int1());
221 case RLoaderTest::EMsgCallRBlkI:
222 r=CallRBlkI(aMessage.Int0(), aMessage.Int1());
224 case RLoaderTest::EMsgCloseDll:
225 r=CloseDll(aMessage.Int0());
227 case RLoaderTest::EMsgGetCDList:
228 r=GetCDList(aMessage);
230 case RLoaderTest::EMsgCheckReadable:
233 r = iTestLdd.ReadMemory((TAny*)aMessage.Int0(),value);
238 case RLoaderTest::EMsgExit:
240 CActiveScheduler::Stop();
245 aMessage.Complete(r);
248 TInt CTestSession::GetExeDepList(const RMessage2& aMsg)
250 TPtrC8 dep_list_ptr((const TUint8*)&iInfo->iExeDepList.iInfo, KNumModules*sizeof(SDllInfo));
251 aMsg.WriteL(0, dep_list_ptr, 0);
255 TInt CTestSession::GetCDList(const RMessage2& aMsg)
257 TPtrC8 list_ptr((const TUint8*)&iInfo->iDllConstructList.iInfo, KNumModules*sizeof(SDllInfo));
258 aMsg.WriteL(0, list_ptr, 0);
262 static void GetDllFileName(const TDesC& aListName, TDes& aTargetName)
264 Helper function for CTestSession::LoadDll transforms the supplied
265 filename to an absolutely qualified name if it has been copied to a drive.
267 @param aListName The DLL name. This will not have a path if it should
268 be loaded from the Z drive. Otherwise it will be fully
269 qualified but with a digit for the drive letter.
270 @param aTargetName Descriptor to populate with target filename. If the
271 DLL should be loaded from Z this is the same as aListName.
272 Otherwise, it is the same as aListName but with the correct
276 aTargetName.Copy(aListName);
277 if (aListName[1] != ':')
280 TText& targetDrive = aTargetName[0];
281 targetDrive = GetSpecialDrive(targetDrive - '0');
285 TInt CTestSession::LoadDll(const RMessage2& aMsg)
287 TInt module=aMsg.Int0();
289 TPtrC8 dll_list_ptr((const TUint8*)dll_list.iInfo, KNumModules*sizeof(SDllInfo));
290 TPtrC dllname0=MODULE_FILENAME(module);
292 GetDllFileName(dllname0, dllname);
293 iInfo->SetupCDList();
295 TInt r=l.Load(dllname, TUidType());
298 RDebug::Printf("RLibrary::Load returned 0x%x !",r);
299 return -999; // return unexpected error type so test fails.
303 TInitFunction f=(TInitFunction)l.Lookup(INIT_ORDINAL);
308 TBlkIFunction bf=(TBlkIFunction)l.Lookup(BLOCK_INC_ORDINAL);
310 TInt result=(*bf)(531441);
311 EXET_ASSERT(result==BlkIValue(module, 531441));
312 TInt h=iInfo->StoreHandle(l.Handle());
314 iInfo->iModuleNum[h]=module;
315 aMsg.WriteL(1, dll_list_ptr, 0);
319 TInt CTestSession::CallBlkI(TInt aHandle, TInt aIn)
321 TInt h=iInfo->iHandles[aHandle];
325 TBlkIFunction bf=(TBlkIFunction)l.Lookup(BLOCK_INC_ORDINAL);
330 TInt CTestSession::CallRBlkI(TInt aHandle, TInt aIn)
332 TInt h=iInfo->iHandles[aHandle];
336 TRBlkIFunction rbf=(TRBlkIFunction)l.Lookup(REC_BLOCK_INC_ORDINAL);
339 return (*rbf)(aIn,iInfo->iNextGen);
342 TInt CTestSession::CloseDll(TInt aHandle)
344 TInt h=iInfo->iHandles[aHandle];
345 TInt m=iInfo->iModuleNum[aHandle];
348 iInfo->iHandles[aHandle]=0;
349 iInfo->iModuleNum[aHandle]=-1;
350 iInfo->SetupCDList();
357 CTestServer::CTestServer()
358 : CServer2(0,ESharableSessions)
362 CTestServer::~CTestServer()
366 CSession2* CTestServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
369 CTestSession* s = new (ELeave) CTestSession;
374 _LIT(KExetErr,"EXETERR");
375 TInt CTestServer::RunError(TInt aError)
377 User::Panic(KExetErr,aError);
381 /******************************************************************************
383 ******************************************************************************/
386 #ifdef __MODULE_HAS_DATA
387 TInt init_mark=~((EXENUM+DLLNUMOFFSET)*(EXENUM+DLLNUMOFFSET));
388 if (InitFlag==init_mark)
394 for (i=0; i<16; ++i) x|=Bss[i];
401 if (StartProcess!=RProcess().Name())
403 if (TheExeDataObject.iTest1!=299792458)
405 if (TheExeDataObject.iFileName != RProcess().FileName())
408 RDebug::Print(_L("ChkC %S OK"),&TheExeDataObject.iFileName);
413 TInt Init(MDllList& aList)
418 info.iEntryPointAddress=((TInt)&_E32Startup);
421 info.iModuleHandle=ldd.ModuleHandleFromAddr((TInt)&_E32Startup);
423 if (!aList.IsPresent(info))
425 TInt pos=aList.Add(info);
426 INITDEPS(r,aList); // Call Init on our dependencies
427 aList.MoveToEnd(pos);
428 #ifdef __MODULE_HAS_DATA
430 r=ChkC(); // Check initial values for .data/.bss and check constructors have been called
432 RegisterInitCall(DLLNUM);
439 Mem::Fill(iModuleNum, sizeof(iModuleNum), 0xff);
442 CDllInfo::~CDllInfo()
446 TInt CDllInfo::Create()
449 r=UserSvr::DllSetTls(0, this);
451 r=UserSvr::DllSetTls(TLS_INDEX, NULL);
459 void CDllInfo::RegisterConstructorCall(TInt aDllNum)
464 void CDllInfo::RegisterInitCall(TInt aDllNum)
469 void CDllInfo::RegisterDestructorCall(TInt aDllNum)
474 TInt CDllInfo::StoreHandle(TInt aHandle)
476 if (iHandleCount==KMaxHandles)
479 for (; i<KMaxHandles && iHandles[i]!=0; ++i) {}
482 for (i=0; i<iNextHandle && iHandles[i]!=0; ++i) {}
483 EXET_ASSERT(i!=iNextHandle);
491 void CDllInfo::RemoveHandle(TInt aIndex)
497 void CDllInfo::SetupCDList()
499 new (&iDllConstructList) TDllList;
500 EXET_ASSERT(UserSvr::DllSetTls(TLS_INDEX, &iDllConstructList)==KErrNone);
503 /******************************************************************************
505 ******************************************************************************/
506 extern "C" __MODULE_EXPORT void RegisterConstructorCall(TInt aDllNum)
508 CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
510 p->RegisterConstructorCall(aDllNum);
513 extern "C" __MODULE_EXPORT void RegisterInitCall(TInt aDllNum)
515 CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
517 p->RegisterInitCall(aDllNum);
520 extern "C" __MODULE_EXPORT void RegisterDestructorCall(TInt aDllNum)
522 CDllInfo* p=(CDllInfo*)UserSvr::DllTls(0);
524 p->RegisterDestructorCall(aDllNum);
527 static TText GetSpecialDrive(TInt aSpecialDriveNum)
529 Work out which physical drive corresponds to the supplied
532 @param aSpecialDriveNum Number which identifies which drive to find.
533 Zero means internal drive.
534 @return Drive letter.
538 TInt r = fs.Connect();
539 EXET_ASSERT(r == KErrNone);
541 // cannot load binaries from emulated removable drives
543 if (aSpecialDriveNum == 1)
548 for (TInt d = 0; d <= (TInt)sizeof(SpecialDriveList); ++d)
550 dr = SpecialDriveList[d];
552 r = fs.Drive(di, dr);
553 EXET_ASSERT(r == KErrNone);
554 if (di.iType == EMediaNotPresent)
557 // drive 0 == internal
558 if (aSpecialDriveNum == 0 && (di.iDriveAtt & KDriveAttInternal) != 0)
560 // drive 1 == removable
561 if (aSpecialDriveNum == 1 && (di.iDriveAtt & KDriveAttRemovable) != 0)
566 r = RFs::DriveToChar(dr, ch0);
567 EXET_ASSERT(r == KErrNone);
569 return static_cast<TText>(TUint(ch0));
572 GLDEF_C TInt E32Main()
574 CTrapCleanup* cleanup=CTrapCleanup::New();
575 EXET_ASSERT(cleanup);
576 CActiveScheduler* sched=new CActiveScheduler;
578 CActiveScheduler::Install(sched);
579 CTestServer* svr=new CTestServer;
582 User::CommandLine(suffix);
583 TName svr_name=KServerName();
586 svr_name.Append('.');
589 EXET_ASSERT(svr->Start(svr_name)==KErrNone);
590 CDllInfo* dllinfo=new CDllInfo;
591 EXET_ASSERT(dllinfo);
592 EXET_ASSERT(dllinfo->Create()==KErrNone);
595 CActiveScheduler::Start();
597 UserSvr::DllFreeTls(0);
598 UserSvr::DllFreeTls(TLS_INDEX);