kerneltest/f32test/demandpaging/integtest/src/t_dpattr.cpp
changeset 43 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 43:96e5fb8b040d
       
     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 // @SYMTestCaseID				KBASE-DP_FUNC_ATTRIBUTES-0303
       
    15 // @SYMTestCaseDesc			Symbian OS Toolchain's Paging Override and the
       
    16 // Paging Policy settings
       
    17 // @SYMREQ						REQ6808
       
    18 // @SYMPREQ					PREQ1110
       
    19 // @SYMTestPriority			High
       
    20 // @SYMTestActions
       
    21 // 1.	Load executables with the RProcess API and run them. Each executable has a
       
    22 // different set of attributes:
       
    23 // "	Paging attribute: paged, unpaged or no paging attribute in MMP and/or
       
    24 // OBY files
       
    25 // "	Compression mode: specified or not
       
    26 // "	Executable built in ROM as 'data' or 'file'
       
    27 // "	Solid binaries or aliases
       
    28 // Retrieve and analyse the demand paging activity trace caused by the preceding
       
    29 // action, in order to determine whether this binary is paged on demand or not.
       
    30 // 2.	Repeat the preceding action by loading DLLs with the RLibrary API and
       
    31 // making calls to them.
       
    32 // @SYMTestExpectedResults
       
    33 // 1.	Process complete without error. If, according to the trace data gathered,
       
    34 // the main thread newly created process causes the executable to be paged in,
       
    35 // then it is a proof that the executable is paged. Depending on the Paging
       
    36 // Override setting and the Loader Paging Policy specified at the time the ROM was
       
    37 // built, the Loader makes a decision as to whether page the binary or not,
       
    38 // according to the rules listed in the Design Sketch. This is how we determine
       
    39 // this, in this order:
       
    40 // a.	If ROM paging is disabled: not paged
       
    41 // b.	If executable was built in ROM as 'data': not paged
       
    42 // c.	If the a file compression scheme was specified at ROM build time: not paged
       
    43 // d.	If the Loader Paging policy is 'NOT PAGED': not paged
       
    44 // e.	If the Loader Paging policy is 'ALWAYS PAGE': paged
       
    45 // f.	If the Paging Override is 'NOT PAGED': not paged
       
    46 // g.	If the Paging Override is 'ALWAYS PAGE': paged
       
    47 // h.	If the OBY paging keyword for this executable is 'PAGED': paged
       
    48 // i.	If the OBY paging keyword for this executable is 'NOT PAGED': unpaged
       
    49 // j.	If the MMP paging keyword for this executable is 'PAGED': paged
       
    50 // k.	If the MMP paging keyword for this executable is 'NOT PAGED': not paged
       
    51 // l.	If the Paging Override is 'DEFAULT UNPAGED': not paged
       
    52 // m.	If the Paging Override is 'DEFAULT PAGED': paged
       
    53 // n.	If the Paging Policy is 'DEFAULT UNPAGED': not paged
       
    54 // o.	The executable must be paged
       
    55 // 2.	DLL is loaded. Functions are called and complete without errors. The rules
       
    56 // to determine whether the binary should be paged or not are the same as in the
       
    57 // preceding action.
       
    58 // 
       
    59 //
       
    60 
       
    61 #include <e32test.h>
       
    62 #include <e32ldr.h>
       
    63 #include <d32btrace.h>
       
    64 #include "u32std.h"
       
    65 #include <f32file.h>
       
    66 #include <dptest.h>
       
    67 
       
    68 #define TEST_EQ(a,b) { if (a != b) { test.Printf(_L("%d != %d\n"), a, b); test(EFalse); } }
       
    69 #define TEST_CONDITION(a) { if (!a) { test.Printf(_L("TEST FAILED at line %d\n"), __LINE__); pass = EFalse; } }
       
    70 #define LE4(a) ((TUint) (*((a) + 3) << 24) + (*((a) + 2) << 16) + (*((a) + 1) << 8) + *(a))
       
    71 
       
    72 RTest test(_L("T_DPATTR"));
       
    73 RBTrace btrace;
       
    74 RFs fs;
       
    75 
       
    76 // ROM paging settings
       
    77 TBool gIsRomDemangPagingEnabled;
       
    78 TInt gPagingOverride;
       
    79 TInt gPagingPolicy;
       
    80 
       
    81 // This process
       
    82 TUint32 gNThreadId = 0;
       
    83 
       
    84 // Test executables attributes flags
       
    85 enum
       
    86 	{
       
    87 	ENone					= 0,
       
    88 	EMMPPaged				= 1 << 0,		// "PAGED" keyword in MMP file
       
    89 	EMMPUnpaged				= 1 << 1,		// "UNPAGED" keyword in MMP file
       
    90 	EMMPCompressTarget		= 1 << 2,		// "COMPRESSTARGET" keyword in MMP file
       
    91 	EMMPNoCompressTarget	= 1 << 3,		// "UNCOMPRESSTARGET" keyword in MMP file
       
    92 	EIBYData				= 1 << 4,		// File included as "data" in IBY file
       
    93 	EIBYFile				= 1 << 5,		// File included as "file" in IBY file
       
    94 	EIBYFileCompress		= 1 << 6,		// File included as "file_x_" in IBY file (_x_=compression scheme)
       
    95 	EIBYPaged				= 1 << 7,		// File declared "paged" in IBY file
       
    96 	EIBYUnpaged				= 1 << 8,		// File declared "unpaged in IBY file
       
    97 	EIBYAlias				= 1 << 9,		// File name is an alias
       
    98 	EDLLWritableStaticData	= 1 << 10		// DLL contains writable static data
       
    99 	};
       
   100 
       
   101 // Test executables attributes
       
   102 const TUint testExeAttr[] =
       
   103 	{
       
   104 	/* 000 - does not exist */ ENone,
       
   105 	/* 001 */ EIBYFile,
       
   106 	/* 002 */ EMMPPaged | EIBYFile,
       
   107 	/* 003 */ EMMPUnpaged | EIBYFile,
       
   108 	/* 004 */ EIBYFileCompress,
       
   109 	/* 005 */ EMMPPaged | EIBYFileCompress,
       
   110 	/* 006 */ EMMPUnpaged | EIBYFileCompress,
       
   111 	/* 007 */ EIBYFileCompress,
       
   112 	/* 008 */ EMMPPaged | EIBYFileCompress,
       
   113 	/* 009 */ EMMPUnpaged | EIBYFileCompress,
       
   114 	/* 010 */ EIBYFileCompress,
       
   115 	/* 011 */ EMMPPaged | EIBYFileCompress,
       
   116 	/* 012 */ EMMPUnpaged | EIBYFileCompress,
       
   117 	/* 013 */ EIBYFile | EMMPCompressTarget,
       
   118 	/* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget,
       
   119 	/* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
       
   120 	/* 016 */ EIBYData,
       
   121 	/* 017 */ EMMPPaged | EIBYData,
       
   122 	/* 018 */ EMMPUnpaged | EIBYData,
       
   123 	/* 019 */ EIBYFile | EIBYPaged,
       
   124 	/* 020 */ EMMPPaged | EIBYFile | EIBYPaged,
       
   125 	/* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged,
       
   126 	/* 022 */ EIBYFile | EIBYUnpaged,
       
   127 	/* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged,
       
   128 	/* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged,
       
   129 	/* 025 */ EIBYData | EIBYPaged,
       
   130 	/* 026 */ EMMPPaged | EIBYData | EIBYPaged,
       
   131 	/* 027 */ EMMPUnpaged | EIBYData | EIBYPaged,
       
   132 	/* 028 */ EIBYData | EIBYUnpaged,
       
   133 	/* 029 */ EMMPPaged | EIBYData | EIBYUnpaged,
       
   134 	/* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged,
       
   135 	/* 031 */ EIBYAlias | EIBYFile,
       
   136 	/* 032 */ EIBYAlias | EMMPPaged | EIBYFile,
       
   137 	/* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile,
       
   138 	/* 034 */ EIBYAlias | EIBYFileCompress,
       
   139 	/* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
       
   140 	/* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
       
   141 	/* 037 */ EIBYAlias | EIBYFileCompress,
       
   142 	/* 038 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
       
   143 	/* 039 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
       
   144 	/* 040 */ EIBYAlias | EIBYFileCompress,
       
   145 	/* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
       
   146 	/* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
       
   147 	/* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget,
       
   148 	/* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget,
       
   149 	/* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
       
   150 	/* 046 */ EIBYAlias | EIBYData,
       
   151 	/* 047 */ EIBYAlias | EMMPPaged | EIBYData,
       
   152 	/* 048 */ EIBYAlias | EMMPUnpaged | EIBYData,
       
   153 	/* 049 */ EIBYAlias | EIBYFile | EIBYPaged,
       
   154 	/* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged,
       
   155 	/* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged,
       
   156 	/* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged,
       
   157 	/* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged,
       
   158 	/* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged,
       
   159 	/* 055 */ EIBYAlias | EIBYData | EIBYPaged,
       
   160 	/* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged,
       
   161 	/* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged,
       
   162 	/* 058 */ EIBYAlias | EIBYData | EIBYUnpaged,
       
   163 	/* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged,
       
   164 	/* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged
       
   165 	};
       
   166 const TUint testDllAttr[] =
       
   167 	{
       
   168 	/* 000 - does not exist */ ENone,
       
   169 	/* 001 */ EIBYFile,
       
   170 	/* 002 */ EMMPPaged | EIBYFile,
       
   171 	/* 003 */ EMMPUnpaged | EIBYFile,
       
   172 	/* 004 */ EIBYFileCompress,
       
   173 	/* 005 */ EMMPPaged | EIBYFileCompress,
       
   174 	/* 006 */ EMMPUnpaged | EIBYFileCompress,
       
   175 	/* 007 */ EDLLWritableStaticData,
       
   176 	/* 008 */ EMMPPaged | EDLLWritableStaticData,
       
   177 	/* 009 */ EMMPUnpaged | EDLLWritableStaticData,
       
   178 	/* 010 */ EIBYFileCompress,
       
   179 	/* 011 */ EMMPPaged | EIBYFileCompress,
       
   180 	/* 012 */ EMMPUnpaged | EIBYFileCompress,
       
   181 	/* 013 */ EIBYFile | EMMPCompressTarget,
       
   182 	/* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget,
       
   183 	/* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
       
   184 	/* 016 */ EIBYData,
       
   185 	/* 017 */ EMMPPaged | EIBYData,
       
   186 	/* 018 */ EMMPUnpaged | EIBYData,
       
   187 	/* 019 */ EIBYFile | EIBYPaged,
       
   188 	/* 020 */ EMMPPaged | EIBYFile | EIBYPaged,
       
   189 	/* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged,
       
   190 	/* 022 */ EIBYFile | EIBYUnpaged,
       
   191 	/* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged,
       
   192 	/* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged,
       
   193 	/* 025 */ EIBYData | EIBYPaged,
       
   194 	/* 026 */ EMMPPaged | EIBYData | EIBYPaged,
       
   195 	/* 027 */ EMMPUnpaged | EIBYData | EIBYPaged,
       
   196 	/* 028 */ EIBYData | EIBYUnpaged,
       
   197 	/* 029 */ EMMPPaged | EIBYData | EIBYUnpaged,
       
   198 	/* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged,
       
   199 	/* 031 */ EIBYAlias | EIBYFile,
       
   200 	/* 032 */ EIBYAlias | EMMPPaged | EIBYFile,
       
   201 	/* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile,
       
   202 	/* 034 */ EIBYAlias | EIBYFileCompress,
       
   203 	/* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
       
   204 	/* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
       
   205 	/* 037 */ EIBYAlias | EDLLWritableStaticData,
       
   206 	/* 038 */ EIBYAlias | EMMPPaged | EDLLWritableStaticData,
       
   207 	/* 039 */ EIBYAlias | EMMPUnpaged | EDLLWritableStaticData,
       
   208 	/* 040 */ EIBYAlias | EIBYFileCompress,
       
   209 	/* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress,
       
   210 	/* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress,
       
   211 	/* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget,
       
   212 	/* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget,
       
   213 	/* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged,
       
   214 	/* 046 */ EIBYAlias | EIBYData,
       
   215 	/* 047 */ EIBYAlias | EMMPPaged | EIBYData,
       
   216 	/* 048 */ EIBYAlias | EMMPUnpaged | EIBYData,
       
   217 	/* 049 */ EIBYAlias | EIBYFile | EIBYPaged,
       
   218 	/* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged,
       
   219 	/* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged,
       
   220 	/* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged,
       
   221 	/* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged,
       
   222 	/* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged,
       
   223 	/* 055 */ EIBYAlias | EIBYData | EIBYPaged,
       
   224 	/* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged,
       
   225 	/* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged,
       
   226 	/* 058 */ EIBYAlias | EIBYData | EIBYUnpaged,
       
   227 	/* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged,
       
   228 	/* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged
       
   229 	};
       
   230 
       
   231 void InitNThreadID()
       
   232 	{
       
   233 	_LIT(KThreadName, "ARandomThreadName");
       
   234 	btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
       
   235 	btrace.Empty();
       
   236 	btrace.SetMode(RBTrace::EEnable);
       
   237 	// rename the current thread to force a ThreadID trace
       
   238 	User::RenameThread(KThreadName);
       
   239 	btrace.SetMode(0);
       
   240 	TInt size;
       
   241 	TUint8* pDataStart;
       
   242 	TUint8* pCurrentRecord;
       
   243 	// extract the nano-kernel thread ID from the trace
       
   244 	while ((size = btrace.GetData(pDataStart)) != 0)
       
   245 		{
       
   246 		pCurrentRecord = pDataStart;
       
   247 		while (pCurrentRecord - pDataStart < size)
       
   248 			{
       
   249 			TInt extensionCount = 4 * (
       
   250 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
       
   251 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
       
   252 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
       
   253 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
       
   254 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
       
   255 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
       
   256 			//
       
   257 			if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EThreadName))
       
   258 				{
       
   259 				TBuf<255> threadName;
       
   260 				threadName.Format(_L(""));
       
   261 				for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++)
       
   262 					{
       
   263 					threadName.AppendFormat(_L("%c"), *j);
       
   264 					}
       
   265 				if (threadName == KThreadName)
       
   266 					{
       
   267 					test.Printf(_L("This thread's NThread ID: %08x\n"), LE4(pCurrentRecord + 4 + extensionCount));
       
   268 					gNThreadId = LE4(pCurrentRecord + 4 + extensionCount);
       
   269 					}
       
   270 				}
       
   271 			pCurrentRecord = BTrace::NextRecord(pCurrentRecord);
       
   272 			}
       
   273 		btrace.DataUsed();
       
   274 		}
       
   275 	}
       
   276 	
       
   277 void LoadExesRom()
       
   278 	{
       
   279 	TInt r;
       
   280 	TBool pass = ETrue;
       
   281 	r = btrace.ResizeBuffer(32768); // 32k should be large enough
       
   282 	TEST_EQ(r, KErrNone);
       
   283 	btrace.SetFilter(BTrace::EPaging, ETrue);
       
   284 	btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
       
   285 	btrace.SetMode(0);
       
   286 	
       
   287 	for (TInt i = 1; i <= 60; i++)
       
   288 		{
       
   289 		TBuf<255> filename;
       
   290 		filename.Format(_L("Z:\\SYS\\BIN\\DPEXE%03d.EXE"), i);
       
   291 	
       
   292 		test.Printf(_L("Loading %S... "), &filename);
       
   293 		
       
   294 		TBool paged = EFalse;
       
   295 		TBool inRom = EFalse;
       
   296 		
       
   297 		TUint32 nthreadAddr = 0;
       
   298 		TBuf<255> processName;
       
   299 		
       
   300 		if (fs.IsFileInRom(filename) != NULL)
       
   301 			{
       
   302 			inRom = ETrue;
       
   303 			}
       
   304 		else
       
   305 			{
       
   306 			inRom = EFalse;
       
   307 			}
       
   308 		
       
   309 		// Ensure that the paging live list is empty
       
   310 		r = DPTest::FlushCache();
       
   311 		if (gIsRomDemangPagingEnabled)
       
   312 			{
       
   313 			TEST_EQ(r, KErrNone);
       
   314 			}
       
   315 		else
       
   316 			{
       
   317 			TEST_EQ(r, KErrNotSupported);
       
   318 			}
       
   319 		
       
   320 		btrace.Empty(); // empty the BTrace buffer
       
   321 		btrace.SetMode(RBTrace::EEnable);
       
   322 		RProcess proc;
       
   323 		r = proc.Create(filename, _L(""));
       
   324 			
       
   325 		if ((testExeAttr[i] & EIBYAlias) && (testExeAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled))
       
   326 		// There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged
       
   327 			{
       
   328 			TEST_EQ(r, KErrNotFound);
       
   329 			continue;
       
   330 			}
       
   331 		else
       
   332 			{
       
   333 			TEST_EQ(r, KErrNone);
       
   334 			}
       
   335 		
       
   336 		// Resume the process and wait until it completes
       
   337 		TRequestStatus ps;
       
   338 		proc.Logon(ps);
       
   339 		proc.Resume();
       
   340 		proc.Close();
       
   341 		User::WaitForRequest(ps);
       
   342 		
       
   343 		// Disable trace
       
   344 		btrace.SetMode(0);
       
   345 		
       
   346 		TInt size;
       
   347 		TUint8* pDataStart;
       
   348 		TUint8* pCurrentRecord;
       
   349 		
       
   350 		// We have a while loop here, in the unlikely case that our trace is fragmented	
       
   351 		while ((size = btrace.GetData(pDataStart)) != 0)
       
   352 			{
       
   353 			pCurrentRecord = pDataStart;
       
   354 			while (pCurrentRecord - pDataStart < size)
       
   355 				{
       
   356 				// Number of bytes used by the BTrace extensions
       
   357 				TInt extensionCount = 4 * (
       
   358 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
       
   359 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
       
   360 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
       
   361 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
       
   362 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
       
   363 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
       
   364 				
       
   365 				if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EProcessName))
       
   366 				// Process renamed
       
   367 					{
       
   368 					processName.Format(_L(""));
       
   369 					for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++)
       
   370 						{
       
   371 						processName.AppendFormat(_L("%c"), *j);
       
   372 						}
       
   373 					TBuf<255> expected;
       
   374 					expected.Format(_L("dpexe%03d.exe[%08x]%04x"), i, 0, 1);
       
   375 					
       
   376 					if (processName == expected)
       
   377 						{
       
   378 						nthreadAddr = LE4(pCurrentRecord + 4 + extensionCount);
       
   379 						}					
       
   380 					}
       
   381 				if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging) && (LE4(pCurrentRecord + 8) == nthreadAddr))
       
   382 				/* The main thread of the test process tries to page in the test executable	*/
       
   383 					{
       
   384 					paged = ETrue;
       
   385 					}
       
   386 				pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record
       
   387 				}
       
   388 			btrace.DataUsed();
       
   389 			}
       
   390 		
       
   391 		if (paged)
       
   392 			test.Printf(_L("paged!\n"));
       
   393 		else
       
   394 			test.Printf(_L("not paged!\n"));
       
   395 		
       
   396 		if (!gIsRomDemangPagingEnabled)
       
   397 		// ROM paging disabled. All files are in ROM and unpaged
       
   398 			{
       
   399 			test.Printf(_L("ROM Paging disabled: shouldn't be paged\n"));
       
   400 			TEST_CONDITION(inRom);
       
   401 			TEST_CONDITION(!paged);
       
   402 			}
       
   403 		else if (testExeAttr[i] & EIBYData)
       
   404 			// data - if ROM paged, then these executables will be moved to ROFS
       
   405 			// these are always expected to be RAM loaded
       
   406 			{
       
   407 			test.Printf(_L("EXE is DATA in ROFS\n"));
       
   408 			TEST_CONDITION(!inRom);
       
   409 			}
       
   410 		else if (testExeAttr[i] & EIBYFileCompress)
       
   411 			// Compression format specified in the IBY file
       
   412 			// These are expected to be stay in ROM, but will be RAM-loaded
       
   413 			{
       
   414 			test.Printf(_L("EXE has own compression method: shouldn't be paged\n"));
       
   415 			TEST_CONDITION(inRom);
       
   416 			TEST_CONDITION(!paged);
       
   417 			}
       
   418 		// from this point onwards, all executables can potentially be paged - paging policy takes precedence
       
   419 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging)
       
   420 			{
       
   421 			test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
       
   422 			TEST_CONDITION(inRom);
       
   423 			TEST_CONDITION(!paged);
       
   424 			}
       
   425 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage)
       
   426 			{
       
   427 			test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
       
   428 			TEST_CONDITION(inRom);
       
   429 			TEST_CONDITION(paged);
       
   430 			}
       
   431 		// from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence
       
   432 		else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging)
       
   433 			{
       
   434 			test.Printf(_L("Paging override is No Paging: shouldn't be paged\n"));
       
   435 			TEST_CONDITION(inRom);
       
   436 			TEST_CONDITION(!paged);
       
   437 			}
       
   438 		else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage)
       
   439 			{
       
   440 			test.Printf(_L("Paging override is Always Page: should be paged\n"));
       
   441 			TEST_CONDITION(inRom);
       
   442 			TEST_CONDITION(paged);
       
   443 			}
       
   444 		// from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence
       
   445 		else if (testExeAttr[i] & EIBYPaged)
       
   446 			{
       
   447 			test.Printf(_L("Paged keyword in OBY: should be paged\n"));
       
   448 			TEST_CONDITION(inRom);
       
   449 			TEST_CONDITION(paged);
       
   450 			}
       
   451 		else if (testExeAttr[i] & EIBYUnpaged)
       
   452 			{
       
   453 			test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n"));
       
   454 			TEST_CONDITION(inRom);
       
   455 			TEST_CONDITION(!paged);
       
   456 			}
       
   457 		// Next, MMP setting takes precedence
       
   458 		else if (testExeAttr[i] & EMMPPaged)
       
   459 			{
       
   460 			test.Printf(_L("Paged keyword in MMP: should be paged\n"));
       
   461 			TEST_CONDITION(inRom);
       
   462 			TEST_CONDITION(paged);
       
   463 			}
       
   464 		else if (testExeAttr[i] & EMMPUnpaged)
       
   465 			{
       
   466 			test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n"));
       
   467 			TEST_CONDITION(inRom);
       
   468 			TEST_CONDITION(!paged);
       
   469 			}
       
   470 		// The test exe has no attribute. Paging overright default paging mode takes precedence
       
   471 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged)
       
   472 			{
       
   473 			test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n"));
       
   474 			TEST_CONDITION(inRom);
       
   475 			TEST_CONDITION(!paged);
       
   476 			}
       
   477 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged)
       
   478 			{
       
   479 			test.Printf(_L("Paging override is Default Paged: should be paged\n"));
       
   480 			TEST_CONDITION(inRom);
       
   481 			TEST_CONDITION(paged);
       
   482 			}
       
   483 		// Paging policy default paging mode takes precedence
       
   484 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged)
       
   485 			{
       
   486 			test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n"));
       
   487 			TEST_CONDITION(inRom);
       
   488 			TEST_CONDITION(!paged);
       
   489 			}
       
   490 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged)
       
   491 			{
       
   492 			test.Printf(_L("Paging policy is Default paged: should be paged\n"));
       
   493 			TEST_CONDITION(inRom);
       
   494 			TEST_CONDITION(paged);
       
   495 			}
       
   496 		// ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging)
       
   497 		else
       
   498 			{
       
   499 			test.Printf(_L("No paging policy!\n"));
       
   500 			test(EFalse);
       
   501 			}
       
   502 		}
       
   503 	test(pass);
       
   504 	}
       
   505 	
       
   506 
       
   507 void LoadDllsRom()
       
   508 	{
       
   509 	TInt r;
       
   510 	TBool pass = ETrue;
       
   511 	r = btrace.ResizeBuffer(32768); // 32k should be large enough
       
   512 	TEST_EQ(r, KErrNone);
       
   513 	btrace.SetFilter(BTrace::EPaging, ETrue);
       
   514 	btrace.SetFilter(BTrace::EThreadIdentification, ETrue);
       
   515 	btrace.SetMode(0);
       
   516 	
       
   517 	for (TInt i = 1; i <= 60; i++)
       
   518 		{
       
   519 		TBuf<255> filename;
       
   520 		filename.Format(_L("Z:\\SYS\\BIN\\DPDLL%03d.DLL"), i);
       
   521 	
       
   522 		test.Printf(_L("Loading %S... "), &filename);
       
   523 		
       
   524 		TBool paged = EFalse;
       
   525 		TBool inRom = EFalse;
       
   526 		
       
   527 		TUint libLoadEnd;
       
   528 		TInt filesize;
       
   529 		
       
   530 		TUint8* addr;
       
   531 		if ((addr = fs.IsFileInRom(filename)) != NULL)
       
   532 			{
       
   533 			inRom = ETrue;
       
   534 			}
       
   535 		else
       
   536 			{
       
   537 			inRom = EFalse;
       
   538 			}
       
   539 		
       
   540 		RFile file;
       
   541 		r = file.Open(fs, filename, EFileRead);
       
   542 		if ((testDllAttr[i] & EIBYAlias) && (testDllAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled))
       
   543 		// There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged
       
   544 			{
       
   545 			TEST_EQ(r, KErrNotFound);
       
   546 			continue;
       
   547 			}
       
   548 		else
       
   549 			{
       
   550 			TEST_EQ(r, KErrNone);
       
   551 			}
       
   552 		r = file.Size(filesize);
       
   553 		TEST_EQ(r, KErrNone);
       
   554 		file.Close();
       
   555 		
       
   556 		// Ensure that the paging live list is empty
       
   557 		r = DPTest::FlushCache();
       
   558 		if (gIsRomDemangPagingEnabled)
       
   559 			{
       
   560 			TEST_EQ(r, KErrNone);
       
   561 			}
       
   562 		else
       
   563 			{
       
   564 			TEST_EQ(r, KErrNotSupported);
       
   565 			}
       
   566 		
       
   567 		btrace.Empty(); // empty the BTrace buffer
       
   568 		btrace.SetMode(RBTrace::EEnable);
       
   569 		RLibrary lib;
       
   570 		r = lib.Load(filename);
       
   571 		libLoadEnd = User::FastCounter();
       
   572 		
       
   573 		TEST_EQ(r, KErrNone);
       
   574 		
       
   575 		TLibraryFunction function1;
       
   576 		TLibraryFunction function2;
       
   577 		TLibraryFunction function3;
       
   578 		TLibraryFunction function4;
       
   579 		
       
   580 		function1 = lib.Lookup(1);
       
   581 		function2 = lib.Lookup(2);
       
   582 		function3 = lib.Lookup(3);
       
   583 		function4 = lib.Lookup(4);
       
   584 		
       
   585 		test(function1 != NULL);
       
   586 		test(function2 != NULL);
       
   587 		test(function3 != NULL);
       
   588 		test(function4 == NULL);
       
   589 		
       
   590 		// Resume the process and wait until it completes
       
   591 	
       
   592 		function1();
       
   593 		function2();
       
   594 		function3();
       
   595 		
       
   596 		lib.Close();
       
   597 		
       
   598 		//processResumeStart = User::FastCounter();
       
   599 		//processResumeEnd = User::FastCounter();
       
   600 		
       
   601 		// Disable trace
       
   602 		btrace.SetMode(0);
       
   603 		
       
   604 		TInt size;
       
   605 		TUint8* pDataStart;
       
   606 		TUint8* pCurrentRecord;
       
   607 		
       
   608 		// We have a while loop here, in the unlikely case that our trace is fragmented	
       
   609 		while ((size = btrace.GetData(pDataStart)) != 0)
       
   610 			{
       
   611 			pCurrentRecord = pDataStart;
       
   612 			while (pCurrentRecord - pDataStart < size)
       
   613 				{
       
   614 				// Number of bytes used by the BTrace extensions
       
   615 				TInt extensionCount = 4 * (
       
   616 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) +
       
   617 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) +
       
   618 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) +
       
   619 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) +
       
   620 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) +
       
   621 				(pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0));
       
   622 
       
   623 				if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging)
       
   624 					&& (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EPagingPageInBegin)
       
   625 					&& (LE4(pCurrentRecord + 4) > libLoadEnd)
       
   626 					&& (LE4(pCurrentRecord + extensionCount) == gNThreadId)
       
   627 					&& (LE4(pCurrentRecord + 4 + extensionCount) >= (TUint32) addr)
       
   628 					&& (LE4(pCurrentRecord + 4 + extensionCount) < ((TUint32) addr) + filesize))
       
   629 				// If the DLL is paged in under this thread after it's been RLibrary::Load'ed, then we assume the DLL is paged
       
   630 					{
       
   631 					paged = ETrue;
       
   632 					}
       
   633 				pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record
       
   634 				}
       
   635 			btrace.DataUsed();
       
   636 			}
       
   637 
       
   638 		if (paged)
       
   639 			test.Printf(_L("paged!\n"));
       
   640 		else
       
   641 			test.Printf(_L("not paged!\n"));
       
   642 
       
   643 		if (!gIsRomDemangPagingEnabled)
       
   644 		// ROM paging disabled. All files are in ROM and unpaged
       
   645 			{
       
   646 			test.Printf(_L("ROM Paging disabled: shouldn't be paged\n"));
       
   647 			test(inRom);
       
   648 			TEST_CONDITION(!paged);
       
   649 			}
       
   650 		else if (testDllAttr[i] & EIBYData)
       
   651 			// data - if ROM paged, then these executables will be moved to ROFS
       
   652 			// these are always expected to be RAM loaded
       
   653 			{
       
   654 			test.Printf(_L("DLL is DATA in ROFS: shouldn't be paged\n"));
       
   655 			TEST_CONDITION(!inRom);
       
   656 			TEST_CONDITION(!paged);
       
   657 			}
       
   658 		else if (testDllAttr[i] & EIBYFileCompress)
       
   659 			// Compression format specified in the IBY file
       
   660 			// These are expected to be stay in ROM, but will be RAM-loaded
       
   661 			{
       
   662 			test.Printf(_L("DLL has own compression method: shouldn't be paged\n"));
       
   663 			TEST_CONDITION(inRom);
       
   664 			TEST_CONDITION(!paged);
       
   665 			}
       
   666 		// from this point onwards, all executables can potentially be paged - paging policy takes precedence
       
   667 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging)
       
   668 			{
       
   669 			test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n"));
       
   670 			TEST_CONDITION(inRom);
       
   671 			TEST_CONDITION(!paged);
       
   672 			}
       
   673 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage)
       
   674 			{
       
   675 			test.Printf(_L("Paging policy is Always Page: should be paged\n"));
       
   676 			TEST_CONDITION(inRom);
       
   677 			TEST_CONDITION(paged);
       
   678 			}
       
   679 		// from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence
       
   680 		else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging)
       
   681 			{
       
   682 			test.Printf(_L("Paging override is No Paging: shouldn't be paged\n"));
       
   683 			TEST_CONDITION(inRom);
       
   684 			TEST_CONDITION(!paged);
       
   685 			}
       
   686 		else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage)
       
   687 			{
       
   688 			test.Printf(_L("Paging override is Always Page: should be paged\n"));
       
   689 			TEST_CONDITION(inRom);
       
   690 			TEST_CONDITION(paged);
       
   691 			}
       
   692 		// from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence
       
   693 		else if (testDllAttr[i] & EIBYPaged)
       
   694 			{
       
   695 			test.Printf(_L("Paged keyword in OBY: should be paged\n"));
       
   696 			TEST_CONDITION(inRom);
       
   697 			TEST_CONDITION(paged);
       
   698 			}
       
   699 		else if (testDllAttr[i] & EIBYUnpaged)
       
   700 			{
       
   701 			test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n"));
       
   702 			TEST_CONDITION(inRom);
       
   703 			TEST_CONDITION(!paged);
       
   704 			}
       
   705 		// Next, MMP setting takes precedence
       
   706 		else if (testDllAttr[i] & EMMPPaged)
       
   707 			{
       
   708 			test.Printf(_L("Paged keyword in MMP: should be paged\n"));
       
   709 			TEST_CONDITION(inRom);
       
   710 			TEST_CONDITION(paged);
       
   711 			}
       
   712 		else if (testDllAttr[i] & EMMPUnpaged)
       
   713 			{
       
   714 			test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n"));
       
   715 			TEST_CONDITION(inRom);
       
   716 			TEST_CONDITION(!paged);
       
   717 			}
       
   718 		// The test exe has no attribute. Paging overright default paging mode takes precedence
       
   719 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged)
       
   720 			{
       
   721 			test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n"));
       
   722 			TEST_CONDITION(inRom);
       
   723 			TEST_CONDITION(!paged);
       
   724 			}
       
   725 		else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged)
       
   726 			{
       
   727 			test.Printf(_L("Paging override is Default Paged: should be paged\n"));
       
   728 			TEST_CONDITION(inRom);
       
   729 			TEST_CONDITION(paged);
       
   730 			}
       
   731 		// Paging policy default paging mode takes precedence
       
   732 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged)
       
   733 			{
       
   734 			test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n"));
       
   735 			TEST_CONDITION(inRom);
       
   736 			TEST_CONDITION(!paged);
       
   737 			}
       
   738 		else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged)
       
   739 			{
       
   740 			test.Printf(_L("Paging policy is Default paged: should be paged\n"));
       
   741 			TEST_CONDITION(inRom);
       
   742 			TEST_CONDITION(paged);
       
   743 			}
       
   744 		// ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging)
       
   745 		else
       
   746 			{
       
   747 			test.Printf(_L("No paging policy!\n"));
       
   748 			test(EFalse);
       
   749 			}
       
   750 		}
       
   751 	test(pass);
       
   752 	}
       
   753 
       
   754 GLDEF_C TInt E32Main()
       
   755 	{
       
   756 	TInt r;
       
   757 	test.Title();
       
   758 	test.Start(_L("Check environment"));
       
   759 	
       
   760 	// Open the BTrace handler
       
   761 	r = btrace.Open();
       
   762 	TEST_EQ(r, KErrNone);
       
   763 	
       
   764 	// capture the NThread ID of the main thread of the current process
       
   765 	InitNThreadID();
       
   766 	test(gNThreadId != 0);
       
   767 	
       
   768 	gPagingPolicy = E32Loader::PagingPolicy();
       
   769 	gPagingOverride = -1;
       
   770 	
       
   771 	r = fs.Connect();
       
   772 	TEST_EQ(r, KErrNone);
       
   773 	
       
   774 	if (fs.IsFileInRom(_L("\\ovr_nopaging")) != NULL)
       
   775 		{
       
   776 		gPagingOverride = EKernelConfigCodePagingPolicyNoPaging;
       
   777 		}
       
   778 	if (fs.IsFileInRom(_L("\\ovr_alwayspage")) != NULL)
       
   779 		{
       
   780 		gPagingOverride = EKernelConfigCodePagingPolicyAlwaysPage;
       
   781 		}
       
   782 	if (fs.IsFileInRom(_L("\\ovr_defaultunpaged")) != NULL)
       
   783 		{
       
   784 		gPagingOverride = EKernelConfigCodePagingPolicyDefaultUnpaged;
       
   785 		}
       
   786 	if (fs.IsFileInRom(_L("\\ovr_defaultpaged")) != NULL)
       
   787 		{
       
   788 		gPagingOverride = EKernelConfigCodePagingPolicyDefaultPaged;
       
   789 		}
       
   790 	if (fs.IsFileInRom(_L("\\pcy_nopaging")) != NULL)
       
   791 		{
       
   792 		gPagingPolicy = EKernelConfigCodePagingPolicyNoPaging;
       
   793 		}
       
   794 	if (fs.IsFileInRom(_L("\\pcy_alwayspage")) != NULL)
       
   795 		{
       
   796 		gPagingPolicy = EKernelConfigCodePagingPolicyAlwaysPage;
       
   797 		}
       
   798 	if (fs.IsFileInRom(_L("\\pcy_defaultunpaged")) != NULL)
       
   799 		{
       
   800 		gPagingPolicy = EKernelConfigCodePagingPolicyDefaultUnpaged;
       
   801 		}
       
   802 	if (fs.IsFileInRom(_L("\\pcy_defaultpaged")) != NULL)
       
   803 		{
       
   804 		gPagingPolicy = EKernelConfigCodePagingPolicyDefaultPaged;
       
   805 		}
       
   806 		
       
   807 	gIsRomDemangPagingEnabled = (fs.IsFileInRom(_L("Z:\\SYS\\BIN\\DPEXE046.EXE")) == NULL);
       
   808 		
       
   809 	test.Printf(_L("Demand Paging Enabled? %d\n"), gIsRomDemangPagingEnabled);
       
   810 	test.Printf(_L("PagingOverride %d\n"), gPagingOverride);
       
   811 	test.Printf(_L("PagingPolicy %d\n"), gPagingPolicy);
       
   812 	
       
   813 	test.Next(_L("Load ROM EXEs"));
       
   814 	LoadExesRom();
       
   815 	test.Next(_L("Load ROM DLLs"));
       
   816 	LoadDllsRom();
       
   817 	
       
   818 	btrace.Close();
       
   819 	fs.Close();
       
   820 	test.End();
       
   821 	test.Close();
       
   822 	return KErrNone;
       
   823 	}