kerneltest/e32test/mmu/t_chunk.cpp
changeset 4 56f325a607ea
parent 0 a41df078684a
child 41 0ffb4e86fcc9
equal deleted inserted replaced
2:4122176ea935 4:56f325a607ea
    35 // - Test sharing a chunk between threads, verify results are as expected.
    35 // - Test sharing a chunk between threads, verify results are as expected.
    36 // - Create a thread to watch for notification of changes in free memory and
    36 // - Create a thread to watch for notification of changes in free memory and
    37 // changes in out of memory status. Verify adjusting an RChunk generates
    37 // changes in out of memory status. Verify adjusting an RChunk generates
    38 // the expected notifications.
    38 // the expected notifications.
    39 // - Test finding a global chunk by name and verify results are as expected.
    39 // - Test finding a global chunk by name and verify results are as expected.
       
    40 // - Check read-only global chunks cannot be written to by other processes.
    40 // Platforms/Drives/Compatibility:
    41 // Platforms/Drives/Compatibility:
    41 // All.
    42 // All.
    42 // Assumptions/Requirement/Pre-requisites:
    43 // Assumptions/Requirement/Pre-requisites:
    43 // Failures and causes:
    44 // Failures and causes:
    44 // Base Port information:
    45 // Base Port information:
  1147 	// kernel memory leaks.
  1148 	// kernel memory leaks.
  1148 	UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
  1149 	UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0);
  1149 	}
  1150 	}
  1150 	
  1151 	
  1151 
  1152 
  1152 /**Returns true if 'extended' is found in the command line*/
  1153 /**Returns true if argument is found in the command line*/
  1153 TBool GetExtended()
  1154 TBool IsInCommandLine(const TDesC& aArg)
  1154 	{
  1155 	{
  1155 	_LIT(KExtended,"extended");
       
  1156 	TBuf<64> c;
  1156 	TBuf<64> c;
  1157 	User::CommandLine(c);
  1157 	User::CommandLine(c);
  1158 	if (c.FindF(KExtended) >= 0)
  1158 	if (c.FindF(aArg) >= 0)
  1159 		return ETrue;
  1159 		return ETrue;
  1160 	return EFalse;
  1160 	return EFalse;
  1161 	}
  1161 	}
  1162 
  1162 
       
  1163 _LIT(KTestChunkReadOnly, "TestReadOnlyChunk");
       
  1164 _LIT(KTestSemaphoreReadOnly, "TestReadOnlySemaphore");
       
  1165 _LIT(KTestParamRo, "restro");
       
  1166 _LIT(KTestParamRw, "restrw");
       
  1167 _LIT(KTestParamWait, "restwait");
       
  1168 _LIT(KTestParamWritableChunk, "restwritable");
       
  1169 
       
  1170 enum TTestProcessParameters
       
  1171 	{
       
  1172 	ETestRw = 0x1,
       
  1173 	ETestWait = 0x2,
       
  1174 	ETestWritableChunk = 0x4,
       
  1175 	};
       
  1176 
       
  1177 void TestReadOnlyProcess(TUint aParams)
       
  1178 	{
       
  1179 	TInt r;
       
  1180 	RChunk chunk;
       
  1181 	RSemaphore sem;
       
  1182 
       
  1183 	test.Start(_L("Open global chunk"));
       
  1184 	r = chunk.OpenGlobal(KTestChunkReadOnly, EFalse);
       
  1185 	test_KErrNone(r);
       
  1186 
       
  1187 	test(chunk.IsReadable());
       
  1188 	r = chunk.Adjust(1);
       
  1189 	if (aParams & ETestWritableChunk)
       
  1190 		{
       
  1191 		test(chunk.IsWritable());
       
  1192 		test_KErrNone(r);
       
  1193 		}
       
  1194 	else
       
  1195 		{
       
  1196 		test(!chunk.IsWritable());
       
  1197 		test_Equal(KErrAccessDenied, r);
       
  1198 		}
       
  1199 
       
  1200 	if (aParams & ETestWait)
       
  1201 		{
       
  1202 		RProcess::Rendezvous(KErrNone);
       
  1203 		test.Next(_L("Wait on semaphore"));
       
  1204 		r = sem.OpenGlobal(KTestSemaphoreReadOnly);
       
  1205 		test_KErrNone(r);
       
  1206 		sem.Wait();
       
  1207 		}
       
  1208 
       
  1209 	test.Next(_L("Read"));
       
  1210 	TUint8 read = *(volatile TUint8*) chunk.Base();
       
  1211 	(void) read;
       
  1212 
       
  1213 	if (aParams & ETestRw)
       
  1214 		{
       
  1215 		test.Next(_L("Write"));
       
  1216 		TUint8* write = chunk.Base();
       
  1217 		*write = 0x3d;
       
  1218 		}
       
  1219 
       
  1220 	chunk.Close();
       
  1221 	if (aParams & ETestWait)
       
  1222 		{
       
  1223 		sem.Close();
       
  1224 		}
       
  1225 	test.End();
       
  1226 	}
       
  1227 
       
  1228 void TestReadOnly()
       
  1229 	{
       
  1230 	TInt r;
       
  1231 	RChunk chunk;
       
  1232 	RProcess process1;
       
  1233 	RProcess process2;
       
  1234 	RSemaphore sem;
       
  1235 	TRequestStatus rs;
       
  1236 	TRequestStatus rv;
       
  1237 
       
  1238 	// Assumption is made that any memory model from Flexible onwards that supports
       
  1239 	// read-only memory also supports read-only chunks
       
  1240 	if (MemModelType() < EMemModelTypeFlexible || !HaveWriteProt())
       
  1241 		{
       
  1242 		test.Printf(_L("Memory model is not expected to support Read-Only Chunks\n"));
       
  1243 		return;
       
  1244 		}
       
  1245 
       
  1246 	TBool jit = User::JustInTime();
       
  1247 	User::SetJustInTime(EFalse);
       
  1248 
       
  1249 	test.Start(_L("Create writable global chunk"));
       
  1250 	TChunkCreateInfo info;
       
  1251 	info.SetNormal(0, 1234567);
       
  1252 	info.SetGlobal(KTestChunkReadOnly);
       
  1253 	r = chunk.Create(info);
       
  1254 	test_KErrNone(r);
       
  1255 	test(chunk.IsReadable());
       
  1256 	test(chunk.IsWritable());
       
  1257 
       
  1258 	test.Next(_L("Adjust size"));
       
  1259 	r = chunk.Adjust(1); // add one page
       
  1260 	test_KErrNone(r);
       
  1261 
       
  1262 	test.Next(_L("Attempt read/write 1"));
       
  1263 	r = process1.Create(RProcess().FileName(), KTestParamWritableChunk);
       
  1264 	test_KErrNone(r);
       
  1265 	process1.Logon(rs);
       
  1266 	process1.Resume();
       
  1267 	User::WaitForRequest(rs);
       
  1268 	test_Equal(EExitKill, process1.ExitType());
       
  1269 	test_KErrNone(process1.ExitReason());
       
  1270 	CLOSE_AND_WAIT(process1);
       
  1271 	CLOSE_AND_WAIT(chunk);
       
  1272 
       
  1273 	test.Next(_L("Create read-only global chunk"));
       
  1274 	info.SetReadOnly();
       
  1275 	r = chunk.Create(info);
       
  1276 	test_KErrNone(r);
       
  1277 	test(chunk.IsReadable());
       
  1278 	test(chunk.IsWritable());
       
  1279 	// To keep in sync with the 'process2' process
       
  1280 	r = sem.CreateGlobal(KTestSemaphoreReadOnly, 0);
       
  1281 	test_KErrNone(r);
       
  1282 
       
  1283 	test.Next(_L("Attempt read 1"));
       
  1284 	r = process1.Create(RProcess().FileName(), KTestParamRo);
       
  1285 	test_KErrNone(r);
       
  1286 	process1.Logon(rs);
       
  1287 	process1.Resume();
       
  1288 	User::WaitForRequest(rs);
       
  1289 	test_Equal(EExitPanic, process1.ExitType());
       
  1290 	test_Equal(3, process1.ExitReason()); // KERN-EXEC 3 assumed
       
  1291 	CLOSE_AND_WAIT(process1);
       
  1292 	// Create second process before commiting memory and make it wait
       
  1293 	r = process2.Create(RProcess().FileName(), KTestParamWait);
       
  1294 	test_KErrNone(r)
       
  1295 	process2.Rendezvous(rv);
       
  1296 	process2.Resume();
       
  1297 	User::WaitForRequest(rv);
       
  1298 
       
  1299 	test.Next(_L("Adjust size"));
       
  1300 	r = chunk.Adjust(1); // add one page
       
  1301 	test_KErrNone(r);
       
  1302 
       
  1303 	test.Next(_L("Attempt read 2"));
       
  1304 	r = process1.Create(RProcess().FileName(), KTestParamRo);
       
  1305 	test_KErrNone(r);
       
  1306 	process1.Logon(rs);
       
  1307 	process1.Resume();
       
  1308 	User::WaitForRequest(rs);
       
  1309 	test_Equal(EExitKill, process1.ExitType());
       
  1310 	test_KErrNone(process1.ExitReason());
       
  1311 	CLOSE_AND_WAIT(process1);
       
  1312 
       
  1313 	test.Next(_L("Attempt read/write 1"));
       
  1314 	r = process1.Create(RProcess().FileName(), KTestParamRw);
       
  1315 	test_KErrNone(r);
       
  1316 	process1.Logon(rs);
       
  1317 	process1.Resume();
       
  1318 	User::WaitForRequest(rs);
       
  1319 	test_Equal(EExitPanic, process1.ExitType());
       
  1320 	test_Equal(3, process1.ExitReason()); // KERN-EXEC 3 assumed
       
  1321 	CLOSE_AND_WAIT(process1);
       
  1322 	// Controlling process is not affected
       
  1323 	TUint8* write = chunk.Base();
       
  1324 	*write = 0x77;
       
  1325 
       
  1326 	test.Next(_L("Attempt read/write 2"));
       
  1327 	test_Equal(EExitPending, process2.ExitType());
       
  1328 	process2.Logon(rs);
       
  1329 	sem.Signal();
       
  1330 	User::WaitForRequest(rs);
       
  1331 	test_Equal(EExitPanic, process2.ExitType());
       
  1332 	test_Equal(3, process2.ExitReason()); // KERN-EXEC 3 assumed
       
  1333 	CLOSE_AND_WAIT(process2);
       
  1334 
       
  1335 	chunk.Close();
       
  1336 	sem.Close();
       
  1337 	test.End();
       
  1338 	User::SetJustInTime(jit);
       
  1339 	}
  1163 
  1340 
  1164 TInt E32Main()
  1341 TInt E32Main()
  1165 //
  1342 //
  1166 //	Test RChunk class
  1343 //	Test RChunk class
  1167 //
  1344 //
  1178 	RLoader l;
  1355 	RLoader l;
  1179 	test(l.Connect()==KErrNone);
  1356 	test(l.Connect()==KErrNone);
  1180 	test(l.CancelLazyDllUnload()==KErrNone);
  1357 	test(l.CancelLazyDllUnload()==KErrNone);
  1181 	l.Close();
  1358 	l.Close();
  1182 
  1359 
  1183 	__KHEAP_MARK;
  1360 	_LIT(KExtended,"extended");
  1184 
  1361 
  1185 	if (GetExtended() ) 
  1362 	if (IsInCommandLine(KExtended))
  1186 		{
  1363 		{
       
  1364 		__KHEAP_MARK;
  1187 		test.Printf(_L("t_chunk extended was called. Ready to call TestFullAddressSpace(Etrue) \n"));
  1365 		test.Printf(_L("t_chunk extended was called. Ready to call TestFullAddressSpace(Etrue) \n"));
  1188 		TestFullAddressSpace(ETrue);	
  1366 		TestFullAddressSpace(ETrue);
  1189 		}	
  1367 		__KHEAP_MARKEND;
       
  1368 		}
       
  1369 	else if (IsInCommandLine(KTestParamRo))
       
  1370 		{
       
  1371 		test_KErrNone(User::RenameProcess(KTestParamRo));
       
  1372 		TestReadOnlyProcess(0);
       
  1373 		}
       
  1374 	else if (IsInCommandLine(KTestParamRw))
       
  1375 		{
       
  1376 		test_KErrNone(User::RenameProcess(KTestParamRw));
       
  1377 		TestReadOnlyProcess(ETestRw);
       
  1378 		}
       
  1379 	else if (IsInCommandLine(KTestParamWait))
       
  1380 		{
       
  1381 		test_KErrNone(User::RenameProcess(KTestParamWait));
       
  1382 		TestReadOnlyProcess(ETestRw | ETestWait);
       
  1383 		}
       
  1384 	else if (IsInCommandLine(KTestParamWritableChunk))
       
  1385 		{
       
  1386 		test_KErrNone(User::RenameProcess(KTestParamWritableChunk));
       
  1387 		TestReadOnlyProcess(ETestWritableChunk | ETestRw);
       
  1388 		}
  1190 	else 
  1389 	else 
  1191 		{
  1390 		{
       
  1391 		__KHEAP_MARK;
  1192 		test.Start(_L("Testing.."));
  1392 		test.Start(_L("Testing.."));
  1193 		testAdjustChunk();
  1393 		testAdjustChunk();
  1194 		test.Next(_L("Test1"));
  1394 		test.Next(_L("Test1"));
  1195 		test1();
  1395 		test1();
  1196 		test.Next(_L("Test2"));
  1396 		test.Next(_L("Test2"));
  1221 		TestExecLocalCode();
  1421 		TestExecLocalCode();
  1222 #endif	//  __WINS__
  1422 #endif	//  __WINS__
  1223 
  1423 
  1224 		test.Next(_L("Test for race conditions in chunk closure"));
  1424 		test.Next(_L("Test for race conditions in chunk closure"));
  1225 		TestClosure();
  1425 		TestClosure();
       
  1426 		test.Next(_L("Read-only chunks"));
       
  1427 		TestReadOnly();
  1226 		test.End();
  1428 		test.End();
  1227 		}	
  1429 		__KHEAP_MARKEND;
       
  1430 		}
  1228 
  1431 
  1229 	test.Close();
  1432 	test.Close();
  1230 	__KHEAP_MARKEND;
       
  1231 	
       
  1232 	
       
  1233 	return(KErrNone);
  1433 	return(KErrNone);
  1234 	}
  1434 	}