|
1 // Copyright (c) 1995-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 // e32test\dll\t_tdll12.cpp |
|
15 // Overview: |
|
16 // Test DLL Thread Local Storage data and DLL Global data access. |
|
17 // API Information: |
|
18 // Dll |
|
19 // Details: |
|
20 // - Test that the local storage of two different DLLs, when accessed from |
|
21 // two different threads is unique. Verify that results are as expected. |
|
22 // - Test the access of DLL Global data including Alloc, Read and Write. Test |
|
23 // the protection of the global data. Verify results are as expected. |
|
24 // Platforms/Drives/Compatibility: |
|
25 // All. |
|
26 // Assumptions/Requirement/Pre-requisites: |
|
27 // Failures and causes: |
|
28 // Base Port information: |
|
29 // |
|
30 // |
|
31 |
|
32 #include "t_dll.h" |
|
33 #include "../mmu/mmudetect.h" |
|
34 |
|
35 const TInt KHeapSize=0x2000; |
|
36 |
|
37 LOCAL_D RTest test(_L("T_TDLL12")); |
|
38 |
|
39 TBool KernProt=EFalse; |
|
40 TUint8* Kern; |
|
41 TUint8* Garbage; |
|
42 |
|
43 void SetupAddresses() |
|
44 { |
|
45 KernProt=HaveDirectKernProt(); |
|
46 Kern=KernData(); |
|
47 TUint32 mm_attr=MemModelAttributes(); |
|
48 TUint32 mm_type=mm_attr & EMemModelTypeMask; |
|
49 switch (mm_type) |
|
50 { |
|
51 case EMemModelTypeDirect: |
|
52 Garbage=(TUint8*)0xa8000000; |
|
53 break; |
|
54 case EMemModelTypeMoving: |
|
55 Garbage=(TUint8*)0x60f00000; |
|
56 break; |
|
57 case EMemModelTypeMultiple: |
|
58 Garbage=(TUint8*)0xfe000000; |
|
59 break; |
|
60 case EMemModelTypeFlexible: |
|
61 Garbage=(TUint8*)0x8ff00000; |
|
62 break; |
|
63 case EMemModelTypeEmul: |
|
64 Garbage=(TUint8*)0xf0000000; |
|
65 break; |
|
66 default: |
|
67 test(0); |
|
68 break; |
|
69 } |
|
70 } |
|
71 |
|
72 void RunTestInThread(TThreadFunction aFn, TAny* aParameter, const TDesC* aPanicCat, TInt aExitCode) |
|
73 { |
|
74 RThread t; |
|
75 TInt r=t.Create(KNullDesC(),aFn,0x2000,NULL,aParameter); |
|
76 test(r==KErrNone); |
|
77 TRequestStatus s; |
|
78 t.Logon(s); |
|
79 t.Resume(); |
|
80 User::WaitForRequest(s); |
|
81 if (aPanicCat) |
|
82 { |
|
83 test(t.ExitType()==EExitPanic); |
|
84 test(t.ExitCategory()==*aPanicCat); |
|
85 test(t.ExitReason()==aExitCode); |
|
86 } |
|
87 else |
|
88 { |
|
89 test(t.ExitType()==EExitKill); |
|
90 test(t.ExitReason()==aExitCode); |
|
91 } |
|
92 CLOSE_AND_WAIT(t); |
|
93 } |
|
94 |
|
95 TInt GlobalReadThread(TAny* a) |
|
96 { |
|
97 return TestDll1::GlobalRead(122,*(TDes8*)a); |
|
98 } |
|
99 |
|
100 TInt GlobalWriteThread(TAny* a) |
|
101 { |
|
102 return TestDll1::GlobalWrite(0,*(TDes8*)a); |
|
103 } |
|
104 |
|
105 _LIT(KLitKernExec,"KERN-EXEC"); |
|
106 void TestProtection() |
|
107 { |
|
108 test.Next(_L("Test protection")); |
|
109 TBool jit=User::JustInTime(); |
|
110 User::SetJustInTime(EFalse); |
|
111 TUint x=0xffffffff; |
|
112 TBuf8<64> ubuf; |
|
113 TPtrC8 uptrc(ubuf.Ptr(),11); |
|
114 TPtr8 uptr((TUint8*)ubuf.Ptr(),1,20); |
|
115 TPtrC8 kptrc(Kern,1); |
|
116 TPtr8 kptr(Kern,10,256); |
|
117 TPtrC8 gptrc(Garbage,1); |
|
118 TPtr8 gptr(Garbage,10,256); |
|
119 RunTestInThread(GlobalReadThread,&x,&KLitKernExec,EKUDesInfoInvalidType); |
|
120 RunTestInThread(GlobalReadThread,&ubuf,NULL,KErrNone); |
|
121 RunTestInThread(GlobalReadThread,&uptr,NULL,KErrNone); |
|
122 RunTestInThread(GlobalReadThread,&uptrc,&KLitKernExec,EKUDesInfoInvalidType); |
|
123 RunTestInThread(GlobalReadThread,&kptrc,&KLitKernExec,EKUDesInfoInvalidType); |
|
124 RunTestInThread(GlobalReadThread,&gptrc,&KLitKernExec,EKUDesInfoInvalidType); |
|
125 RunTestInThread(GlobalReadThread,&gptr,&KLitKernExec,ECausedException); |
|
126 if (KernProt) |
|
127 { |
|
128 RunTestInThread(GlobalReadThread,Kern,&KLitKernExec,ECausedException); |
|
129 RunTestInThread(GlobalReadThread,&kptr,&KLitKernExec,ECausedException); |
|
130 } |
|
131 RunTestInThread(GlobalWriteThread,&x,&KLitKernExec,EKUDesInfoInvalidType); |
|
132 RunTestInThread(GlobalWriteThread,&ubuf,NULL,KErrNone); |
|
133 RunTestInThread(GlobalWriteThread,&uptr,NULL,KErrNone); |
|
134 RunTestInThread(GlobalWriteThread,&uptrc,NULL,KErrNone); |
|
135 RunTestInThread(GlobalWriteThread,&gptrc,&KLitKernExec,ECausedException); |
|
136 RunTestInThread(GlobalWriteThread,&gptr,&KLitKernExec,ECausedException); |
|
137 if (KernProt) |
|
138 { |
|
139 RunTestInThread(GlobalWriteThread,Kern,&KLitKernExec,ECausedException); |
|
140 RunTestInThread(GlobalWriteThread,&kptrc,&KLitKernExec,ECausedException); |
|
141 RunTestInThread(GlobalWriteThread,&kptr,&KLitKernExec,ECausedException); |
|
142 } |
|
143 User::SetJustInTime(jit); |
|
144 } |
|
145 |
|
146 LOCAL_C TInt Dll1Thread2(TAny* /*anArg*/) |
|
147 // |
|
148 // The entry point for thread2. |
|
149 // |
|
150 { |
|
151 |
|
152 test(TestDll1::Attach(ETrue)==KErrNone); |
|
153 test((TUint)TestDll1::Data()==0x12345678); |
|
154 TestDll1::SetData(0xfedcba98); |
|
155 test((TUint)TestDll1::Data()==0xfedcba98); |
|
156 test(TestDll1::Attach(EFalse)==KErrNone); |
|
157 return KErrNone; |
|
158 } |
|
159 |
|
160 LOCAL_C TInt Dll2Thread2(TAny* /*anArg*/) |
|
161 // |
|
162 // The entry point for thread2. |
|
163 // |
|
164 { |
|
165 |
|
166 test(TestDll2::Attach(ETrue)==KErrNone); |
|
167 test((TUint)TestDll2::Data()==0xABCDABCD); |
|
168 TestDll2::SetData(0x12341234); |
|
169 test((TUint)TestDll2::Data()==0x12341234); |
|
170 test(TestDll2::Attach(EFalse)==KErrNone); |
|
171 return KErrNone; |
|
172 } |
|
173 |
|
174 void testGlobalAlloc() |
|
175 // |
|
176 // |
|
177 // |
|
178 { |
|
179 |
|
180 __KHEAP_MARK; |
|
181 test.Start(_L("Test Dll::GlobalAlloc")); |
|
182 TInt r; |
|
183 test(TestDll1::GlobalAllocated()==EFalse); |
|
184 test(TestDll2::GlobalAllocated()==EFalse); |
|
185 r=TestDll2::GlobalAlloc(0); |
|
186 test(r==KErrNone); |
|
187 r=TestDll1::GlobalAlloc(256); |
|
188 test(r==KErrNone); |
|
189 test(TestDll1::GlobalAllocated()); |
|
190 test(TestDll2::GlobalAllocated()==EFalse); |
|
191 r=TestDll2::GlobalAlloc(256); |
|
192 test(r==KErrNone); |
|
193 test(TestDll1::GlobalAllocated()); |
|
194 test(TestDll2::GlobalAllocated()); |
|
195 |
|
196 test.Next(_L("Write")); |
|
197 // Write 256 bytes |
|
198 TBuf8<0x100> buf100; |
|
199 TInt i; |
|
200 buf100.SetLength(0x100); |
|
201 for (i=0; i<256; i++) |
|
202 buf100[i]=(TText8)('A'+i%26); |
|
203 r=TestDll1::GlobalWrite(0, buf100); |
|
204 test(r==KErrNone); |
|
205 buf100.Fill('X'); |
|
206 r=TestDll2::GlobalWrite(0, buf100); |
|
207 test(r==KErrNone); |
|
208 |
|
209 test.Next(_L("Read")); |
|
210 // Read 256 bytes |
|
211 r=TestDll1::GlobalRead(0, buf100); |
|
212 test(r==KErrNone); |
|
213 for (i=0; i<256; i++) |
|
214 test(buf100[i]=='A'+i%26); |
|
215 buf100.Fill('D'); |
|
216 r=TestDll2::GlobalRead(0, buf100); |
|
217 test(r==KErrNone); |
|
218 for (i=0; i<256; i++) |
|
219 test(buf100[i]=='X'); |
|
220 |
|
221 test.Next(_L("Realloc")); |
|
222 r=TestDll1::GlobalAlloc(128); |
|
223 test(r==KErrNone); |
|
224 test(TestDll1::GlobalAllocated()); |
|
225 test(TestDll2::GlobalAllocated()); |
|
226 test.Next(_L("Read")); |
|
227 r=TestDll1::GlobalRead(0,buf100); |
|
228 for (i=0; i<128; i++) |
|
229 test(buf100[i]=='A'+i%26); |
|
230 test(buf100.Length()==128); |
|
231 r=TestDll2::GlobalRead(0,buf100); |
|
232 test(r==KErrNone); |
|
233 for (i=0; i<256; i++) |
|
234 test(buf100[i]=='X'); |
|
235 test(buf100.Length()==256); |
|
236 |
|
237 test.Next(_L("Read @ pos")); |
|
238 // Read from position |
|
239 r=TestDll1::GlobalRead(1, buf100); |
|
240 test(r==KErrNone); |
|
241 test(buf100.Length()==127); |
|
242 for (i=0; i<127; i++) |
|
243 test(buf100[i]=='A'+(i+1)%26); |
|
244 test.Next(_L("Write @ pos")); |
|
245 buf100=_L8("LALALALALALA"); |
|
246 r=TestDll1::GlobalWrite(5, buf100); |
|
247 test(r==KErrNone); |
|
248 buf100=_L8("POPOPOPOPO"); |
|
249 r=TestDll2::GlobalWrite(4, buf100); |
|
250 test(r==KErrNone); |
|
251 r=TestDll1::GlobalRead(0, buf100); |
|
252 buf100.SetLength(20); |
|
253 test(buf100==_L8("ABCDELALALALALALARST")); |
|
254 r=TestDll2::GlobalRead(0, buf100); |
|
255 buf100.SetLength(20); |
|
256 test(buf100==_L8("XXXXPOPOPOPOPOXXXXXX")); |
|
257 |
|
258 TestProtection(); |
|
259 |
|
260 test.Next(_L("Free Global Alloc")); |
|
261 r=TestDll1::GlobalAlloc(0); |
|
262 test(r==KErrNone); |
|
263 test(TestDll1::GlobalAllocated()==EFalse); |
|
264 test(TestDll2::GlobalAllocated()); |
|
265 |
|
266 r=TestDll2::GlobalWrite(0, _L8("WEEEEEEEEEE")); |
|
267 test(r==KErrNone); |
|
268 r=TestDll2::GlobalRead(0, buf100); |
|
269 buf100.SetLength(11); |
|
270 test(buf100==_L8("WEEEEEEEEEE")); |
|
271 r=TestDll1::GlobalAlloc(0); |
|
272 test(r==KErrNone); |
|
273 r=TestDll2::GlobalAlloc(0); |
|
274 test(r==KErrNone); |
|
275 test(TestDll1::GlobalAllocated()==EFalse); |
|
276 test(TestDll2::GlobalAllocated()==EFalse); |
|
277 __KHEAP_MARKEND; |
|
278 test.End(); |
|
279 } |
|
280 |
|
281 GLDEF_C TInt E32Main() |
|
282 // |
|
283 // Test DLL Thread Local Storage data. |
|
284 // |
|
285 { |
|
286 |
|
287 test.Title(); |
|
288 SetupAddresses(); |
|
289 // |
|
290 test.Start(_L("Dll1 Thread 1")); |
|
291 test(TestDll1::Attach(ETrue)==KErrNone); |
|
292 test((TUint)TestDll1::Data()==0x12345678); |
|
293 TestDll1::SetData(0x87654321); |
|
294 test((TUint)TestDll1::Data()==0x87654321); |
|
295 // |
|
296 test.Next(_L("Dll1 Thread 2")); |
|
297 RThread t; |
|
298 TInt r=t.Create(_L("Dll1 Thread2"),Dll1Thread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL); |
|
299 test(r==KErrNone); |
|
300 TRequestStatus tStat; |
|
301 t.Logon(tStat); |
|
302 test(tStat==KRequestPending); |
|
303 t.Resume(); |
|
304 User::WaitForRequest(tStat); |
|
305 test(tStat==KErrNone); |
|
306 // |
|
307 test.Next(_L("Dll1 Thread 1 again")); |
|
308 test((TUint)TestDll1::Data()==0x87654321); |
|
309 TestDll1::SetData(0x12345678); |
|
310 test((TUint)TestDll1::Data()==0x12345678); |
|
311 // |
|
312 test(TestDll1::Attach(EFalse)==KErrNone); |
|
313 // |
|
314 test.Next(_L("Dll2 Thread 1")); |
|
315 test(TestDll2::Attach(ETrue)==KErrNone); |
|
316 test((TUint)TestDll2::Data()==0xABCDABCD); |
|
317 TestDll2::SetData(0xDCBADCBA); |
|
318 test((TUint)TestDll2::Data()==0xDCBADCBA); |
|
319 // |
|
320 test.Next(_L("Dll2 Thread 2")); |
|
321 r=t.Create(_L("Dll2 Thread2"),Dll2Thread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL); |
|
322 test(r==KErrNone); |
|
323 t.Logon(tStat); |
|
324 test(tStat==KRequestPending); |
|
325 t.Resume(); |
|
326 User::WaitForRequest(tStat); |
|
327 test(tStat==KErrNone); |
|
328 // |
|
329 test.Next(_L("Dll2 Thread 1 again")); |
|
330 test((TUint)TestDll2::Data()==0xDCBADCBA); |
|
331 TestDll2::SetData(0xABCDABCD); |
|
332 test((TUint)TestDll2::Data()==0xABCDABCD); |
|
333 // |
|
334 test(TestDll2::Attach(EFalse)==KErrNone); |
|
335 // |
|
336 test.Next(_L("Dll1 Thread 1")); |
|
337 test(TestDll1::Attach(ETrue)==KErrNone); |
|
338 test((TUint)TestDll1::Data()==0x12345678); |
|
339 TestDll1::SetData(0x87654321); |
|
340 test((TUint)TestDll1::Data()==0x87654321); |
|
341 // |
|
342 test.Next(_L("Dll2 Thread 1")); |
|
343 test(TestDll2::Attach(ETrue)==KErrNone); |
|
344 test((TUint)TestDll2::Data()==0xABCDABCD); |
|
345 TestDll2::SetData(0xDCBADCBA); |
|
346 test((TUint)TestDll2::Data()==0xDCBADCBA); |
|
347 // |
|
348 test((TUint)TestDll1::Data()==0x87654321); |
|
349 TestDll1::SetData(0x12345678); |
|
350 test((TUint)TestDll1::Data()==0x12345678); |
|
351 // |
|
352 test((TUint)TestDll2::Data()==0xDCBADCBA); |
|
353 TestDll2::SetData(0xABCDABCD); |
|
354 test((TUint)TestDll2::Data()==0xABCDABCD); |
|
355 // |
|
356 test(TestDll1::Attach(EFalse)==KErrNone); |
|
357 test(TestDll2::Attach(EFalse)==KErrNone); |
|
358 // |
|
359 |
|
360 test.End(); |
|
361 return(0); |
|
362 } |
|
363 |