kerneltest/e32test/mmu/t_wsd_tst.cpp
branchRCL_3
changeset 21 e7d2d738d3c2
equal deleted inserted replaced
20:597aaf25e343 21:e7d2d738d3c2
       
     1 // Copyright (c) 2006-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 // e32test\mmu\t_wsd_tst.cpp
       
    15 // Test exporting and importing writable static data in DLLs.
       
    16 // This test relies on three dlls:
       
    17 // - t_wsd_dl1_[cx][pu]		Which is statically linked, and exports both code & data
       
    18 // - t_wsd_dl2_[cx][pu]		Which is dyanamically loaded, and imports code & writable static data from
       
    19 // - t_wsd_dl3_[cx][pu]		Which exports code and writable static data
       
    20 // The [cx] suffix indicates code-in-RAM vs XIP (ROM), and [pu] indicate paged or unpaged code.
       
    21 //
       
    22 
       
    23 //! @SYMTestCaseID			KBASE-T_CODEPAGING-0335
       
    24 //! @SYMTestType			UT
       
    25 //! @SYMPREQ				PREQ1110
       
    26 //! @SYMTestCaseDesc		Demand Paging Code Paging tests.
       
    27 //! @SYMTestActions			001 Code paging tests
       
    28 //! @SYMTestExpectedResults All tests should pass.
       
    29 //! @SYMTestPriority        High
       
    30 //! @SYMTestStatus          Implemented
       
    31 
       
    32 #define __E32TEST_EXTENSION__
       
    33 #include <e32test.h>
       
    34 #include <e32math.h>
       
    35 #include <f32file.h>
       
    36 #include <f32dbg.h>
       
    37 
       
    38 #include "mmudetect.h"
       
    39 #include "t_wsd_tst.h"
       
    40 
       
    41 // Global data /////////////////////////////////////////////////////////////////
       
    42 
       
    43 _LIT(KSearchPathTemplate, "%c:\\sys\\bin");		// drive letter
       
    44 _LIT(KLibraryName, "t_wsd_dl%d_%c%c");			// [23] [cx] [pu]
       
    45 
       
    46 TInt TheFailure = KErrNone;
       
    47 TChar CurrentDrive = 'Z';
       
    48 
       
    49 void SetCurrentDrive(TChar aDrive)
       
    50 	{
       
    51 	CurrentDrive = aDrive;
       
    52 	}
       
    53 
       
    54 class TPagingDriveInfo
       
    55 	{
       
    56 public:
       
    57 	TChar iDriveLetter;
       
    58 	TDriveInfo iDriveInfo;
       
    59 	};
       
    60 
       
    61 RArray<TPagingDriveInfo> SupportedDrives;
       
    62 
       
    63 // RTest stuff /////////////////////////////////////////////////////////////////
       
    64 
       
    65 RTest test(_L("T_WSD"));
       
    66 
       
    67 #define test_noError(x) { TInt _r = (x); if (_r < 0) HandleError(_r, __LINE__); }
       
    68 #define test_notNull(x) { TAny* _a = (TAny*)(x); if (_a == NULL) HandleNull(__LINE__); }
       
    69 #define test_equal(e, a) { TInt _e = TInt(e); TInt _a = TInt(a); if (_e != _a) HandleNotEqual(_e, _a, __LINE__); }
       
    70 
       
    71 void HandleError(TInt aError, TInt aLine)
       
    72 	{
       
    73 	test.Printf(_L("Error %d\n"), aError);
       
    74 	test.operator()(EFalse, aLine);
       
    75 	}
       
    76 
       
    77 void HandleNull(TInt aLine)
       
    78 	{
       
    79 	test.Printf(_L("Null value\n"));
       
    80 	test.operator()(EFalse, aLine);
       
    81 	}
       
    82 
       
    83 void HandleNotEqual(TInt aExpected, TInt aActual, TInt aLine)
       
    84 	{
       
    85 	test.Printf(_L("Expected 0x%x but got 0x%x\n"), aExpected, aActual);
       
    86 	test.operator()(EFalse, aLine);
       
    87 	}
       
    88 
       
    89 // Utility functions ///////////////////////////////////////////////////////////
       
    90 
       
    91 TPtrC16 GetMediaType(TInt aMediaType)
       
    92 	{
       
    93 	_LIT(KMediaNotPresent, "MediaNotPresent");
       
    94 	_LIT(KMediaUnknown, "MediaUnknown");
       
    95 	_LIT(KMediaFloppy, "MediaFloppy");
       
    96 	_LIT(KMediaHardDisk, "MediaHardDisk");
       
    97 	_LIT(KMediaCdRom, "MediaCdRom");
       
    98 	_LIT(KMediaRam, "MediaRam");
       
    99 	_LIT(KMediaFlash, "MediaFlash");
       
   100 	_LIT(KMediaRom, "MediaRom");
       
   101 	_LIT(KMediaRemote, "MediaRemote");
       
   102 	_LIT(KMediaNANDFlash, "MediaNANDFlash");
       
   103 	_LIT(KMediaUnKnown, "MediaUnKnown");
       
   104 
       
   105 	switch (aMediaType)
       
   106 		{
       
   107 	case EMediaNotPresent:
       
   108 		return KMediaNotPresent();
       
   109 	case EMediaUnknown:
       
   110 		return KMediaUnknown();
       
   111 	case EMediaFloppy:
       
   112 		return KMediaFloppy();
       
   113 	case EMediaHardDisk:
       
   114 		return KMediaHardDisk();
       
   115 	case EMediaCdRom:
       
   116 		return KMediaCdRom();
       
   117 	case EMediaRam:
       
   118 		return KMediaRam();
       
   119 	case EMediaFlash:
       
   120 		return KMediaFlash();
       
   121 	case EMediaRom:
       
   122 		return KMediaRom();
       
   123 	case EMediaRemote:
       
   124 		return KMediaRemote();
       
   125 	case EMediaNANDFlash:
       
   126 		return KMediaNANDFlash();
       
   127 	default:
       
   128 		return KMediaUnKnown();
       
   129 		}
       
   130 	}
       
   131 
       
   132 // Get the list of testable drives
       
   133 void GetSupportedDrives(TBool aVerbose = EFalse)
       
   134 	{
       
   135 	TUint32 memModelAttributes = UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);
       
   136 	TBool codePagingSupported = (memModelAttributes & EMemModelAttrCodePaging) != 0;
       
   137 	TUint32 pagingPolicy = E32Loader::PagingPolicy();
       
   138 	TBool pagingPolicyAllowsPaging = pagingPolicy != EKernelConfigCodePagingPolicyNoPaging;
       
   139 	test_Equal(codePagingSupported, pagingPolicyAllowsPaging);
       
   140 	if (codePagingSupported)
       
   141 		test.Printf(_L("Code paging is enabled.\n"));
       
   142 	else
       
   143 		test.Printf(_L("Code paging is NOT enabled.\n"));
       
   144 
       
   145 	if (aVerbose)
       
   146 		{
       
   147 		test.Printf(_L("Available drives:\n"));
       
   148 		test.Printf(_L("     Type             Attr     MedAttr  Filesystem\n"));
       
   149 		}
       
   150 
       
   151 	RFs fs;
       
   152 	test_noError(fs.Connect());
       
   153 
       
   154 	TDriveList driveList;
       
   155 	TInt r = fs.DriveList(driveList);
       
   156 	test_noError(r);
       
   157 
       
   158 	TBool NandPageableMediaFound = EFalse;
       
   159 	for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
       
   160 		{
       
   161 		if (!driveList[drvNum])
       
   162 			continue;   //-- skip unexisting drive
       
   163 
       
   164 		TDriveInfo driveInfo;
       
   165 		r = fs.Drive(driveInfo, drvNum);
       
   166 		test_noError(r);
       
   167 
       
   168 		TChar ch;
       
   169 		r = fs.DriveToChar(drvNum, ch);
       
   170 		test_noError(r);
       
   171 
       
   172 		TBuf<256> fileSystemName;
       
   173 		r = fs.FileSystemName(fileSystemName, drvNum);
       
   174 		test_noError(r);
       
   175 
       
   176 		// Decide which drives to exclude:
       
   177 		//		Locked/nonwritable drives, except the Z: ROM drive
       
   178 		//		Win32 drives on the emulator
       
   179 		//		Remote/nonlocal, removable/noninternal, redirected, substed drives
       
   180 		//	All others are included by default iff code paging is supported
       
   181 		//	If not, only the Z: ROM/XIP drive is tested
       
   182 		_LIT(KWin32FS, "Win32");
       
   183 		TBool include = codePagingSupported;
       
   184 		if (driveInfo.iDriveAtt & KDriveAttRom)
       
   185 			include = (ch == 'Z');
       
   186 		else if (driveInfo.iMediaAtt & (KMediaAttWriteProtected|KMediaAttLocked))
       
   187 			include = EFalse;
       
   188 		else if (fileSystemName == KWin32FS())
       
   189 			include = EFalse;
       
   190 		else if (driveInfo.iDriveAtt & (KDriveAttRedirected|KDriveAttSubsted|KDriveAttRemovable|KDriveAttRemote))
       
   191 			include = EFalse;
       
   192 		else if ((KDriveAttInternal|KDriveAttLocal) & ~driveInfo.iDriveAtt)
       
   193 			include = EFalse;
       
   194 
       
   195 		if (include)
       
   196 			{
       
   197 			TPagingDriveInfo pagingDriveInfo;
       
   198 			pagingDriveInfo.iDriveLetter = ch;
       
   199 			pagingDriveInfo.iDriveInfo = driveInfo;
       
   200 			r = SupportedDrives.Append(pagingDriveInfo);
       
   201 			test_noError(r);
       
   202 			}
       
   203 
       
   204 		TBool pageable = EFalse;
       
   205 		if (driveInfo.iDriveAtt & KDriveAttPageable)
       
   206 			{
       
   207 			pageable = ETrue;
       
   208 			if (driveInfo.iType == EMediaNANDFlash)
       
   209 				NandPageableMediaFound = ETrue;
       
   210 			}
       
   211 
       
   212 		// If we've already found a pageable NAND drive, then assume the
       
   213 		// Z: drive is pageable too if it's got a composite file system
       
   214 		_LIT(KCompositeName,"Composite");
       
   215 		if (NandPageableMediaFound && fileSystemName == KCompositeName())
       
   216 			pageable = ETrue;
       
   217 
       
   218 		if (aVerbose)
       
   219 			{
       
   220 			TPtrC16 mediaType = GetMediaType(driveInfo.iType);
       
   221 			_LIT(KPageable, "pageable");
       
   222 			test.Printf(_L("%c  %c: %16S %08x %08x %10S %S\n"),
       
   223 						include ? '*' : ' ', (TUint)ch, &mediaType,
       
   224 						driveInfo.iDriveAtt, driveInfo.iMediaAtt,
       
   225 			            &fileSystemName, (pageable ? &KPageable : &KNullDesC));
       
   226 			}
       
   227 		}
       
   228 
       
   229 	fs.Close();
       
   230 	}
       
   231 
       
   232 const TDesC& LibrarySearchPath(TChar aDrive)
       
   233 	{
       
   234 	static TBuf<64> path;
       
   235 	path.Format(KSearchPathTemplate, (TUint)aDrive);
       
   236 	return path;
       
   237 	}
       
   238 
       
   239 const TDesC& LibraryName(TChar aDrive, TInt aLibNo, TBool aRam, TBool aPaged)
       
   240 	{
       
   241 	// this gives DLL#2 a different name on each drive so we can be sure we're loading the right one
       
   242 	static TBuf<64> name;
       
   243 	name.Format(KLibraryName, aLibNo, aRam ? 'c' : 'x', aPaged ? 'p' : 'u');
       
   244 	if (aLibNo == 2 && aDrive != 'Z')
       
   245 		name.AppendFormat(_L("_%c"), (TUint)aDrive);
       
   246 	return name;
       
   247 	}
       
   248 
       
   249 const TDesC& LibraryFilename(TChar aDrive, TInt aLibNo, TBool aRam, TBool aPaged)
       
   250 	{
       
   251 	static TBuf<64> filename;
       
   252 	filename = LibrarySearchPath(aDrive);
       
   253 	filename.AppendFormat(_L("\\%S.dll"), &LibraryName(aDrive, aLibNo, aRam, aPaged));
       
   254 	return filename;
       
   255 	}
       
   256 
       
   257 TInt LoadSpecificLibrary(RLibrary& aLibrary, TChar aDrive, TInt aLibNo, TBool aRam, TBool aPaged)
       
   258 	{
       
   259 	const TDesC& path = LibrarySearchPath(aDrive);
       
   260 	const TDesC& name = LibraryName(aDrive, aLibNo, aRam, aPaged);
       
   261 	TInt err = aLibrary.Load(name, path);
       
   262 	TBuf<256> message;
       
   263 	message.Format(_L("Loading %S\\%S.dll returns %d\n"), &path, &name, err);
       
   264 	test.Printf(message);
       
   265 	return err;
       
   266 	}
       
   267 
       
   268 // Test functions //////////////////////////////////////////////////////////////
       
   269 
       
   270 void CopyDllToCurrentDrive(RFs& aFs, TBool aPaged, TInt aLibNo)
       
   271 	{
       
   272 	TBuf<64> source = LibraryFilename('Z', aLibNo, ETrue, aPaged);
       
   273 	TBuf<64> dest = LibraryFilename(CurrentDrive, aLibNo, ETrue, aPaged);
       
   274 	test.Printf(_L("Copying %S to %S\n"), &source, &dest);
       
   275 
       
   276 	TInt r = aFs.MkDirAll(dest);
       
   277 	test(r == KErrNone || r == KErrAlreadyExists);
       
   278 
       
   279 	TBuf<64> tempName(dest);
       
   280 	tempName.Append(_L(".tmp"));
       
   281 
       
   282 	RFile in, out, temp;
       
   283 	test_noError(in.Open(aFs, source, EFileRead));
       
   284 	test_noError(out.Replace(aFs, dest, EFileWrite));
       
   285 	test_noError(temp.Replace(aFs, tempName, EFileWrite));
       
   286 
       
   287 	const TInt KBufferSize = 3333;
       
   288 	TBuf8<KBufferSize> buffer;
       
   289 
       
   290 	test_noError(temp.Write(buffer));
       
   291 	test_noError(temp.Flush());
       
   292 
       
   293 	TInt size;
       
   294 	test_noError(in.Size(size));
       
   295 	TInt pos = 0;
       
   296 	while (pos < size)
       
   297 		{
       
   298 		test_noError(in.Read(buffer));
       
   299 		test_noError(out.Write(buffer));
       
   300 		test_noError(out.Flush());
       
   301 		test_noError(temp.Write(buffer));
       
   302 		test_noError(temp.Flush());
       
   303 		pos += buffer.Length();
       
   304 		}
       
   305 
       
   306 	out.SetAtt(KEntryAttNormal, KEntryAttReadOnly|
       
   307 								KEntryAttHidden|
       
   308 								KEntryAttSystem|
       
   309 								KEntryAttArchive|
       
   310 								KEntryAttXIP);
       
   311 
       
   312 	in.Close();
       
   313 	out.Close();
       
   314 	temp.Close();
       
   315 	}
       
   316 
       
   317 void CopyDllsToCurrentDrive()
       
   318 	{
       
   319 	RFs fs;
       
   320 	test_noError(fs.Connect());
       
   321 
       
   322 	CopyDllToCurrentDrive(fs, EFalse, 2);		// Unpaged library 2
       
   323 	CopyDllToCurrentDrive(fs, EFalse, 3);		// Unpaged library 3
       
   324 	CopyDllToCurrentDrive(fs, ETrue, 2);		// Paged library 2
       
   325 	CopyDllToCurrentDrive(fs, ETrue, 3);		// Paged library 3
       
   326 
       
   327 	fs.Close();
       
   328 	}
       
   329 
       
   330 void EraseDllsFromCurrentDrive()
       
   331 	{
       
   332 	RFs fs;
       
   333 	test_noError(fs.Connect());
       
   334 
       
   335 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
   336 	test_notNull(cleanup);
       
   337 
       
   338 	CFileMan* fileMan = NULL;
       
   339 	TRAPD(r, fileMan = CFileMan::NewL(fs));
       
   340 	test_noError(r);
       
   341 
       
   342 	TBuf<64> libdir = LibrarySearchPath(CurrentDrive);
       
   343 	test.Printf(_L("Erasing %S\n"), &libdir);
       
   344 	fileMan->RmDir(libdir);
       
   345 
       
   346 	delete fileMan;
       
   347 	delete cleanup;
       
   348 	fs.Close();
       
   349 	}
       
   350 
       
   351 void CheckRelocatableData(RLibrary& library)
       
   352 	{
       
   353 	TGetAddressOfDataFunction func = (TGetAddressOfDataFunction)library.Lookup(KGetAddressOfDataFunctionOrdinal);
       
   354 	test_notNull(func);
       
   355 
       
   356 	TInt size;
       
   357 	void* codeAddr;
       
   358 	void* dataAddr;
       
   359 	void*** dataPtrPtr = (void***)func(size, codeAddr, dataAddr);
       
   360 	void **dp = (void **)dataAddr;
       
   361 
       
   362 	for (TInt i = 0; i < size/4; i += 2)
       
   363 		{
       
   364 		test_equal(dp[i], codeAddr);
       
   365 		test_equal(dp[i+1], dataAddr);
       
   366 		}
       
   367 
       
   368 	test_equal(*dataPtrPtr, dp);
       
   369 	}
       
   370 
       
   371 void CheckWritableStaticData(RLibrary& library)
       
   372 	{
       
   373 	TInt (*func)(void) = (TInt (*)(void))library.Lookup(KCheckWritableStaticDataFunctionOrdinal);
       
   374 	RDebug::Printf("CheckWritableStaticData() is export %d at %08x", KCheckWritableStaticDataFunctionOrdinal, func);
       
   375 	test_notNull(func);
       
   376 	TInt err = func();
       
   377 	RDebug::Printf("CheckWritableStaticData() returned %d", err);
       
   378 	// test_noError(err);
       
   379 	if (TheFailure == KErrNone)
       
   380 		TheFailure = err;
       
   381 	}
       
   382 
       
   383 void RunPerDriveTests(TBool aPaged, TBool aRam)
       
   384 	{
       
   385 	TBuf<64> message = _L("Running ");
       
   386 	if (!aPaged)
       
   387 		message.Append(_L("un"));
       
   388 	message.AppendFormat(_L("paged R%cM tests on drive %c:"),
       
   389 		aRam ? 'A' : 'O', (TUint)CurrentDrive);
       
   390 	test.Next(message);
       
   391 
       
   392 	RFs fs;
       
   393 	test_noError(fs.Connect());
       
   394 	fs.SetDebugRegister(KFLDR);
       
   395 
       
   396 	// Explicitly loading dl2 will implicitly load dl3 as well
       
   397 	RLibrary dl2;
       
   398 	test_noError(LoadSpecificLibrary(dl2, CurrentDrive, 2, aRam, aPaged));
       
   399 	CheckRelocatableData(dl2);
       
   400 	CheckWritableStaticData(dl2);
       
   401 	dl2.Close();
       
   402 
       
   403 	fs.SetDebugRegister(0);
       
   404 	fs.Close();
       
   405 	}
       
   406 
       
   407 TInt E32Main()
       
   408 	{
       
   409 	test.Title();
       
   410 	test.Start(_L("WSD tests"));
       
   411 
       
   412 	// Check static linkage to dl1
       
   413 	test_noError(CheckExportedDataAddress(&ExportedData));
       
   414 
       
   415 	GetSupportedDrives(ETrue);
       
   416 	test(SupportedDrives.Count() > 0);
       
   417 
       
   418 	// Turn off evil lazy dll unloading
       
   419 	RLoader l;
       
   420 	test(l.Connect()==KErrNone);
       
   421 	test(l.CancelLazyDllUnload()==KErrNone);
       
   422 	l.Close();
       
   423 
       
   424 	// Make sure there aren't any DLLs left over from earlier tests
       
   425 	TInt i = SupportedDrives.Count();
       
   426 	while (--i >= 0)
       
   427 		{
       
   428 		SetCurrentDrive(SupportedDrives[i].iDriveLetter);
       
   429 		if (CurrentDrive != 'Z')
       
   430 				EraseDllsFromCurrentDrive();
       
   431 		}
       
   432 
       
   433 	// We want to test all supported drives in order of increasing priority, so
       
   434 	// that the CurrentDrive is always the hghest priority of those tested so far.
       
   435 	// Therefore, if Z (XIP ROM, lowest priority) is a valid test drive, do it first
       
   436 	i = SupportedDrives.Count();
       
   437 	if (--i >= 0)
       
   438 		{
       
   439 		SetCurrentDrive(SupportedDrives[i].iDriveLetter);
       
   440 		if (CurrentDrive == 'Z')
       
   441 			{
       
   442 			// ROM (XIP) tests can only be run from Z:
       
   443 			RunPerDriveTests(EFalse, EFalse);		// Unpaged ROM
       
   444 			RunPerDriveTests(ETrue, EFalse);		// Paged ROM
       
   445 			RunPerDriveTests(EFalse, ETrue);		// Unpaged RAM
       
   446 			RunPerDriveTests(ETrue, ETrue);			// Paged RAM
       
   447 			}
       
   448 		}
       
   449 
       
   450 	// Now run the RAM-based versions from each remaining drive in turn
       
   451 	for (i = 0; i < SupportedDrives.Count(); ++i)
       
   452 		{
       
   453 		SetCurrentDrive(SupportedDrives[i].iDriveLetter);
       
   454 		if (CurrentDrive != 'Z')
       
   455 			{
       
   456 			CopyDllsToCurrentDrive();
       
   457 			RunPerDriveTests(EFalse, ETrue);			// Unpaged RAM
       
   458 			RunPerDriveTests(ETrue, ETrue);				// Paged RAM
       
   459 			}
       
   460 		}
       
   461 
       
   462 	test_noError(TheFailure);
       
   463 	test.End();
       
   464 	return 0;
       
   465 	}
       
   466