|
1 // memoryaccess.h |
|
2 // |
|
3 // Copyright (c) 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "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 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #ifndef __MemoryAccess_H__ |
|
14 #define __MemoryAccess_H__ |
|
15 |
|
16 #ifndef __KERNEL_MODE__ |
|
17 #include <e32std.h> |
|
18 #endif |
|
19 #include <u32std.h> |
|
20 |
|
21 _LIT(KMemoryAccessName,"memoryAccess-fshell"); |
|
22 |
|
23 typedef TBuf8<KMaxFullName> TFullName8; |
|
24 typedef TBuf8<KMaxFileName> TFileName8; |
|
25 |
|
26 //size of buffer used for returning queues |
|
27 const TInt KQueBufferLength = 1024; |
|
28 |
|
29 //Buffer used to pass pointer arrays, of pointers to kernel side objects |
|
30 class TPointerArrayBuffer |
|
31 { |
|
32 public: |
|
33 TUint8* iBuffer[KQueBufferLength]; //buffer holding up to KQueBufferLength items of the array or queue |
|
34 TUint iStartFrom; //the point in the array to start from |
|
35 TUint iCount; //the total number of entries written into iBuffer. If KMaxTInt, there are more available |
|
36 }; |
|
37 |
|
38 // |
|
39 //Structures used for communication with driver |
|
40 // |
|
41 |
|
42 class RProcess; |
|
43 |
|
44 class TObjectInfoByIndexParams |
|
45 { |
|
46 public: |
|
47 TObjectType iObjectType; |
|
48 TUint iObjectIndex; |
|
49 }; |
|
50 typedef TPckgBuf<TObjectInfoByIndexParams> TObjectInfoByIndexParamsBuf; |
|
51 |
|
52 class TObjectInfoByPtrParams |
|
53 { |
|
54 public: |
|
55 TObjectType iObjectType; |
|
56 TUint8* iObjectPtr; |
|
57 }; |
|
58 typedef TPckgBuf<TObjectInfoByPtrParams> TObjectInfoByPtrParamsBuf; |
|
59 |
|
60 class TObjectInfoByNameParams |
|
61 { |
|
62 public: |
|
63 TObjectType iObjectType; |
|
64 TBuf8<KMaxFullName> iObjectName; |
|
65 }; |
|
66 typedef TPckgBuf<TObjectInfoByNameParams> TObjectInfoByNameParamsBuf; |
|
67 |
|
68 class TObjectInfoByHandleParams |
|
69 { |
|
70 public: |
|
71 TObjectType iObjectType; |
|
72 TInt iThreadId; |
|
73 TInt iObjectHandle; |
|
74 }; |
|
75 typedef TPckgBuf<TObjectInfoByHandleParams> TObjectInfoByHandleParamsBuf; |
|
76 |
|
77 class TThreadMemoryAccessParams |
|
78 { |
|
79 public: |
|
80 TUint iId; |
|
81 const TUint8* iAddr; |
|
82 TInt iSize; |
|
83 }; |
|
84 typedef TPckgBuf<TThreadMemoryAccessParams> TThreadMemoryAccessParamsBuf; |
|
85 |
|
86 class TObjectKillParams |
|
87 { |
|
88 public: |
|
89 TObjectType iObjectType; |
|
90 TUint iObjectId; |
|
91 TUint8* iObjectPtr; |
|
92 TExitType iType; |
|
93 TInt iReason; |
|
94 TFullName8 iCategory; |
|
95 }; |
|
96 typedef TPckgBuf<TObjectKillParams> TObjectKillParamsBuf; |
|
97 |
|
98 class TGetObjectAddressesParams |
|
99 { |
|
100 public: |
|
101 TObjectType iObjectType; |
|
102 TFullName8 iOwningProcess; |
|
103 }; |
|
104 typedef TPckgBuf<TGetObjectAddressesParams> TGetObjectAddressesParamsBuf; |
|
105 |
|
106 class TGetChunkAddressesParams |
|
107 { |
|
108 public: |
|
109 TUint iControllingProcessId; |
|
110 }; |
|
111 typedef TPckgBuf<TGetChunkAddressesParams> TGetChunkAddressesParamsBuf; |
|
112 |
|
113 class TObjectKernelInfo |
|
114 { |
|
115 public: |
|
116 TUint8* iAddressOfKernelObject; |
|
117 TFullName8 iName; |
|
118 TFullName8 iFullName; |
|
119 TInt iAccessCount; |
|
120 TInt iUniqueID; |
|
121 TUint iProtection; |
|
122 TUint8* iAddressOfKernelOwner; |
|
123 }; |
|
124 typedef TPckgBuf<TObjectKernelInfo> TObjectKernelInfoBuf; |
|
125 |
|
126 class TThreadKernelInfo : public TObjectKernelInfo |
|
127 { |
|
128 public: |
|
129 TUint iThreadId; |
|
130 TUint8* iAddressOfOwningProcess; |
|
131 TInt iThreadPriority; |
|
132 TInt iUserStackSize; |
|
133 TUint32 iFlags; |
|
134 TLinAddr iSupervisorStack; |
|
135 TInt iSupervisorStackSize; |
|
136 TLinAddr iUserStackLimit; |
|
137 TInt iNThreadSuspendCount; |
|
138 inline TLinAddr UserStackBase() const { return iUserStackLimit + iUserStackSize; } |
|
139 }; |
|
140 typedef TPckgBuf<TThreadKernelInfo> TThreadKernelInfoBuf; |
|
141 |
|
142 const TInt KNumEnvironmentSlots = 16; |
|
143 |
|
144 class TProcessKernelInfo : public TObjectKernelInfo |
|
145 { |
|
146 public: |
|
147 TUint iProcessId; |
|
148 TInt iPriority; |
|
149 TUint8* iAddressOfOwningProcess; |
|
150 TUint iCreatorId; |
|
151 TUint iSecurityZone; |
|
152 TUidType iUids; |
|
153 TInt iAttributes; |
|
154 TUint8* iAddressOfDataBssStackChunk; |
|
155 TPointerArrayBuffer iThreadQ; |
|
156 SSecurityInfo iProcessSecurityInfo; |
|
157 SSecurityInfo iProcessCreatorSecurityInfo; |
|
158 TBuf8<256> iCommandLine; |
|
159 TUint32 iFlags; |
|
160 TInt iEnvironmentData[KNumEnvironmentSlots]; |
|
161 TUint iFirstThreadId; |
|
162 }; |
|
163 typedef TPckgBuf<TProcessKernelInfo> TProcessKernelInfoBuf; |
|
164 |
|
165 class TChunkKernelInfo : public TObjectKernelInfo |
|
166 { |
|
167 public: |
|
168 TInt iSize; |
|
169 TInt iMaxSize; |
|
170 TUint8* iBase; |
|
171 TInt iBottom; |
|
172 TInt iTop; |
|
173 TInt iAttributes; |
|
174 TInt iStartPos; |
|
175 TUint iControllingOwnerProcessId; |
|
176 TUint iRestrictions; |
|
177 TUint iMapAttr; |
|
178 TUint iChunkType; |
|
179 TUint8* iAddressOfOwningProcess; |
|
180 }; |
|
181 typedef TPckgBuf<TChunkKernelInfo> TChunkKernelInfoBuf; |
|
182 |
|
183 class TLibraryKernelInfo : public TObjectKernelInfo |
|
184 { |
|
185 public: |
|
186 TInt iMapCount; |
|
187 TUint8 iState; |
|
188 TUint8* iAddressOfCodeSeg; |
|
189 }; |
|
190 typedef TPckgBuf<TLibraryKernelInfo> TLibraryKernelInfoBuf; |
|
191 |
|
192 class TSemaphoreKernelInfo : public TObjectKernelInfo |
|
193 { |
|
194 public: |
|
195 TInt iCount; |
|
196 TUint8 iResetting; |
|
197 TPointerArrayBuffer iSuspendedQ; |
|
198 }; |
|
199 typedef TPckgBuf<TSemaphoreKernelInfo> TSemaphoreKernelInfoBuf; |
|
200 |
|
201 class TMutexKernelInfo : public TObjectKernelInfo |
|
202 { |
|
203 public: |
|
204 TInt iHoldCount; |
|
205 TInt iWaitCount; |
|
206 TUint8 iResetting; |
|
207 TUint8 iOrder; |
|
208 TPointerArrayBuffer iSuspendedQ; |
|
209 TPointerArrayBuffer iPendingQ; |
|
210 }; |
|
211 typedef TPckgBuf<TMutexKernelInfo> TMutexKernelInfoBuf; |
|
212 |
|
213 class TTimerKernelInfo : public TObjectKernelInfo |
|
214 { |
|
215 public: |
|
216 TUint8 iState; |
|
217 TUint8 iType; |
|
218 TLinAddr iClientStatus; |
|
219 }; |
|
220 typedef TPckgBuf<TTimerKernelInfo> TTimerKernelInfoBuf; |
|
221 |
|
222 class TServerKernelInfo : public TObjectKernelInfo |
|
223 { |
|
224 public: |
|
225 TUint8* iAddressOfOwningThread; |
|
226 TUint8 iSessionType; |
|
227 TPointerArrayBuffer iSessionQ; |
|
228 TUint iOwningThreadId; |
|
229 }; |
|
230 typedef TPckgBuf<TServerKernelInfo> TServerKernelInfoBuf; |
|
231 |
|
232 class TSessionKernelInfo : public TObjectKernelInfo |
|
233 { |
|
234 public: |
|
235 TUint8* iServer; |
|
236 TAny* iSessionPtr; |
|
237 TUint16 iTotalAccessCount; |
|
238 TUint8 iSessionType; |
|
239 TUint8 iSvrSessionType; |
|
240 TInt iMsgCount; |
|
241 TInt iMsgLimit; |
|
242 }; |
|
243 typedef TPckgBuf<TSessionKernelInfo> TSessionKernelInfoBuf; |
|
244 |
|
245 class TLogicalDeviceKernelInfo : public TObjectKernelInfo |
|
246 { |
|
247 public: |
|
248 TVersion iVersion; |
|
249 TUint iParseMask; |
|
250 TUint iUnitsMask; |
|
251 TInt iOpenChannels; |
|
252 }; |
|
253 typedef TPckgBuf<TLogicalDeviceKernelInfo> TLogicalDeviceKernelInfoBuf; |
|
254 |
|
255 class TPhysicalDeviceKernelInfo : public TObjectKernelInfo |
|
256 { |
|
257 public: |
|
258 TVersion iVersion; |
|
259 TUint iUnitsMask; |
|
260 TUint8* iAddressOfCodeSeg; |
|
261 }; |
|
262 typedef TPckgBuf<TPhysicalDeviceKernelInfo> TPhysicalDeviceKernelInfoBuf; |
|
263 |
|
264 class TLogicalChannelKernelInfo : public TObjectKernelInfo |
|
265 { |
|
266 public: |
|
267 }; |
|
268 typedef TPckgBuf<TLogicalChannelKernelInfo> TLogicalChannelKernelInfoBuf; |
|
269 |
|
270 class TChangeNotifierKernelInfo : public TObjectKernelInfo |
|
271 { |
|
272 public: |
|
273 TUint iChanges; |
|
274 TUint8* iAddressOfThread; |
|
275 }; |
|
276 typedef TPckgBuf<TChangeNotifierKernelInfo> TChangeNotifierKernelInfoBuf; |
|
277 |
|
278 class TUndertakerKernelInfo : public TObjectKernelInfo |
|
279 { |
|
280 public: |
|
281 TUint8* iOwningThread; |
|
282 }; |
|
283 typedef TPckgBuf<TUndertakerKernelInfo> TUndertakerKernelInfoBuf; |
|
284 |
|
285 class TMsgQueueKernelInfo : public TObjectKernelInfo |
|
286 { |
|
287 public: |
|
288 TUint iMaxMsgLength; |
|
289 }; |
|
290 typedef TPckgBuf<TMsgQueueKernelInfo> TMsgQueueKernelInfoBuf; |
|
291 |
|
292 class TPropertyRefKernelInfo : public TObjectKernelInfo |
|
293 { |
|
294 public: |
|
295 }; |
|
296 typedef TPckgBuf<TPropertyRefKernelInfo> TPropertyRefKernelInfoBuf; |
|
297 |
|
298 class TCondVarKernelInfo : public TObjectKernelInfo |
|
299 { |
|
300 public: |
|
301 TUint8 iResetting; |
|
302 TUint8* iAddressOfMutex; |
|
303 TInt iWaitCount; |
|
304 TPointerArrayBuffer iSuspendedQ; |
|
305 }; |
|
306 typedef TPckgBuf<TCondVarKernelInfo> TCondVarKernelInfoBuf; |
|
307 |
|
308 class TCodeSegKernelInfo |
|
309 { |
|
310 public: |
|
311 TUint32 iRunAddress; |
|
312 TInt iSize; |
|
313 TFileName8 iFileName; |
|
314 }; |
|
315 typedef TPckgBuf<TCodeSegKernelInfo> TCodeSegKernelInfoBuf; |
|
316 |
|
317 class TTomsciCodeSegKernelInfo : public TCodeSegKernelInfo |
|
318 { |
|
319 public: |
|
320 TUint8* iAddressOfKernelObject; |
|
321 TFullName8 iName; |
|
322 TInt iAccessCount; |
|
323 TInt iDepCount; |
|
324 }; |
|
325 |
|
326 class TProp |
|
327 { |
|
328 public: |
|
329 TUid iCategory; |
|
330 TUint iKey; |
|
331 TInt iActualSize; // Return value, only used when getting a descriptor property |
|
332 TBool iDefine; |
|
333 }; |
|
334 |
|
335 class TPropNotifyResult |
|
336 { |
|
337 public: |
|
338 TUint iCategory; |
|
339 TUint iKey; |
|
340 TInt iMissedChanges; |
|
341 TInt iError; |
|
342 }; |
|
343 |
|
344 class TRamZoneInfo |
|
345 { |
|
346 public: |
|
347 TUint iFreePages; |
|
348 TUint iUnknownPages; |
|
349 TUint iFixedPages; |
|
350 TUint iMovablePages; |
|
351 TUint iDiscardablePages; |
|
352 }; |
|
353 |
|
354 class TProcessProperties |
|
355 { |
|
356 public: |
|
357 TProcessProperties() : iSid(0xFFFFFFFFu), iVid(0xFFFFFFFFu), /*iHeapMin(0), iHeapMax(0), iStackSize(0),*/ iProcessPriority(0) |
|
358 { |
|
359 iCapsToAdd.SetEmpty(); |
|
360 iCapsToRemove.SetEmpty(); |
|
361 } |
|
362 |
|
363 TCapabilitySet iCapsToAdd; |
|
364 TCapabilitySet iCapsToRemove; |
|
365 TUint iSid; |
|
366 TUint iVid; |
|
367 //TUint iHeapMin; |
|
368 //TUint iHeapMax; |
|
369 //TUint iStackSize; |
|
370 TInt iProcessPriority; |
|
371 }; |
|
372 |
|
373 // class RMemoryAccess |
|
374 // User side communication interface to Memory Access driver. |
|
375 // Provides access to arbitrary kernel objects, memory, and some basic object manipulation. |
|
376 // For use in debugging tools only! Do not include in a release ROM. |
|
377 class RMemoryAccess : public RBusLogicalChannel |
|
378 { |
|
379 public: |
|
380 enum TControl |
|
381 { |
|
382 EControlGetThreadMem, |
|
383 EControlGetAllocatorAddress, |
|
384 EControlResetTimer, |
|
385 EControlGetContainerCount, |
|
386 EControlAcquireContainerMutex, |
|
387 EControlReleaseContainerMutex, |
|
388 EControlGetObjectType, |
|
389 EControlGetObjectInfo, |
|
390 EControlGetObjectInfoByPtr, |
|
391 EControlGetObjectInfoByHandle, |
|
392 EControlAcquireCodeSegMutex, |
|
393 EControlReleaseCodeSegMutex, |
|
394 EControlGetNextCodeSegInfo, |
|
395 EControlObjectDie, |
|
396 EControlGetObjectInfoByName, |
|
397 EControlGetObjectAddresses, |
|
398 EControlGetChunkAddresses, |
|
399 EControlGetCurrentAllocatorAddress, |
|
400 EControlFindPtrInCodeSegments, |
|
401 EControlGetHandleOwners, |
|
402 EControlForceCrash, |
|
403 EControlGetPropertyInt, |
|
404 EControlGetPropertyDesc, |
|
405 EControlSetPropertyInt, |
|
406 EControlSetPropertyDesc, |
|
407 EControlDeleteProperty, |
|
408 EControlSetThreadPriority, |
|
409 EControlNotifyThreadCreation, |
|
410 EControlCancelNotifyThreadCreation, |
|
411 EControlSetPriorityOverride, |
|
412 EControlSetCriticalFlags, |
|
413 EControlOpenThread, |
|
414 EControlGetThreadHandles, |
|
415 EControlGetProcessHandles, |
|
416 EControlInPlaceThreadRename, |
|
417 ERemoved1, //EControlGetBinaryPropertyKernelLocation |
|
418 EControlInPlaceObjectRename, |
|
419 EControlInPlaceSetProcessFileName, |
|
420 ERemoved2, //EControlGetAllProperties, |
|
421 ERemoved3, //EControlSetupMassPropertyNotify, |
|
422 ERemoved4, //EControlMassPropertyNotifyStart, |
|
423 ERemoved5, //EControlMassPropertyNotifyStop, |
|
424 EControlEnableHeapTracing, |
|
425 EControlDefragRam, |
|
426 EControlEmptyRamZone, |
|
427 EControlGetRamZoneInfo, |
|
428 EControlSetProcessProperties, |
|
429 EControlWriteShadowMemory, |
|
430 EControlFreeShadowMemory, |
|
431 EControlSetZombieDebugMode, |
|
432 EControlWriteMem, |
|
433 EControlSetTextTraceMode, |
|
434 EControlGetRegisters, |
|
435 EControlGetZombies, |
|
436 EControlGetZombieDebugMode, |
|
437 EControlReleaseZombie, |
|
438 EControlSuspendThread, |
|
439 EControlNotifyBreakpoint, |
|
440 EControlSetBreakpoint, |
|
441 EControlSetBreakpointEnabled, |
|
442 EControlClearBreakpoint, |
|
443 EControlContinueFromBreakpoint, |
|
444 EControlGetBreakpoints, |
|
445 EControlCancelNotifyBreakpoint, |
|
446 EControlRegisterPersistantBreakpoint, |
|
447 EControlSetSymbolicBreakpoint, |
|
448 EControlSetDebugPort, |
|
449 EControlReboot, |
|
450 EControlGetCreatorThread, |
|
451 EControlPropertyNotify, |
|
452 EControlPropertyNotifyCancel, |
|
453 EControlSubscribeToProperty, |
|
454 ENumRequests, // Add new commands above this line |
|
455 }; |
|
456 public: |
|
457 static TInt LoadDriver(); |
|
458 static void CloseDriver(); |
|
459 |
|
460 public: |
|
461 //Open the driver |
|
462 TInt Open(); |
|
463 //Deprecated. |
|
464 TInt ResetTimer(); |
|
465 //Read memory from the context of a thread |
|
466 TInt GetThreadMem(const TThreadMemoryAccessParamsBuf& aParams, TDes8& aBuf); |
|
467 //Get the address of the allocator of a thread |
|
468 TInt GetAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject); |
|
469 TInt GetCurrentAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject); |
|
470 TInt FindAddressInCodeSegments(TFullName8& aDllName, TAny* aPtr); |
|
471 TInt GetHandleOwners(TAny* aKernelObjectPtr, TDes8& aOwnersBuf); |
|
472 TInt GetThreadHandles(TUint aThreadId, TDes8& aHandlesBuf); |
|
473 TInt GetProcessHandles(TUint aProcessId, TDes8& aHandlesBuf); |
|
474 void ForceCrash(); |
|
475 void Reboot(TInt aReason); |
|
476 |
|
477 //Get the number of objects in a specified kernel container |
|
478 TInt GetContainerCount (const TObjectType aObjectType, TUint& aCount); |
|
479 //Wait on the mutex of a specified kernel container |
|
480 TInt AcquireContainerMutex (const TObjectType aObjectType); |
|
481 //Signal the mutex of a specified kernel container |
|
482 TInt ReleaseContainerMutex (const TObjectType aObjectType); |
|
483 //Get the type of a DObject* object in the kernel |
|
484 TInt GetObjectType (TUint8* aKernelObjectAddr, TObjectType& aObjectType); |
|
485 //Get info about a kernel object, referenced by position in its container. Call AcquireContainerMutex before calling. |
|
486 TInt GetObjectInfo (TObjectType aObjectType, TUint aIndexInKernelContainer, TDes8& aObjectInfoBuf); |
|
487 //Get info about a kernel object specified as a DObject* |
|
488 TInt GetObjectInfo (TObjectType aObjectType, TUint8* aAddressOfKernelObject, TDes8& aObjectInfoBuf); |
|
489 //Get info about a kernel object specified by name. |
|
490 TInt GetObjectInfo (TObjectType aObjectType, const TDesC& aObjectName, TDes8& aObjectInfoBuf); |
|
491 //Get info about a kernel object specified as a user side handle |
|
492 TInt GetObjectInfoByHandle (TObjectType aObjectType, TInt aThreadId, TInt aObjectHandle, TDes8& aObjectInfoBuf); |
|
493 //Wait on the kernel's code seg mutex |
|
494 TInt AcquireCodeSegMutex(); |
|
495 //Signal the kernel's code seg mutex |
|
496 TInt ReleaseCodeSegMutex(); |
|
497 //Get info about the next code seg. Call repeatedly to iterate all code segs. Call AcquireCodeSegMutex before calling. |
|
498 TInt GetNextCodeSegInfo(TDes8& aCodeSegInfoBuf); |
|
499 //Kill an object. aObyType should be a thread or process. Either an objectId (user side handle) _OR_ objectPtr (kernel side DObject*) should be provided. |
|
500 TInt ObjectDie(TObjectType aObjType, TUint aObjectId, TUint8* aObjectPtr, TExitType aType, TInt aReason, const TDesC& aCategory); |
|
501 //Pack the addresses of all the kernel objects of the specified type belonging to the specified process into the supplied buffer. |
|
502 //Returns KErrOverflow if the buffer isn't big enough to hold all the addresses. aOwningProcess may contain '?' and '*' wild characters. |
|
503 TInt GetObjectAddresses(TObjectType aObjType, const TDesC& aOwningProcess, TDes8& aAddressBuffer); |
|
504 //Pack the addresses of all the chunks with a the specified controlling process id into the supplied buffer. |
|
505 //Returns KErrOverflow if the buffer isn't big enough to hold all the addresses. Note, this interface allows global chunks (which have |
|
506 //a NULL owner pointers, hence can't be found using RMemoryAccess::GetObjectAddresses) that were created by a particular process to be found. |
|
507 TInt GetChunkAddresses(TUint aControllingProcessId, TDes8& aAddressBuffer); |
|
508 |
|
509 TInt GetProperty(TUid aCategory, TUint aKey, TInt& aValue); |
|
510 TInt GetProperty(TUid aCategory, TUint aKey, TDes8& aValue, TInt& aActualSize); |
|
511 TInt SetProperty(TUid aCategory, TUint aKey, TInt aValue, TBool aDefineIfNotSet=EFalse); |
|
512 TInt SetProperty(TUid aCategory, TUint aKey, const TDesC8& aValue, TBool aDefineIfNotSet=EFalse); |
|
513 TInt DeleteProperty(TUid aCategory, TUint aKey); |
|
514 TInt SubscribeToProperty(TUid aCategory, TUint aKey, TBool aOutputToBtrace); // If aOutputToBtrace is false, use NotifyPropertyChange to get details |
|
515 |
|
516 void NotifyPropertyChange(TPropNotifyResult& aResult, TRequestStatus& aStatus); |
|
517 void CancelPropertyChange(); |
|
518 |
|
519 TInt RThreadForceOpen(RThread& aThread, TUint aId); |
|
520 TInt SetThreadPriority(RThread& aThread, TInt aPriority); |
|
521 void NotifyThreadCreation(TRequestStatus& aStatus); |
|
522 void CancelNotifyThreadCreation(); |
|
523 TInt SetPriorityOverride(TInt aPriority, const TDesC8& aMatchString); // any thread that is created that matches the wildcard string aMatchString is given thread priority aPriority |
|
524 TInt SetThreadCriticalFlags(RThread& aThread, TUint aFlags); |
|
525 TLinAddr InPlaceThreadRename(RThread& aThread, const TDesC8& aNewName); |
|
526 TInt InPlaceObjectRename(TObjectType aObjectType, TUint8* aAddressOfKernelObject, const TDesC8& aNewName); |
|
527 TInt InPlaceSetProcessFileName(RProcess& aProcess, const TDesC8& aNewName); |
|
528 TInt SetProcessProperties(RProcess& aProcess, const TProcessProperties& aProperties); |
|
529 TInt WriteShadowMemory(TLinAddr aAddress, const TDesC8& aNewContents); |
|
530 TInt FreeShadowMemory(TLinAddr aAddress, TInt aLen); |
|
531 TInt SetDebugPort(TInt aPort); |
|
532 TUint GetThreadCreatorId(TUint aThreadId); |
|
533 |
|
534 TInt EnableHeapTracing(TUint aThreadId, TBool aEnable); |
|
535 TInt DefragRam(TInt aPriority); |
|
536 TInt EmptyRamZone(TUint aZone, TInt aPriority); |
|
537 TInt GetRamZoneInfo(TUint aZone, TDes8& aInfoPkg); |
|
538 |
|
539 // Debugger APIs |
|
540 TInt GetZombieDebugMode(); |
|
541 TInt SetZombieDebugMode(TInt aMode); |
|
542 class TZombieInfo |
|
543 { |
|
544 public: |
|
545 TUint iThreadId; |
|
546 enum TFlags { ESuspended = 1, EBreakpoint = 2 }; |
|
547 TUint iFlags; |
|
548 }; |
|
549 TInt GetZombies(TDes8& aResultBuf); // buffer full of TZombieInfos |
|
550 TInt WriteMem(TUint aThreadId, const TDesC8& aMem, TAny* aAddr); |
|
551 TInt SetTextTraceMode(TUint& aMode, TUint aMask); |
|
552 TInt GetRegisters(RThread& aThread, TBool aUserMode, TDes8& aRegBuf, TUint32& aValid); |
|
553 TInt ReleaseZombie(RThread& aThread); |
|
554 TInt SuspendThread(RThread& aThread); // To resume, call ReleaseZombie |
|
555 |
|
556 class TBreakpointNotification |
|
557 { |
|
558 public: |
|
559 TUint iThreadId; |
|
560 TInt iBreakpointId; |
|
561 TLinAddr iAddress; |
|
562 }; |
|
563 |
|
564 class TPredicate |
|
565 { |
|
566 public: |
|
567 enum { KNumSlots = 4 }; |
|
568 enum TOp |
|
569 { |
|
570 ENothing = 0, |
|
571 EEq, ENe, ELt, ELe, EGt, EGe, ESignedEq, ESignedNe, ESignedLt, ESignedLe, ESignedGt, ESignedGe, |
|
572 }; |
|
573 TPredicate() : iOp(0) {} |
|
574 TBool HasConditions() const { return iOp != 0; } |
|
575 |
|
576 #ifdef __KERNEL_MODE__ |
|
577 TBool SatisfiesConditions(TUint32* aRegisterSet) const; |
|
578 private: |
|
579 static TBool Test(TOp aOperation, TUint32 aCurrentValue, TUint32 aStoredValue); |
|
580 #else |
|
581 TInt AddCondition(TOp aOperation, TInt aRegNum, TUint32 aValue); |
|
582 void Description(TDes& aBuf); |
|
583 #endif |
|
584 |
|
585 private: |
|
586 TUint32 iOp; // 8 bits for each, of which top 4 is reg that the relevant iVals is to be compared against, bottom 4 is the comparison operation (one of TOp) |
|
587 TUint32 iVals[KNumSlots]; |
|
588 }; |
|
589 |
|
590 void NotifyBreakpoint(TPckg<TBreakpointNotification>& aPkg, TRequestStatus& aStatus); |
|
591 void CancelNotifyBreakpoint(); |
|
592 //TInt SetBreakpoint(TLinAddr aAddress); // Global, all threads (except caller and the memaccess DFC thread). Returns breakpoint ID or an error code |
|
593 TInt SetBreakpoint(RThread& aThread, TLinAddr aAddress, TPredicate* aCondition = NULL); // Returns breakpoint ID or an error code. Breakpoint ID may be OR'd with TBreakpointInfo::EHardware if a hardware breakpoint was sucessfully set |
|
594 TInt SetSymbolicBreakpoint(RThread& aThread, const TDesC8& aCodeseg, TUint aOffset, TPredicate* aCondition = NULL); |
|
595 TInt RegisterPersistantBreakpoint(TLinAddr aAddress); |
|
596 TInt SetBreakpointEnabled(TInt aBreakpointId, TBool aEnabled); |
|
597 TInt ClearBreakpoint(TInt aBreakpointId); // Removes it completely. Doesn't resume anything waiting on it though |
|
598 TInt ContinueFromBreakpoint(RThread& aThread); // aThread must be waiting on a breakpoint otherwise KErrNotReady |
|
599 |
|
600 class TBreakpointInfo |
|
601 { |
|
602 public: |
|
603 TUint iThreadId; |
|
604 TInt iBreakpointId; |
|
605 TLinAddr iAddress; |
|
606 enum TFlags |
|
607 { |
|
608 EPending = 1, |
|
609 EEnabled = 2, // Enabled by user, that is. It could still be pending and thus not actually going to case a break at this point in time |
|
610 EHardware = 0x40000000, |
|
611 }; |
|
612 TUint32 iFlags; |
|
613 TPredicate iCondition; |
|
614 }; |
|
615 TInt GetBreakpoints(TDes8& aBuf); // buffer full of TBreakpointInfos |
|
616 }; |
|
617 |
|
618 #ifndef __KERNEL_MODE__ |
|
619 // Inline implementations of user side interface |
|
620 |
|
621 inline TInt RMemoryAccess::LoadDriver() |
|
622 { return User::LoadLogicalDevice(KMemoryAccessName); } |
|
623 inline void RMemoryAccess::CloseDriver() |
|
624 { User::FreeLogicalDevice(KMemoryAccessName); } |
|
625 inline TInt RMemoryAccess::Open() |
|
626 { return DoCreate(KMemoryAccessName,TVersion(1,0,0),KNullUnit,NULL,NULL); } |
|
627 inline TInt RMemoryAccess::GetThreadMem(const TThreadMemoryAccessParamsBuf& aParams, TDes8& aBuf) |
|
628 { return DoControl(EControlGetThreadMem, (TAny*)&aParams, (TAny*)&aBuf); } |
|
629 inline TInt RMemoryAccess::GetAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject) |
|
630 { return DoControl(EControlGetAllocatorAddress, (TAny*)aThreadId, &aAddressOfKernelObject); } |
|
631 // This returns the current allocator (User::Allocator) as opposed to the one created in SThreadCreateInfo |
|
632 inline TInt RMemoryAccess::GetCurrentAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject) |
|
633 { return DoControl(EControlGetCurrentAllocatorAddress, (TAny*)aThreadId, &aAddressOfKernelObject); } |
|
634 inline TInt RMemoryAccess::FindAddressInCodeSegments(TFullName8& aDllName, TAny* aPtr) |
|
635 { return DoControl(EControlFindPtrInCodeSegments, (TAny*)&aDllName, aPtr); } |
|
636 inline TInt RMemoryAccess::GetHandleOwners(TAny* aHandle, TDes8& aOwnersBuf) |
|
637 { return DoControl(EControlGetHandleOwners, (TAny*)aHandle, (TAny*)&aOwnersBuf); } |
|
638 inline TInt RMemoryAccess::GetThreadHandles(TUint aThreadId, TDes8& aHandlesBuf) |
|
639 { return DoControl(EControlGetThreadHandles, (TAny*)aThreadId, &aHandlesBuf); } |
|
640 inline TInt RMemoryAccess::GetProcessHandles(TUint aProcessId, TDes8& aHandlesBuf) |
|
641 { return DoControl(EControlGetProcessHandles, (TAny*)aProcessId, &aHandlesBuf); } |
|
642 inline void RMemoryAccess::ForceCrash() |
|
643 { DoControl(EControlForceCrash); } |
|
644 inline void RMemoryAccess::Reboot(TInt aReason) |
|
645 { DoControl(EControlReboot, (TAny*)aReason); } |
|
646 inline TInt RMemoryAccess::ResetTimer() |
|
647 { return DoControl(EControlResetTimer, NULL, NULL); } |
|
648 inline TInt RMemoryAccess::GetContainerCount (const TObjectType aObjectType, TUint& aCount) |
|
649 { return DoControl(EControlGetContainerCount, (TAny*)aObjectType, (TAny*)&aCount); } |
|
650 inline TInt RMemoryAccess::AcquireContainerMutex (const TObjectType aObjectType) { return DoControl(EControlAcquireContainerMutex, (TAny*)aObjectType, NULL); } |
|
651 inline TInt RMemoryAccess::ReleaseContainerMutex (const TObjectType aObjectType) |
|
652 { return DoControl(EControlReleaseContainerMutex, (TAny*)aObjectType, NULL); } |
|
653 inline TInt RMemoryAccess::GetObjectType (TUint8* aKernelObjectAddr, TObjectType& aObjectType) |
|
654 { return DoControl(EControlGetObjectType, (TAny*)aKernelObjectAddr, (TAny*)&aObjectType); } |
|
655 inline TInt RMemoryAccess::GetObjectInfo (TObjectType aObjectType, TUint aIndexInKernelContainer, TDes8& aObjectInfoBuf) |
|
656 { |
|
657 TObjectInfoByIndexParamsBuf params; |
|
658 params().iObjectType=aObjectType; |
|
659 params().iObjectIndex=aIndexInKernelContainer; |
|
660 return DoControl(EControlGetObjectInfo, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); |
|
661 } |
|
662 inline TInt RMemoryAccess::GetObjectInfo (TObjectType aObjectType, TUint8* aAddressOfKernelObject, TDes8& aObjectInfoBuf) |
|
663 { |
|
664 TObjectInfoByPtrParamsBuf params; |
|
665 params().iObjectType=aObjectType; |
|
666 params().iObjectPtr=aAddressOfKernelObject; |
|
667 return DoControl(EControlGetObjectInfoByPtr, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); |
|
668 } |
|
669 inline TInt RMemoryAccess::GetObjectInfo (TObjectType aObjectType, const TDesC& aObjectName, TDes8& aObjectInfoBuf) |
|
670 { |
|
671 TObjectInfoByNameParamsBuf params; |
|
672 params().iObjectType=aObjectType; |
|
673 params().iObjectName.Copy(aObjectName); |
|
674 return DoControl(EControlGetObjectInfoByName, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); |
|
675 } |
|
676 inline TInt RMemoryAccess::GetObjectInfoByHandle (TObjectType aObjectType, TInt aThreadId, TInt aObjectHandle, TDes8& aObjectInfoBuf) |
|
677 { |
|
678 TObjectInfoByHandleParamsBuf params; |
|
679 params().iObjectType=aObjectType; |
|
680 params().iThreadId=aThreadId; |
|
681 params().iObjectHandle=aObjectHandle; |
|
682 return DoControl(EControlGetObjectInfoByHandle, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); |
|
683 } |
|
684 inline TInt RMemoryAccess::AcquireCodeSegMutex() |
|
685 { return DoControl(EControlAcquireCodeSegMutex, NULL, NULL); } |
|
686 inline TInt RMemoryAccess::ReleaseCodeSegMutex() |
|
687 { return DoControl(EControlReleaseCodeSegMutex, NULL, NULL); } |
|
688 inline TInt RMemoryAccess::GetNextCodeSegInfo(TDes8& aCodeSegInfoBuf) |
|
689 { return DoControl(EControlGetNextCodeSegInfo, (TAny*)&aCodeSegInfoBuf, NULL); } |
|
690 inline TInt RMemoryAccess::ObjectDie(TObjectType aObjType, TUint aObjectId, TUint8* aObjectPtr, TExitType aType, TInt aReason, const TDesC& aCategory) |
|
691 { |
|
692 TObjectKillParamsBuf params; |
|
693 params().iObjectType=aObjType; |
|
694 params().iObjectId=aObjectId; |
|
695 params().iObjectPtr=aObjectPtr; |
|
696 params().iType=aType; |
|
697 params().iReason=aReason; |
|
698 params().iCategory.Copy(aCategory); |
|
699 return DoControl(EControlObjectDie, (TAny*)¶ms, NULL); |
|
700 } |
|
701 inline TInt RMemoryAccess::GetObjectAddresses(TObjectType aObjType, const TDesC& aOwningProcess, TDes8& aAddressBuffer) |
|
702 { |
|
703 TGetObjectAddressesParamsBuf params; |
|
704 params().iObjectType=aObjType; |
|
705 params().iOwningProcess.Copy(aOwningProcess); |
|
706 return DoControl(EControlGetObjectAddresses, (TAny*)¶ms, (TAny*)&aAddressBuffer); |
|
707 } |
|
708 inline TInt RMemoryAccess::GetChunkAddresses(TUint aControllingProcessId, TDes8& aAddressBuffer) |
|
709 { |
|
710 TGetChunkAddressesParamsBuf params; |
|
711 params().iControllingProcessId=aControllingProcessId; |
|
712 return DoControl(EControlGetChunkAddresses, (TAny*)¶ms, (TAny*)&aAddressBuffer); |
|
713 } |
|
714 |
|
715 inline TInt RMemoryAccess::GetProperty(TUid aCategory, TUint aKey, TInt& aValue) |
|
716 { |
|
717 TProp params; |
|
718 params.iCategory = aCategory; |
|
719 params.iKey = aKey; |
|
720 params.iDefine = EFalse; |
|
721 |
|
722 TPckg<TInt> res(aValue); |
|
723 |
|
724 return DoControl(EControlGetPropertyInt, (TAny*)¶ms, (TAny*)&res); |
|
725 } |
|
726 |
|
727 inline TInt RMemoryAccess::GetProperty(TUid aCategory, TUint aKey, TDes8& aValue, TInt& aActualSize) |
|
728 { |
|
729 TProp params; |
|
730 params.iCategory = aCategory; |
|
731 params.iKey = aKey; |
|
732 params.iDefine = EFalse; |
|
733 |
|
734 TInt err = DoControl(EControlGetPropertyDesc, (TAny*)¶ms, (TAny*)&aValue); |
|
735 if (err == KErrOverflow) |
|
736 { |
|
737 aActualSize = params.iActualSize; |
|
738 } |
|
739 return err; |
|
740 } |
|
741 |
|
742 inline TInt RMemoryAccess::SetProperty(TUid aCategory, TUint aKey, TInt aValue, TBool aDefineIfNotSet) |
|
743 { |
|
744 TProp params; |
|
745 params.iCategory = aCategory; |
|
746 params.iKey = aKey; |
|
747 params.iDefine = aDefineIfNotSet; |
|
748 |
|
749 return DoControl(EControlSetPropertyInt, (TAny*)¶ms, (TAny*)aValue); |
|
750 } |
|
751 |
|
752 inline TInt RMemoryAccess::SetProperty(TUid aCategory, TUint aKey, const TDesC8& aValue, TBool aDefineIfNotSet) |
|
753 { |
|
754 TProp params; |
|
755 params.iCategory = aCategory; |
|
756 params.iKey = aKey; |
|
757 params.iDefine = aDefineIfNotSet; |
|
758 |
|
759 return DoControl(EControlSetPropertyDesc, (TAny*)¶ms, (TAny*)&aValue); |
|
760 } |
|
761 |
|
762 inline TInt RMemoryAccess::DeleteProperty(TUid aCategory, TUint aKey) |
|
763 { |
|
764 TProp params; |
|
765 params.iCategory = aCategory; |
|
766 params.iKey = aKey; |
|
767 params.iDefine = EFalse; |
|
768 |
|
769 return DoControl(EControlDeleteProperty, (TAny*)¶ms, NULL); |
|
770 } |
|
771 |
|
772 inline void RMemoryAccess::NotifyPropertyChange(TPropNotifyResult& aResult, TRequestStatus& aStatus) |
|
773 { |
|
774 aStatus = KRequestPending; |
|
775 TInt err = DoControl(EControlPropertyNotify, (TAny*)&aResult, (TAny*)&aStatus); |
|
776 if (err) |
|
777 { |
|
778 TRequestStatus* ffs = &aStatus; |
|
779 User::RequestComplete(ffs, err); |
|
780 } |
|
781 } |
|
782 |
|
783 inline void RMemoryAccess::CancelPropertyChange() |
|
784 { |
|
785 DoControl(EControlPropertyNotifyCancel, NULL, NULL); |
|
786 } |
|
787 |
|
788 inline TInt RMemoryAccess::SubscribeToProperty(TUid aCategory, TUint aKey, TBool aOutputToBtrace) |
|
789 { |
|
790 TProp params; |
|
791 params.iCategory = aCategory; |
|
792 params.iKey = aKey; |
|
793 params.iDefine = EFalse; |
|
794 return DoControl(EControlSubscribeToProperty, (TAny*)¶ms, (TAny*)aOutputToBtrace); |
|
795 } |
|
796 |
|
797 inline TInt RMemoryAccess::SetThreadPriority(RThread& aThread, TInt aPriority) |
|
798 { |
|
799 return DoControl(EControlSetThreadPriority, (TAny*)aThread.Handle(), (TAny*)aPriority); |
|
800 } |
|
801 |
|
802 inline void RMemoryAccess::NotifyThreadCreation(TRequestStatus& aStatus) |
|
803 { |
|
804 aStatus = KRequestPending; |
|
805 TRequestStatus* stat = &aStatus; |
|
806 TInt err = DoControl(EControlNotifyThreadCreation, stat, NULL); |
|
807 if (err) User::RequestComplete(stat, err); |
|
808 } |
|
809 |
|
810 inline void RMemoryAccess::CancelNotifyThreadCreation() |
|
811 { |
|
812 DoControl(EControlCancelNotifyThreadCreation); |
|
813 } |
|
814 |
|
815 inline TInt RMemoryAccess::SetPriorityOverride(TInt aPriority, const TDesC8& aMatchString) |
|
816 { |
|
817 return DoControl(EControlSetPriorityOverride, (TAny*)aPriority, (TAny*)&aMatchString); |
|
818 } |
|
819 |
|
820 inline TInt RMemoryAccess::SetThreadCriticalFlags(RThread& aThread, TUint aFlags) |
|
821 { |
|
822 return DoControl(EControlSetCriticalFlags, (TAny*)aThread.Handle(), (TAny*)aFlags); |
|
823 } |
|
824 |
|
825 inline TInt RMemoryAccess::RThreadForceOpen(RThread& aThread, TUint aId) |
|
826 { |
|
827 TInt handle = DoControl(EControlOpenThread, (TAny*)aId, NULL); |
|
828 if (handle < 0) return handle; // error |
|
829 aThread.SetHandle(handle); |
|
830 return KErrNone; |
|
831 } |
|
832 |
|
833 inline TLinAddr RMemoryAccess::InPlaceThreadRename(RThread& aThread, const TDesC8& aNewName) |
|
834 { |
|
835 return DoControl(EControlInPlaceThreadRename, (TAny*)aThread.Handle(), (TAny*)&aNewName); |
|
836 } |
|
837 |
|
838 inline TInt RMemoryAccess::InPlaceObjectRename(TObjectType aObjectType, TUint8* aAddressOfKernelObject, const TDesC8& aNewName) |
|
839 { |
|
840 TObjectInfoByPtrParamsBuf params; |
|
841 params().iObjectType = aObjectType; |
|
842 params().iObjectPtr = aAddressOfKernelObject; |
|
843 return DoControl(EControlInPlaceObjectRename, (TAny*)¶ms, (TAny*)&aNewName); |
|
844 } |
|
845 |
|
846 inline TInt RMemoryAccess::InPlaceSetProcessFileName(RProcess& aProcess, const TDesC8& aNewName) |
|
847 { |
|
848 return DoControl(EControlInPlaceSetProcessFileName, (TAny*)aProcess.Handle(), (TAny*)&aNewName); |
|
849 } |
|
850 |
|
851 inline TInt RMemoryAccess::EnableHeapTracing(TUint aThreadId, TBool aEnable) |
|
852 { |
|
853 return DoControl(EControlEnableHeapTracing, (TAny*)aThreadId, (TAny*)aEnable); |
|
854 } |
|
855 |
|
856 inline TInt RMemoryAccess::DefragRam(TInt aPriority) |
|
857 { |
|
858 return DoControl(EControlDefragRam, (TAny*)aPriority, NULL); |
|
859 } |
|
860 |
|
861 inline TInt RMemoryAccess::EmptyRamZone(TUint aZone, TInt aPriority) |
|
862 { |
|
863 return DoControl(EControlEmptyRamZone, (TAny*)aPriority, (TAny*)aZone); |
|
864 } |
|
865 |
|
866 inline TInt RMemoryAccess::GetRamZoneInfo(TUint aZone, TDes8& aInfoPkg) |
|
867 { |
|
868 return DoControl(EControlGetRamZoneInfo, (TAny*)aZone, &aInfoPkg); |
|
869 } |
|
870 |
|
871 inline TInt RMemoryAccess::SetProcessProperties(RProcess& aProcess, const TProcessProperties& aProperties) |
|
872 { |
|
873 const TPckgC<TProcessProperties> props(aProperties); |
|
874 return DoControl(EControlSetProcessProperties, (TAny*)aProcess.Handle(), (TAny*)&props); |
|
875 } |
|
876 |
|
877 inline TInt RMemoryAccess::WriteShadowMemory(TLinAddr aAddress, const TDesC8& aNewContents) |
|
878 { |
|
879 return DoControl(EControlWriteShadowMemory, (TAny*)aAddress, (TAny*)&aNewContents); |
|
880 } |
|
881 |
|
882 inline TInt RMemoryAccess::FreeShadowMemory(TLinAddr aAddress, TInt aLen) |
|
883 { |
|
884 return DoControl(EControlFreeShadowMemory, (TAny*)aAddress, (TAny*)aLen); |
|
885 } |
|
886 |
|
887 inline TInt RMemoryAccess::SetZombieDebugMode(TInt aMode) |
|
888 { |
|
889 return DoControl(EControlSetZombieDebugMode, (TAny*)aMode, NULL); |
|
890 } |
|
891 |
|
892 inline TInt RMemoryAccess::GetZombieDebugMode() |
|
893 { |
|
894 return DoControl(EControlGetZombieDebugMode, NULL, NULL); |
|
895 } |
|
896 |
|
897 inline TInt RMemoryAccess::WriteMem(TUint aThreadId, const TDesC8& aMem, TAny* aAddr) |
|
898 { |
|
899 TAny* args[3]; |
|
900 args[0] = (TAny*)aThreadId; |
|
901 args[1] = (TAny*)&aMem; |
|
902 args[2] = aAddr; |
|
903 return DoControl(EControlWriteMem, &args[0], NULL); |
|
904 } |
|
905 |
|
906 inline TInt RMemoryAccess::SetTextTraceMode(TUint& aMode, TUint aMask) |
|
907 { |
|
908 return DoControl(EControlSetTextTraceMode, (TAny*)&aMode, (TAny*)aMask); |
|
909 } |
|
910 |
|
911 inline TInt RMemoryAccess::GetRegisters(RThread& aThread, TBool aUserMode, TDes8& aRegBuf, TUint32& aValid) |
|
912 { |
|
913 TUint32 args[4]; |
|
914 args[0] = aThread.Handle(); |
|
915 args[1] = aUserMode; |
|
916 args[2] = (TUint32)&aRegBuf; |
|
917 args[3] = (TUint32)&aValid; |
|
918 return DoControl(EControlGetRegisters, (TAny*)&args[0], NULL); |
|
919 } |
|
920 |
|
921 inline TInt RMemoryAccess::GetZombies(TDes8& aResultBuf) |
|
922 { |
|
923 return DoControl(EControlGetZombies, (TAny*)&aResultBuf, NULL); |
|
924 } |
|
925 |
|
926 inline TInt RMemoryAccess::ReleaseZombie(RThread& aThread) |
|
927 { |
|
928 return DoControl(EControlReleaseZombie, (TAny*)aThread.Handle(), NULL); |
|
929 } |
|
930 |
|
931 inline TInt RMemoryAccess::SuspendThread(RThread& aThread) |
|
932 { |
|
933 return DoControl(EControlSuspendThread, (TAny*)aThread.Handle(), NULL); |
|
934 } |
|
935 |
|
936 inline void RMemoryAccess::NotifyBreakpoint(TPckg<TBreakpointNotification>& aPkg, TRequestStatus& aStatus) |
|
937 { |
|
938 TRequestStatus* stat = &aStatus; |
|
939 TInt err = DoControl(EControlNotifyBreakpoint, &aPkg, stat); |
|
940 if (err) User::RequestComplete(stat, err); |
|
941 } |
|
942 |
|
943 inline void RMemoryAccess::CancelNotifyBreakpoint() |
|
944 { |
|
945 DoControl(EControlCancelNotifyBreakpoint, NULL, NULL); |
|
946 } |
|
947 |
|
948 inline TInt RMemoryAccess::SetBreakpoint(RThread& aThread, TLinAddr aAddress, RMemoryAccess::TPredicate* aCondition /*=NULL*/) |
|
949 { |
|
950 TUint32 args[2] = { aAddress, (TUint32)aCondition }; |
|
951 return DoControl(EControlSetBreakpoint, (TAny*)aThread.Handle(), (TAny*)&args[0]); |
|
952 } |
|
953 |
|
954 inline TInt RMemoryAccess::SetSymbolicBreakpoint(RThread& aThread, const TDesC8& aCodeseg, TUint aOffset, RMemoryAccess::TPredicate* aCondition /*=NULL*/) |
|
955 { |
|
956 TUint32 args[3] = { aThread.Handle(), aOffset, (TUint32)aCondition }; |
|
957 return DoControl(EControlSetSymbolicBreakpoint, (TAny*)&args[0], (TAny*)&aCodeseg); |
|
958 } |
|
959 |
|
960 inline TInt RMemoryAccess::SetBreakpointEnabled(TInt aBreakpointId, TBool aEnabled) |
|
961 { |
|
962 return DoControl(EControlSetBreakpointEnabled, (TAny*)aBreakpointId, (TAny*)aEnabled); |
|
963 } |
|
964 |
|
965 inline TInt RMemoryAccess::ClearBreakpoint(TInt aBreakpointId) |
|
966 { |
|
967 return DoControl(EControlClearBreakpoint, (TAny*)aBreakpointId, NULL); |
|
968 } |
|
969 |
|
970 inline TInt RMemoryAccess::ContinueFromBreakpoint(RThread& aThread) |
|
971 { |
|
972 return DoControl(EControlContinueFromBreakpoint, (TAny*)aThread.Handle()); |
|
973 } |
|
974 |
|
975 inline TInt RMemoryAccess::GetBreakpoints(TDes8& aBuf) |
|
976 { |
|
977 return DoControl(EControlGetBreakpoints, &aBuf); |
|
978 } |
|
979 |
|
980 inline TInt RMemoryAccess::RegisterPersistantBreakpoint(TLinAddr aAddress) |
|
981 { |
|
982 // aAddress is implicitly in the current thread |
|
983 return DoControl(EControlRegisterPersistantBreakpoint, (TAny*)aAddress, NULL); |
|
984 } |
|
985 |
|
986 inline TInt RMemoryAccess::TPredicate::AddCondition(TOp aOperation, TInt aRegNum, TUint32 aValue) |
|
987 { |
|
988 if (aRegNum < 0 || aRegNum > 15) return KErrArgument; |
|
989 |
|
990 TInt freeSlot = 0; |
|
991 while (((iOp >> (freeSlot*8)) & 0xF) != ENothing) |
|
992 { |
|
993 freeSlot++; |
|
994 if (freeSlot >= KNumSlots) return KErrOverflow; |
|
995 } |
|
996 |
|
997 TInt slotShift = freeSlot * 8; |
|
998 TUint32 slotMask = 0xFF << slotShift; |
|
999 iOp = (iOp & ~slotMask) | (aOperation << slotShift) | (aRegNum << (slotShift+4)); |
|
1000 iVals[freeSlot] = aValue; |
|
1001 return KErrNone; |
|
1002 } |
|
1003 |
|
1004 inline void RMemoryAccess::TPredicate::Description(TDes& aBuf) |
|
1005 { |
|
1006 TInt origLen = aBuf.Length(); |
|
1007 for (TInt slot = 0; slot < KNumSlots; slot++) |
|
1008 { |
|
1009 TInt slotShift = slot * 8; |
|
1010 TUint32 opAndReg = (iOp >> slotShift) & 0xFF; |
|
1011 TOp op = (TOp)(opAndReg & 0xF); |
|
1012 if (op == ENothing) break; |
|
1013 TInt reg = opAndReg >> 4; |
|
1014 |
|
1015 aBuf.AppendFormat(_L("r%d"), reg); |
|
1016 switch(op) |
|
1017 { |
|
1018 case EEq: |
|
1019 case ESignedEq: |
|
1020 aBuf.Append(_L("==")); break; |
|
1021 case ENe: |
|
1022 case ESignedNe: |
|
1023 aBuf.Append(_L("!=")); break; |
|
1024 case ELt: |
|
1025 case ESignedLt: |
|
1026 aBuf.Append('<'); break; |
|
1027 case ELe: |
|
1028 case ESignedLe: |
|
1029 aBuf.Append(_L("<=")); break; |
|
1030 case EGt: |
|
1031 case ESignedGt: |
|
1032 aBuf.Append('>'); break; |
|
1033 case EGe: |
|
1034 case ESignedGe: |
|
1035 aBuf.Append(_L(">=")); break; |
|
1036 default: |
|
1037 break; |
|
1038 } |
|
1039 if (op >= ESignedEq) |
|
1040 { |
|
1041 aBuf.AppendFormat(_L("%d,"), (TInt)iVals[slot]); |
|
1042 } |
|
1043 else |
|
1044 { |
|
1045 aBuf.AppendFormat(_L("%uu,"), iVals[slot]); |
|
1046 } |
|
1047 } |
|
1048 if (aBuf.Length() > origLen) aBuf.SetLength(aBuf.Length() - 1); // Chomp final comma |
|
1049 } |
|
1050 |
|
1051 inline TInt RMemoryAccess::SetDebugPort(TInt aPort) |
|
1052 { |
|
1053 return DoControl(EControlSetDebugPort, (TAny*)aPort, NULL); |
|
1054 } |
|
1055 |
|
1056 inline TUint RMemoryAccess::GetThreadCreatorId(TUint aThreadId) |
|
1057 { |
|
1058 TUint result = 0; |
|
1059 /*TInt err =*/ DoControl(EControlGetCreatorThread, (TAny*)aThreadId, &result); |
|
1060 return result; |
|
1061 } |
|
1062 |
|
1063 #endif //__KERNEL_MODE__ |
|
1064 |
|
1065 #endif //__MemoryAccess_H__ |