0
|
1 |
// Copyright (c) 1999-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 |
// f32test\loader\t_ldrtst2.cpp
|
|
15 |
//
|
|
16 |
//
|
|
17 |
|
|
18 |
#include "t_ldrtst.h"
|
|
19 |
|
|
20 |
extern TInt GetModuleFlags(TInt);
|
|
21 |
|
|
22 |
inline TBool AlwaysLoaded(TInt aModule)
|
|
23 |
{
|
|
24 |
#ifdef __EPOC32__
|
|
25 |
TUint32 f=GetModuleFlags(aModule);
|
|
26 |
return ( (f&(KModuleFlagExe|KModuleFlagDataInTree|KModuleFlagXIP)) == (TUint32)KModuleFlagXIP );
|
|
27 |
#else
|
|
28 |
TUint32 f=GetModuleFlags(aModule);
|
|
29 |
return ( (f&(KModuleFlagExe|KModuleFlagDataInTree)) == 0 );
|
|
30 |
#endif
|
|
31 |
}
|
|
32 |
|
|
33 |
TInt Order(const SModuleInstance& m1, const SModuleInstance& m2)
|
|
34 |
{
|
|
35 |
return TInt(m1.iCodeSeg)-TInt(m2.iCodeSeg);
|
|
36 |
}
|
|
37 |
|
|
38 |
CGlobalModuleList::CGlobalModuleList()
|
|
39 |
: iModules(KNumModules)
|
|
40 |
{
|
|
41 |
}
|
|
42 |
|
|
43 |
CGlobalModuleList::~CGlobalModuleList()
|
|
44 |
{
|
|
45 |
iModules.Close();
|
|
46 |
User::Free(iModuleAlloc);
|
|
47 |
TInt i;
|
|
48 |
for (i=0; i<KNumModules; ++i)
|
|
49 |
{
|
|
50 |
delete iPPInfo[i];
|
|
51 |
}
|
|
52 |
}
|
|
53 |
|
|
54 |
void CGlobalModuleList::Init()
|
|
55 |
{
|
|
56 |
TBool proc_sym=(iMemModelAtt & (EMemModelAttrSameVA|EMemModelAttrSupportFixed))==EMemModelAttrSameVA;
|
|
57 |
TInt i;
|
|
58 |
for (i=0; i<KNumModules; ++i)
|
|
59 |
{
|
|
60 |
TUint32 f=GetModuleFlags(i);
|
|
61 |
if (f&KModuleFlagExe)
|
|
62 |
{
|
|
63 |
++iNumExes;
|
|
64 |
if (!proc_sym && (f&KModuleFlagFixed))
|
|
65 |
++iFixedExes;
|
|
66 |
}
|
|
67 |
}
|
|
68 |
iMaxModules=(1+iFixedExes)*(KNumModules-iNumExes)+iNumExes;
|
|
69 |
test.Printf(_L("iNumExes=%d iFixedExes=%d iMaxModules=%d\n"),iNumExes,iFixedExes,iMaxModules);
|
|
70 |
SModuleInstance* mi=(SModuleInstance*)User::Alloc(iMaxModules*sizeof(SModuleInstance));
|
|
71 |
test(mi!=NULL);
|
|
72 |
iFreeModules=mi;
|
|
73 |
iModuleAlloc=mi;
|
|
74 |
SModuleInstance* miE=mi+iMaxModules;
|
|
75 |
for (; mi<miE; ++mi)
|
|
76 |
{
|
|
77 |
SModuleInstance* miN=mi+1;
|
|
78 |
mi->iCodeSeg=(miN<miE)?miN:NULL;
|
|
79 |
}
|
|
80 |
for (i=0; i<KNumModules; ++i)
|
|
81 |
{
|
|
82 |
TUint32 f=GetModuleFlags(i);
|
|
83 |
if (f&KModuleFlagExe)
|
|
84 |
{
|
|
85 |
CPerProcessInfo* p=CPerProcessInfo::New(i,*this);
|
|
86 |
iPPInfo[i]=p;
|
|
87 |
}
|
|
88 |
}
|
|
89 |
}
|
|
90 |
|
|
91 |
CGlobalModuleList* CGlobalModuleList::New(const LoaderTest& a)
|
|
92 |
{
|
|
93 |
CGlobalModuleList* p=new CGlobalModuleList;
|
|
94 |
test(p!=NULL);
|
|
95 |
test.Printf(_L("CGlobalModuleList at %08x\n"),p);
|
|
96 |
p->iDev=a.iDev;
|
|
97 |
p->iMemModelAtt=a.iMemModelAtt;
|
|
98 |
p->Init();
|
|
99 |
return p;
|
|
100 |
}
|
|
101 |
|
|
102 |
void CGlobalModuleList::Free(SModuleInstance* a)
|
|
103 |
{
|
|
104 |
a->iCodeSeg=iFreeModules;
|
|
105 |
iFreeModules=a;
|
|
106 |
}
|
|
107 |
|
|
108 |
SModuleInstance* CGlobalModuleList::GetMI()
|
|
109 |
{
|
|
110 |
SModuleInstance* p=iFreeModules;
|
|
111 |
test(p!=NULL);
|
|
112 |
iFreeModules=(SModuleInstance*)p->iCodeSeg;
|
|
113 |
return p;
|
|
114 |
}
|
|
115 |
|
|
116 |
TAny* CGlobalModuleList::CodeSegFromHandle(TModuleHandle aModHandle)
|
|
117 |
{
|
|
118 |
return iDev.ModuleCodeSeg(aModHandle);
|
|
119 |
}
|
|
120 |
|
|
121 |
void CGlobalModuleList::Close(SModuleInstance* a)
|
|
122 |
{
|
|
123 |
test.Printf(_L("Module %d@%08x Close(%d)\n"),a->iModNum,a->iCodeSeg,a->iAccessCount);
|
|
124 |
if (!--a->iAccessCount)
|
|
125 |
{
|
|
126 |
TCodeSegCreateInfo codeSeg;
|
|
127 |
TInt r=iDev.GetCodeSegInfo(a->iCodeSeg, codeSeg);
|
|
128 |
test(r==KErrArgument);
|
|
129 |
r=iModules.FindInOrder(a, Order);
|
|
130 |
test(r>=0);
|
|
131 |
iModules.Remove(r);
|
|
132 |
Free(a);
|
|
133 |
}
|
|
134 |
}
|
|
135 |
|
|
136 |
|
|
137 |
void CGlobalModuleList::CheckAll()
|
|
138 |
{
|
|
139 |
TInt i;
|
|
140 |
for (i=0; i<KNumModules; ++i)
|
|
141 |
{
|
|
142 |
if (iPPInfo[i])
|
|
143 |
iPPInfo[i]->Check();
|
|
144 |
}
|
|
145 |
}
|
|
146 |
|
|
147 |
TInt CGlobalModuleList::Load(TInt aExeNum, TInt aDllNum)
|
|
148 |
{
|
|
149 |
return iPPInfo[aExeNum]->Load(aDllNum);
|
|
150 |
}
|
|
151 |
|
|
152 |
TInt CGlobalModuleList::CloseHandle(TInt aExeNum, TInt aDllNum)
|
|
153 |
{
|
|
154 |
CPerProcessInfo* p=iPPInfo[aExeNum];
|
|
155 |
TInt i;
|
|
156 |
for (i=0; i<KMaxHandles && p->iModuleNum[i]!=aDllNum; ++i) {}
|
|
157 |
if (i==KMaxHandles)
|
|
158 |
return KErrNotFound;
|
|
159 |
return p->CloseHandle(i);
|
|
160 |
}
|
|
161 |
|
|
162 |
CPerProcessInfo::CPerProcessInfo()
|
|
163 |
{
|
|
164 |
Mem::Fill(iModuleNum, sizeof(iModuleNum), 0xff);
|
|
165 |
}
|
|
166 |
|
|
167 |
CPerProcessInfo::~CPerProcessInfo()
|
|
168 |
{
|
|
169 |
if (iSession.Handle())
|
|
170 |
{
|
|
171 |
iSession.Exit();
|
|
172 |
iSession.Close();
|
|
173 |
User::WaitForRequest(iStatus);
|
|
174 |
test(iProcess.ExitType()==EExitKill);
|
|
175 |
test(iProcess.ExitReason()==KErrNone);
|
|
176 |
}
|
|
177 |
iProcess.Close();
|
|
178 |
}
|
|
179 |
|
|
180 |
CPerProcessInfo* CPerProcessInfo::New(TInt aExeNum, CGlobalModuleList& aG)
|
|
181 |
{
|
|
182 |
CPerProcessInfo* p=new CPerProcessInfo;
|
|
183 |
test(p!=NULL);
|
|
184 |
test.Printf(_L("CPerProcessInfo for %d at %08x\n"),aExeNum,p);
|
|
185 |
p->iExeNum=aExeNum;
|
|
186 |
p->iDev=aG.iDev;
|
|
187 |
p->iGlobalList=&aG;
|
|
188 |
TInt r = p->Init();
|
|
189 |
if (r==KErrNone)
|
|
190 |
return p;
|
|
191 |
delete p;
|
|
192 |
return NULL;
|
|
193 |
}
|
|
194 |
|
|
195 |
TInt CPerProcessInfo::Init()
|
|
196 |
{
|
|
197 |
TUint32 tt;
|
|
198 |
TInt r=LoadExe(iExeNum, 0, iProcess, tt);
|
|
199 |
test.Printf(_L("LoadExe(%d)->%d\n"),iExeNum,r);
|
|
200 |
#ifdef __EPOC32__
|
|
201 |
test(r==KErrNone);
|
|
202 |
test.Printf(_L("BENCHMARK: LoadExe(%d)->%dms\n"),iExeNum,tt);
|
|
203 |
#else
|
|
204 |
test(r==KErrNone || r==KErrNotSupported);
|
|
205 |
if (r!=KErrNone)
|
|
206 |
return r;
|
|
207 |
#endif
|
|
208 |
iProcess.Logon(iStatus);
|
|
209 |
test(iStatus==KRequestPending);
|
|
210 |
r=iSession.Connect(iExeNum);
|
|
211 |
test.Printf(_L("Connect(%d)->%d\n"),iExeNum,r);
|
|
212 |
test(r==KErrNone);
|
|
213 |
TModuleList exe_info;
|
|
214 |
r=iSession.GetExeDepList(exe_info.iInfo);
|
|
215 |
exe_info.SetCount();
|
|
216 |
test.Printf(_L("GetExeDepList(%d)->%d count %d\n"),iExeNum,r,exe_info.iCount);
|
|
217 |
test(r==KErrNone);
|
|
218 |
r=AddModules(iExeNum, NULL, &exe_info);
|
|
219 |
test.Printf(_L("AddModules->%d\n"),r);
|
|
220 |
test(r==KErrNone);
|
|
221 |
return KErrNone;
|
|
222 |
}
|
|
223 |
|
|
224 |
void CPerProcessInfo::GetModuleSet(TModuleSet& aSet)
|
|
225 |
{
|
|
226 |
TInt m;
|
|
227 |
for (m=0; m<KNumModules; ++m)
|
|
228 |
{
|
|
229 |
if (iHandleCount[m]==0 && m!=iExeNum)
|
|
230 |
continue;
|
|
231 |
aSet.Add(m);
|
|
232 |
const TInt* deps=ModuleDependencies[m];
|
|
233 |
TInt ndeps=*deps++;
|
|
234 |
TInt i;
|
|
235 |
for (i=0; i<ndeps; ++i)
|
|
236 |
{
|
|
237 |
TInt dm=*deps++;
|
|
238 |
#ifndef __EPOC32__
|
|
239 |
// Emulator doesn't register subtrees without data
|
|
240 |
TInt f = GetModuleFlags(dm);
|
|
241 |
if (f & KModuleFlagDataInTree)
|
|
242 |
#endif
|
|
243 |
aSet.Add(dm);
|
|
244 |
}
|
|
245 |
}
|
|
246 |
}
|
|
247 |
|
|
248 |
void CPerProcessInfo::Check()
|
|
249 |
{
|
|
250 |
test.Printf(_L("%d:Check\n"),iExeNum);
|
|
251 |
TBool code_prot=iGlobalList->iMemModelAtt&EMemModelAttrRamCodeProt;
|
|
252 |
TBool data_prot=iGlobalList->iMemModelAtt&EMemModelAttrProcessProt;
|
|
253 |
TInt mmtype=iGlobalList->iMemModelAtt&EMemModelTypeMask;
|
|
254 |
TModuleSet set;
|
|
255 |
GetModuleSet(set);
|
|
256 |
TInt m;
|
|
257 |
for (m=0; m<KNumModules; ++m)
|
|
258 |
{
|
|
259 |
TUint32 f=GetModuleFlags(m);
|
|
260 |
if (set.Present(m))
|
|
261 |
{
|
|
262 |
test.Printf(_L("%d "),m);
|
|
263 |
SModuleInstance* pM=iModules[m];
|
|
264 |
test(pM!=NULL);
|
|
265 |
test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrNone);
|
|
266 |
if (f&KModuleFlagData)
|
|
267 |
test(iSession.CheckReadable(pM->iData)==KErrNone);
|
|
268 |
}
|
|
269 |
else
|
|
270 |
{
|
|
271 |
SModuleInstance* pM=iModules[m];
|
|
272 |
test(pM==NULL);
|
|
273 |
}
|
|
274 |
}
|
|
275 |
TInt ix;
|
|
276 |
TInt c=iGlobalList->iModules.Count();
|
|
277 |
test.Printf(_L("\n%d:CheckNP\n"),iExeNum);
|
|
278 |
for (ix=0; ix<c; ++ix)
|
|
279 |
{
|
|
280 |
const SModuleInstance* pM=iGlobalList->iModules[ix];
|
|
281 |
if (set.Present(pM->iModNum))
|
|
282 |
continue;
|
|
283 |
test.Printf(_L("%d "),pM->iModNum);
|
|
284 |
TUint32 f=GetModuleFlags(pM->iModNum);
|
|
285 |
if (!(f&KModuleFlagXIP) && code_prot)
|
|
286 |
{
|
|
287 |
if(mmtype==EMemModelTypeFlexible && (f&KModuleFlagExe))
|
|
288 |
{
|
|
289 |
// don't test EXEs on FlexibleMM because they don't live at unique addresses
|
|
290 |
}
|
|
291 |
else
|
|
292 |
{
|
|
293 |
// check code not loaded into this porcess....
|
|
294 |
test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrGeneral);
|
|
295 |
}
|
|
296 |
}
|
|
297 |
TBool check_data=(f&(KModuleFlagData|KModuleFlagExe))==(TUint32)KModuleFlagData;
|
|
298 |
if (check_data && mmtype==EMemModelTypeMoving)
|
|
299 |
{
|
|
300 |
if (f&KModuleFlagXIP)
|
|
301 |
{
|
|
302 |
const TInt* exeinfo=ModuleExeInfo[pM->iModNum];
|
|
303 |
TInt attp=exeinfo[0];
|
|
304 |
if (attp>=0 && (GetModuleFlags(attp)&KModuleFlagFixed))
|
|
305 |
check_data=EFalse;
|
|
306 |
}
|
|
307 |
}
|
|
308 |
if (check_data && data_prot)
|
|
309 |
test(iSession.CheckReadable(pM->iData)==KErrGeneral);
|
|
310 |
}
|
|
311 |
TInt h;
|
|
312 |
for (h=0; h<KMaxHandles; ++h)
|
|
313 |
{
|
|
314 |
m=iModuleNum[h];
|
|
315 |
if (m<0)
|
|
316 |
continue;
|
|
317 |
test(set.Present(m));
|
|
318 |
TInt y=++iGlobalList->iParam;
|
|
319 |
TInt r=iSession.CallRBlkI(h,y);
|
|
320 |
r-=y;
|
|
321 |
r/=INC_BLOCK_SZ;
|
|
322 |
test.Printf(_L("DLL %d RBlkI->%d\n"),m,r);
|
|
323 |
y=ModuleRBlkIParams[m][1]+ModuleRBlkIParams[m][0]*DLLNUMOFFSET;
|
|
324 |
test(r==y);
|
|
325 |
}
|
|
326 |
}
|
|
327 |
|
|
328 |
void CPerProcessInfo::Unlink(const SDllInfo& a, TModuleList& aList)
|
|
329 |
{
|
|
330 |
test.Printf(_L("%d:Unlink %d %08x\n"),iExeNum,a.iDllNum,a.iModuleHandle);
|
|
331 |
test(iHandleCount[a.iDllNum]==0);
|
|
332 |
TBool code_prot=iGlobalList->iMemModelAtt&EMemModelAttrRamCodeProt;
|
|
333 |
TBool data_prot=iGlobalList->iMemModelAtt&EMemModelAttrProcessProt;
|
|
334 |
TInt mmtype=iGlobalList->iMemModelAtt&EMemModelTypeMask;
|
|
335 |
TModuleSet set;
|
|
336 |
GetModuleSet(set);
|
|
337 |
set.Display(_L("set: "));
|
|
338 |
TInt m;
|
|
339 |
for (m=0; m<KNumModules; ++m)
|
|
340 |
{
|
|
341 |
if (set.Present(m))
|
|
342 |
continue;
|
|
343 |
SModuleInstance* pM=iModules[m];
|
|
344 |
if (!pM)
|
|
345 |
continue;
|
|
346 |
iModules[m]=NULL;
|
|
347 |
TUint32 f=GetModuleFlags(m);
|
|
348 |
SDllInfo info;
|
|
349 |
info.iDllNum=m;
|
|
350 |
info.iEntryPointAddress=pM->iEntryPointAddress;
|
|
351 |
info.iModuleHandle=pM->iModuleHandle;
|
|
352 |
aList.Add(info);
|
|
353 |
test(pM->iModNum==m);
|
|
354 |
if (!(f&KModuleFlagXIP) && code_prot)
|
|
355 |
test(iSession.CheckReadable(pM->iEntryPointAddress)==KErrGeneral);
|
|
356 |
TBool check_data=f&KModuleFlagData;
|
|
357 |
if (check_data && mmtype==EMemModelTypeMoving)
|
|
358 |
{
|
|
359 |
if (f&KModuleFlagXIP)
|
|
360 |
{
|
|
361 |
const TInt* exeinfo=ModuleExeInfo[pM->iModNum];
|
|
362 |
TInt attp=exeinfo[0];
|
|
363 |
if (attp>=0 && (GetModuleFlags(attp)&KModuleFlagFixed))
|
|
364 |
check_data=EFalse;
|
|
365 |
}
|
|
366 |
}
|
|
367 |
if (check_data && data_prot)
|
|
368 |
test(iSession.CheckReadable(pM->iData)==KErrGeneral);
|
|
369 |
iGlobalList->Close(pM);
|
|
370 |
}
|
|
371 |
}
|
|
372 |
|
|
373 |
TInt CPerProcessInfo::CloseHandle(TInt aHandle)
|
|
374 |
{
|
|
375 |
TInt m=iModuleNum[aHandle];
|
|
376 |
test(m>=0);
|
|
377 |
iModuleNum[aHandle]=-1;
|
|
378 |
SModuleInstance* pM=iModules[m];
|
|
379 |
test(pM!=NULL);
|
|
380 |
SDllInfo dll_info;
|
|
381 |
dll_info.iDllNum=m;
|
|
382 |
dll_info.iEntryPointAddress=pM->iEntryPointAddress;
|
|
383 |
dll_info.iModuleHandle=pM->iModuleHandle;
|
|
384 |
TModuleList d_list;
|
|
385 |
TInt r=iSession.CloseDll(aHandle);
|
|
386 |
test(r==KErrNone);
|
|
387 |
r=iSession.GetCDList(d_list.iInfo);
|
|
388 |
test(r==KErrNone);
|
|
389 |
d_list.SetCount();
|
|
390 |
if (--iHandleCount[m])
|
|
391 |
{
|
|
392 |
test(d_list.iCount==0);
|
|
393 |
return KErrNone;
|
|
394 |
}
|
|
395 |
TModuleList xd_list;
|
|
396 |
if (!AlwaysLoaded(m))
|
|
397 |
Unlink(dll_info, xd_list);
|
|
398 |
TInt i;
|
|
399 |
TInt dcount=0;
|
|
400 |
for (i=0; i<xd_list.iCount; ++i)
|
|
401 |
{
|
|
402 |
TInt mn=xd_list.iInfo[i].iDllNum;
|
|
403 |
TUint32 f=GetModuleFlags(mn);
|
|
404 |
if (f&KModuleFlagData)
|
|
405 |
{
|
|
406 |
++dcount;
|
|
407 |
test(d_list.IsPresent(mn));
|
|
408 |
}
|
|
409 |
}
|
|
410 |
d_list.Display(_L("d_list: "));
|
|
411 |
xd_list.Display(_L("xd_list: "));
|
|
412 |
test(dcount==d_list.iCount);
|
|
413 |
return KErrNone;
|
|
414 |
}
|
|
415 |
|
|
416 |
TInt CPerProcessInfo::Load(TInt aDllNum)
|
|
417 |
{
|
|
418 |
TModuleList init_list;
|
|
419 |
TModuleList c_list;
|
|
420 |
TInt h=iSession.LoadDll(aDllNum, init_list.iInfo);
|
|
421 |
init_list.SetCount();
|
|
422 |
test.Printf(_L("%d:Load(%d)->%d Icount %d\n"),iExeNum,aDllNum,h,init_list.iCount);
|
|
423 |
if (h<0)
|
|
424 |
{
|
|
425 |
return h;
|
|
426 |
}
|
|
427 |
test(iSession.GetCDList(c_list.iInfo)==KErrNone);
|
|
428 |
c_list.SetCount();
|
|
429 |
iModuleNum[h]=aDllNum;
|
|
430 |
return AddModules(aDllNum, &c_list, &init_list);
|
|
431 |
}
|
|
432 |
|
|
433 |
TInt CPerProcessInfo::AddModules(TInt aDllNum, TModuleList* aCList, TModuleList* aIList)
|
|
434 |
{
|
|
435 |
TInt r=0;
|
|
436 |
if (++iHandleCount[aDllNum]>1)
|
|
437 |
{
|
|
438 |
if (aCList)
|
|
439 |
test(aCList->iCount==0);
|
|
440 |
return KErrNone;
|
|
441 |
}
|
|
442 |
TModuleSet set;
|
|
443 |
if (!iModules[aDllNum] && !AlwaysLoaded(aDllNum))
|
|
444 |
set.Add(aDllNum);
|
|
445 |
const TInt* deps=ModuleDependencies[aDllNum];
|
|
446 |
TInt ndeps=*deps++;
|
|
447 |
TInt i;
|
|
448 |
TInt ccount=0;
|
|
449 |
for (i=0; i<ndeps; ++i)
|
|
450 |
{
|
|
451 |
TInt dm=*deps++;
|
|
452 |
if (!iModules[dm] && !AlwaysLoaded(dm))
|
|
453 |
{
|
|
454 |
set.Add(dm);
|
|
455 |
if (GetModuleFlags(dm)&KModuleFlagData)
|
|
456 |
++ccount;
|
|
457 |
}
|
|
458 |
}
|
|
459 |
if (aCList)
|
|
460 |
test(ccount==aCList->iCount);
|
|
461 |
for (i=0; i<KNumModules; ++i)
|
|
462 |
{
|
|
463 |
if (!set.Present(i))
|
|
464 |
continue;
|
|
465 |
SModuleInstance mi;
|
|
466 |
mi.iAccessCount=1;
|
|
467 |
mi.iModNum=i;
|
|
468 |
if (GetModuleFlags(i)&KModuleFlagData)
|
|
469 |
{
|
|
470 |
if (aCList)
|
|
471 |
test(aCList->Find(i)>=0);
|
|
472 |
}
|
|
473 |
TInt j=aIList->Find(i);
|
|
474 |
test(j>=0);
|
|
475 |
mi.iEntryPointAddress=aIList->iInfo[j].iEntryPointAddress;
|
|
476 |
mi.iModuleHandle=aIList->iInfo[j].iModuleHandle;
|
|
477 |
mi.iCodeSeg=iGlobalList->CodeSegFromHandle(mi.iModuleHandle);
|
|
478 |
test(mi.iCodeSeg!=NULL);
|
|
479 |
if (GetModuleFlags(i)&KModuleFlagData)
|
|
480 |
{
|
|
481 |
TCodeSegCreateInfo cs_info;
|
|
482 |
r=iDev.GetCodeSegInfo(mi.iCodeSeg, cs_info);
|
|
483 |
test(r==KErrNone);
|
|
484 |
mi.iData=cs_info.iDataRunAddress;
|
|
485 |
}
|
|
486 |
else
|
|
487 |
{
|
|
488 |
mi.iData=0;
|
|
489 |
}
|
|
490 |
|
|
491 |
r=iGlobalList->iModules.FindInOrder(&mi, Order);
|
|
492 |
if (r>=0)
|
|
493 |
{
|
|
494 |
test.Printf(_L("Module %d@%08x already exists\n"),mi.iModNum,mi.iCodeSeg);
|
|
495 |
SModuleInstance& mi0=*iGlobalList->iModules[r];
|
|
496 |
++mi0.iAccessCount;
|
|
497 |
test(mi.iEntryPointAddress==mi0.iEntryPointAddress);
|
|
498 |
test(mi.iModuleHandle==mi0.iModuleHandle);
|
|
499 |
test(mi.iData==mi0.iData);
|
|
500 |
test(mi.iModNum==mi0.iModNum);
|
|
501 |
iModules[i]=&mi0;
|
|
502 |
}
|
|
503 |
else
|
|
504 |
{
|
|
505 |
test.Printf(_L("Module %d@%08x new\n"),mi.iModNum,mi.iCodeSeg);
|
|
506 |
SModuleInstance* pM=iGlobalList->GetMI();
|
|
507 |
test(pM!=NULL);
|
|
508 |
*pM=mi;
|
|
509 |
iModules[i]=pM;
|
|
510 |
r=iGlobalList->iModules.InsertInOrder(pM, Order);
|
|
511 |
test(r==KErrNone);
|
|
512 |
}
|
|
513 |
}
|
|
514 |
return KErrNone;
|
|
515 |
}
|
|
516 |
|
|
517 |
void LoaderTest::TestMultipleLoads()
|
|
518 |
{
|
|
519 |
CGlobalModuleList* p=CGlobalModuleList::New(*this);
|
|
520 |
p->CheckAll();
|
|
521 |
|
|
522 |
#ifdef __WINS__
|
|
523 |
const TInt* multiLoad[] = {TC_MultLoad,0};
|
|
524 |
#else
|
|
525 |
const TInt* multiLoad[] = {TC_MultLoad,TC_MultLoadTargetOnly,0};
|
|
526 |
#endif
|
|
527 |
const TInt** multiLoadLists = multiLoad;
|
|
528 |
const TInt* tests;
|
|
529 |
while((tests=*multiLoadLists++)!=0)
|
|
530 |
{
|
|
531 |
TInt ntests=*tests++;
|
|
532 |
while(ntests>=4)
|
|
533 |
{
|
|
534 |
ntests-=4;
|
|
535 |
TInt exe1=*tests++;
|
|
536 |
TInt dll1=*tests++;
|
|
537 |
TInt exe2=*tests++;
|
|
538 |
TInt dll2=*tests++;
|
|
539 |
TUint32 xf1=GetModuleFlags(exe1);
|
|
540 |
TUint32 xf2=GetModuleFlags(exe2);
|
|
541 |
if (xf1&KModuleFlagExe)
|
|
542 |
{
|
|
543 |
TInt r=p->Load(exe1, dll1);
|
|
544 |
test.Printf(_L("%d:Load %d->%d"),exe1,dll1,r);
|
|
545 |
p->CheckAll();
|
|
546 |
}
|
|
547 |
if (xf2&KModuleFlagExe)
|
|
548 |
{
|
|
549 |
TInt r=p->CloseHandle(exe2, dll2);
|
|
550 |
test.Printf(_L("%d:Close %d->%d"),exe2,dll2,r);
|
|
551 |
p->CheckAll();
|
|
552 |
}
|
|
553 |
}
|
|
554 |
}
|
|
555 |
|
|
556 |
delete p;
|
|
557 |
}
|
|
558 |
|