diff -r 000000000000 -r 7f656887cf89 libraries/memoryaccess/memoryaccess.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libraries/memoryaccess/memoryaccess.h Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,1065 @@ +// memoryaccess.h +// +// Copyright (c) 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Accenture - Initial contribution +// + +#ifndef __MemoryAccess_H__ +#define __MemoryAccess_H__ + +#ifndef __KERNEL_MODE__ +#include +#endif +#include + +_LIT(KMemoryAccessName,"memoryAccess-fshell"); + +typedef TBuf8 TFullName8; +typedef TBuf8 TFileName8; + +//size of buffer used for returning queues +const TInt KQueBufferLength = 1024; + +//Buffer used to pass pointer arrays, of pointers to kernel side objects +class TPointerArrayBuffer + { +public: + TUint8* iBuffer[KQueBufferLength]; //buffer holding up to KQueBufferLength items of the array or queue + TUint iStartFrom; //the point in the array to start from + TUint iCount; //the total number of entries written into iBuffer. If KMaxTInt, there are more available + }; + +// +//Structures used for communication with driver +// + +class RProcess; + +class TObjectInfoByIndexParams + { +public: + TObjectType iObjectType; + TUint iObjectIndex; + }; +typedef TPckgBuf TObjectInfoByIndexParamsBuf; + +class TObjectInfoByPtrParams + { +public: + TObjectType iObjectType; + TUint8* iObjectPtr; + }; +typedef TPckgBuf TObjectInfoByPtrParamsBuf; + +class TObjectInfoByNameParams + { +public: + TObjectType iObjectType; + TBuf8 iObjectName; + }; +typedef TPckgBuf TObjectInfoByNameParamsBuf; + +class TObjectInfoByHandleParams + { +public: + TObjectType iObjectType; + TInt iThreadId; + TInt iObjectHandle; + }; +typedef TPckgBuf TObjectInfoByHandleParamsBuf; + +class TThreadMemoryAccessParams + { +public: + TUint iId; + const TUint8* iAddr; + TInt iSize; + }; +typedef TPckgBuf TThreadMemoryAccessParamsBuf; + +class TObjectKillParams + { +public: + TObjectType iObjectType; + TUint iObjectId; + TUint8* iObjectPtr; + TExitType iType; + TInt iReason; + TFullName8 iCategory; + }; +typedef TPckgBuf TObjectKillParamsBuf; + +class TGetObjectAddressesParams + { +public: + TObjectType iObjectType; + TFullName8 iOwningProcess; + }; +typedef TPckgBuf TGetObjectAddressesParamsBuf; + +class TGetChunkAddressesParams + { +public: + TUint iControllingProcessId; + }; +typedef TPckgBuf TGetChunkAddressesParamsBuf; + +class TObjectKernelInfo + { +public: + TUint8* iAddressOfKernelObject; + TFullName8 iName; + TFullName8 iFullName; + TInt iAccessCount; + TInt iUniqueID; + TUint iProtection; + TUint8* iAddressOfKernelOwner; + }; +typedef TPckgBuf TObjectKernelInfoBuf; + +class TThreadKernelInfo : public TObjectKernelInfo + { +public: + TUint iThreadId; + TUint8* iAddressOfOwningProcess; + TInt iThreadPriority; + TInt iUserStackSize; + TUint32 iFlags; + TLinAddr iSupervisorStack; + TInt iSupervisorStackSize; + TLinAddr iUserStackLimit; + TInt iNThreadSuspendCount; + inline TLinAddr UserStackBase() const { return iUserStackLimit + iUserStackSize; } + }; +typedef TPckgBuf TThreadKernelInfoBuf; + +const TInt KNumEnvironmentSlots = 16; + +class TProcessKernelInfo : public TObjectKernelInfo + { +public: + TUint iProcessId; + TInt iPriority; + TUint8* iAddressOfOwningProcess; + TUint iCreatorId; + TUint iSecurityZone; + TUidType iUids; + TInt iAttributes; + TUint8* iAddressOfDataBssStackChunk; + TPointerArrayBuffer iThreadQ; + SSecurityInfo iProcessSecurityInfo; + SSecurityInfo iProcessCreatorSecurityInfo; + TBuf8<256> iCommandLine; + TUint32 iFlags; + TInt iEnvironmentData[KNumEnvironmentSlots]; + TUint iFirstThreadId; + }; +typedef TPckgBuf TProcessKernelInfoBuf; + +class TChunkKernelInfo : public TObjectKernelInfo + { +public: + TInt iSize; + TInt iMaxSize; + TUint8* iBase; + TInt iBottom; + TInt iTop; + TInt iAttributes; + TInt iStartPos; + TUint iControllingOwnerProcessId; + TUint iRestrictions; + TUint iMapAttr; + TUint iChunkType; + TUint8* iAddressOfOwningProcess; + }; +typedef TPckgBuf TChunkKernelInfoBuf; + +class TLibraryKernelInfo : public TObjectKernelInfo + { +public: + TInt iMapCount; + TUint8 iState; + TUint8* iAddressOfCodeSeg; + }; +typedef TPckgBuf TLibraryKernelInfoBuf; + +class TSemaphoreKernelInfo : public TObjectKernelInfo + { +public: + TInt iCount; + TUint8 iResetting; + TPointerArrayBuffer iSuspendedQ; + }; +typedef TPckgBuf TSemaphoreKernelInfoBuf; + +class TMutexKernelInfo : public TObjectKernelInfo + { +public: + TInt iHoldCount; + TInt iWaitCount; + TUint8 iResetting; + TUint8 iOrder; + TPointerArrayBuffer iSuspendedQ; + TPointerArrayBuffer iPendingQ; + }; +typedef TPckgBuf TMutexKernelInfoBuf; + +class TTimerKernelInfo : public TObjectKernelInfo + { +public: + TUint8 iState; + TUint8 iType; + TLinAddr iClientStatus; + }; +typedef TPckgBuf TTimerKernelInfoBuf; + +class TServerKernelInfo : public TObjectKernelInfo + { +public: + TUint8* iAddressOfOwningThread; + TUint8 iSessionType; + TPointerArrayBuffer iSessionQ; + TUint iOwningThreadId; + }; +typedef TPckgBuf TServerKernelInfoBuf; + +class TSessionKernelInfo : public TObjectKernelInfo + { +public: + TUint8* iServer; + TAny* iSessionPtr; + TUint16 iTotalAccessCount; + TUint8 iSessionType; + TUint8 iSvrSessionType; + TInt iMsgCount; + TInt iMsgLimit; + }; +typedef TPckgBuf TSessionKernelInfoBuf; + +class TLogicalDeviceKernelInfo : public TObjectKernelInfo + { +public: + TVersion iVersion; + TUint iParseMask; + TUint iUnitsMask; + TInt iOpenChannels; + }; +typedef TPckgBuf TLogicalDeviceKernelInfoBuf; + +class TPhysicalDeviceKernelInfo : public TObjectKernelInfo + { +public: + TVersion iVersion; + TUint iUnitsMask; + TUint8* iAddressOfCodeSeg; + }; +typedef TPckgBuf TPhysicalDeviceKernelInfoBuf; + +class TLogicalChannelKernelInfo : public TObjectKernelInfo + { +public: + }; +typedef TPckgBuf TLogicalChannelKernelInfoBuf; + +class TChangeNotifierKernelInfo : public TObjectKernelInfo + { +public: + TUint iChanges; + TUint8* iAddressOfThread; + }; +typedef TPckgBuf TChangeNotifierKernelInfoBuf; + +class TUndertakerKernelInfo : public TObjectKernelInfo + { +public: + TUint8* iOwningThread; + }; +typedef TPckgBuf TUndertakerKernelInfoBuf; + +class TMsgQueueKernelInfo : public TObjectKernelInfo + { +public: + TUint iMaxMsgLength; + }; +typedef TPckgBuf TMsgQueueKernelInfoBuf; + +class TPropertyRefKernelInfo : public TObjectKernelInfo + { +public: + }; +typedef TPckgBuf TPropertyRefKernelInfoBuf; + +class TCondVarKernelInfo : public TObjectKernelInfo + { +public: + TUint8 iResetting; + TUint8* iAddressOfMutex; + TInt iWaitCount; + TPointerArrayBuffer iSuspendedQ; + }; +typedef TPckgBuf TCondVarKernelInfoBuf; + +class TCodeSegKernelInfo + { +public: + TUint32 iRunAddress; + TInt iSize; + TFileName8 iFileName; + }; +typedef TPckgBuf TCodeSegKernelInfoBuf; + +class TTomsciCodeSegKernelInfo : public TCodeSegKernelInfo + { +public: + TUint8* iAddressOfKernelObject; + TFullName8 iName; + TInt iAccessCount; + TInt iDepCount; + }; + +class TProp + { +public: + TUid iCategory; + TUint iKey; + TInt iActualSize; // Return value, only used when getting a descriptor property + TBool iDefine; + }; + +class TPropNotifyResult + { +public: + TUint iCategory; + TUint iKey; + TInt iMissedChanges; + TInt iError; + }; + +class TRamZoneInfo + { +public: + TUint iFreePages; + TUint iUnknownPages; + TUint iFixedPages; + TUint iMovablePages; + TUint iDiscardablePages; + }; + +class TProcessProperties + { +public: + TProcessProperties() : iSid(0xFFFFFFFFu), iVid(0xFFFFFFFFu), /*iHeapMin(0), iHeapMax(0), iStackSize(0),*/ iProcessPriority(0) + { + iCapsToAdd.SetEmpty(); + iCapsToRemove.SetEmpty(); + } + + TCapabilitySet iCapsToAdd; + TCapabilitySet iCapsToRemove; + TUint iSid; + TUint iVid; + //TUint iHeapMin; + //TUint iHeapMax; + //TUint iStackSize; + TInt iProcessPriority; + }; + +// class RMemoryAccess +// User side communication interface to Memory Access driver. +// Provides access to arbitrary kernel objects, memory, and some basic object manipulation. +// For use in debugging tools only! Do not include in a release ROM. +class RMemoryAccess : public RBusLogicalChannel + { +public: + enum TControl + { + EControlGetThreadMem, + EControlGetAllocatorAddress, + EControlResetTimer, + EControlGetContainerCount, + EControlAcquireContainerMutex, + EControlReleaseContainerMutex, + EControlGetObjectType, + EControlGetObjectInfo, + EControlGetObjectInfoByPtr, + EControlGetObjectInfoByHandle, + EControlAcquireCodeSegMutex, + EControlReleaseCodeSegMutex, + EControlGetNextCodeSegInfo, + EControlObjectDie, + EControlGetObjectInfoByName, + EControlGetObjectAddresses, + EControlGetChunkAddresses, + EControlGetCurrentAllocatorAddress, + EControlFindPtrInCodeSegments, + EControlGetHandleOwners, + EControlForceCrash, + EControlGetPropertyInt, + EControlGetPropertyDesc, + EControlSetPropertyInt, + EControlSetPropertyDesc, + EControlDeleteProperty, + EControlSetThreadPriority, + EControlNotifyThreadCreation, + EControlCancelNotifyThreadCreation, + EControlSetPriorityOverride, + EControlSetCriticalFlags, + EControlOpenThread, + EControlGetThreadHandles, + EControlGetProcessHandles, + EControlInPlaceThreadRename, + ERemoved1, //EControlGetBinaryPropertyKernelLocation + EControlInPlaceObjectRename, + EControlInPlaceSetProcessFileName, + ERemoved2, //EControlGetAllProperties, + ERemoved3, //EControlSetupMassPropertyNotify, + ERemoved4, //EControlMassPropertyNotifyStart, + ERemoved5, //EControlMassPropertyNotifyStop, + EControlEnableHeapTracing, + EControlDefragRam, + EControlEmptyRamZone, + EControlGetRamZoneInfo, + EControlSetProcessProperties, + EControlWriteShadowMemory, + EControlFreeShadowMemory, + EControlSetZombieDebugMode, + EControlWriteMem, + EControlSetTextTraceMode, + EControlGetRegisters, + EControlGetZombies, + EControlGetZombieDebugMode, + EControlReleaseZombie, + EControlSuspendThread, + EControlNotifyBreakpoint, + EControlSetBreakpoint, + EControlSetBreakpointEnabled, + EControlClearBreakpoint, + EControlContinueFromBreakpoint, + EControlGetBreakpoints, + EControlCancelNotifyBreakpoint, + EControlRegisterPersistantBreakpoint, + EControlSetSymbolicBreakpoint, + EControlSetDebugPort, + EControlReboot, + EControlGetCreatorThread, + EControlPropertyNotify, + EControlPropertyNotifyCancel, + EControlSubscribeToProperty, + ENumRequests, // Add new commands above this line + }; +public: + static TInt LoadDriver(); + static void CloseDriver(); + +public: + //Open the driver + TInt Open(); + //Deprecated. + TInt ResetTimer(); + //Read memory from the context of a thread + TInt GetThreadMem(const TThreadMemoryAccessParamsBuf& aParams, TDes8& aBuf); + //Get the address of the allocator of a thread + TInt GetAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject); + TInt GetCurrentAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject); + TInt FindAddressInCodeSegments(TFullName8& aDllName, TAny* aPtr); + TInt GetHandleOwners(TAny* aKernelObjectPtr, TDes8& aOwnersBuf); + TInt GetThreadHandles(TUint aThreadId, TDes8& aHandlesBuf); + TInt GetProcessHandles(TUint aProcessId, TDes8& aHandlesBuf); + void ForceCrash(); + void Reboot(TInt aReason); + + //Get the number of objects in a specified kernel container + TInt GetContainerCount (const TObjectType aObjectType, TUint& aCount); + //Wait on the mutex of a specified kernel container + TInt AcquireContainerMutex (const TObjectType aObjectType); + //Signal the mutex of a specified kernel container + TInt ReleaseContainerMutex (const TObjectType aObjectType); + //Get the type of a DObject* object in the kernel + TInt GetObjectType (TUint8* aKernelObjectAddr, TObjectType& aObjectType); + //Get info about a kernel object, referenced by position in its container. Call AcquireContainerMutex before calling. + TInt GetObjectInfo (TObjectType aObjectType, TUint aIndexInKernelContainer, TDes8& aObjectInfoBuf); + //Get info about a kernel object specified as a DObject* + TInt GetObjectInfo (TObjectType aObjectType, TUint8* aAddressOfKernelObject, TDes8& aObjectInfoBuf); + //Get info about a kernel object specified by name. + TInt GetObjectInfo (TObjectType aObjectType, const TDesC& aObjectName, TDes8& aObjectInfoBuf); + //Get info about a kernel object specified as a user side handle + TInt GetObjectInfoByHandle (TObjectType aObjectType, TInt aThreadId, TInt aObjectHandle, TDes8& aObjectInfoBuf); + //Wait on the kernel's code seg mutex + TInt AcquireCodeSegMutex(); + //Signal the kernel's code seg mutex + TInt ReleaseCodeSegMutex(); + //Get info about the next code seg. Call repeatedly to iterate all code segs. Call AcquireCodeSegMutex before calling. + TInt GetNextCodeSegInfo(TDes8& aCodeSegInfoBuf); + //Kill an object. aObyType should be a thread or process. Either an objectId (user side handle) _OR_ objectPtr (kernel side DObject*) should be provided. + TInt ObjectDie(TObjectType aObjType, TUint aObjectId, TUint8* aObjectPtr, TExitType aType, TInt aReason, const TDesC& aCategory); + //Pack the addresses of all the kernel objects of the specified type belonging to the specified process into the supplied buffer. + //Returns KErrOverflow if the buffer isn't big enough to hold all the addresses. aOwningProcess may contain '?' and '*' wild characters. + TInt GetObjectAddresses(TObjectType aObjType, const TDesC& aOwningProcess, TDes8& aAddressBuffer); + //Pack the addresses of all the chunks with a the specified controlling process id into the supplied buffer. + //Returns KErrOverflow if the buffer isn't big enough to hold all the addresses. Note, this interface allows global chunks (which have + //a NULL owner pointers, hence can't be found using RMemoryAccess::GetObjectAddresses) that were created by a particular process to be found. + TInt GetChunkAddresses(TUint aControllingProcessId, TDes8& aAddressBuffer); + + TInt GetProperty(TUid aCategory, TUint aKey, TInt& aValue); + TInt GetProperty(TUid aCategory, TUint aKey, TDes8& aValue, TInt& aActualSize); + TInt SetProperty(TUid aCategory, TUint aKey, TInt aValue, TBool aDefineIfNotSet=EFalse); + TInt SetProperty(TUid aCategory, TUint aKey, const TDesC8& aValue, TBool aDefineIfNotSet=EFalse); + TInt DeleteProperty(TUid aCategory, TUint aKey); + TInt SubscribeToProperty(TUid aCategory, TUint aKey, TBool aOutputToBtrace); // If aOutputToBtrace is false, use NotifyPropertyChange to get details + + void NotifyPropertyChange(TPropNotifyResult& aResult, TRequestStatus& aStatus); + void CancelPropertyChange(); + + TInt RThreadForceOpen(RThread& aThread, TUint aId); + TInt SetThreadPriority(RThread& aThread, TInt aPriority); + void NotifyThreadCreation(TRequestStatus& aStatus); + void CancelNotifyThreadCreation(); + TInt SetPriorityOverride(TInt aPriority, const TDesC8& aMatchString); // any thread that is created that matches the wildcard string aMatchString is given thread priority aPriority + TInt SetThreadCriticalFlags(RThread& aThread, TUint aFlags); + TLinAddr InPlaceThreadRename(RThread& aThread, const TDesC8& aNewName); + TInt InPlaceObjectRename(TObjectType aObjectType, TUint8* aAddressOfKernelObject, const TDesC8& aNewName); + TInt InPlaceSetProcessFileName(RProcess& aProcess, const TDesC8& aNewName); + TInt SetProcessProperties(RProcess& aProcess, const TProcessProperties& aProperties); + TInt WriteShadowMemory(TLinAddr aAddress, const TDesC8& aNewContents); + TInt FreeShadowMemory(TLinAddr aAddress, TInt aLen); + TInt SetDebugPort(TInt aPort); + TUint GetThreadCreatorId(TUint aThreadId); + + TInt EnableHeapTracing(TUint aThreadId, TBool aEnable); + TInt DefragRam(TInt aPriority); + TInt EmptyRamZone(TUint aZone, TInt aPriority); + TInt GetRamZoneInfo(TUint aZone, TDes8& aInfoPkg); + + // Debugger APIs + TInt GetZombieDebugMode(); + TInt SetZombieDebugMode(TInt aMode); + class TZombieInfo + { + public: + TUint iThreadId; + enum TFlags { ESuspended = 1, EBreakpoint = 2 }; + TUint iFlags; + }; + TInt GetZombies(TDes8& aResultBuf); // buffer full of TZombieInfos + TInt WriteMem(TUint aThreadId, const TDesC8& aMem, TAny* aAddr); + TInt SetTextTraceMode(TUint& aMode, TUint aMask); + TInt GetRegisters(RThread& aThread, TBool aUserMode, TDes8& aRegBuf, TUint32& aValid); + TInt ReleaseZombie(RThread& aThread); + TInt SuspendThread(RThread& aThread); // To resume, call ReleaseZombie + + class TBreakpointNotification + { + public: + TUint iThreadId; + TInt iBreakpointId; + TLinAddr iAddress; + }; + + class TPredicate + { + public: + enum { KNumSlots = 4 }; + enum TOp + { + ENothing = 0, + EEq, ENe, ELt, ELe, EGt, EGe, ESignedEq, ESignedNe, ESignedLt, ESignedLe, ESignedGt, ESignedGe, + }; + TPredicate() : iOp(0) {} + TBool HasConditions() const { return iOp != 0; } + +#ifdef __KERNEL_MODE__ + TBool SatisfiesConditions(TUint32* aRegisterSet) const; + private: + static TBool Test(TOp aOperation, TUint32 aCurrentValue, TUint32 aStoredValue); +#else + TInt AddCondition(TOp aOperation, TInt aRegNum, TUint32 aValue); + void Description(TDes& aBuf); +#endif + + private: + 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) + TUint32 iVals[KNumSlots]; + }; + + void NotifyBreakpoint(TPckg& aPkg, TRequestStatus& aStatus); + void CancelNotifyBreakpoint(); + //TInt SetBreakpoint(TLinAddr aAddress); // Global, all threads (except caller and the memaccess DFC thread). Returns breakpoint ID or an error code + 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 + TInt SetSymbolicBreakpoint(RThread& aThread, const TDesC8& aCodeseg, TUint aOffset, TPredicate* aCondition = NULL); + TInt RegisterPersistantBreakpoint(TLinAddr aAddress); + TInt SetBreakpointEnabled(TInt aBreakpointId, TBool aEnabled); + TInt ClearBreakpoint(TInt aBreakpointId); // Removes it completely. Doesn't resume anything waiting on it though + TInt ContinueFromBreakpoint(RThread& aThread); // aThread must be waiting on a breakpoint otherwise KErrNotReady + + class TBreakpointInfo + { + public: + TUint iThreadId; + TInt iBreakpointId; + TLinAddr iAddress; + enum TFlags + { + EPending = 1, + 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 + EHardware = 0x40000000, + }; + TUint32 iFlags; + TPredicate iCondition; + }; + TInt GetBreakpoints(TDes8& aBuf); // buffer full of TBreakpointInfos + }; + +#ifndef __KERNEL_MODE__ +// Inline implementations of user side interface + +inline TInt RMemoryAccess::LoadDriver() + { return User::LoadLogicalDevice(KMemoryAccessName); } +inline void RMemoryAccess::CloseDriver() + { User::FreeLogicalDevice(KMemoryAccessName); } +inline TInt RMemoryAccess::Open() + { return DoCreate(KMemoryAccessName,TVersion(1,0,0),KNullUnit,NULL,NULL); } +inline TInt RMemoryAccess::GetThreadMem(const TThreadMemoryAccessParamsBuf& aParams, TDes8& aBuf) + { return DoControl(EControlGetThreadMem, (TAny*)&aParams, (TAny*)&aBuf); } +inline TInt RMemoryAccess::GetAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject) + { return DoControl(EControlGetAllocatorAddress, (TAny*)aThreadId, &aAddressOfKernelObject); } +// This returns the current allocator (User::Allocator) as opposed to the one created in SThreadCreateInfo +inline TInt RMemoryAccess::GetCurrentAllocatorAddress(TUint aThreadId, TUint8*& aAddressOfKernelObject) + { return DoControl(EControlGetCurrentAllocatorAddress, (TAny*)aThreadId, &aAddressOfKernelObject); } +inline TInt RMemoryAccess::FindAddressInCodeSegments(TFullName8& aDllName, TAny* aPtr) + { return DoControl(EControlFindPtrInCodeSegments, (TAny*)&aDllName, aPtr); } +inline TInt RMemoryAccess::GetHandleOwners(TAny* aHandle, TDes8& aOwnersBuf) + { return DoControl(EControlGetHandleOwners, (TAny*)aHandle, (TAny*)&aOwnersBuf); } +inline TInt RMemoryAccess::GetThreadHandles(TUint aThreadId, TDes8& aHandlesBuf) + { return DoControl(EControlGetThreadHandles, (TAny*)aThreadId, &aHandlesBuf); } +inline TInt RMemoryAccess::GetProcessHandles(TUint aProcessId, TDes8& aHandlesBuf) + { return DoControl(EControlGetProcessHandles, (TAny*)aProcessId, &aHandlesBuf); } +inline void RMemoryAccess::ForceCrash() + { DoControl(EControlForceCrash); } +inline void RMemoryAccess::Reboot(TInt aReason) + { DoControl(EControlReboot, (TAny*)aReason); } +inline TInt RMemoryAccess::ResetTimer() + { return DoControl(EControlResetTimer, NULL, NULL); } +inline TInt RMemoryAccess::GetContainerCount (const TObjectType aObjectType, TUint& aCount) + { return DoControl(EControlGetContainerCount, (TAny*)aObjectType, (TAny*)&aCount); } +inline TInt RMemoryAccess::AcquireContainerMutex (const TObjectType aObjectType) { return DoControl(EControlAcquireContainerMutex, (TAny*)aObjectType, NULL); } +inline TInt RMemoryAccess::ReleaseContainerMutex (const TObjectType aObjectType) + { return DoControl(EControlReleaseContainerMutex, (TAny*)aObjectType, NULL); } +inline TInt RMemoryAccess::GetObjectType (TUint8* aKernelObjectAddr, TObjectType& aObjectType) + { return DoControl(EControlGetObjectType, (TAny*)aKernelObjectAddr, (TAny*)&aObjectType); } +inline TInt RMemoryAccess::GetObjectInfo (TObjectType aObjectType, TUint aIndexInKernelContainer, TDes8& aObjectInfoBuf) + { + TObjectInfoByIndexParamsBuf params; + params().iObjectType=aObjectType; + params().iObjectIndex=aIndexInKernelContainer; + return DoControl(EControlGetObjectInfo, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); + } +inline TInt RMemoryAccess::GetObjectInfo (TObjectType aObjectType, TUint8* aAddressOfKernelObject, TDes8& aObjectInfoBuf) + { + TObjectInfoByPtrParamsBuf params; + params().iObjectType=aObjectType; + params().iObjectPtr=aAddressOfKernelObject; + return DoControl(EControlGetObjectInfoByPtr, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); + } +inline TInt RMemoryAccess::GetObjectInfo (TObjectType aObjectType, const TDesC& aObjectName, TDes8& aObjectInfoBuf) + { + TObjectInfoByNameParamsBuf params; + params().iObjectType=aObjectType; + params().iObjectName.Copy(aObjectName); + return DoControl(EControlGetObjectInfoByName, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); + } +inline TInt RMemoryAccess::GetObjectInfoByHandle (TObjectType aObjectType, TInt aThreadId, TInt aObjectHandle, TDes8& aObjectInfoBuf) + { + TObjectInfoByHandleParamsBuf params; + params().iObjectType=aObjectType; + params().iThreadId=aThreadId; + params().iObjectHandle=aObjectHandle; + return DoControl(EControlGetObjectInfoByHandle, (TAny*)¶ms, (TAny*)&aObjectInfoBuf); + } +inline TInt RMemoryAccess::AcquireCodeSegMutex() + { return DoControl(EControlAcquireCodeSegMutex, NULL, NULL); } +inline TInt RMemoryAccess::ReleaseCodeSegMutex() + { return DoControl(EControlReleaseCodeSegMutex, NULL, NULL); } +inline TInt RMemoryAccess::GetNextCodeSegInfo(TDes8& aCodeSegInfoBuf) + { return DoControl(EControlGetNextCodeSegInfo, (TAny*)&aCodeSegInfoBuf, NULL); } +inline TInt RMemoryAccess::ObjectDie(TObjectType aObjType, TUint aObjectId, TUint8* aObjectPtr, TExitType aType, TInt aReason, const TDesC& aCategory) + { + TObjectKillParamsBuf params; + params().iObjectType=aObjType; + params().iObjectId=aObjectId; + params().iObjectPtr=aObjectPtr; + params().iType=aType; + params().iReason=aReason; + params().iCategory.Copy(aCategory); + return DoControl(EControlObjectDie, (TAny*)¶ms, NULL); + } +inline TInt RMemoryAccess::GetObjectAddresses(TObjectType aObjType, const TDesC& aOwningProcess, TDes8& aAddressBuffer) + { + TGetObjectAddressesParamsBuf params; + params().iObjectType=aObjType; + params().iOwningProcess.Copy(aOwningProcess); + return DoControl(EControlGetObjectAddresses, (TAny*)¶ms, (TAny*)&aAddressBuffer); + } +inline TInt RMemoryAccess::GetChunkAddresses(TUint aControllingProcessId, TDes8& aAddressBuffer) + { + TGetChunkAddressesParamsBuf params; + params().iControllingProcessId=aControllingProcessId; + return DoControl(EControlGetChunkAddresses, (TAny*)¶ms, (TAny*)&aAddressBuffer); + } + +inline TInt RMemoryAccess::GetProperty(TUid aCategory, TUint aKey, TInt& aValue) + { + TProp params; + params.iCategory = aCategory; + params.iKey = aKey; + params.iDefine = EFalse; + + TPckg res(aValue); + + return DoControl(EControlGetPropertyInt, (TAny*)¶ms, (TAny*)&res); + } + +inline TInt RMemoryAccess::GetProperty(TUid aCategory, TUint aKey, TDes8& aValue, TInt& aActualSize) + { + TProp params; + params.iCategory = aCategory; + params.iKey = aKey; + params.iDefine = EFalse; + + TInt err = DoControl(EControlGetPropertyDesc, (TAny*)¶ms, (TAny*)&aValue); + if (err == KErrOverflow) + { + aActualSize = params.iActualSize; + } + return err; + } + +inline TInt RMemoryAccess::SetProperty(TUid aCategory, TUint aKey, TInt aValue, TBool aDefineIfNotSet) + { + TProp params; + params.iCategory = aCategory; + params.iKey = aKey; + params.iDefine = aDefineIfNotSet; + + return DoControl(EControlSetPropertyInt, (TAny*)¶ms, (TAny*)aValue); + } + +inline TInt RMemoryAccess::SetProperty(TUid aCategory, TUint aKey, const TDesC8& aValue, TBool aDefineIfNotSet) + { + TProp params; + params.iCategory = aCategory; + params.iKey = aKey; + params.iDefine = aDefineIfNotSet; + + return DoControl(EControlSetPropertyDesc, (TAny*)¶ms, (TAny*)&aValue); + } + +inline TInt RMemoryAccess::DeleteProperty(TUid aCategory, TUint aKey) + { + TProp params; + params.iCategory = aCategory; + params.iKey = aKey; + params.iDefine = EFalse; + + return DoControl(EControlDeleteProperty, (TAny*)¶ms, NULL); + } + +inline void RMemoryAccess::NotifyPropertyChange(TPropNotifyResult& aResult, TRequestStatus& aStatus) + { + aStatus = KRequestPending; + TInt err = DoControl(EControlPropertyNotify, (TAny*)&aResult, (TAny*)&aStatus); + if (err) + { + TRequestStatus* ffs = &aStatus; + User::RequestComplete(ffs, err); + } + } + +inline void RMemoryAccess::CancelPropertyChange() + { + DoControl(EControlPropertyNotifyCancel, NULL, NULL); + } + +inline TInt RMemoryAccess::SubscribeToProperty(TUid aCategory, TUint aKey, TBool aOutputToBtrace) + { + TProp params; + params.iCategory = aCategory; + params.iKey = aKey; + params.iDefine = EFalse; + return DoControl(EControlSubscribeToProperty, (TAny*)¶ms, (TAny*)aOutputToBtrace); + } + +inline TInt RMemoryAccess::SetThreadPriority(RThread& aThread, TInt aPriority) + { + return DoControl(EControlSetThreadPriority, (TAny*)aThread.Handle(), (TAny*)aPriority); + } + +inline void RMemoryAccess::NotifyThreadCreation(TRequestStatus& aStatus) + { + aStatus = KRequestPending; + TRequestStatus* stat = &aStatus; + TInt err = DoControl(EControlNotifyThreadCreation, stat, NULL); + if (err) User::RequestComplete(stat, err); + } + +inline void RMemoryAccess::CancelNotifyThreadCreation() + { + DoControl(EControlCancelNotifyThreadCreation); + } + +inline TInt RMemoryAccess::SetPriorityOverride(TInt aPriority, const TDesC8& aMatchString) + { + return DoControl(EControlSetPriorityOverride, (TAny*)aPriority, (TAny*)&aMatchString); + } + +inline TInt RMemoryAccess::SetThreadCriticalFlags(RThread& aThread, TUint aFlags) + { + return DoControl(EControlSetCriticalFlags, (TAny*)aThread.Handle(), (TAny*)aFlags); + } + +inline TInt RMemoryAccess::RThreadForceOpen(RThread& aThread, TUint aId) + { + TInt handle = DoControl(EControlOpenThread, (TAny*)aId, NULL); + if (handle < 0) return handle; // error + aThread.SetHandle(handle); + return KErrNone; + } + +inline TLinAddr RMemoryAccess::InPlaceThreadRename(RThread& aThread, const TDesC8& aNewName) + { + return DoControl(EControlInPlaceThreadRename, (TAny*)aThread.Handle(), (TAny*)&aNewName); + } + +inline TInt RMemoryAccess::InPlaceObjectRename(TObjectType aObjectType, TUint8* aAddressOfKernelObject, const TDesC8& aNewName) + { + TObjectInfoByPtrParamsBuf params; + params().iObjectType = aObjectType; + params().iObjectPtr = aAddressOfKernelObject; + return DoControl(EControlInPlaceObjectRename, (TAny*)¶ms, (TAny*)&aNewName); + } + +inline TInt RMemoryAccess::InPlaceSetProcessFileName(RProcess& aProcess, const TDesC8& aNewName) + { + return DoControl(EControlInPlaceSetProcessFileName, (TAny*)aProcess.Handle(), (TAny*)&aNewName); + } + +inline TInt RMemoryAccess::EnableHeapTracing(TUint aThreadId, TBool aEnable) + { + return DoControl(EControlEnableHeapTracing, (TAny*)aThreadId, (TAny*)aEnable); + } + +inline TInt RMemoryAccess::DefragRam(TInt aPriority) + { + return DoControl(EControlDefragRam, (TAny*)aPriority, NULL); + } + +inline TInt RMemoryAccess::EmptyRamZone(TUint aZone, TInt aPriority) + { + return DoControl(EControlEmptyRamZone, (TAny*)aPriority, (TAny*)aZone); + } + +inline TInt RMemoryAccess::GetRamZoneInfo(TUint aZone, TDes8& aInfoPkg) + { + return DoControl(EControlGetRamZoneInfo, (TAny*)aZone, &aInfoPkg); + } + +inline TInt RMemoryAccess::SetProcessProperties(RProcess& aProcess, const TProcessProperties& aProperties) + { + const TPckgC props(aProperties); + return DoControl(EControlSetProcessProperties, (TAny*)aProcess.Handle(), (TAny*)&props); + } + +inline TInt RMemoryAccess::WriteShadowMemory(TLinAddr aAddress, const TDesC8& aNewContents) + { + return DoControl(EControlWriteShadowMemory, (TAny*)aAddress, (TAny*)&aNewContents); + } + +inline TInt RMemoryAccess::FreeShadowMemory(TLinAddr aAddress, TInt aLen) + { + return DoControl(EControlFreeShadowMemory, (TAny*)aAddress, (TAny*)aLen); + } + +inline TInt RMemoryAccess::SetZombieDebugMode(TInt aMode) + { + return DoControl(EControlSetZombieDebugMode, (TAny*)aMode, NULL); + } + +inline TInt RMemoryAccess::GetZombieDebugMode() + { + return DoControl(EControlGetZombieDebugMode, NULL, NULL); + } + +inline TInt RMemoryAccess::WriteMem(TUint aThreadId, const TDesC8& aMem, TAny* aAddr) + { + TAny* args[3]; + args[0] = (TAny*)aThreadId; + args[1] = (TAny*)&aMem; + args[2] = aAddr; + return DoControl(EControlWriteMem, &args[0], NULL); + } + +inline TInt RMemoryAccess::SetTextTraceMode(TUint& aMode, TUint aMask) + { + return DoControl(EControlSetTextTraceMode, (TAny*)&aMode, (TAny*)aMask); + } + +inline TInt RMemoryAccess::GetRegisters(RThread& aThread, TBool aUserMode, TDes8& aRegBuf, TUint32& aValid) + { + TUint32 args[4]; + args[0] = aThread.Handle(); + args[1] = aUserMode; + args[2] = (TUint32)&aRegBuf; + args[3] = (TUint32)&aValid; + return DoControl(EControlGetRegisters, (TAny*)&args[0], NULL); + } + +inline TInt RMemoryAccess::GetZombies(TDes8& aResultBuf) + { + return DoControl(EControlGetZombies, (TAny*)&aResultBuf, NULL); + } + +inline TInt RMemoryAccess::ReleaseZombie(RThread& aThread) + { + return DoControl(EControlReleaseZombie, (TAny*)aThread.Handle(), NULL); + } + +inline TInt RMemoryAccess::SuspendThread(RThread& aThread) + { + return DoControl(EControlSuspendThread, (TAny*)aThread.Handle(), NULL); + } + +inline void RMemoryAccess::NotifyBreakpoint(TPckg& aPkg, TRequestStatus& aStatus) + { + TRequestStatus* stat = &aStatus; + TInt err = DoControl(EControlNotifyBreakpoint, &aPkg, stat); + if (err) User::RequestComplete(stat, err); + } + +inline void RMemoryAccess::CancelNotifyBreakpoint() + { + DoControl(EControlCancelNotifyBreakpoint, NULL, NULL); + } + +inline TInt RMemoryAccess::SetBreakpoint(RThread& aThread, TLinAddr aAddress, RMemoryAccess::TPredicate* aCondition /*=NULL*/) + { + TUint32 args[2] = { aAddress, (TUint32)aCondition }; + return DoControl(EControlSetBreakpoint, (TAny*)aThread.Handle(), (TAny*)&args[0]); + } + +inline TInt RMemoryAccess::SetSymbolicBreakpoint(RThread& aThread, const TDesC8& aCodeseg, TUint aOffset, RMemoryAccess::TPredicate* aCondition /*=NULL*/) + { + TUint32 args[3] = { aThread.Handle(), aOffset, (TUint32)aCondition }; + return DoControl(EControlSetSymbolicBreakpoint, (TAny*)&args[0], (TAny*)&aCodeseg); + } + +inline TInt RMemoryAccess::SetBreakpointEnabled(TInt aBreakpointId, TBool aEnabled) + { + return DoControl(EControlSetBreakpointEnabled, (TAny*)aBreakpointId, (TAny*)aEnabled); + } + +inline TInt RMemoryAccess::ClearBreakpoint(TInt aBreakpointId) + { + return DoControl(EControlClearBreakpoint, (TAny*)aBreakpointId, NULL); + } + +inline TInt RMemoryAccess::ContinueFromBreakpoint(RThread& aThread) + { + return DoControl(EControlContinueFromBreakpoint, (TAny*)aThread.Handle()); + } + +inline TInt RMemoryAccess::GetBreakpoints(TDes8& aBuf) + { + return DoControl(EControlGetBreakpoints, &aBuf); + } + +inline TInt RMemoryAccess::RegisterPersistantBreakpoint(TLinAddr aAddress) + { + // aAddress is implicitly in the current thread + return DoControl(EControlRegisterPersistantBreakpoint, (TAny*)aAddress, NULL); + } + +inline TInt RMemoryAccess::TPredicate::AddCondition(TOp aOperation, TInt aRegNum, TUint32 aValue) + { + if (aRegNum < 0 || aRegNum > 15) return KErrArgument; + + TInt freeSlot = 0; + while (((iOp >> (freeSlot*8)) & 0xF) != ENothing) + { + freeSlot++; + if (freeSlot >= KNumSlots) return KErrOverflow; + } + + TInt slotShift = freeSlot * 8; + TUint32 slotMask = 0xFF << slotShift; + iOp = (iOp & ~slotMask) | (aOperation << slotShift) | (aRegNum << (slotShift+4)); + iVals[freeSlot] = aValue; + return KErrNone; + } + +inline void RMemoryAccess::TPredicate::Description(TDes& aBuf) + { + TInt origLen = aBuf.Length(); + for (TInt slot = 0; slot < KNumSlots; slot++) + { + TInt slotShift = slot * 8; + TUint32 opAndReg = (iOp >> slotShift) & 0xFF; + TOp op = (TOp)(opAndReg & 0xF); + if (op == ENothing) break; + TInt reg = opAndReg >> 4; + + aBuf.AppendFormat(_L("r%d"), reg); + switch(op) + { + case EEq: + case ESignedEq: + aBuf.Append(_L("==")); break; + case ENe: + case ESignedNe: + aBuf.Append(_L("!=")); break; + case ELt: + case ESignedLt: + aBuf.Append('<'); break; + case ELe: + case ESignedLe: + aBuf.Append(_L("<=")); break; + case EGt: + case ESignedGt: + aBuf.Append('>'); break; + case EGe: + case ESignedGe: + aBuf.Append(_L(">=")); break; + default: + break; + } + if (op >= ESignedEq) + { + aBuf.AppendFormat(_L("%d,"), (TInt)iVals[slot]); + } + else + { + aBuf.AppendFormat(_L("%uu,"), iVals[slot]); + } + } + if (aBuf.Length() > origLen) aBuf.SetLength(aBuf.Length() - 1); // Chomp final comma + } + +inline TInt RMemoryAccess::SetDebugPort(TInt aPort) + { + return DoControl(EControlSetDebugPort, (TAny*)aPort, NULL); + } + +inline TUint RMemoryAccess::GetThreadCreatorId(TUint aThreadId) + { + TUint result = 0; + /*TInt err =*/ DoControl(EControlGetCreatorThread, (TAny*)aThreadId, &result); + return result; + } + +#endif //__KERNEL_MODE__ + +#endif //__MemoryAccess_H__