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