|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "MemSpyDriverLogChanCodeSegs.h" |
|
19 |
|
20 // System includes |
|
21 #include <plat_priv.h> |
|
22 #include <memspy/driver/memspydriverobjectsshared.h> |
|
23 |
|
24 // Shared includes |
|
25 #include "MemSpyDriverOpCodes.h" |
|
26 #include "MemSpyDriverObjectsInternal.h" |
|
27 |
|
28 // User includes |
|
29 #include "MemSpyDriverUtils.h" |
|
30 #include "MemSpyDriverOSAdaption.h" |
|
31 |
|
32 |
|
33 |
|
34 DMemSpyDriverLogChanCodeSegs::DMemSpyDriverLogChanCodeSegs( DMemSpyDriverDevice& aDevice, DThread& aThread ) |
|
35 : DMemSpyDriverLogChanBase( aDevice, aThread ) |
|
36 { |
|
37 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::DMemSpyDriverLogChanCodeSegs() - this: 0x%08x", this )); |
|
38 } |
|
39 |
|
40 |
|
41 DMemSpyDriverLogChanCodeSegs::~DMemSpyDriverLogChanCodeSegs() |
|
42 { |
|
43 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::~DMemSpyDriverLogChanCodeSegs() - START - this: 0x%08x", this )); |
|
44 |
|
45 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::~DMemSpyDriverLogChanCodeSegs() - END - this: 0x%08x", this )); |
|
46 } |
|
47 |
|
48 |
|
49 |
|
50 TInt DMemSpyDriverLogChanCodeSegs::Request( TInt aFunction, TAny* a1, TAny* a2 ) |
|
51 { |
|
52 TInt r = DMemSpyDriverLogChanBase::Request( aFunction, a1, a2 ); |
|
53 if ( r == KErrNone ) |
|
54 { |
|
55 switch( aFunction ) |
|
56 { |
|
57 case EMemSpyDriverOpCodeCodeSegsGetAll: |
|
58 r = GetCodeSegs( (TMemSpyDriverInternalCodeSnapshotParams*) a1 ); |
|
59 break; |
|
60 case EMemSpyDriverOpCodeCodeSegsGetCodeSegsForProcess: |
|
61 r = GetCodeSegsForProcess( (TMemSpyDriverInternalCodeSnapshotParams*) a1 ); |
|
62 break; |
|
63 case EMemSpyDriverOpCodeCodeSegsGetCodeSegInfo: |
|
64 r = GetCodeSegInfo( (TMemSpyDriverInternalCodeSegParams*) a1 ); |
|
65 break; |
|
66 |
|
67 default: |
|
68 r = KErrNotSupported; |
|
69 break; |
|
70 } |
|
71 } |
|
72 // |
|
73 return r; |
|
74 } |
|
75 |
|
76 |
|
77 TBool DMemSpyDriverLogChanCodeSegs::IsHandler( TInt aFunction ) const |
|
78 { |
|
79 return ( aFunction > EMemSpyDriverOpCodeCodeSegsBase && aFunction < EMemSpyDriverOpCodeCodeSegsEnd ); |
|
80 } |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 TInt DMemSpyDriverLogChanCodeSegs::GetCodeSegs( TMemSpyDriverInternalCodeSnapshotParams* aParams ) |
|
98 { |
|
99 TMemSpyDriverInternalCodeSnapshotParams params; |
|
100 TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalCodeSnapshotParams) ); |
|
101 if ( r != KErrNone ) |
|
102 { |
|
103 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegsForProcess() - END - params read error: %d", r)); |
|
104 return r; |
|
105 } |
|
106 |
|
107 DMemSpyDriverOSAdaptionDCodeSeg& codeSegAdaption = OSAdaption().DCodeSeg(); |
|
108 |
|
109 const TInt maxCount = params.iMaxCount; |
|
110 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegsForProcess() - START - RAM-only: %d, maxCount: %d", params.iFilter, maxCount)); |
|
111 |
|
112 // This is the number of items we have written to the client |
|
113 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs() - START - maxCount: %d", maxCount)); |
|
114 TInt clientWriteCount = 0; |
|
115 |
|
116 // Need to get the code segs for each process. We'll let the client worry about filtering |
|
117 // duplicates. |
|
118 DObjectCon* container = Kern::Containers()[ EProcess ]; |
|
119 Kern::AccessCode(); |
|
120 container->Wait(); |
|
121 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 1")); |
|
122 // |
|
123 TFullName name; |
|
124 const TInt count = container->Count(); |
|
125 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 2, count: %d", count)); |
|
126 for(TInt i=0; i<count && r == KErrNone; i++) |
|
127 { |
|
128 DProcess* process = (DProcess*) (*container)[ i ]; |
|
129 process->Name( name ); |
|
130 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 3, proc: %O", process)); |
|
131 |
|
132 SDblQue queue; |
|
133 // |
|
134 const TInt clientSpaceRemaining = maxCount - clientWriteCount; |
|
135 const TInt numberOfCodeSegs = codeSegAdaption.GetCodeSegQueue( *process, queue ); |
|
136 const TInt numberOfCodeSegsToWriteToClient = Min( numberOfCodeSegs, clientSpaceRemaining ); |
|
137 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 4, clientSpaceRemaining: %d", clientSpaceRemaining)); |
|
138 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 5, numberOfCodeSegs: %d", numberOfCodeSegs)); |
|
139 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 6, numberOfCodeSegsToWriteToClient: %d", numberOfCodeSegsToWriteToClient)); |
|
140 // |
|
141 SDblQueLink* link = queue.iA.iNext; |
|
142 r = KErrNone; |
|
143 // |
|
144 for( TInt j=0; j<numberOfCodeSegsToWriteToClient && r == KErrNone; ++j, link = link->iNext ) |
|
145 { |
|
146 DCodeSeg* codeSegment = codeSegAdaption.GetCodeSeg( link ); |
|
147 |
|
148 // If the client only wants RAM-loaded codesegs, then ignore XIP. |
|
149 TBool writeEntryToClient = ETrue; |
|
150 if ( params.iFilter ) |
|
151 { |
|
152 const TBool isXIP = codeSegAdaption.GetIsXIP( *codeSegment ); |
|
153 writeEntryToClient = ( !isXIP ); |
|
154 } |
|
155 |
|
156 // Now write |
|
157 if ( writeEntryToClient ) |
|
158 { |
|
159 r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + clientWriteCount, &codeSegment, sizeof(TAny*) ); |
|
160 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 7, codeSegment: 0x%08x to client: %d", codeSegment, r)); |
|
161 if ( r == KErrNone ) |
|
162 { |
|
163 ++clientWriteCount; |
|
164 } |
|
165 } |
|
166 } |
|
167 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 8")); |
|
168 codeSegAdaption.EmptyCodeSegQueue( queue ); |
|
169 |
|
170 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 9")); |
|
171 } |
|
172 // |
|
173 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 10")); |
|
174 container->Signal(); |
|
175 Kern::EndAccessCode(); |
|
176 |
|
177 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs - 11 - r: %d", r)); |
|
178 if ( r == KErrBadDescriptor ) |
|
179 { |
|
180 MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); |
|
181 } |
|
182 else |
|
183 { |
|
184 const TInt finalWrite = Kern::ThreadRawWrite( &ClientThread(), params.iCountPtr, &clientWriteCount, sizeof(TInt) ); |
|
185 if ( r == KErrNone ) |
|
186 { |
|
187 r = finalWrite; |
|
188 } |
|
189 } |
|
190 |
|
191 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegs() - END - wrote %d handles to client, r: %d", clientWriteCount, r)); |
|
192 return r; |
|
193 } |
|
194 |
|
195 |
|
196 TInt DMemSpyDriverLogChanCodeSegs::GetCodeSegsForProcess( TMemSpyDriverInternalCodeSnapshotParams* aParams ) |
|
197 { |
|
198 TMemSpyDriverInternalCodeSnapshotParams params; |
|
199 TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalCodeSnapshotParams) ); |
|
200 if ( r != KErrNone ) |
|
201 { |
|
202 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegsForProcess() - END - params read error: %d", r)); |
|
203 return r; |
|
204 } |
|
205 |
|
206 DMemSpyDriverOSAdaptionDCodeSeg& codeSegAdaption = OSAdaption().DCodeSeg(); |
|
207 |
|
208 const TInt maxCount = params.iMaxCount; |
|
209 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegsForProcess() - START - pid: %d, maxCount: %d", params.iFilter, maxCount)); |
|
210 |
|
211 r = OpenTempObject( params.iFilter, EProcess ); |
|
212 if (r != KErrNone) |
|
213 { |
|
214 Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegsForProcess() - END - process not found"); |
|
215 return r; |
|
216 } |
|
217 |
|
218 DProcess* pP = (DProcess*) TempObject(); |
|
219 |
|
220 SDblQue q; |
|
221 |
|
222 Kern::AccessCode(); |
|
223 const TInt actcount = codeSegAdaption.GetCodeSegQueue( *pP, q ); |
|
224 |
|
225 CloseTempObject(); |
|
226 |
|
227 TInt n = Min(actcount, maxCount); |
|
228 SDblQueLink* pL = q.iA.iNext; |
|
229 r = KErrNone; |
|
230 // |
|
231 for (TInt i=0; i<n; ++i, pL = pL->iNext) |
|
232 { |
|
233 DCodeSeg* pS = codeSegAdaption.GetCodeSeg( pL ); |
|
234 |
|
235 r = Kern::ThreadRawWrite( &ClientThread(), params.iHandles + i, &pS, sizeof(TAny*) ); |
|
236 if ( r != KErrNone ) |
|
237 { |
|
238 break; |
|
239 } |
|
240 } |
|
241 codeSegAdaption.EmptyCodeSegQueue( q ); |
|
242 Kern::EndAccessCode(); |
|
243 |
|
244 if (r == KErrBadDescriptor) |
|
245 { |
|
246 MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); |
|
247 } |
|
248 else |
|
249 { |
|
250 const TInt finalWrite = Kern::ThreadRawWrite( &ClientThread(), params.iCountPtr, &actcount, sizeof(TInt) ); |
|
251 if ( r == KErrNone ) |
|
252 { |
|
253 r = finalWrite; |
|
254 } |
|
255 } |
|
256 |
|
257 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegsForProcess() - END - act count: %d, r: %d", actcount, r)); |
|
258 return r; |
|
259 } |
|
260 |
|
261 |
|
262 TInt DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo( TMemSpyDriverInternalCodeSegParams* aParams ) |
|
263 { |
|
264 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - START")); |
|
265 TMemSpyDriverInternalCodeSegParams params; |
|
266 TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalCodeSegParams) ); |
|
267 if ( r != KErrNone ) |
|
268 { |
|
269 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - END - params read error: %d", r)); |
|
270 return r; |
|
271 } |
|
272 |
|
273 TMemSpyDriverCodeSegInfo codeSegInfo; |
|
274 codeSegInfo.iSize = 0; |
|
275 |
|
276 // Create info |
|
277 codeSegInfo.iCreateInfo.iFileName.Zero(); |
|
278 codeSegInfo.iCreateInfo.iCodeSize = 0; |
|
279 codeSegInfo.iCreateInfo.iTextSize = 0; |
|
280 codeSegInfo.iCreateInfo.iDataSize = 0; |
|
281 codeSegInfo.iCreateInfo.iBssSize = 0; |
|
282 codeSegInfo.iCreateInfo.iTotalDataSize = 0; |
|
283 |
|
284 // Memory Info |
|
285 codeSegInfo.iMemoryInfo.iCodeBase = 0; |
|
286 codeSegInfo.iMemoryInfo.iCodeSize = 0; |
|
287 codeSegInfo.iMemoryInfo.iConstDataBase = 0; |
|
288 codeSegInfo.iMemoryInfo.iConstDataSize = 0; |
|
289 codeSegInfo.iMemoryInfo.iInitialisedDataBase = 0; |
|
290 codeSegInfo.iMemoryInfo.iInitialisedDataSize = 0; |
|
291 codeSegInfo.iMemoryInfo.iUninitialisedDataBase = 0; |
|
292 codeSegInfo.iMemoryInfo.iUninitialisedDataSize = 0; |
|
293 |
|
294 DProcess* process = NULL; |
|
295 DMemSpyDriverOSAdaptionDCodeSeg& codeSegAdaption = OSAdaption().DCodeSeg(); |
|
296 |
|
297 r = KErrNotFound; |
|
298 Kern::AccessCode(); |
|
299 DCodeSeg* codeSeg = codeSegAdaption.GetCodeSegFromHandle( params.iHandle ); |
|
300 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - codeSeg: 0x%08x, handle: 0x%08x", codeSeg, params.iHandle )); |
|
301 |
|
302 if ( codeSeg != NULL ) |
|
303 { |
|
304 #ifdef __EPOC32__ |
|
305 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - calling Kern::CodeSegGetMemoryInfo for code seg: %C...", codeSeg ) ); |
|
306 Kern::CodeSegGetMemoryInfo( *codeSeg, codeSegInfo.iMemoryInfo, process ); |
|
307 r = KErrNone; |
|
308 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - called Kern::CodeSegGetMemoryInfo, r: %d", r ) ); |
|
309 #else |
|
310 r = KErrNone; |
|
311 #endif |
|
312 // |
|
313 if ( r == KErrNone ) |
|
314 { |
|
315 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - calling Info...") ); |
|
316 codeSegAdaption.GetCreateInfo( *codeSeg, codeSegInfo.iCreateInfo ); |
|
317 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - called info" ) ); |
|
318 |
|
319 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - codeSegInfo.iMemoryInfo.iCodeBase: 0x%08x, codeSegInfo.iMemoryInfo.iCodeSize: %8d", codeSegInfo.iMemoryInfo.iCodeBase, codeSegInfo.iMemoryInfo.iCodeSize ) ); |
|
320 codeSegInfo.iSize = codeSegAdaption.GetSize( *codeSeg ); |
|
321 |
|
322 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - doing write to user land..." ) ); |
|
323 r = Kern::ThreadRawWrite( &ClientThread(), params.iInfoPointer, &codeSegInfo, sizeof(TMemSpyDriverCodeSegInfo) ); |
|
324 TRACE( Kern::Printf("DMemSpyDriverLogChanCodeSegs::GetCodeSegInfo() - done write to user-land, r: %d", r ) ); |
|
325 } |
|
326 } |
|
327 Kern::EndAccessCode(); |
|
328 // |
|
329 if ( r == KErrBadDescriptor ) |
|
330 { |
|
331 MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); |
|
332 } |
|
333 // |
|
334 return r; |
|
335 } |
|
336 |