|
1 // Copyright (c) 1998-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\d_ldrtst.cpp |
|
15 // LDD for testing loader |
|
16 // |
|
17 // |
|
18 |
|
19 #include <kernel/kern_priv.h> |
|
20 #include "d_ldrtst.h" |
|
21 |
|
22 const TInt KMajorVersionNumber=0; |
|
23 const TInt KMinorVersionNumber=1; |
|
24 const TInt KBuildVersionNumber=1; |
|
25 |
|
26 class DLdrTest; |
|
27 class DLdrTestFactory : public DLogicalDevice |
|
28 // |
|
29 // Test LDD factory |
|
30 // |
|
31 { |
|
32 public: |
|
33 DLdrTestFactory(); |
|
34 virtual TInt Install(); |
|
35 virtual void GetCaps(TDes8& aDes) const; |
|
36 virtual TInt Create(DLogicalChannelBase*& aChannel); |
|
37 }; |
|
38 |
|
39 class DLdrTest : public DLogicalChannelBase |
|
40 // |
|
41 // Test logical channel |
|
42 // |
|
43 { |
|
44 public: |
|
45 virtual ~DLdrTest(); |
|
46 protected: |
|
47 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
48 virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2); |
|
49 public: |
|
50 TInt GetCodeSegInfo(TAny* aHandle, TAny* aDest); |
|
51 TAny* ModuleCodeSeg(TModuleHandle aModuleHandle); |
|
52 TAny* ProcessCodeSeg(TInt aProcessHandle); |
|
53 TAny* LibraryCodeSeg(TInt aLibraryHandle); |
|
54 TInt GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax); |
|
55 TAny* CodeSegFromAddr(TLinAddr aAddr); |
|
56 TModuleHandle ModuleHandleFromAddr(TLinAddr aAddr); |
|
57 TInt ProcessSMPUnsafeCount(TInt aProcessHandle); |
|
58 private: |
|
59 SDblQueLink* FindCodeSegQueueAnchor(); |
|
60 }; |
|
61 |
|
62 DECLARE_STANDARD_LDD() |
|
63 { |
|
64 return new DLdrTestFactory; |
|
65 } |
|
66 |
|
67 DLdrTestFactory::DLdrTestFactory() |
|
68 // |
|
69 // Constructor |
|
70 // |
|
71 { |
|
72 iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
73 } |
|
74 |
|
75 TInt DLdrTestFactory::Create(DLogicalChannelBase*& aChannel) |
|
76 // |
|
77 // Create a new DLdrTest on this logical device |
|
78 // |
|
79 { |
|
80 aChannel=new DLdrTest; |
|
81 return aChannel?KErrNone:KErrNoMemory; |
|
82 } |
|
83 |
|
84 TInt DLdrTestFactory::Install() |
|
85 // |
|
86 // Install the LDD - overriding pure virtual |
|
87 // |
|
88 { |
|
89 return SetName(&KLdrTestLddName); |
|
90 } |
|
91 |
|
92 void DLdrTestFactory::GetCaps(TDes8& aDes) const |
|
93 // |
|
94 // Get capabilities - overriding pure virtual |
|
95 // |
|
96 { |
|
97 TCapsTestV01 b; |
|
98 b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
99 Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b)); |
|
100 } |
|
101 |
|
102 TInt DLdrTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) |
|
103 // |
|
104 // Create channel |
|
105 // |
|
106 { |
|
107 |
|
108 if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) |
|
109 return KErrNotSupported; |
|
110 return KErrNone; |
|
111 } |
|
112 |
|
113 DLdrTest::~DLdrTest() |
|
114 // |
|
115 // Destructor |
|
116 // |
|
117 { |
|
118 } |
|
119 |
|
120 TInt DLdrTest::GetCodeSegInfo(TAny* aHandle, TAny* aDest) |
|
121 { |
|
122 TCodeSegCreateInfo info; |
|
123 DCodeSeg* pS=DCodeSeg::VerifyHandle(aHandle); |
|
124 if (pS) |
|
125 { |
|
126 Kern::AccessCode(); |
|
127 pS->Info(info); |
|
128 Kern::EndAccessCode(); |
|
129 kumemput32(aDest, &info, sizeof(info)); |
|
130 return KErrNone; |
|
131 } |
|
132 return KErrArgument; |
|
133 } |
|
134 |
|
135 TAny* DLdrTest::ModuleCodeSeg(TModuleHandle aModuleHandle) |
|
136 { |
|
137 DCodeSeg* pS=DCodeSeg::VerifyHandle(aModuleHandle); |
|
138 if(!pS) |
|
139 { |
|
140 Kern::AccessCode(); |
|
141 DCodeSeg::CodeSegFromEntryPoint((TLinAddr)aModuleHandle); // ignore returned DCodeSeg* |
|
142 Kern::EndAccessCode(); |
|
143 } |
|
144 return pS; |
|
145 } |
|
146 |
|
147 TAny* DLdrTest::CodeSegFromAddr(TLinAddr aAddr) |
|
148 { |
|
149 Kern::AccessCode(); |
|
150 DCodeSeg* s = Kern::CodeSegFromAddress(aAddr, Kern::CurrentThread().iOwningProcess); |
|
151 Kern::EndAccessCode(); |
|
152 return s; |
|
153 } |
|
154 |
|
155 TModuleHandle DLdrTest::ModuleHandleFromAddr(TLinAddr aAddr) |
|
156 { |
|
157 TModuleHandle h = (TModuleHandle)CodeSegFromAddr(aAddr); |
|
158 if(!h) |
|
159 h = (TModuleHandle)aAddr; |
|
160 return h; |
|
161 } |
|
162 |
|
163 TAny* DLdrTest::ProcessCodeSeg(TInt aProcessHandle) |
|
164 { |
|
165 DCodeSeg* pS=NULL; |
|
166 DThread& t=Kern::CurrentThread(); |
|
167 NKern::LockSystem(); |
|
168 DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess); |
|
169 if (pP) |
|
170 { |
|
171 pS=pP->iCodeSeg; |
|
172 if (!pS) |
|
173 pS=pP->iTempCodeSeg; |
|
174 } |
|
175 NKern::UnlockSystem(); |
|
176 return pS; |
|
177 } |
|
178 |
|
179 TAny* DLdrTest::LibraryCodeSeg(TInt aLibraryHandle) |
|
180 { |
|
181 DCodeSeg* pS=NULL; |
|
182 DThread& t=Kern::CurrentThread(); |
|
183 NKern::LockSystem(); |
|
184 DLibrary* pL=(DLibrary*)t.ObjectFromHandle(aLibraryHandle, ELibrary); |
|
185 if (pL) |
|
186 pS=pL->iCodeSeg; |
|
187 NKern::UnlockSystem(); |
|
188 return pS; |
|
189 } |
|
190 |
|
191 SDblQueLink* DLdrTest::FindCodeSegQueueAnchor() |
|
192 { |
|
193 SDblQueLink* p=&iDevice->iCodeSeg->iLink; // this device driver's code segment |
|
194 for (;;) |
|
195 { |
|
196 p=p->iPrev; |
|
197 DCodeSeg* s=_LOFF(p, DCodeSeg, iLink); |
|
198 if (s->iExeCodeSeg==s && (s->iAttr & ECodeSegAttKernel)) |
|
199 { |
|
200 // s is the kernel's code segment, which is the first one to be created |
|
201 return s->iLink.iPrev; |
|
202 } |
|
203 } |
|
204 } |
|
205 |
|
206 TInt DLdrTest::GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax) |
|
207 { |
|
208 if (aMax<=0) |
|
209 return KErrArgument; |
|
210 RLdrTest::SEntry list[128]; |
|
211 Kern::AccessCode(); |
|
212 SDblQueLink* anchor=FindCodeSegQueueAnchor(); |
|
213 SDblQueLink* p=anchor->iNext; |
|
214 if (aMax>128) |
|
215 aMax=128; |
|
216 TInt n=0; |
|
217 for(; p!=anchor && n<aMax; p=p->iNext, ++n) |
|
218 { |
|
219 DCodeSeg* s=_LOFF(p, DCodeSeg, iLink); |
|
220 list[n].iHandle=s; |
|
221 list[n].iUid3=(TUint32)s->iUids.iUid[2].iUid; |
|
222 } |
|
223 Kern::EndAccessCode(); |
|
224 if (n>0) |
|
225 kumemput32(aList, list, n*sizeof(RLdrTest::SEntry)); |
|
226 return n; |
|
227 } |
|
228 |
|
229 TInt DLdrTest::ProcessSMPUnsafeCount(TInt aProcessHandle) |
|
230 { |
|
231 TInt count=KErrNotFound; |
|
232 DThread& t=Kern::CurrentThread(); |
|
233 NKern::LockSystem(); |
|
234 DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess); |
|
235 if (pP) |
|
236 count=pP->iSMPUnsafeCount; |
|
237 NKern::UnlockSystem(); |
|
238 return count; |
|
239 } |
|
240 |
|
241 TInt DLdrTest::Request(TInt aFunction, TAny* a1, TAny* a2) |
|
242 { |
|
243 TInt r=KErrNone; |
|
244 switch (aFunction) |
|
245 { |
|
246 case RLdrTest::EControlGetCodeSegInfo: |
|
247 r=GetCodeSegInfo(a1,a2); |
|
248 break; |
|
249 case RLdrTest::EControlProcessCodeSeg: |
|
250 r=(TInt)ProcessCodeSeg((TInt)a1); |
|
251 break; |
|
252 case RLdrTest::EControlLibraryCodeSeg: |
|
253 r=(TInt)LibraryCodeSeg((TInt)a1); |
|
254 break; |
|
255 case RLdrTest::EControlModuleCodeSeg: |
|
256 r=(TInt)ModuleCodeSeg((TModuleHandle)a1); |
|
257 break; |
|
258 case RLdrTest::EControlGetCodeSegList: |
|
259 r=GetCodeSegList( (RLdrTest::SEntry*)a1, (TInt)a2 ); |
|
260 break; |
|
261 case RLdrTest::EControlCodeSegFromAddr: |
|
262 r=(TInt)CodeSegFromAddr((TLinAddr)a1); |
|
263 break; |
|
264 case RLdrTest::EControlModuleHandleFromAddr: |
|
265 r=(TInt)ModuleHandleFromAddr((TLinAddr)a1); |
|
266 break; |
|
267 case RLdrTest::EControlProcessSMPUnsafeCount: |
|
268 r=ProcessSMPUnsafeCount((TInt)a1); |
|
269 break; |
|
270 default: |
|
271 r=KErrNotSupported; |
|
272 break; |
|
273 } |
|
274 return r; |
|
275 } |
|
276 |