diff -r 000000000000 -r a41df078684a kerneltest/e32test/dll/t_tdll12.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/dll/t_tdll12.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,363 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\dll\t_tdll12.cpp +// Overview: +// Test DLL Thread Local Storage data and DLL Global data access. +// API Information: +// Dll +// Details: +// - Test that the local storage of two different DLLs, when accessed from +// two different threads is unique. Verify that results are as expected. +// - Test the access of DLL Global data including Alloc, Read and Write. Test +// the protection of the global data. Verify results are as expected. +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#include "t_dll.h" +#include "../mmu/mmudetect.h" + +const TInt KHeapSize=0x2000; + +LOCAL_D RTest test(_L("T_TDLL12")); + +TBool KernProt=EFalse; +TUint8* Kern; +TUint8* Garbage; + +void SetupAddresses() + { + KernProt=HaveDirectKernProt(); + Kern=KernData(); + TUint32 mm_attr=MemModelAttributes(); + TUint32 mm_type=mm_attr & EMemModelTypeMask; + switch (mm_type) + { + case EMemModelTypeDirect: + Garbage=(TUint8*)0xa8000000; + break; + case EMemModelTypeMoving: + Garbage=(TUint8*)0x60f00000; + break; + case EMemModelTypeMultiple: + Garbage=(TUint8*)0xfe000000; + break; + case EMemModelTypeFlexible: + Garbage=(TUint8*)0x8ff00000; + break; + case EMemModelTypeEmul: + Garbage=(TUint8*)0xf0000000; + break; + default: + test(0); + break; + } + } + +void RunTestInThread(TThreadFunction aFn, TAny* aParameter, const TDesC* aPanicCat, TInt aExitCode) + { + RThread t; + TInt r=t.Create(KNullDesC(),aFn,0x2000,NULL,aParameter); + test(r==KErrNone); + TRequestStatus s; + t.Logon(s); + t.Resume(); + User::WaitForRequest(s); + if (aPanicCat) + { + test(t.ExitType()==EExitPanic); + test(t.ExitCategory()==*aPanicCat); + test(t.ExitReason()==aExitCode); + } + else + { + test(t.ExitType()==EExitKill); + test(t.ExitReason()==aExitCode); + } + CLOSE_AND_WAIT(t); + } + +TInt GlobalReadThread(TAny* a) + { + return TestDll1::GlobalRead(122,*(TDes8*)a); + } + +TInt GlobalWriteThread(TAny* a) + { + return TestDll1::GlobalWrite(0,*(TDes8*)a); + } + +_LIT(KLitKernExec,"KERN-EXEC"); +void TestProtection() + { + test.Next(_L("Test protection")); + TBool jit=User::JustInTime(); + User::SetJustInTime(EFalse); + TUint x=0xffffffff; + TBuf8<64> ubuf; + TPtrC8 uptrc(ubuf.Ptr(),11); + TPtr8 uptr((TUint8*)ubuf.Ptr(),1,20); + TPtrC8 kptrc(Kern,1); + TPtr8 kptr(Kern,10,256); + TPtrC8 gptrc(Garbage,1); + TPtr8 gptr(Garbage,10,256); + RunTestInThread(GlobalReadThread,&x,&KLitKernExec,EKUDesInfoInvalidType); + RunTestInThread(GlobalReadThread,&ubuf,NULL,KErrNone); + RunTestInThread(GlobalReadThread,&uptr,NULL,KErrNone); + RunTestInThread(GlobalReadThread,&uptrc,&KLitKernExec,EKUDesInfoInvalidType); + RunTestInThread(GlobalReadThread,&kptrc,&KLitKernExec,EKUDesInfoInvalidType); + RunTestInThread(GlobalReadThread,&gptrc,&KLitKernExec,EKUDesInfoInvalidType); + RunTestInThread(GlobalReadThread,&gptr,&KLitKernExec,ECausedException); + if (KernProt) + { + RunTestInThread(GlobalReadThread,Kern,&KLitKernExec,ECausedException); + RunTestInThread(GlobalReadThread,&kptr,&KLitKernExec,ECausedException); + } + RunTestInThread(GlobalWriteThread,&x,&KLitKernExec,EKUDesInfoInvalidType); + RunTestInThread(GlobalWriteThread,&ubuf,NULL,KErrNone); + RunTestInThread(GlobalWriteThread,&uptr,NULL,KErrNone); + RunTestInThread(GlobalWriteThread,&uptrc,NULL,KErrNone); + RunTestInThread(GlobalWriteThread,&gptrc,&KLitKernExec,ECausedException); + RunTestInThread(GlobalWriteThread,&gptr,&KLitKernExec,ECausedException); + if (KernProt) + { + RunTestInThread(GlobalWriteThread,Kern,&KLitKernExec,ECausedException); + RunTestInThread(GlobalWriteThread,&kptrc,&KLitKernExec,ECausedException); + RunTestInThread(GlobalWriteThread,&kptr,&KLitKernExec,ECausedException); + } + User::SetJustInTime(jit); + } + +LOCAL_C TInt Dll1Thread2(TAny* /*anArg*/) +// +// The entry point for thread2. +// + { + + test(TestDll1::Attach(ETrue)==KErrNone); + test((TUint)TestDll1::Data()==0x12345678); + TestDll1::SetData(0xfedcba98); + test((TUint)TestDll1::Data()==0xfedcba98); + test(TestDll1::Attach(EFalse)==KErrNone); + return KErrNone; + } + +LOCAL_C TInt Dll2Thread2(TAny* /*anArg*/) +// +// The entry point for thread2. +// + { + + test(TestDll2::Attach(ETrue)==KErrNone); + test((TUint)TestDll2::Data()==0xABCDABCD); + TestDll2::SetData(0x12341234); + test((TUint)TestDll2::Data()==0x12341234); + test(TestDll2::Attach(EFalse)==KErrNone); + return KErrNone; + } + +void testGlobalAlloc() +// +// +// + { + + __KHEAP_MARK; + test.Start(_L("Test Dll::GlobalAlloc")); + TInt r; + test(TestDll1::GlobalAllocated()==EFalse); + test(TestDll2::GlobalAllocated()==EFalse); + r=TestDll2::GlobalAlloc(0); + test(r==KErrNone); + r=TestDll1::GlobalAlloc(256); + test(r==KErrNone); + test(TestDll1::GlobalAllocated()); + test(TestDll2::GlobalAllocated()==EFalse); + r=TestDll2::GlobalAlloc(256); + test(r==KErrNone); + test(TestDll1::GlobalAllocated()); + test(TestDll2::GlobalAllocated()); + + test.Next(_L("Write")); + // Write 256 bytes + TBuf8<0x100> buf100; + TInt i; + buf100.SetLength(0x100); + for (i=0; i<256; i++) + buf100[i]=(TText8)('A'+i%26); + r=TestDll1::GlobalWrite(0, buf100); + test(r==KErrNone); + buf100.Fill('X'); + r=TestDll2::GlobalWrite(0, buf100); + test(r==KErrNone); + + test.Next(_L("Read")); + // Read 256 bytes + r=TestDll1::GlobalRead(0, buf100); + test(r==KErrNone); + for (i=0; i<256; i++) + test(buf100[i]=='A'+i%26); + buf100.Fill('D'); + r=TestDll2::GlobalRead(0, buf100); + test(r==KErrNone); + for (i=0; i<256; i++) + test(buf100[i]=='X'); + + test.Next(_L("Realloc")); + r=TestDll1::GlobalAlloc(128); + test(r==KErrNone); + test(TestDll1::GlobalAllocated()); + test(TestDll2::GlobalAllocated()); + test.Next(_L("Read")); + r=TestDll1::GlobalRead(0,buf100); + for (i=0; i<128; i++) + test(buf100[i]=='A'+i%26); + test(buf100.Length()==128); + r=TestDll2::GlobalRead(0,buf100); + test(r==KErrNone); + for (i=0; i<256; i++) + test(buf100[i]=='X'); + test(buf100.Length()==256); + + test.Next(_L("Read @ pos")); + // Read from position + r=TestDll1::GlobalRead(1, buf100); + test(r==KErrNone); + test(buf100.Length()==127); + for (i=0; i<127; i++) + test(buf100[i]=='A'+(i+1)%26); + test.Next(_L("Write @ pos")); + buf100=_L8("LALALALALALA"); + r=TestDll1::GlobalWrite(5, buf100); + test(r==KErrNone); + buf100=_L8("POPOPOPOPO"); + r=TestDll2::GlobalWrite(4, buf100); + test(r==KErrNone); + r=TestDll1::GlobalRead(0, buf100); + buf100.SetLength(20); + test(buf100==_L8("ABCDELALALALALALARST")); + r=TestDll2::GlobalRead(0, buf100); + buf100.SetLength(20); + test(buf100==_L8("XXXXPOPOPOPOPOXXXXXX")); + + TestProtection(); + + test.Next(_L("Free Global Alloc")); + r=TestDll1::GlobalAlloc(0); + test(r==KErrNone); + test(TestDll1::GlobalAllocated()==EFalse); + test(TestDll2::GlobalAllocated()); + + r=TestDll2::GlobalWrite(0, _L8("WEEEEEEEEEE")); + test(r==KErrNone); + r=TestDll2::GlobalRead(0, buf100); + buf100.SetLength(11); + test(buf100==_L8("WEEEEEEEEEE")); + r=TestDll1::GlobalAlloc(0); + test(r==KErrNone); + r=TestDll2::GlobalAlloc(0); + test(r==KErrNone); + test(TestDll1::GlobalAllocated()==EFalse); + test(TestDll2::GlobalAllocated()==EFalse); + __KHEAP_MARKEND; + test.End(); + } + +GLDEF_C TInt E32Main() +// +// Test DLL Thread Local Storage data. +// + { + + test.Title(); + SetupAddresses(); +// + test.Start(_L("Dll1 Thread 1")); + test(TestDll1::Attach(ETrue)==KErrNone); + test((TUint)TestDll1::Data()==0x12345678); + TestDll1::SetData(0x87654321); + test((TUint)TestDll1::Data()==0x87654321); +// + test.Next(_L("Dll1 Thread 2")); + RThread t; + TInt r=t.Create(_L("Dll1 Thread2"),Dll1Thread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL); + test(r==KErrNone); + TRequestStatus tStat; + t.Logon(tStat); + test(tStat==KRequestPending); + t.Resume(); + User::WaitForRequest(tStat); + test(tStat==KErrNone); +// + test.Next(_L("Dll1 Thread 1 again")); + test((TUint)TestDll1::Data()==0x87654321); + TestDll1::SetData(0x12345678); + test((TUint)TestDll1::Data()==0x12345678); +// + test(TestDll1::Attach(EFalse)==KErrNone); +// + test.Next(_L("Dll2 Thread 1")); + test(TestDll2::Attach(ETrue)==KErrNone); + test((TUint)TestDll2::Data()==0xABCDABCD); + TestDll2::SetData(0xDCBADCBA); + test((TUint)TestDll2::Data()==0xDCBADCBA); +// + test.Next(_L("Dll2 Thread 2")); + r=t.Create(_L("Dll2 Thread2"),Dll2Thread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL); + test(r==KErrNone); + t.Logon(tStat); + test(tStat==KRequestPending); + t.Resume(); + User::WaitForRequest(tStat); + test(tStat==KErrNone); +// + test.Next(_L("Dll2 Thread 1 again")); + test((TUint)TestDll2::Data()==0xDCBADCBA); + TestDll2::SetData(0xABCDABCD); + test((TUint)TestDll2::Data()==0xABCDABCD); +// + test(TestDll2::Attach(EFalse)==KErrNone); +// + test.Next(_L("Dll1 Thread 1")); + test(TestDll1::Attach(ETrue)==KErrNone); + test((TUint)TestDll1::Data()==0x12345678); + TestDll1::SetData(0x87654321); + test((TUint)TestDll1::Data()==0x87654321); +// + test.Next(_L("Dll2 Thread 1")); + test(TestDll2::Attach(ETrue)==KErrNone); + test((TUint)TestDll2::Data()==0xABCDABCD); + TestDll2::SetData(0xDCBADCBA); + test((TUint)TestDll2::Data()==0xDCBADCBA); +// + test((TUint)TestDll1::Data()==0x87654321); + TestDll1::SetData(0x12345678); + test((TUint)TestDll1::Data()==0x12345678); +// + test((TUint)TestDll2::Data()==0xDCBADCBA); + TestDll2::SetData(0xABCDABCD); + test((TUint)TestDll2::Data()==0xABCDABCD); +// + test(TestDll1::Attach(EFalse)==KErrNone); + test(TestDll2::Attach(EFalse)==KErrNone); +// + + test.End(); + return(0); + } +