First public contribution.
1 // Copyright (c) 2005-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 // e32test\debug\t_codemodifier.cpp
16 // Exercises Kernel's Code Modifier. This is common use case for run-mode debuggers.
18 // DebugSupport::InitialiseCodeModifier
19 // DebugSupport::CloseCodeModifier
20 // DebugSupport::ModifyCode
21 // DebugSupport::RestoreCode
22 // Kern::ThreadRawRead
23 // Kern::ThreadRawWrite
25 // -Three applications are running in the test:
26 // - t_codemodifier.exe client
27 // - t_codemodifier.exe server (XIP code)
28 // - t_codemodifier2.exe client (non-XIP code)
29 // -Test1 -Checks that the TestFunc (that will be altered by breakpoints) is really deadly if un-altered.
30 // -Test2 -Checks Code Modifier if data segment address is passed to set breakpoint.
31 // -Test3 -Checks Code Modifier if invalid address is passed to set breakpoint.Kern::ThreadRawRead\Write is also checked.
32 // -Test4 -Replaces BRK instruction in TestFunc with NOP using 1.2 and 4 bytes long breakpoints. Executes the
33 // function in the servers.
34 // -Test5 -Repeats Test4 (for XIP server only) with previously shedowed TestFunc
35 // -Test6 -Tests scenario when a process terminates while there are still associated breakpoints.
36 // -Test7 -Tests out-of-breakpoints scenario
37 // -Test8 -Tests breakpoint-already-exists scenario
38 // -Test9 -Tests CodeModifier closing when there are still active breakpoints. Breakpoints in this test occupies more then
40 // -Test10-A random stress test. Sets/Clears random brekpoints in CodeArea of the both servers. Then replaces
41 // all BRKs with NOPs in CodeArea and executes them.
42 // -Test11-Checks that overlaping breakpoints are rejected.
43 // Platforms/Drives/Compatibility:
44 // Hardware (Automatic). Not supported on emulator.
45 // Assumptions/Requirement/Pre-requisites:
46 // Failures and causes:
47 // Base Port information:
51 #define __E32TEST_EXTENSION__
54 #include <e32ldr_private.h>
56 #include "d_codemodifier.h"
57 #include "../misc/prbs.h"
59 LOCAL_D RTest test(_L("T_CODEMODIFIER"));
60 _LIT(KServerXIP,"ServerXIP");
61 _LIT(KServerNONXIP,"ServerNONXIP");
62 _LIT(KAppXIP,"t_codemodifier.exe");
63 _LIT(KAppNONXIP,"t_codemodifier2.exe");
65 extern void TestFunc();
66 extern void CodeArea();
68 //------------client globals---------------------
69 RCodeModifierDevice Device;
71 /** These addresses/names is all the client needs to test a server.
72 There are XIP and non-XIP server in the test*/
80 const TDesC* iAppName;
81 const TDesC* iServerName;
85 /**Will hold assembler instructions that make TestFunc.*/
93 /**ServerData[0] is about XIP server, ServerData[1] is non-XIP server*/
101 class CCodeModifierServer : public CServer2
104 static CCodeModifierServer* New(TInt aPriority);
106 CCodeModifierServer(TInt aPriority) : CServer2(aPriority){}
107 CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
113 CCodeModifierServer* CCodeModifierServer::New(TInt aPriority)
115 return new CCodeModifierServer(aPriority);
118 /**Server side session*/
119 class CCodeModifierSession : public CSession2
122 enum TCommand {EStop, EGetServerInfo, ERunTestFunc, ERunCodeAreaFunc};
124 void ServiceL(const RMessage2& aMessage);
127 /*Client-side session*/
128 class RCodeModifierSession : private RSessionBase
131 /**Updates ServerData[aServer] with data from the server*/
132 static TInt GetServerInfo(TInt aServer)
134 TPtr8 ptr((TUint8*)&ServerData[aServer].iThreadId, 5*sizeof(TInt),5*sizeof(TInt));
136 return Control(CCodeModifierSession::EGetServerInfo,aServer,args);
138 /**Stops the server*/
139 static TInt Stop(TInt aServer)
140 {TIpcArgs args;return Control(CCodeModifierSession::EStop,aServer, args);};
141 /**Issues the command to server to run TestFunc*/
142 static TInt RunTestFunc(TInt aServer)
143 {TIpcArgs args;return Control(CCodeModifierSession::ERunTestFunc,aServer,args);};
144 /**Issues the command to server to run CodeArea*/
145 static TInt RunCodeAreaFunc(TInt aServer)
146 {TIpcArgs args;return Control(CCodeModifierSession::ERunCodeAreaFunc,aServer,args);};
148 /*Executes a synchronius client-server request*/
149 static TInt Control(CCodeModifierSession::TCommand aRequest, TInt aServer, TIpcArgs& aArgs)
151 RCodeModifierSession p;
152 TInt r = p.CreateSession(*ServerData[aServer].iServerName, TVersion(), 0);
154 p.SendReceive(aRequest, aArgs);
160 //------------server globals---------------------
161 CCodeModifierServer* CodeModifierServer;
163 /**Creates a new client for this server.*/
164 CSession2* CCodeModifierServer::NewSessionL(const TVersion&, const RMessage2&) const
166 return new(ELeave) CCodeModifierSession();
169 /**Session entry point on the server side.*/
170 void CCodeModifierSession::ServiceL(const RMessage2& aMessage)
173 switch (aMessage.Function())
175 case EGetServerInfo: //Pass threadId and addresses to the client
186 info.iThreadId = (TInt) thread.Id();
187 info.iVarAddr = (TUint) &CodeModifierServer->iTestVar;
188 info.iInvalidAddr = (TUint)CodeModifierServer->chunk.Base()+0x1000;
189 info.iFuncAddr = (TUint)&TestFunc;
190 info.iCodeAreaAddr =(TUint)&CodeArea;
191 TPtrC8 ptr((TUint8*)&info, sizeof(SInfo));
192 r=aMessage.Write(0,ptr);
196 case ERunTestFunc: //Execute TestFunc
200 case ERunCodeAreaFunc: //Execute CodeArea
204 case EStop: //This will stop the server thread.
205 CActiveScheduler::Stop();
211 aMessage.Complete(r);
214 /**Server application entry point*/
215 LOCAL_C TInt ServerEntryPoint(TInt aServer)
220 CActiveScheduler *pR=new CActiveScheduler;
222 User::Panic(_L("SVR:Could't create Active Scheduler\n"), KErrNoMemory);
223 CActiveScheduler::Install(pR);
225 CodeModifierServer = CCodeModifierServer::New(0);
226 if(!CodeModifierServer)
229 User::Panic(_L("SVR:Create svr error\n"), KErrNoMemory);
232 //Create a chunk with a hole between addresses 0x1000 & 0x2000
233 r=CodeModifierServer->chunk.CreateDisconnectedLocal(0,0,0x200000);
235 r=CodeModifierServer->chunk.Commit(0,0x1000);
237 r=CodeModifierServer->chunk.Commit(0x2000,0x1000);
240 //We decide here which server to start.
242 r=CodeModifierServer->Start(KServerXIP);
244 r=CodeModifierServer->Start(KServerNONXIP);
248 delete CodeModifierServer;
250 User::Panic(_L("SVR:Error starting server\n"), r);
252 RProcess::Rendezvous(KErrNone);
253 CActiveScheduler::Start();
255 //We come here on CActiveScheduler::Stop()
256 delete CodeModifierServer;
262 //Initializes the globals and switch off lazy (un)loader. Called just once at the start.
263 void UpdateClientsGlobals()
265 TInt* ptr = (TInt*)TestFunc;
266 TestFuncCode.iBRK = *(ptr++);
267 TestFuncCode.iNOP = *(ptr++);
268 TestFuncCode.iRET = *(ptr++);
269 test.Printf(_L("UpdateClientsGlobals BRK:%x NOP:%x RET:%x\n"),TestFuncCode.iBRK,TestFuncCode.iNOP,TestFuncCode.iRET);
271 ServerData[0].iAppName=&KAppXIP;
272 ServerData[1].iAppName=&KAppNONXIP;
273 ServerData[0].iServerName=&KServerXIP;
274 ServerData[1].iServerName=&KServerNONXIP;
276 //Turn off lazy dll (un)loader.
277 //If we don't this, the second run of the test (within 2 minutes of the first one) would fail.
279 test_KErrNone(l.Connect());
280 test_KErrNone(l.CancelLazyDllUnload());
284 //Starts the server (0-XIP 1-NONXIP server)
285 //Obtains data from the server
286 //Updates the driver with the threadID of the server
287 void StartAndUpdate(TInt aServer)
289 TRequestStatus status;
290 RProcess& p = ServerData[aServer].iProcess;
291 test.Printf(_L("StartAndUpdate %d\n"),aServer);
293 TInt r = p.Create(*ServerData[aServer].iAppName,*ServerData[aServer].iServerName);
295 p.Rendezvous(status);
297 User::WaitForRequest(status);
298 test.Printf(_L("%d returned\n"),status.Int());
299 test_KErrNone(status.Int());
300 //Get threadId and addresses from the server
301 test_KErrNone(RCodeModifierSession::GetServerInfo(aServer));
302 SServerData& s = ServerData[aServer];
303 test.Printf(_L("ServerData:TId:%x VA:%x FA:%x IA:%x CA:%x \n"),s.iThreadId,s.iVarAddr,s.iFuncAddr,s.iInvalidAddr,s.iCodeAreaAddr);
304 //Update threadID of the server in device driver
305 test_KErrNone(Device.ThreadId(aServer, s.iThreadId));
308 //Kills the server(by forcing to execute TestFunc), then restarts it.
309 void KillAndRestart(TInt aServer)
311 test.Printf(_L("KillAndRestart %d\n"),aServer);
312 TInt r=RCodeModifierSession::RunTestFunc(aServer);
313 test.Printf(_L("%d returned\n"),r);
315 test.Printf(_L("Check the server died\n"));
316 r = RCodeModifierSession::GetServerInfo(aServer);
317 test.Printf(_L("%d returned\n"),r);
320 StartAndUpdate(aServer);
323 //Terminates the server
324 void TerminateServer(TInt aServer)
326 TRequestStatus status;
327 RProcess& p = ServerData[aServer].iProcess;
329 test.Printf(_L("TerminateServer %d\n"),aServer);
330 test_KErrNone(RCodeModifierSession::Stop(aServer));
332 User::WaitForRequest(status);
333 test_Equal(EExitKill, p.ExitType());
340 test.Printf(_L("StartDriver\n"));
341 TInt r = User::LoadLogicalDevice(KCodeModifierName);
342 test_Value(r, r==KErrNone || r==KErrAlreadyExists);
343 if((r = Device.Open())!=KErrNone)
345 User::FreeLogicalDevice(KCodeModifierName);
346 test.Printf(_L("Could not open LDD"));
354 test.Printf(_L("StopDriver\n"));
356 User::FreeLogicalDevice(KCodeModifierName);
359 //Checks that TestFunc in servers is really deadly if we do not alter the code
362 test.Printf(_L("Test1\n"));
363 KillAndRestart(EXip);
366 //Passing data segment address to set breakpoint.
367 //The actual behaviour depends of the memory model
368 //ARMv5: KErrBadDescriptor (-38) is returned
369 //ARMv6: Will return 0
370 //We have to make sure here that nothing panics or take any nasty behaviour.
371 void Test2(TInt aServer)
374 test.Printf(_L("Test2 %d\n"), aServer);
375 test_KErrNone(Device.InitialiseCodeModifier(10));
377 //Write/read data through ThreadRowWrite/Read
378 test_KErrNone(Device.WriteWord(aServer, ServerData[aServer].iVarAddr,/*value*/1));
379 test_KErrNone(Device.ReadWord(aServer, ServerData[aServer].iVarAddr,&val));
383 TInt r=Device.WriteCode(aServer, ServerData[aServer].iVarAddr,/*value*/5, /*size*/4);
384 test.Printf(_L("returns %d\n"),r);
386 test_KErrNone(Device.CloseCodeModifier());
389 //Passing invalid address to set breakpoint.
390 void Test3(TInt aServer)
393 test.Printf(_L("Test3 %d\n"), aServer);
394 test_KErrNone(Device.InitialiseCodeModifier(10));
396 //Write/read by ThreadRowWrite/Read
397 test_Equal(KErrBadDescriptor, Device.WriteWord(aServer, ServerData[aServer].iInvalidAddr,/*value*/1));
398 test_Equal(KErrBadDescriptor, Device.ReadWord(aServer, ServerData[aServer].iInvalidAddr,&val));
401 test_Equal(KErrBadDescriptor, Device.WriteCode(aServer, ServerData[aServer].iInvalidAddr,/*value*/5, /*size*/1));
402 test_Equal(KErrBadDescriptor, Device.WriteCode(aServer, ServerData[aServer].iInvalidAddr,/*value*/5, /*size*/2));
403 test_Equal(KErrBadDescriptor, Device.WriteCode(aServer, ServerData[aServer].iInvalidAddr,/*value*/5, /*size*/4));
405 test_KErrNone(Device.CloseCodeModifier());
408 //Replace BRK in TestFunc in server using 1,2 and 4 long breakpoints.
409 //Check the content of test func.
411 void Test4(TInt aServer)
414 test.Printf(_L("Test4 %d\n"), aServer);
416 //Try to write code segment throught Kern::ThreadRowWrite
417 test_Equal(KErrBadDescriptor, Device.WriteWord(aServer, ServerData[aServer].iFuncAddr,/*value*/1));
419 test_KErrNone(Device.InitialiseCodeModifier(10));
421 test.Printf(_L("Replace byte 3 of the 1st instruction\n"));
422 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iFuncAddr+3,TestFuncCode.iNOP>>24, /*size*/1));
423 test_KErrNone(Device.ReadWord(aServer,ServerData[aServer].iFuncAddr, &var));
424 test.Printf(_L("%xH returned\n"),var);
425 test((TUint)var == ((TestFuncCode.iBRK & 0xffffff) | (TestFuncCode.iNOP & 0xff000000)));
427 test.Printf(_L("Replace byte 2 of the 1st instruction\n"));
428 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iFuncAddr+2,TestFuncCode.iNOP>>16, /*size*/1));
429 test_KErrNone(Device.ReadWord(aServer,ServerData[aServer].iFuncAddr, &var));
430 test.Printf(_L("%xH returned\n"),var);
431 test((TUint)var == ((TestFuncCode.iBRK & 0xffff) | (TestFuncCode.iNOP & 0xffff0000)));
433 test.Printf(_L("Replace bytes 0 & 1 of the 1st instruction\n"));
434 var = TestFuncCode.iNOP | 0xff0000; //byte 3 is messed up - but it won't be writen into code bacause iSize is 2
435 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iFuncAddr,var, /*size*/2));
436 test_KErrNone(Device.ReadWord(aServer,ServerData[aServer].iFuncAddr, &var));
437 test.Printf(_L("%xH returned\n"),var);
438 test_Equal(TestFuncCode.iNOP, var);
440 //We have replaced BRK with NOP. It should be safe now for the server to execute TestFunc.
441 test.Printf(_L("Run TestFunc in server and check the server is still alive\n"));
442 test_KErrNone(RCodeModifierSession::RunTestFunc(aServer));
443 test_KErrNone(RCodeModifierSession::GetServerInfo(aServer));//Any call will work here
445 test.Printf(_L("Revert bytes 0 & 1\n"));
446 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iFuncAddr));
447 test_KErrNone(Device.ReadWord(aServer, ServerData[aServer].iFuncAddr, &var));
448 test.Printf(_L("%xH returned\n"),var);
449 test((TUint)var == ((TestFuncCode.iBRK & 0xffff) | (TestFuncCode.iNOP & 0xffff0000)));
451 test.Printf(_L("Revert byte 2\n"));
452 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iFuncAddr+2));
453 test_KErrNone(Device.ReadWord(aServer, ServerData[aServer].iFuncAddr, &var));
454 test.Printf(_L("%xH returned\n"),var);
455 test((TUint)var == ((TestFuncCode.iBRK & 0xffffff) | (TestFuncCode.iNOP & 0xff000000)));
457 test.Printf(_L("Revert byte 3\n"));
458 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iFuncAddr+3));
459 test_KErrNone(Device.ReadWord(aServer, ServerData[aServer].iFuncAddr, &var));
460 test.Printf(_L("%xH returned\n"),var);
461 test(var == TestFuncCode.iBRK);
463 test.Printf(_L("Replace the 1st instruction with the 2nd one in TestFunc\n"));
464 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iFuncAddr,TestFuncCode.iNOP, /*size*/4));
465 test_KErrNone(Device.ReadWord(aServer,ServerData[aServer].iFuncAddr, &var));
466 test.Printf(_L("%xH returned\n"),var);
467 test(var == TestFuncCode.iNOP);
469 //We have replaced BRK with NOP. It should be safe now for the server to execute TestFunc.
470 test.Printf(_L("Run TestFunc in server and check the server is still alive\n"));
471 test_KErrNone(RCodeModifierSession::RunTestFunc(aServer));
472 test_KErrNone(RCodeModifierSession::GetServerInfo(aServer));//Any call will work here
474 test_KErrNone(Device.CloseCodeModifier());
477 //Executes Test4 but with previously shadowed page
478 void Test5(TInt aServer)
480 test.Printf(_L("Test5 %d\n"), aServer);
482 test_KErrNone(Device.AllocShadowPage(ServerData[aServer].iFuncAddr));
484 test_KErrNone(Device.FreeShadowPage(ServerData[aServer].iFuncAddr));
487 //Tests scenario when a process terminates while there are still associated breakpoints.
488 void Test6(TInt aServer)
491 test.Printf(_L("Test6 %d\n"), aServer);
493 test_KErrNone(Device.InitialiseCodeModifier(10));
495 test.Printf(_L("Replace the 1st instruction (BRK) with the 2nd one (NOP) in TestFunc\n"));
496 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iFuncAddr,TestFuncCode.iNOP, /*size*/4));
497 test_KErrNone(Device.ReadWord(aServer,ServerData[aServer].iFuncAddr, &var));
498 test.Printf(_L("%xH returned\n"),var);
499 test(var == TestFuncCode.iNOP);
501 TerminateServer(aServer);
502 //After application has stopped, Kernel should clean the breakpoint associated to the server's process....
504 StartAndUpdate(aServer);
505 KillAndRestart(aServer);//... and TestFunct must be deadly again.
507 test_KErrNone(Device.CloseCodeModifier());
510 //Tests out-of-breakpoints scenario
511 void Test7(TInt aServer)
513 test.Printf(_L("Test7 %d\n"), aServer);
514 test_KErrNone(Device.InitialiseCodeModifier(1));
516 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr,TestFuncCode.iNOP, /*size*/4));
517 test_Equal(KErrNoMemory, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+4,TestFuncCode.iNOP, /*size*/4));
519 test_KErrNone(Device.CloseCodeModifier());
522 //Tests breakpoint-already-exists scenario
523 void Test8(TInt aServer)
525 test.Printf(_L("Test8 %d\n"), aServer);
526 test_KErrNone(Device.InitialiseCodeModifier(1));
528 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr,TestFuncCode.iNOP, /*size*/4));
529 test_Equal(KErrAlreadyExists, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr,TestFuncCode.iNOP, /*size*/4));
531 test_KErrNone(Device.CloseCodeModifier());
534 //Tests CodeModifier closing when there are still breakpoints.
535 //Breakpoints in this test occupies more then one shadowed page.
539 test.Printf(_L("Test9\n"));
540 test_KErrNone(Device.InitialiseCodeModifier(10));
542 //Put NOPs at the beginning of the code area
543 test_KErrNone(Device.WriteCode(EXip, ServerData[EXip].iCodeAreaAddr,TestFuncCode.iNOP, /*size*/4));
544 test_KErrNone(Device.WriteCode(ENonxip, ServerData[ENonxip].iCodeAreaAddr,TestFuncCode.iNOP, /*size*/4));
546 //Put NOPs at the end of the code area (there are 1024 BRK instructions in CodeArea
547 test_KErrNone(Device.WriteCode(EXip, ServerData[EXip].iCodeAreaAddr+1024*sizeof(TInt),TestFuncCode.iNOP, /*size*/4));
548 test_KErrNone(Device.WriteCode(ENonxip, ServerData[ENonxip].iCodeAreaAddr+1024*sizeof(TInt),TestFuncCode.iNOP, /*size*/4));
550 //Check NOPs are there
551 test_KErrNone(Device.ReadWord(EXip,ServerData[EXip].iCodeAreaAddr, &var));
552 test_Equal(TestFuncCode.iNOP, var);
553 test_KErrNone(Device.ReadWord(ENonxip,ServerData[ENonxip].iCodeAreaAddr, &var));
554 test_Equal(TestFuncCode.iNOP, var);
555 test_KErrNone(Device.ReadWord(EXip,ServerData[EXip].iCodeAreaAddr+1024*sizeof(TInt), &var));
556 test_Equal(TestFuncCode.iNOP, var);
557 test_KErrNone(Device.ReadWord(ENonxip,ServerData[ENonxip].iCodeAreaAddr+1024*sizeof(TInt), &var));
558 test_Equal(TestFuncCode.iNOP, var);
560 //Close Code Modifier. It should revert the changes in the code.
561 test_KErrNone(Device.CloseCodeModifier());
563 //Check BRKs are back
564 test_KErrNone(Device.ReadWord(EXip,ServerData[EXip].iCodeAreaAddr, &var));
565 test_Equal(TestFuncCode.iBRK, var);
566 test_KErrNone(Device.ReadWord(ENonxip,ServerData[ENonxip].iCodeAreaAddr, &var));
567 test_Equal(TestFuncCode.iBRK, var);
568 test_KErrNone(Device.ReadWord(EXip,ServerData[EXip].iCodeAreaAddr+1023*sizeof(TInt), &var));
569 test_Equal(TestFuncCode.iBRK, var);
570 test_KErrNone(Device.ReadWord(ENonxip,ServerData[ENonxip].iCodeAreaAddr+1023*sizeof(TInt), &var));
571 test_Equal(TestFuncCode.iBRK, var);
576 //Used in test 10 to keep the list of breakpoints
577 class TBrks:public CBase //derived from CBase as we need data initialized to 0
580 TInt iCounter; //Counts the number of the active brakpoints
581 TInt8 iBreakpoint[1025][2]; //0 - no breakpoint, 1-breakpoint set in CodeArea of XIP Server & NON-XIP server
584 //Performs a random stress test on breakpoint pool.
585 //There are 1025*2 words in CodeArea in xip and non-xip server.
586 //A word is randomly picked up to set or clear 4 bytes long breakpoint.
589 TInt i,index,whichServer,var;
590 TBrks* brks = new TBrks;
591 test((TInt)brks);//fail if no memory
593 iSeed[0]=User::TickCount();
595 test.Printf(_L("Test10 iSeed=%x\n"), iSeed[0]);
597 test_KErrNone(Device.InitialiseCodeModifier(2050));//enought to replace all BRK instructions in CodeArea with NOPs in both servers
599 for (i=0; i<1000;i++)
601 index=Random(iSeed)%2050;
602 whichServer = index>1024 ? 1 : 0;
606 TInt8& brk = brks->iBreakpoint[index][whichServer];
610 test_KErrNone(Device.RestoreCode(whichServer, ServerData[whichServer].iCodeAreaAddr+index*sizeof(TInt)));
616 test_KErrNone(Device.WriteCode(whichServer, ServerData[whichServer].iCodeAreaAddr+index*sizeof(TInt),TestFuncCode.iNOP, /*size*/4));
621 test.Printf(_L("Breakpoints left:%d\n"), brks->iCounter);
623 //Check the content of the CodeArea in both XIP and Non-XIP Server
624 for (i=0; i<2050;i++)
626 whichServer = i>1024 ? 1 : 0;
627 if (i<=1024)index = i;
630 test_KErrNone(Device.ReadWord(whichServer,ServerData[whichServer].iCodeAreaAddr+index*sizeof(TInt), &var));
631 if(brks->iBreakpoint[index][whichServer])
632 test(var == TestFuncCode.iNOP); //Well, breakpoint is actually NOP ...
634 test(var == TestFuncCode.iBRK); //... while the original content is BRK instruction
637 //Now, apply breakpoints on all remaining addresses
638 for (i=0; i<2050;i++)
640 whichServer = i>1024 ? 1 : 0;
641 if (i<=1024)index = i;
644 if(!brks->iBreakpoint[index][whichServer])
645 test_KErrNone(Device.WriteCode(whichServer, ServerData[whichServer].iCodeAreaAddr+index*sizeof(TInt),TestFuncCode.iNOP, /*size*/4));
648 //All BRKs are replaced with NOPs in CodeArea function in both Servers. It should be safe to call the function.
649 test_KErrNone(RCodeModifierSession::RunCodeAreaFunc(EXip));
650 test_KErrNone(RCodeModifierSession::GetServerInfo(EXip));//This will check the server is still alive
651 test_KErrNone(RCodeModifierSession::RunCodeAreaFunc(ENonxip));
652 test_KErrNone(RCodeModifierSession::GetServerInfo(ENonxip));//This will check the server is still alive
654 test_KErrNone(Device.CloseCodeModifier()); //This will also remove all breakpoints
658 //Tests out-of-breakpoints scenario
659 void Test11(TInt aServer)
661 test.Printf(_L("Test11 %d\n"), aServer);
662 test_KErrNone(Device.InitialiseCodeModifier(10));
664 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+4, /*aValue*/0, /*size*/4));
667 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/4));
668 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/2));
669 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+2, /*aValue*/0, /*size*/2));
670 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/1));
671 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+1, /*aValue*/0, /*size*/1));
672 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+2, /*aValue*/0, /*size*/1));
673 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+3, /*aValue*/0, /*size*/1));
674 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr));
676 //2 bytes breakpoint aligned to word
677 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/2));
678 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/4));
679 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/1));
680 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+1, /*aValue*/0, /*size*/1));
681 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+2, /*aValue*/0, /*size*/2));
682 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr));
683 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr+2));
685 //2 bytes breakpoint aligned to word+2
686 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+2, /*aValue*/0, /*size*/2));
687 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/4));
688 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+2, /*aValue*/0, /*size*/1));
689 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+3, /*aValue*/0, /*size*/1));
690 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/2));
691 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr));
692 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr+2));
695 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/1));
696 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/4));
697 test_Equal(KErrAccessDenied, Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr, /*aValue*/0, /*size*/2));
698 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+1, /*aValue*/0, /*size*/1));
699 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+2, /*aValue*/0, /*size*/1));
700 test_KErrNone(Device.WriteCode(aServer, ServerData[aServer].iCodeAreaAddr+3, /*aValue*/0, /*size*/1));
701 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr));
702 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr+1));
703 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr+2));
704 test_KErrNone(Device.RestoreCode(aServer, ServerData[aServer].iCodeAreaAddr+3));
706 test_KErrNone(Device.CloseCodeModifier());
712 test.Start(_L("ClientAppL"));
713 UpdateClientsGlobals();
715 StartAndUpdate(EXip);
716 StartAndUpdate(ENonxip);
718 // All tests run with the following pre-conditions:
719 // - both XIP and nonXIP server are running.
720 // - device driver has updated servers' threadIDs (used for setting breakpoints and reading/writing data).
721 // - all global variables (ServerData, TestFuncCode)are valid.
722 // - CodeModifier is not installed.
738 TerminateServer(EXip);
739 TerminateServer(ENonxip);
744 /**Entry point for both client and server apps*/
747 //Chech if we are client, XIP server or nonXIP server
749 User::CommandLine(c);
750 if (c.FindF(KServerXIP) >= 0)
751 return ServerEntryPoint(EXip);
752 if (c.FindF(KServerNONXIP) >= 0)
753 return ServerEntryPoint(ENonxip);
756 CTrapCleanup* trap = CTrapCleanup::New();
761 TRAPD(r,ClientAppL());