|
1 // Copyright (c) 2006-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 // @SYMTestCaseID KBASE-DP_FUNC_ATTRIBUTES-0303 |
|
15 // @SYMTestCaseDesc Symbian OS Toolchain's Paging Override and the |
|
16 // Paging Policy settings |
|
17 // @SYMREQ REQ6808 |
|
18 // @SYMPREQ PREQ1110 |
|
19 // @SYMTestPriority High |
|
20 // @SYMTestActions |
|
21 // 1. Load executables with the RProcess API and run them. Each executable has a |
|
22 // different set of attributes: |
|
23 // " Paging attribute: paged, unpaged or no paging attribute in MMP and/or |
|
24 // OBY files |
|
25 // " Compression mode: specified or not |
|
26 // " Executable built in ROM as 'data' or 'file' |
|
27 // " Solid binaries or aliases |
|
28 // Retrieve and analyse the demand paging activity trace caused by the preceding |
|
29 // action, in order to determine whether this binary is paged on demand or not. |
|
30 // 2. Repeat the preceding action by loading DLLs with the RLibrary API and |
|
31 // making calls to them. |
|
32 // @SYMTestExpectedResults |
|
33 // 1. Process complete without error. If, according to the trace data gathered, |
|
34 // the main thread newly created process causes the executable to be paged in, |
|
35 // then it is a proof that the executable is paged. Depending on the Paging |
|
36 // Override setting and the Loader Paging Policy specified at the time the ROM was |
|
37 // built, the Loader makes a decision as to whether page the binary or not, |
|
38 // according to the rules listed in the Design Sketch. This is how we determine |
|
39 // this, in this order: |
|
40 // a. If ROM paging is disabled: not paged |
|
41 // b. If executable was built in ROM as 'data': not paged |
|
42 // c. If the a file compression scheme was specified at ROM build time: not paged |
|
43 // d. If the Loader Paging policy is 'NOT PAGED': not paged |
|
44 // e. If the Loader Paging policy is 'ALWAYS PAGE': paged |
|
45 // f. If the Paging Override is 'NOT PAGED': not paged |
|
46 // g. If the Paging Override is 'ALWAYS PAGE': paged |
|
47 // h. If the OBY paging keyword for this executable is 'PAGED': paged |
|
48 // i. If the OBY paging keyword for this executable is 'NOT PAGED': unpaged |
|
49 // j. If the MMP paging keyword for this executable is 'PAGED': paged |
|
50 // k. If the MMP paging keyword for this executable is 'NOT PAGED': not paged |
|
51 // l. If the Paging Override is 'DEFAULT UNPAGED': not paged |
|
52 // m. If the Paging Override is 'DEFAULT PAGED': paged |
|
53 // n. If the Paging Policy is 'DEFAULT UNPAGED': not paged |
|
54 // o. The executable must be paged |
|
55 // 2. DLL is loaded. Functions are called and complete without errors. The rules |
|
56 // to determine whether the binary should be paged or not are the same as in the |
|
57 // preceding action. |
|
58 // |
|
59 // |
|
60 |
|
61 #include <e32test.h> |
|
62 #include <e32ldr.h> |
|
63 #include <d32btrace.h> |
|
64 #include "u32std.h" |
|
65 #include <f32file.h> |
|
66 #include <dptest.h> |
|
67 |
|
68 #define TEST_EQ(a,b) { if (a != b) { test.Printf(_L("%d != %d\n"), a, b); test(EFalse); } } |
|
69 #define TEST_CONDITION(a) { if (!a) { test.Printf(_L("TEST FAILED at line %d\n"), __LINE__); pass = EFalse; } } |
|
70 #define LE4(a) ((TUint) (*((a) + 3) << 24) + (*((a) + 2) << 16) + (*((a) + 1) << 8) + *(a)) |
|
71 |
|
72 RTest test(_L("T_DPATTR")); |
|
73 RBTrace btrace; |
|
74 RFs fs; |
|
75 |
|
76 // ROM paging settings |
|
77 TBool gIsRomDemangPagingEnabled; |
|
78 TInt gPagingOverride; |
|
79 TInt gPagingPolicy; |
|
80 |
|
81 // This process |
|
82 TUint32 gNThreadId = 0; |
|
83 |
|
84 // Test executables attributes flags |
|
85 enum |
|
86 { |
|
87 ENone = 0, |
|
88 EMMPPaged = 1 << 0, // "PAGED" keyword in MMP file |
|
89 EMMPUnpaged = 1 << 1, // "UNPAGED" keyword in MMP file |
|
90 EMMPCompressTarget = 1 << 2, // "COMPRESSTARGET" keyword in MMP file |
|
91 EMMPNoCompressTarget = 1 << 3, // "UNCOMPRESSTARGET" keyword in MMP file |
|
92 EIBYData = 1 << 4, // File included as "data" in IBY file |
|
93 EIBYFile = 1 << 5, // File included as "file" in IBY file |
|
94 EIBYFileCompress = 1 << 6, // File included as "file_x_" in IBY file (_x_=compression scheme) |
|
95 EIBYPaged = 1 << 7, // File declared "paged" in IBY file |
|
96 EIBYUnpaged = 1 << 8, // File declared "unpaged in IBY file |
|
97 EIBYAlias = 1 << 9, // File name is an alias |
|
98 EDLLWritableStaticData = 1 << 10 // DLL contains writable static data |
|
99 }; |
|
100 |
|
101 // Test executables attributes |
|
102 const TUint testExeAttr[] = |
|
103 { |
|
104 /* 000 - does not exist */ ENone, |
|
105 /* 001 */ EIBYFile, |
|
106 /* 002 */ EMMPPaged | EIBYFile, |
|
107 /* 003 */ EMMPUnpaged | EIBYFile, |
|
108 /* 004 */ EIBYFileCompress, |
|
109 /* 005 */ EMMPPaged | EIBYFileCompress, |
|
110 /* 006 */ EMMPUnpaged | EIBYFileCompress, |
|
111 /* 007 */ EIBYFileCompress, |
|
112 /* 008 */ EMMPPaged | EIBYFileCompress, |
|
113 /* 009 */ EMMPUnpaged | EIBYFileCompress, |
|
114 /* 010 */ EIBYFileCompress, |
|
115 /* 011 */ EMMPPaged | EIBYFileCompress, |
|
116 /* 012 */ EMMPUnpaged | EIBYFileCompress, |
|
117 /* 013 */ EIBYFile | EMMPCompressTarget, |
|
118 /* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget, |
|
119 /* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged, |
|
120 /* 016 */ EIBYData, |
|
121 /* 017 */ EMMPPaged | EIBYData, |
|
122 /* 018 */ EMMPUnpaged | EIBYData, |
|
123 /* 019 */ EIBYFile | EIBYPaged, |
|
124 /* 020 */ EMMPPaged | EIBYFile | EIBYPaged, |
|
125 /* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged, |
|
126 /* 022 */ EIBYFile | EIBYUnpaged, |
|
127 /* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged, |
|
128 /* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged, |
|
129 /* 025 */ EIBYData | EIBYPaged, |
|
130 /* 026 */ EMMPPaged | EIBYData | EIBYPaged, |
|
131 /* 027 */ EMMPUnpaged | EIBYData | EIBYPaged, |
|
132 /* 028 */ EIBYData | EIBYUnpaged, |
|
133 /* 029 */ EMMPPaged | EIBYData | EIBYUnpaged, |
|
134 /* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged, |
|
135 /* 031 */ EIBYAlias | EIBYFile, |
|
136 /* 032 */ EIBYAlias | EMMPPaged | EIBYFile, |
|
137 /* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile, |
|
138 /* 034 */ EIBYAlias | EIBYFileCompress, |
|
139 /* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress, |
|
140 /* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress, |
|
141 /* 037 */ EIBYAlias | EIBYFileCompress, |
|
142 /* 038 */ EIBYAlias | EMMPPaged | EIBYFileCompress, |
|
143 /* 039 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress, |
|
144 /* 040 */ EIBYAlias | EIBYFileCompress, |
|
145 /* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress, |
|
146 /* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress, |
|
147 /* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget, |
|
148 /* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget, |
|
149 /* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged, |
|
150 /* 046 */ EIBYAlias | EIBYData, |
|
151 /* 047 */ EIBYAlias | EMMPPaged | EIBYData, |
|
152 /* 048 */ EIBYAlias | EMMPUnpaged | EIBYData, |
|
153 /* 049 */ EIBYAlias | EIBYFile | EIBYPaged, |
|
154 /* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged, |
|
155 /* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged, |
|
156 /* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged, |
|
157 /* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged, |
|
158 /* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged, |
|
159 /* 055 */ EIBYAlias | EIBYData | EIBYPaged, |
|
160 /* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged, |
|
161 /* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged, |
|
162 /* 058 */ EIBYAlias | EIBYData | EIBYUnpaged, |
|
163 /* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged, |
|
164 /* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged |
|
165 }; |
|
166 const TUint testDllAttr[] = |
|
167 { |
|
168 /* 000 - does not exist */ ENone, |
|
169 /* 001 */ EIBYFile, |
|
170 /* 002 */ EMMPPaged | EIBYFile, |
|
171 /* 003 */ EMMPUnpaged | EIBYFile, |
|
172 /* 004 */ EIBYFileCompress, |
|
173 /* 005 */ EMMPPaged | EIBYFileCompress, |
|
174 /* 006 */ EMMPUnpaged | EIBYFileCompress, |
|
175 /* 007 */ EDLLWritableStaticData, |
|
176 /* 008 */ EMMPPaged | EDLLWritableStaticData, |
|
177 /* 009 */ EMMPUnpaged | EDLLWritableStaticData, |
|
178 /* 010 */ EIBYFileCompress, |
|
179 /* 011 */ EMMPPaged | EIBYFileCompress, |
|
180 /* 012 */ EMMPUnpaged | EIBYFileCompress, |
|
181 /* 013 */ EIBYFile | EMMPCompressTarget, |
|
182 /* 014 */ EMMPPaged | EIBYFile | EMMPNoCompressTarget, |
|
183 /* 015 */ EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged, |
|
184 /* 016 */ EIBYData, |
|
185 /* 017 */ EMMPPaged | EIBYData, |
|
186 /* 018 */ EMMPUnpaged | EIBYData, |
|
187 /* 019 */ EIBYFile | EIBYPaged, |
|
188 /* 020 */ EMMPPaged | EIBYFile | EIBYPaged, |
|
189 /* 021 */ EMMPUnpaged | EIBYFile | EIBYPaged, |
|
190 /* 022 */ EIBYFile | EIBYUnpaged, |
|
191 /* 023 */ EMMPPaged | EIBYFile | EIBYUnpaged, |
|
192 /* 024 */ EMMPUnpaged | EIBYFile | EIBYUnpaged, |
|
193 /* 025 */ EIBYData | EIBYPaged, |
|
194 /* 026 */ EMMPPaged | EIBYData | EIBYPaged, |
|
195 /* 027 */ EMMPUnpaged | EIBYData | EIBYPaged, |
|
196 /* 028 */ EIBYData | EIBYUnpaged, |
|
197 /* 029 */ EMMPPaged | EIBYData | EIBYUnpaged, |
|
198 /* 030 */ EMMPUnpaged | EIBYData | EIBYUnpaged, |
|
199 /* 031 */ EIBYAlias | EIBYFile, |
|
200 /* 032 */ EIBYAlias | EMMPPaged | EIBYFile, |
|
201 /* 033 */ EIBYAlias | EMMPUnpaged | EIBYFile, |
|
202 /* 034 */ EIBYAlias | EIBYFileCompress, |
|
203 /* 035 */ EIBYAlias | EMMPPaged | EIBYFileCompress, |
|
204 /* 036 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress, |
|
205 /* 037 */ EIBYAlias | EDLLWritableStaticData, |
|
206 /* 038 */ EIBYAlias | EMMPPaged | EDLLWritableStaticData, |
|
207 /* 039 */ EIBYAlias | EMMPUnpaged | EDLLWritableStaticData, |
|
208 /* 040 */ EIBYAlias | EIBYFileCompress, |
|
209 /* 041 */ EIBYAlias | EMMPPaged | EIBYFileCompress, |
|
210 /* 042 */ EIBYAlias | EMMPUnpaged | EIBYFileCompress, |
|
211 /* 043 */ EIBYAlias | EIBYFile | EMMPCompressTarget, |
|
212 /* 044 */ EIBYAlias | EMMPPaged | EIBYFile | EMMPNoCompressTarget, |
|
213 /* 045 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYFileCompress | EIBYPaged, |
|
214 /* 046 */ EIBYAlias | EIBYData, |
|
215 /* 047 */ EIBYAlias | EMMPPaged | EIBYData, |
|
216 /* 048 */ EIBYAlias | EMMPUnpaged | EIBYData, |
|
217 /* 049 */ EIBYAlias | EIBYFile | EIBYPaged, |
|
218 /* 050 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYPaged, |
|
219 /* 051 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYPaged, |
|
220 /* 052 */ EIBYAlias | EIBYFile | EIBYUnpaged, |
|
221 /* 053 */ EIBYAlias | EMMPPaged | EIBYFile | EIBYUnpaged, |
|
222 /* 054 */ EIBYAlias | EMMPUnpaged | EIBYFile | EIBYUnpaged, |
|
223 /* 055 */ EIBYAlias | EIBYData | EIBYPaged, |
|
224 /* 056 */ EIBYAlias | EMMPPaged | EIBYData | EIBYPaged, |
|
225 /* 057 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYPaged, |
|
226 /* 058 */ EIBYAlias | EIBYData | EIBYUnpaged, |
|
227 /* 059 */ EIBYAlias | EMMPPaged | EIBYData | EIBYUnpaged, |
|
228 /* 060 */ EIBYAlias | EMMPUnpaged | EIBYData | EIBYUnpaged |
|
229 }; |
|
230 |
|
231 void InitNThreadID() |
|
232 { |
|
233 _LIT(KThreadName, "ARandomThreadName"); |
|
234 btrace.SetFilter(BTrace::EThreadIdentification, ETrue); |
|
235 btrace.Empty(); |
|
236 btrace.SetMode(RBTrace::EEnable); |
|
237 // rename the current thread to force a ThreadID trace |
|
238 User::RenameThread(KThreadName); |
|
239 btrace.SetMode(0); |
|
240 TInt size; |
|
241 TUint8* pDataStart; |
|
242 TUint8* pCurrentRecord; |
|
243 // extract the nano-kernel thread ID from the trace |
|
244 while ((size = btrace.GetData(pDataStart)) != 0) |
|
245 { |
|
246 pCurrentRecord = pDataStart; |
|
247 while (pCurrentRecord - pDataStart < size) |
|
248 { |
|
249 TInt extensionCount = 4 * ( |
|
250 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) + |
|
251 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) + |
|
252 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) + |
|
253 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) + |
|
254 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) + |
|
255 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0)); |
|
256 // |
|
257 if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EThreadName)) |
|
258 { |
|
259 TBuf<255> threadName; |
|
260 threadName.Format(_L("")); |
|
261 for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++) |
|
262 { |
|
263 threadName.AppendFormat(_L("%c"), *j); |
|
264 } |
|
265 if (threadName == KThreadName) |
|
266 { |
|
267 test.Printf(_L("This thread's NThread ID: %08x\n"), LE4(pCurrentRecord + 4 + extensionCount)); |
|
268 gNThreadId = LE4(pCurrentRecord + 4 + extensionCount); |
|
269 } |
|
270 } |
|
271 pCurrentRecord = BTrace::NextRecord(pCurrentRecord); |
|
272 } |
|
273 btrace.DataUsed(); |
|
274 } |
|
275 } |
|
276 |
|
277 void LoadExesRom() |
|
278 { |
|
279 TInt r; |
|
280 TBool pass = ETrue; |
|
281 r = btrace.ResizeBuffer(32768); // 32k should be large enough |
|
282 TEST_EQ(r, KErrNone); |
|
283 btrace.SetFilter(BTrace::EPaging, ETrue); |
|
284 btrace.SetFilter(BTrace::EThreadIdentification, ETrue); |
|
285 btrace.SetMode(0); |
|
286 |
|
287 for (TInt i = 1; i <= 60; i++) |
|
288 { |
|
289 TBuf<255> filename; |
|
290 filename.Format(_L("Z:\\SYS\\BIN\\DPEXE%03d.EXE"), i); |
|
291 |
|
292 test.Printf(_L("Loading %S... "), &filename); |
|
293 |
|
294 TBool paged = EFalse; |
|
295 TBool inRom = EFalse; |
|
296 |
|
297 TUint32 nthreadAddr = 0; |
|
298 TBuf<255> processName; |
|
299 |
|
300 if (fs.IsFileInRom(filename) != NULL) |
|
301 { |
|
302 inRom = ETrue; |
|
303 } |
|
304 else |
|
305 { |
|
306 inRom = EFalse; |
|
307 } |
|
308 |
|
309 // Ensure that the paging live list is empty |
|
310 r = DPTest::FlushCache(); |
|
311 if (gIsRomDemangPagingEnabled) |
|
312 { |
|
313 TEST_EQ(r, KErrNone); |
|
314 } |
|
315 else |
|
316 { |
|
317 TEST_EQ(r, KErrNotSupported); |
|
318 } |
|
319 |
|
320 btrace.Empty(); // empty the BTrace buffer |
|
321 btrace.SetMode(RBTrace::EEnable); |
|
322 RProcess proc; |
|
323 r = proc.Create(filename, _L("")); |
|
324 |
|
325 if ((testExeAttr[i] & EIBYAlias) && (testExeAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled)) |
|
326 // There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged |
|
327 { |
|
328 TEST_EQ(r, KErrNotFound); |
|
329 continue; |
|
330 } |
|
331 else |
|
332 { |
|
333 TEST_EQ(r, KErrNone); |
|
334 } |
|
335 |
|
336 // Resume the process and wait until it completes |
|
337 TRequestStatus ps; |
|
338 proc.Logon(ps); |
|
339 proc.Resume(); |
|
340 proc.Close(); |
|
341 User::WaitForRequest(ps); |
|
342 |
|
343 // Disable trace |
|
344 btrace.SetMode(0); |
|
345 |
|
346 TInt size; |
|
347 TUint8* pDataStart; |
|
348 TUint8* pCurrentRecord; |
|
349 |
|
350 // We have a while loop here, in the unlikely case that our trace is fragmented |
|
351 while ((size = btrace.GetData(pDataStart)) != 0) |
|
352 { |
|
353 pCurrentRecord = pDataStart; |
|
354 while (pCurrentRecord - pDataStart < size) |
|
355 { |
|
356 // Number of bytes used by the BTrace extensions |
|
357 TInt extensionCount = 4 * ( |
|
358 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) + |
|
359 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) + |
|
360 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) + |
|
361 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) + |
|
362 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) + |
|
363 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0)); |
|
364 |
|
365 if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EThreadIdentification) && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EProcessName)) |
|
366 // Process renamed |
|
367 { |
|
368 processName.Format(_L("")); |
|
369 for (TUint8* j = pCurrentRecord + 12 + extensionCount; j < pCurrentRecord + *pCurrentRecord; j++) |
|
370 { |
|
371 processName.AppendFormat(_L("%c"), *j); |
|
372 } |
|
373 TBuf<255> expected; |
|
374 expected.Format(_L("dpexe%03d.exe[%08x]%04x"), i, 0, 1); |
|
375 |
|
376 if (processName == expected) |
|
377 { |
|
378 nthreadAddr = LE4(pCurrentRecord + 4 + extensionCount); |
|
379 } |
|
380 } |
|
381 if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging) && (LE4(pCurrentRecord + 8) == nthreadAddr)) |
|
382 /* The main thread of the test process tries to page in the test executable */ |
|
383 { |
|
384 paged = ETrue; |
|
385 } |
|
386 pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record |
|
387 } |
|
388 btrace.DataUsed(); |
|
389 } |
|
390 |
|
391 if (paged) |
|
392 test.Printf(_L("paged!\n")); |
|
393 else |
|
394 test.Printf(_L("not paged!\n")); |
|
395 |
|
396 if (!gIsRomDemangPagingEnabled) |
|
397 // ROM paging disabled. All files are in ROM and unpaged |
|
398 { |
|
399 test.Printf(_L("ROM Paging disabled: shouldn't be paged\n")); |
|
400 TEST_CONDITION(inRom); |
|
401 TEST_CONDITION(!paged); |
|
402 } |
|
403 else if (testExeAttr[i] & EIBYData) |
|
404 // data - if ROM paged, then these executables will be moved to ROFS |
|
405 // these are always expected to be RAM loaded |
|
406 { |
|
407 test.Printf(_L("EXE is DATA in ROFS\n")); |
|
408 TEST_CONDITION(!inRom); |
|
409 } |
|
410 else if (testExeAttr[i] & EIBYFileCompress) |
|
411 // Compression format specified in the IBY file |
|
412 // These are expected to be stay in ROM, but will be RAM-loaded |
|
413 { |
|
414 test.Printf(_L("EXE has own compression method: shouldn't be paged\n")); |
|
415 TEST_CONDITION(inRom); |
|
416 TEST_CONDITION(!paged); |
|
417 } |
|
418 // from this point onwards, all executables can potentially be paged - paging policy takes precedence |
|
419 else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging) |
|
420 { |
|
421 test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n")); |
|
422 TEST_CONDITION(inRom); |
|
423 TEST_CONDITION(!paged); |
|
424 } |
|
425 else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage) |
|
426 { |
|
427 test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n")); |
|
428 TEST_CONDITION(inRom); |
|
429 TEST_CONDITION(paged); |
|
430 } |
|
431 // from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence |
|
432 else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging) |
|
433 { |
|
434 test.Printf(_L("Paging override is No Paging: shouldn't be paged\n")); |
|
435 TEST_CONDITION(inRom); |
|
436 TEST_CONDITION(!paged); |
|
437 } |
|
438 else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage) |
|
439 { |
|
440 test.Printf(_L("Paging override is Always Page: should be paged\n")); |
|
441 TEST_CONDITION(inRom); |
|
442 TEST_CONDITION(paged); |
|
443 } |
|
444 // from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence |
|
445 else if (testExeAttr[i] & EIBYPaged) |
|
446 { |
|
447 test.Printf(_L("Paged keyword in OBY: should be paged\n")); |
|
448 TEST_CONDITION(inRom); |
|
449 TEST_CONDITION(paged); |
|
450 } |
|
451 else if (testExeAttr[i] & EIBYUnpaged) |
|
452 { |
|
453 test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n")); |
|
454 TEST_CONDITION(inRom); |
|
455 TEST_CONDITION(!paged); |
|
456 } |
|
457 // Next, MMP setting takes precedence |
|
458 else if (testExeAttr[i] & EMMPPaged) |
|
459 { |
|
460 test.Printf(_L("Paged keyword in MMP: should be paged\n")); |
|
461 TEST_CONDITION(inRom); |
|
462 TEST_CONDITION(paged); |
|
463 } |
|
464 else if (testExeAttr[i] & EMMPUnpaged) |
|
465 { |
|
466 test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n")); |
|
467 TEST_CONDITION(inRom); |
|
468 TEST_CONDITION(!paged); |
|
469 } |
|
470 // The test exe has no attribute. Paging overright default paging mode takes precedence |
|
471 else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged) |
|
472 { |
|
473 test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n")); |
|
474 TEST_CONDITION(inRom); |
|
475 TEST_CONDITION(!paged); |
|
476 } |
|
477 else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged) |
|
478 { |
|
479 test.Printf(_L("Paging override is Default Paged: should be paged\n")); |
|
480 TEST_CONDITION(inRom); |
|
481 TEST_CONDITION(paged); |
|
482 } |
|
483 // Paging policy default paging mode takes precedence |
|
484 else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged) |
|
485 { |
|
486 test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n")); |
|
487 TEST_CONDITION(inRom); |
|
488 TEST_CONDITION(!paged); |
|
489 } |
|
490 else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged) |
|
491 { |
|
492 test.Printf(_L("Paging policy is Default paged: should be paged\n")); |
|
493 TEST_CONDITION(inRom); |
|
494 TEST_CONDITION(paged); |
|
495 } |
|
496 // ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging) |
|
497 else |
|
498 { |
|
499 test.Printf(_L("No paging policy!\n")); |
|
500 test(EFalse); |
|
501 } |
|
502 } |
|
503 test(pass); |
|
504 } |
|
505 |
|
506 |
|
507 void LoadDllsRom() |
|
508 { |
|
509 TInt r; |
|
510 TBool pass = ETrue; |
|
511 r = btrace.ResizeBuffer(32768); // 32k should be large enough |
|
512 TEST_EQ(r, KErrNone); |
|
513 btrace.SetFilter(BTrace::EPaging, ETrue); |
|
514 btrace.SetFilter(BTrace::EThreadIdentification, ETrue); |
|
515 btrace.SetMode(0); |
|
516 |
|
517 for (TInt i = 1; i <= 60; i++) |
|
518 { |
|
519 TBuf<255> filename; |
|
520 filename.Format(_L("Z:\\SYS\\BIN\\DPDLL%03d.DLL"), i); |
|
521 |
|
522 test.Printf(_L("Loading %S... "), &filename); |
|
523 |
|
524 TBool paged = EFalse; |
|
525 TBool inRom = EFalse; |
|
526 |
|
527 TUint libLoadEnd; |
|
528 TInt filesize; |
|
529 |
|
530 TUint8* addr; |
|
531 if ((addr = fs.IsFileInRom(filename)) != NULL) |
|
532 { |
|
533 inRom = ETrue; |
|
534 } |
|
535 else |
|
536 { |
|
537 inRom = EFalse; |
|
538 } |
|
539 |
|
540 RFile file; |
|
541 r = file.Open(fs, filename, EFileRead); |
|
542 if ((testDllAttr[i] & EIBYAlias) && (testDllAttr[i] & EIBYData) && (gIsRomDemangPagingEnabled)) |
|
543 // There cannot be aliases mapping to "data" files since they are moved to ROFS if the ROM is paged |
|
544 { |
|
545 TEST_EQ(r, KErrNotFound); |
|
546 continue; |
|
547 } |
|
548 else |
|
549 { |
|
550 TEST_EQ(r, KErrNone); |
|
551 } |
|
552 r = file.Size(filesize); |
|
553 TEST_EQ(r, KErrNone); |
|
554 file.Close(); |
|
555 |
|
556 // Ensure that the paging live list is empty |
|
557 r = DPTest::FlushCache(); |
|
558 if (gIsRomDemangPagingEnabled) |
|
559 { |
|
560 TEST_EQ(r, KErrNone); |
|
561 } |
|
562 else |
|
563 { |
|
564 TEST_EQ(r, KErrNotSupported); |
|
565 } |
|
566 |
|
567 btrace.Empty(); // empty the BTrace buffer |
|
568 btrace.SetMode(RBTrace::EEnable); |
|
569 RLibrary lib; |
|
570 r = lib.Load(filename); |
|
571 libLoadEnd = User::FastCounter(); |
|
572 |
|
573 TEST_EQ(r, KErrNone); |
|
574 |
|
575 TLibraryFunction function1; |
|
576 TLibraryFunction function2; |
|
577 TLibraryFunction function3; |
|
578 TLibraryFunction function4; |
|
579 |
|
580 function1 = lib.Lookup(1); |
|
581 function2 = lib.Lookup(2); |
|
582 function3 = lib.Lookup(3); |
|
583 function4 = lib.Lookup(4); |
|
584 |
|
585 test(function1 != NULL); |
|
586 test(function2 != NULL); |
|
587 test(function3 != NULL); |
|
588 test(function4 == NULL); |
|
589 |
|
590 // Resume the process and wait until it completes |
|
591 |
|
592 function1(); |
|
593 function2(); |
|
594 function3(); |
|
595 |
|
596 lib.Close(); |
|
597 |
|
598 //processResumeStart = User::FastCounter(); |
|
599 //processResumeEnd = User::FastCounter(); |
|
600 |
|
601 // Disable trace |
|
602 btrace.SetMode(0); |
|
603 |
|
604 TInt size; |
|
605 TUint8* pDataStart; |
|
606 TUint8* pCurrentRecord; |
|
607 |
|
608 // We have a while loop here, in the unlikely case that our trace is fragmented |
|
609 while ((size = btrace.GetData(pDataStart)) != 0) |
|
610 { |
|
611 pCurrentRecord = pDataStart; |
|
612 while (pCurrentRecord - pDataStart < size) |
|
613 { |
|
614 // Number of bytes used by the BTrace extensions |
|
615 TInt extensionCount = 4 * ( |
|
616 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EHeader2Present ? 1 : 0) + |
|
617 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestampPresent ? 1 : 0) + |
|
618 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::ETimestamp2Present ? 1 : 0) + |
|
619 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EContextIdPresent ? 1 : 0) + |
|
620 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EPcPresent ? 1 : 0) + |
|
621 (pCurrentRecord[BTrace::EFlagsIndex] & BTrace::EExtraPresent ? 1 : 0)); |
|
622 |
|
623 if ((pCurrentRecord[BTrace::ECategoryIndex] == BTrace::EPaging) |
|
624 && (pCurrentRecord[BTrace::ESubCategoryIndex] == BTrace::EPagingPageInBegin) |
|
625 && (LE4(pCurrentRecord + 4) > libLoadEnd) |
|
626 && (LE4(pCurrentRecord + extensionCount) == gNThreadId) |
|
627 && (LE4(pCurrentRecord + 4 + extensionCount) >= (TUint32) addr) |
|
628 && (LE4(pCurrentRecord + 4 + extensionCount) < ((TUint32) addr) + filesize)) |
|
629 // If the DLL is paged in under this thread after it's been RLibrary::Load'ed, then we assume the DLL is paged |
|
630 { |
|
631 paged = ETrue; |
|
632 } |
|
633 pCurrentRecord = BTrace::NextRecord(pCurrentRecord); // move on to the next record |
|
634 } |
|
635 btrace.DataUsed(); |
|
636 } |
|
637 |
|
638 if (paged) |
|
639 test.Printf(_L("paged!\n")); |
|
640 else |
|
641 test.Printf(_L("not paged!\n")); |
|
642 |
|
643 if (!gIsRomDemangPagingEnabled) |
|
644 // ROM paging disabled. All files are in ROM and unpaged |
|
645 { |
|
646 test.Printf(_L("ROM Paging disabled: shouldn't be paged\n")); |
|
647 test(inRom); |
|
648 TEST_CONDITION(!paged); |
|
649 } |
|
650 else if (testDllAttr[i] & EIBYData) |
|
651 // data - if ROM paged, then these executables will be moved to ROFS |
|
652 // these are always expected to be RAM loaded |
|
653 { |
|
654 test.Printf(_L("DLL is DATA in ROFS: shouldn't be paged\n")); |
|
655 TEST_CONDITION(!inRom); |
|
656 TEST_CONDITION(!paged); |
|
657 } |
|
658 else if (testDllAttr[i] & EIBYFileCompress) |
|
659 // Compression format specified in the IBY file |
|
660 // These are expected to be stay in ROM, but will be RAM-loaded |
|
661 { |
|
662 test.Printf(_L("DLL has own compression method: shouldn't be paged\n")); |
|
663 TEST_CONDITION(inRom); |
|
664 TEST_CONDITION(!paged); |
|
665 } |
|
666 // from this point onwards, all executables can potentially be paged - paging policy takes precedence |
|
667 else if (gPagingPolicy == EKernelConfigCodePagingPolicyNoPaging) |
|
668 { |
|
669 test.Printf(_L("Paging policy is No Paging: shouldn't be paged\n")); |
|
670 TEST_CONDITION(inRom); |
|
671 TEST_CONDITION(!paged); |
|
672 } |
|
673 else if (gPagingPolicy == EKernelConfigCodePagingPolicyAlwaysPage) |
|
674 { |
|
675 test.Printf(_L("Paging policy is Always Page: should be paged\n")); |
|
676 TEST_CONDITION(inRom); |
|
677 TEST_CONDITION(paged); |
|
678 } |
|
679 // from this point onwards, paging policy is either Default Paged or Default Unpaged - paging override takes precedence |
|
680 else if (gPagingOverride == EKernelConfigCodePagingPolicyNoPaging) |
|
681 { |
|
682 test.Printf(_L("Paging override is No Paging: shouldn't be paged\n")); |
|
683 TEST_CONDITION(inRom); |
|
684 TEST_CONDITION(!paged); |
|
685 } |
|
686 else if (gPagingOverride == EKernelConfigCodePagingPolicyAlwaysPage) |
|
687 { |
|
688 test.Printf(_L("Paging override is Always Page: should be paged\n")); |
|
689 TEST_CONDITION(inRom); |
|
690 TEST_CONDITION(paged); |
|
691 } |
|
692 // from this point onwards, paging policy and override are either Default Paged or Default Unpaged - IBY setting takes precedence |
|
693 else if (testDllAttr[i] & EIBYPaged) |
|
694 { |
|
695 test.Printf(_L("Paged keyword in OBY: should be paged\n")); |
|
696 TEST_CONDITION(inRom); |
|
697 TEST_CONDITION(paged); |
|
698 } |
|
699 else if (testDllAttr[i] & EIBYUnpaged) |
|
700 { |
|
701 test.Printf(_L("Unpaged keyword in OBY: shouldn't be paged\n")); |
|
702 TEST_CONDITION(inRom); |
|
703 TEST_CONDITION(!paged); |
|
704 } |
|
705 // Next, MMP setting takes precedence |
|
706 else if (testDllAttr[i] & EMMPPaged) |
|
707 { |
|
708 test.Printf(_L("Paged keyword in MMP: should be paged\n")); |
|
709 TEST_CONDITION(inRom); |
|
710 TEST_CONDITION(paged); |
|
711 } |
|
712 else if (testDllAttr[i] & EMMPUnpaged) |
|
713 { |
|
714 test.Printf(_L("Unpaged keyword in MMP: shouldn't be paged\n")); |
|
715 TEST_CONDITION(inRom); |
|
716 TEST_CONDITION(!paged); |
|
717 } |
|
718 // The test exe has no attribute. Paging overright default paging mode takes precedence |
|
719 else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultUnpaged) |
|
720 { |
|
721 test.Printf(_L("Paging override is Default Unpaged: shouldn't be paged\n")); |
|
722 TEST_CONDITION(inRom); |
|
723 TEST_CONDITION(!paged); |
|
724 } |
|
725 else if (gPagingOverride == EKernelConfigCodePagingPolicyDefaultPaged) |
|
726 { |
|
727 test.Printf(_L("Paging override is Default Paged: should be paged\n")); |
|
728 TEST_CONDITION(inRom); |
|
729 TEST_CONDITION(paged); |
|
730 } |
|
731 // Paging policy default paging mode takes precedence |
|
732 else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultUnpaged) |
|
733 { |
|
734 test.Printf(_L("Paging policy is Default Unpaged: shouldn't be paged\n")); |
|
735 TEST_CONDITION(inRom); |
|
736 TEST_CONDITION(!paged); |
|
737 } |
|
738 else if (gPagingPolicy == EKernelConfigCodePagingPolicyDefaultPaged) |
|
739 { |
|
740 test.Printf(_L("Paging policy is Default paged: should be paged\n")); |
|
741 TEST_CONDITION(inRom); |
|
742 TEST_CONDITION(paged); |
|
743 } |
|
744 // ROM Paging enabled without a default paging policy - this should not happen (default policy is No Paging) |
|
745 else |
|
746 { |
|
747 test.Printf(_L("No paging policy!\n")); |
|
748 test(EFalse); |
|
749 } |
|
750 } |
|
751 test(pass); |
|
752 } |
|
753 |
|
754 GLDEF_C TInt E32Main() |
|
755 { |
|
756 TInt r; |
|
757 test.Title(); |
|
758 test.Start(_L("Check environment")); |
|
759 |
|
760 // Open the BTrace handler |
|
761 r = btrace.Open(); |
|
762 TEST_EQ(r, KErrNone); |
|
763 |
|
764 // capture the NThread ID of the main thread of the current process |
|
765 InitNThreadID(); |
|
766 test(gNThreadId != 0); |
|
767 |
|
768 gPagingPolicy = E32Loader::PagingPolicy(); |
|
769 gPagingOverride = -1; |
|
770 |
|
771 r = fs.Connect(); |
|
772 TEST_EQ(r, KErrNone); |
|
773 |
|
774 if (fs.IsFileInRom(_L("\\ovr_nopaging")) != NULL) |
|
775 { |
|
776 gPagingOverride = EKernelConfigCodePagingPolicyNoPaging; |
|
777 } |
|
778 if (fs.IsFileInRom(_L("\\ovr_alwayspage")) != NULL) |
|
779 { |
|
780 gPagingOverride = EKernelConfigCodePagingPolicyAlwaysPage; |
|
781 } |
|
782 if (fs.IsFileInRom(_L("\\ovr_defaultunpaged")) != NULL) |
|
783 { |
|
784 gPagingOverride = EKernelConfigCodePagingPolicyDefaultUnpaged; |
|
785 } |
|
786 if (fs.IsFileInRom(_L("\\ovr_defaultpaged")) != NULL) |
|
787 { |
|
788 gPagingOverride = EKernelConfigCodePagingPolicyDefaultPaged; |
|
789 } |
|
790 if (fs.IsFileInRom(_L("\\pcy_nopaging")) != NULL) |
|
791 { |
|
792 gPagingPolicy = EKernelConfigCodePagingPolicyNoPaging; |
|
793 } |
|
794 if (fs.IsFileInRom(_L("\\pcy_alwayspage")) != NULL) |
|
795 { |
|
796 gPagingPolicy = EKernelConfigCodePagingPolicyAlwaysPage; |
|
797 } |
|
798 if (fs.IsFileInRom(_L("\\pcy_defaultunpaged")) != NULL) |
|
799 { |
|
800 gPagingPolicy = EKernelConfigCodePagingPolicyDefaultUnpaged; |
|
801 } |
|
802 if (fs.IsFileInRom(_L("\\pcy_defaultpaged")) != NULL) |
|
803 { |
|
804 gPagingPolicy = EKernelConfigCodePagingPolicyDefaultPaged; |
|
805 } |
|
806 |
|
807 gIsRomDemangPagingEnabled = (fs.IsFileInRom(_L("Z:\\SYS\\BIN\\DPEXE046.EXE")) == NULL); |
|
808 |
|
809 test.Printf(_L("Demand Paging Enabled? %d\n"), gIsRomDemangPagingEnabled); |
|
810 test.Printf(_L("PagingOverride %d\n"), gPagingOverride); |
|
811 test.Printf(_L("PagingPolicy %d\n"), gPagingPolicy); |
|
812 |
|
813 test.Next(_L("Load ROM EXEs")); |
|
814 LoadExesRom(); |
|
815 test.Next(_L("Load ROM DLLs")); |
|
816 LoadDllsRom(); |
|
817 |
|
818 btrace.Close(); |
|
819 fs.Close(); |
|
820 test.End(); |
|
821 test.Close(); |
|
822 return KErrNone; |
|
823 } |