sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Definitions for the run mode debug agent client side sessions. sl@0: // sl@0: // WARNING: This file contains some APIs which are internal and are subject sl@0: // to change without notice. Such APIs should therefore not be used sl@0: // outside the Kernel and Hardware Services package. sl@0: // sl@0: sl@0: #ifndef RM_DEBUG_API_H sl@0: #define RM_DEBUG_API_H sl@0: sl@0: /** sl@0: @file sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: sl@0: /** sl@0: The Debug namespace contains all API definitions used for on-target debugging. sl@0: */ sl@0: namespace Debug { sl@0: sl@0: /** This is the maximum size in bytes a user trace can be */ sl@0: const TInt TUserTraceSize = 256; sl@0: sl@0: /** sl@0: Information in the debug functionality block is represented as a concatenation sl@0: of pairs of TTagHeader structures and arrays of TTag objects. sl@0: @see TTagHeader sl@0: @see RSecuritySvrSession::GetDebugFunctionality sl@0: */ sl@0: struct TTag sl@0: { sl@0: /** Tag ID, value identifying this tag. */ sl@0: TUint32 iTagId; sl@0: /** sl@0: Values correspond to TTagType enumerators. sl@0: @see TTagType sl@0: */ sl@0: TUint16 iType; sl@0: /** Size of external data associated with this tag. */ sl@0: TUint16 iSize; sl@0: /** Data associated with this tag. */ sl@0: TUint32 iValue; sl@0: }; sl@0: sl@0: /** sl@0: Enumeration defining the supported tag types. These enumerators are used in TTag.iTagId. sl@0: @see TTag sl@0: */ sl@0: enum TTagType sl@0: { sl@0: /** Indicates that the iValue field of a TTag structure will contain either ETrue or EFalse. */ sl@0: ETagTypeBoolean = 0, sl@0: /** Indicates that the iValue field of a TTag structure will contain a value in the TUint32 range. */ sl@0: ETagTypeTUint32 = 1, sl@0: /** Indicates that the iValue field of a TTag structure will contain values from an enumeration. */ sl@0: ETagTypeEnum = 2, sl@0: /** Indicates that the iValue field of a TTag structure should be interpreted as a bit field. */ sl@0: ETagTypeBitField = 3, sl@0: /** Indicates that the type of the iValue field of a TTag structure is unknown. */ sl@0: ETagTypeUnknown = 4, sl@0: /** Indicates that the iValue field of a TTag structure will contain a pointer. */ sl@0: ETagTypePointer = 5 sl@0: }; sl@0: sl@0: /** sl@0: Information in the debug functionality block is represented as a concatenation sl@0: of pairs of TTagHeader structures and arrays of TTag objects. sl@0: @see TTag sl@0: @see RSecuritySvrSession::GetDebugFunctionality sl@0: */ sl@0: struct TTagHeader sl@0: { sl@0: /** Value identifying the contents of this TTagHeader, should be interpreted as an enumerator from TTagHeaderId. sl@0: @see TTagHeaderId sl@0: */ sl@0: TUint16 iTagHdrId; sl@0: /** The number of TTag elements in the array associated with this TTagHeader. */ sl@0: TUint16 iNumTags; sl@0: }; sl@0: sl@0: /** sl@0: Enumeration used to identify TTagHeader structures, TTagHeader::iTagHdrId elements take these enumerators as values. sl@0: @see TTagHeader sl@0: */ sl@0: enum TTagHeaderId sl@0: { sl@0: ETagHeaderIdCore = 0, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityCore. */ sl@0: ETagHeaderIdMemory = 1, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityMemory. */ sl@0: /** sl@0: Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityRegister. sl@0: These values are defined as in the document Symbian Core Dump File Format Appendix C sl@0: (see SGL.TS0028.027 - Symbian Core Dump File Format v1.0.doc). sl@0: The TTag objects in the associated array have an iSize value corresponding to the size of the register's data in bytes. sl@0: */ sl@0: ETagHeaderIdRegistersCore = 2, sl@0: /** sl@0: Identifies a TTagHeader with associated TTag elements with iTagId values corresponding to coprocessor register identifiers. sl@0: Coprocessor registers are defined as in the document Symbian Core Dump File Format Appendix C as follows sl@0: (see SGL.TS0028.027 - Symbian Core Dump File Format v1.0.doc): sl@0: sl@0: For each 32-bit data word defining a co-pro register, the definition of the meaning of the bits follows sl@0: the ARM Architecture Reference manual instruction coding sl@0: sl@0: Upper Halfword Lower Halfword sl@0: Opcode 2 CRm sl@0: sl@0: For example: The Domain Access Control Register is Register 3 of co-processor 15. The encoding is therefore sl@0: CRm = 3 sl@0: Opcode2 = 0 sl@0: sl@0: Therefore the functionality tag would be: sl@0: TagID: 15 // co-processor number sl@0: Type: ETagTypeTUint32 sl@0: Data: 0x00000003 // Opcode2 = 0, CRm = 3 sl@0: */ sl@0: ETagHeaderIdCoProRegisters = 3, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityRegister. */ sl@0: ETagHeaderIdBreakpoints = 4, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityBreakpoint. */ sl@0: ETagHeaderIdStepping = 5, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityStep. */ sl@0: ETagHeaderIdExecution = 6, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityExec. */ sl@0: ETagHeaderIdEvents = 7, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TEventType. */ sl@0: ETagHeaderIdApiConstants = 8, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityApiConstants.*/ sl@0: ETagHeaderList = 9, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TListId. */ sl@0: ETagHeaderIdKillObjects = 10, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityKillObject. */ sl@0: ETagHeaderIdSecurity = 11, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalitySecurity */ sl@0: ETagHeaderIdBuffers = 12, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TBufferType. */ sl@0: ETagHeaderIdStopModeFunctions = 13, /**< Identifies a TTagHeader with associated TTag elements with iTagId values from TFunctionalityStopModeFunctions. */ sl@0: }; sl@0: sl@0: /** sl@0: This structure is not used in the run-mode debug API. sl@0: @deprecated sl@0: */ sl@0: struct TSubBlock sl@0: { sl@0: /** Header to identify the TSubBlock. */ sl@0: TTagHeader iHeader; sl@0: /** Pointer to array of TTag values associated with this TSubBlock. */ sl@0: TTag* iTagArray; sl@0: }; sl@0: sl@0: /** sl@0: These tags define what kinds of core functionality are supported by the run-mode debug subsystem. sl@0: TTag structures associated with the ETagHeaderIdCore sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalityCore sl@0: { sl@0: ECoreEvents = 0, /**< Indicates whether events processing is supported. */ sl@0: ECoreStartStop = 1, /**< Indicates whether suspending and resuming threads is supported. */ sl@0: ECoreMemory = 2, /**< Indicates whether reading and writing memory is supported. */ sl@0: ECoreRegister = 3, /**< Indicates whether reading and writing register values is supported. */ sl@0: ECoreBreakpoint = 4, /**< Indicates whether breakpoints are supported. */ sl@0: ECoreStepping = 5, /**< Indicates whether stepping is supported. */ sl@0: ECoreLists = 6, /**< Indicates whether listings are supported. */ sl@0: ECoreLogging = 7, /**< Indicates whether logging is supported. */ sl@0: ECoreHardware = 8, /**< Indicates whether hardware support is supported. */ sl@0: ECoreApiConstants = 9, /**< Indicates whether the information in the ETagHeaderIdApiConstants sub-block is relevant. */ sl@0: ECoreKillObjects = 10, /**< Indicates whether killing objects (i.e. threads and processes) is supported. */ sl@0: ECoreSecurity = 11, /**< Indicates whether OEM Debug token support or other security info is supported. */ sl@0: ECoreStopModeFunctions = 12, /**< Indicates whether Stop Mode function calling is supported. */ sl@0: ECoreStopModeBuffers = 13, /**< Indicates whether Stop Mode buffers are supported. */ sl@0: sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of core tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: ECoreLast sl@0: }; sl@0: sl@0: /** sl@0: These tags define what kind of memory operations can be performed. sl@0: TTag structures associated with the ETagHeaderIdMemory sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalityMemory sl@0: { sl@0: EMemoryRead = 0, /**< Indicates whether reading memory is supported. */ sl@0: EMemoryWrite = 1, /**< Indicates whether writing memory is supported. */ sl@0: EMemoryAccess64 = 2, /**< Indicates whether 64 bit memory access is supported. */ sl@0: EMemoryAccess32 = 3, /**< Indicates whether 32 bit memory access is supported. */ sl@0: EMemoryAccess16 = 4, /**< Indicates whether 16 bit memory access is supported. */ sl@0: EMemoryAccess8 = 5, /**< Indicates whether 8 bit memory access is supported. */ sl@0: EMemoryBE8 = 6, /**< Indicates whether reading memory as 8 bit big-endian values is supported. */ sl@0: EMemoryBE32 = 7, /**< Indicates whether reading memory as 32 bit big-endian values is supported. */ sl@0: EMemoryLE8 = 8, /**< Indicates whether reading memory as 8 bit little-endian values is supported. */ sl@0: EMemoryMaxBlockSize = 9, /**< Corresponds to the maximum size of a block of memory which can be requested. */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of memory tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: EMemoryLast sl@0: }; sl@0: sl@0: /** sl@0: These tags define which objects can be killed by the device driver. sl@0: TTag structures associated with the ETagHeaderIdKillObjects sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalityKillObject sl@0: { sl@0: EFunctionalityKillThread = 0, /**< Indicates whether killing threads is supported. */ sl@0: EFunctionalityKillProcess = 1, /**< Indicates whether killing processes is supported. */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of kill object tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: EFunctionalityKillObjectLast sl@0: }; sl@0: sl@0: /** sl@0: A TTag with an id from the TFunctionalityRegister enum will have a value from this enumeration. sl@0: The values define how a register can be accessed, if at all. sl@0: */ sl@0: enum TFunctionalityAccess sl@0: { sl@0: EAccessNone = 0, /**< Indicates that a register cannot be accessed. */ sl@0: EAccessReadOnly = 1, /**< Indicates that a register can be read, but not written to. */ sl@0: EAccessWriteOnly = 2, /**< Indicates that a register can be written to, but not read. */ sl@0: EAccessReadWrite = 3, /**< Indicates that a register can be both read and written to. */ sl@0: EAccessUnknown = 4, /**< Indicates that it is unspecified whether reading or writing to a register is possible. */ sl@0: }; sl@0: sl@0: /** sl@0: These enumerators act as core register identifiers. sl@0: TTag structures associated with the ETagHeaderIdRegistersCore sub-block will have iTagId values from this enumeration. sl@0: The numeric value of each enumerator identifies the register according to the definitions in the Symbian Core Dump File Format Appendix B sl@0: (see SGL.TS0028.027 - Symbian Core Dump File Format v1.0.doc). sl@0: */ sl@0: enum TFunctionalityRegister sl@0: { sl@0: ERegisterR0 = 0x00000000, /**< Identifier for user mode register R0. */ sl@0: ERegisterR1 = 0x00000100, /**< Identifier for user mode register R1. */ sl@0: ERegisterR2 = 0x00000200, /**< Identifier for user mode register R2. */ sl@0: ERegisterR3 = 0x00000300, /**< Identifier for user mode register R3. */ sl@0: ERegisterR4 = 0x00000400, /**< Identifier for user mode register R4. */ sl@0: ERegisterR5 = 0x00000500, /**< Identifier for user mode register R5. */ sl@0: ERegisterR6 = 0x00000600, /**< Identifier for user mode register R6. */ sl@0: ERegisterR7 = 0x00000700, /**< Identifier for user mode register R7. */ sl@0: ERegisterR8 = 0x00000800, /**< Identifier for user mode register R8. */ sl@0: ERegisterR9 = 0x00000900, /**< Identifier for user mode register R9. */ sl@0: ERegisterR10 = 0x00000a00, /**< Identifier for user mode register R10. */ sl@0: ERegisterR11 = 0x00000b00, /**< Identifier for user mode register R11. */ sl@0: ERegisterR12 = 0x00000c00, /**< Identifier for user mode register R12. */ sl@0: ERegisterR13 = 0x00000d00, /**< Identifier for user mode register R13. */ sl@0: ERegisterR14 = 0x00000e00, /**< Identifier for user mode register R14. */ sl@0: ERegisterR15 = 0x00000f00, /**< Identifier for user mode register R15. */ sl@0: ERegisterCpsr = 0x00001000, /**< Identifier for CPSR. */ sl@0: ERegisterR13Svc = 0x00001100, /**< Identifier for R13 supervisor mode banked register. */ sl@0: ERegisterR14Svc = 0x00001200, /**< Identifier for R14 supervisor mode banked register. */ sl@0: ERegisterSpsrSvc = 0x00001300, /**< Identifier for SPSR supervisor mode banked register. */ sl@0: ERegisterR13Abt = 0x00001400, /**< Identifier for R13 Abort mode banked register. */ sl@0: ERegisterR14Abt = 0x00001500, /**< Identifier for R14 Abort mode banked register. */ sl@0: ERegisterSpsrAbt = 0x00001600, /**< Identifier for SPSR Abort mode banked register. */ sl@0: ERegisterR13Und = 0x00001700, /**< Identifier for R13 Undefined mode banked register. */ sl@0: ERegisterR14Und = 0x00001800, /**< Identifier for R14 Undefined mode banked register. */ sl@0: ERegisterSpsrUnd = 0x00001900, /**< Identifier for SPSR Undefined mode banked register. */ sl@0: ERegisterR13Irq = 0x00001a00, /**< Identifier for R13 Interrupt mode banked register. */ sl@0: ERegisterR14Irq = 0x00001b00, /**< Identifier for R14 Interrupt mode banked register. */ sl@0: ERegisterSpsrIrq = 0x00001c00, /**< Identifier for SPSR Interrupt mode banked register. */ sl@0: ERegisterR8Fiq = 0x00001d00, /**< Identifier for R8 Fast Interrupt mode banked register. */ sl@0: ERegisterR9Fiq = 0x00001e00, /**< Identifier for R9 Fast Interrupt mode banked register. */ sl@0: ERegisterR10Fiq = 0x00001f00, /**< Identifier for R10 Fast Interrupt mode banked register. */ sl@0: ERegisterR11Fiq = 0x00002000, /**< Identifier for R11 Fast Interrupt mode banked register. */ sl@0: ERegisterR12Fiq = 0x00002100, /**< Identifier for R12 Fast Interrupt mode banked register. */ sl@0: ERegisterR13Fiq = 0x00002200, /**< Identifier for R13 Fast Interrupt mode banked register. */ sl@0: ERegisterR14Fiq = 0x00002300, /**< Identifier for R14 Fast Interrupt mode banked register. */ sl@0: ERegisterSpsrFiq = 0x00002400, /**< Identifier for SPSR Fast Interrupt mode banked register. */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of core registers from the DFBlock rather than this enumerator. sl@0: */ sl@0: ERegisterLast = 37 sl@0: }; sl@0: sl@0: sl@0: /** sl@0: These tags define the kind of breakpoints that are supported. sl@0: TTag structures associated with the ETagHeaderIdBreakpoints sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalityBreakpoint sl@0: { sl@0: EBreakpointThread = 0, /**< Indicates whether thread specific breakpoints are supported. */ sl@0: EBreakpointProcess = 1, /**< Indicates whether process specific breakpoints are supported. */ sl@0: EBreakpointSystem = 2, /**< Indicates whether system wide breakpoints are supported. */ sl@0: EBreakpointArm = 3, /**< Indicates whether ARM mode breakpoints are supported. */ sl@0: EBreakpointThumb = 4, /**< Indicates whether Thumb mode breakpoints are supported. */ sl@0: EBreakpointT2EE = 5, /**< Indicates whether Thumb2 mode breakpoints are supported. */ sl@0: EBreakpointArmInst = 6, /**< Reserved for future use. */ sl@0: EBreakpointThumbInst = 7, /**< Reserved for future use. */ sl@0: EBreakpointT2EEInst = 8, /**< Reserved for future use. */ sl@0: EBreakpointSetArmInst = 9, /**< Reserved for future use. */ sl@0: EBreakpointSetThumbInst = 10, /**< Reserved for future use. */ sl@0: EBreakpointSetT2EEInst = 11, /**< Reserved for future use. */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of breakpoint tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: EBreakpointLast sl@0: }; sl@0: sl@0: /** sl@0: These enumerators provide information about the stepping capabilities of the debug sub-system. sl@0: TTag structures associated with the ETagHeaderIdStepping sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalityStep sl@0: { sl@0: EStep = 0, /**< Indicates whether instruction stepping is supported. */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of stepping tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: EStepLast sl@0: }; sl@0: sl@0: /** sl@0: These enumerators provide information about the execution control capabilities of the debug sub-system. sl@0: TTag structures associated with the ETagHeaderIdExecution sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalityExec sl@0: { sl@0: EExecThreadSuspendResume = 0, /**< Indicates whether suspending and resuming threads is supported. */ sl@0: EExecProcessSuspendResume = 1, /**< Indicates whether suspending and resuming processes is supported. */ sl@0: EExecSystemSuspendResume = 2, /**< Indicates whether suspending and resuming the entire system is supported. */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of execution control tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: EExecLast sl@0: }; sl@0: sl@0: /** sl@0: This enumeration defines the event types supported by the debug sub-system. sl@0: TTag structures associated with the ETagHeaderIdEvents sub-block will have sl@0: iTagId values from this enumeration, and iValue values from the TKernelEventAction enumeration. sl@0: sl@0: These enumerators are also used by the RSecuritySvrSession API to identify events. sl@0: @see RSecuritySvrSession sl@0: @see TKernelEventAction sl@0: */ sl@0: enum TEventType sl@0: { sl@0: EEventsBreakPoint = 0, /**< Identifies a breakpoint event. */ sl@0: EEventsSwExc = 1, /**< Identifies a software exception event. */ sl@0: EEventsHwExc = 2, /**< Identifies a hardware exception event. */ sl@0: EEventsKillThread = 3, /**< Identifies a kill thread event. */ sl@0: EEventsAddLibrary = 4, /**< Identifies an add library event. */ sl@0: EEventsRemoveLibrary = 5, /**< Identifies a remove library event. */ sl@0: /** sl@0: If an event is generated and there is only a single space remaining in the events queue then sl@0: an event of type EEventsBufferFull will be stored in the queue and the generated event will sl@0: be discarded. If further events occur while the buffer is full the events will be discarded. sl@0: As such an event of type EEventsBufferFull being returned signifies that one or more events sl@0: were discarded. An event of this type has no valid data associated with it. sl@0: */ sl@0: EEventsBufferFull = 6, sl@0: EEventsUnknown = 7, /**< Identifies an event of unknown type. */ sl@0: EEventsUserTrace = 8, /**< Identifies a user trace. */ sl@0: EEventsProcessBreakPoint = 9, /**< Identifies a process breakpoint event. */ sl@0: EEventsStartThread = 10, /**< Identifies a start thread event. */ sl@0: EEventsUserTracesLost = 11, /**< Identifies user traces being lost. */ sl@0: EEventsAddProcess = 12, /**< Identifies an AddProcess event */ sl@0: EEventsRemoveProcess = 13, /**< Identifies a RemoveProcess event */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of event types from the DFBlock rather than this enumerator. sl@0: */ sl@0: EEventsLast sl@0: }; sl@0: sl@0: /** sl@0: These enumerators provide information about constants which are used in the RSecuritySvrSession API. sl@0: TTag structures associated with the ETagHeaderIdApiConstants sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalityApiConstants sl@0: { sl@0: /** sl@0: Corresponds to the size of a buffer required to store a TEventInfo. sl@0: @see TEventInfo sl@0: */ sl@0: EApiConstantsTEventInfoSize = 0, sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of API constants tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: EApiConstantsLast, sl@0: }; sl@0: sl@0: /** sl@0: The set of possible actions which could be taken when a kernel event occurs. sl@0: Not all actions are possible for all events. The debug functionality sub-block with header id ETagHeaderIdEvents sl@0: indicates which values are permitted for each event. The value given for that event should be sl@0: considered as the most intrusive action the debugger may set: with the definition that EActionSuspend is more sl@0: intrusive than EActionContinue, which is more intrusive than EActionIgnore. sl@0: @see RSecuritySvrSession sl@0: */ sl@0: enum TKernelEventAction sl@0: { sl@0: /** If an event action is set to this value then events of that type will be sl@0: ignored, and not reported to the debugger. */ sl@0: EActionIgnore = 0, sl@0: /** If an event action is set to this value then events of that type will be sl@0: reported to the debugger and the thread which generated the event will be sl@0: allowed to continue executing. */ sl@0: EActionContinue = 1, sl@0: /** If an event action is set to this value then events of that type will be sl@0: reported to the debugger and the thread which generated the event will be sl@0: suspended. */ sl@0: EActionSuspend = 2, sl@0: /** sl@0: @internalTechnology sl@0: Count of event actions. sl@0: */ sl@0: EActionLast sl@0: }; sl@0: sl@0: /** sl@0: These enumerators provide information about the ability of the debug subsystem to support OEM Debug tokens. sl@0: TTag structures associated with the ETagHeaderIdSecurity sub-block will have iTagId values from this enumeration. sl@0: See each enumerator for an explanation of how a TTag with that iTagId should be interpreted. sl@0: */ sl@0: enum TFunctionalitySecurity sl@0: { sl@0: ESecurityOEMDebugToken = 0, /**< Indicates whether the DSS supports the use of OEM Debug Tokens. */ sl@0: sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: ESecurityLast sl@0: }; sl@0: sl@0: /** sl@0: Used for storing the contents of a 32 bit register sl@0: */ sl@0: typedef TUint32 TRegisterValue32; sl@0: sl@0: sl@0: /** sl@0: * Processor mode sl@0: */ sl@0: enum TArmProcessorModes sl@0: { sl@0: EUserMode=0x10, //!< EUserMode sl@0: EFiqMode=0x11, //!< EFiqMode sl@0: EIrqMode=0x12, //!< EIrqMode sl@0: ESvcMode=0x13, //!< ESvcMode sl@0: EAbortMode=0x17, //!< EAbortMode sl@0: EUndefMode=0x1b, //!< EUndefMode sl@0: EMaskMode=0x1f //!< EMaskMode sl@0: }; sl@0: sl@0: sl@0: sl@0: /** sl@0: Structure containing information about the state of the registers when a sl@0: hardware exception occurred sl@0: */ sl@0: class TRmdArmExcInfo sl@0: { sl@0: public: sl@0: /** Enumeration detailing the types of exception which may occur. */ sl@0: enum TExceptionType sl@0: { sl@0: /** Enumerator signifying that a prefetch abort error has occurred. */ sl@0: EPrefetchAbort = 0, sl@0: /** Enumerator signifying that a data abort error has occurred. */ sl@0: EDataAbort = 1, sl@0: /** Enumerator signifying that an undefined instruction error has occurred. */ sl@0: EUndef =2 sl@0: }; sl@0: sl@0: /** Value of CPSR. */ sl@0: TRegisterValue32 iCpsr; sl@0: /** Type of exception which has occurred. */ sl@0: TExceptionType iExcCode; sl@0: /** Value of R13 supervisor mode banked register. */ sl@0: TRegisterValue32 iR13Svc; sl@0: /** Value of user mode register R4. */ sl@0: TRegisterValue32 iR4; sl@0: /** Value of user mode register R5. */ sl@0: TRegisterValue32 iR5; sl@0: /** Value of user mode register R6. */ sl@0: TRegisterValue32 iR6; sl@0: /** Value of user mode register R7. */ sl@0: TRegisterValue32 iR7; sl@0: /** Value of user mode register R8. */ sl@0: TRegisterValue32 iR8; sl@0: /** Value of user mode register R9. */ sl@0: TRegisterValue32 iR9; sl@0: /** Value of user mode register R10. */ sl@0: TRegisterValue32 iR10; sl@0: /** Value of user mode register R11. */ sl@0: TRegisterValue32 iR11; sl@0: /** Value of R14 supervisor mode banked register. */ sl@0: TRegisterValue32 iR14Svc; sl@0: /** Address which caused exception (System Control Coprocessor Fault Address Register) */ sl@0: TRegisterValue32 iFaultAddress; sl@0: /** Value of System Control Coprocessor Fault Status Register. */ sl@0: TRegisterValue32 iFaultStatus; sl@0: /** Value of SPSR supervisor mode banked register. */ sl@0: TRegisterValue32 iSpsrSvc; sl@0: /** Value of user mode register R13. */ sl@0: TRegisterValue32 iR13; sl@0: /** Value of user mode register R14. */ sl@0: TRegisterValue32 iR14; sl@0: /** Value of user mode register R0. */ sl@0: TRegisterValue32 iR0; sl@0: /** Value of user mode register R1. */ sl@0: TRegisterValue32 iR1; sl@0: /** Value of user mode register R2. */ sl@0: TRegisterValue32 iR2; sl@0: /** Value of user mode register R3. */ sl@0: TRegisterValue32 iR3; sl@0: /** Value of user mode register R12. */ sl@0: TRegisterValue32 iR12; sl@0: /** Value of user mode register R15, points to instruction which caused exception. */ sl@0: TRegisterValue32 iR15; sl@0: }; sl@0: sl@0: /** sl@0: The maximum size, in bytes, of the panic category string returned as part of a sl@0: TEventInfo object. sl@0: sl@0: @see TEventInfo sl@0: @see TThreadKillInfo sl@0: */ sl@0: const TInt KPanicCategoryMaxName = KMaxName; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: an agent set breakpoint is hit. sl@0: */ sl@0: class TThreadBreakPointInfo sl@0: { sl@0: public: sl@0: /** Identifies the type of exception. */ sl@0: TExcType iExceptionNumber; sl@0: /** Structure containing information about the ARM register values. */ sl@0: TRmdArmExcInfo iRmdArmExcInfo; sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a software exception occurs. sl@0: */ sl@0: class TThreadSwExceptionInfo sl@0: { sl@0: public: sl@0: /** The value of the program counter. */ sl@0: TUint32 iCurrentPC; sl@0: /** Identifies the type of exception. */ sl@0: TExcType iExceptionNumber; sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a hardware exception occurs. sl@0: */ sl@0: class TThreadHwExceptionInfo sl@0: { sl@0: public: sl@0: /** Identifies the type of exception. */ sl@0: TExcType iExceptionNumber; sl@0: /** Structure containing information about the ARM register values. */ sl@0: TRmdArmExcInfo iRmdArmExcInfo; sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a thread kill event occurs. sl@0: */ sl@0: class TThreadKillInfo sl@0: { sl@0: public: sl@0: /** The value of the program counter. */ sl@0: TUint32 iCurrentPC; sl@0: /** Specifies the reason for the kill thread event, this value is specific to the killed thread and does not correspond to a standard Symbian enumeration. */ sl@0: TInt iExitReason; sl@0: /** Specifies the type of the thread kill event, values correspond to elements of TExitType. */ sl@0: TUint8 iExitType; sl@0: /** The panic category of the killed thread. */ sl@0: TUint8 iPanicCategory[KPanicCategoryMaxName]; sl@0: /** Contains the length in bytes of the initialised data in iPanicCategory. */ sl@0: TInt iPanicCategoryLength; sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a library load event occurs. sl@0: */ sl@0: class TLibraryLoadedInfo sl@0: { sl@0: public: sl@0: /** The name of the file that the library was loaded from. */ sl@0: TUint8 iFileName[KMaxName]; sl@0: /** Contains the length in bytes of the initialised data in iFileName. */ sl@0: TInt iFileNameLength; sl@0: /** The code base address (.text). */ sl@0: TUint32 iCodeAddress; sl@0: /** The base address of the initialised data section (.data). */ sl@0: TUint32 iDataAddress; sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a thread is started sl@0: */ sl@0: class TStartThreadInfo sl@0: { sl@0: public: sl@0: /** The name of the file that the process owning the thread was created from. */ sl@0: TUint8 iFileName[KMaxName]; sl@0: /** Contains the length in bytes of the initialised data in iFileName. */ sl@0: TInt iFileNameLength; sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a process is added. Note that the Process may not be fully constructed, sl@0: e.g. no threads. sl@0: */ sl@0: class TAddProcessInfo sl@0: { sl@0: public: sl@0: /** The name of the file that the process was created from. */ sl@0: TUint8 iFileName[KMaxName]; sl@0: /** Contains the length in bytes of the initialised data in iFileName. */ sl@0: TInt iFileNameLength; sl@0: /** The UID3 of this process */ sl@0: TUint32 iUid3; sl@0: /** Contains the CreatorThread ID if available: May be 0 */ sl@0: TUint64 iCreatorThreadId; sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a process is removed. Note that the Process may not be fully destroyed, sl@0: so its resources should only be accessed if you already have a handle to it. sl@0: */ sl@0: class TRemoveProcessInfo sl@0: { sl@0: public: sl@0: /** The name of the file that the process was created from. */ sl@0: TUint8 iFileName[KMaxName]; sl@0: /** Contains the length in bytes of the initialised data in iFileName. */ sl@0: TInt iFileNameLength; sl@0: TUint32 iSpare1; // Unused sl@0: }; sl@0: sl@0: /** sl@0: Event specific information returned as part of a TEventInfo object when sl@0: a library unload event occurs. sl@0: */ sl@0: class TLibraryUnloadedInfo sl@0: { sl@0: public: sl@0: /** The name of the file that the library was loaded from. */ sl@0: TUint8 iFileName[KMaxName]; sl@0: /** Contains the length in bytes of the initialised data in iFileName. */ sl@0: TInt iFileNameLength; sl@0: }; sl@0: sl@0: /** sl@0: * Enum to represent the context of a user trace message sl@0: */ sl@0: enum TUserTraceMessageContext sl@0: { sl@0: ESingleMessage = 0x1, /** Indicates this message is the only one corresponding to a given user trace */ sl@0: EMultiStart = 0x2, /** Indicates this message is the start of a user trace which consists of multiple messages */ sl@0: EMultiMid = 0x3, /** Indicates this message is one in a series of user trace messages */ sl@0: EMultiEnd = 0x4, /** Indicates this message is the last in a series of user trace messages */ sl@0: /** sl@0: @internalTechnology sl@0: A debug agent should find the number of core tags from the DFBlock rather than this enumerator. sl@0: */ sl@0: ELast = 0x5 sl@0: }; sl@0: sl@0: /** sl@0: * Event specific information returned as part of a TEventInfo object sl@0: * when a user trace event occurs. sl@0: */ sl@0: class TUserTraceInfo sl@0: { sl@0: public: sl@0: /** The user trace text */ sl@0: TUint8 iUserTraceText[TUserTraceSize]; sl@0: sl@0: /** User trace text length */ sl@0: TInt iUserTraceLength; sl@0: sl@0: /** The context of the message */ sl@0: TUserTraceMessageContext iMessageStatus; sl@0: }; sl@0: sl@0: sl@0: /** sl@0: Structure used to store information about an event. An object of this type sl@0: is passed as an argument to the RSecuritySvrSession::GetEvent function, sl@0: and is filled in by the debug driver, and returned to the agent, when a sl@0: relevant event occurs. sl@0: sl@0: The debug functionality block contains the size in bytes of the data that sl@0: the driver will return when a GetEvent call is issued. A debug agent should sl@0: ensure that this value equals the size of this TEventInfo object to ensure sl@0: that a compatible debug driver is being used. The value is stored as sl@0: EApiConstantsTEventInfoSize in the TFunctionalityApiConstants block. sl@0: sl@0: @see RSecuritySvrSession::GetDebugFunctionality sl@0: @see RSecuritySvrSession::GetEvent sl@0: */ sl@0: class TEventInfo sl@0: { sl@0: public: sl@0: sl@0: /** Constructor sets all elements to default values. */ sl@0: inline TEventInfo() { Reset(); }; sl@0: sl@0: /** Resets all values to default values. */ sl@0: inline void Reset() sl@0: { sl@0: iProcessId = 0; sl@0: iProcessIdValid = EFalse; sl@0: iThreadId = 0; sl@0: iThreadIdValid = EFalse; sl@0: iEventType = (TEventType)NULL; sl@0: }; sl@0: sl@0: public: sl@0: sl@0: /** The process ID of the process which the event occurred in. */ sl@0: TUint64 iProcessId; sl@0: /** The thread ID of the thread which the event occurred in. */ sl@0: TUint64 iThreadId; sl@0: /** Has value ETrue if iProcessId is valid, EFalse otherwise. */ sl@0: TUint8 iProcessIdValid; sl@0: /** Has value ETrue if iThreadId is valid, EFalse otherwise. */ sl@0: TUint8 iThreadIdValid; sl@0: /** Indicates the type of the event. This type should be used to determine sl@0: the type of the information stored in the union which is part of this class. */ sl@0: TEventType iEventType; sl@0: union sl@0: { sl@0: /** Information which is specific to the break point event. */ sl@0: TThreadBreakPointInfo iThreadBreakPointInfo; sl@0: /** Information which is specific to the software exception event. */ sl@0: TThreadSwExceptionInfo iThreadSwExceptionInfo; sl@0: /** Information which is specific to the hardware exception event. */ sl@0: TThreadHwExceptionInfo iThreadHwExceptionInfo; sl@0: /** Information which is specific to the thread kill event. */ sl@0: TThreadKillInfo iThreadKillInfo; sl@0: /** Information which is specific to the library loaded event. */ sl@0: TLibraryLoadedInfo iLibraryLoadedInfo; sl@0: /** Information which is specific to the library unloaded event. */ sl@0: TLibraryUnloadedInfo iLibraryUnloadedInfo; sl@0: /** Information which is specific to the user trace event. */ sl@0: TUserTraceInfo iUserTraceInfo; sl@0: /** Information which is specific to the start thread event. */ sl@0: TStartThreadInfo iStartThreadInfo; sl@0: /** Information which is specific to the Add Process event. */ sl@0: TAddProcessInfo iAddProcessInfo; sl@0: /** Information which is specific to the Remove Process event. */ sl@0: TRemoveProcessInfo iRemoveProcessInfo; sl@0: }; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TProcessInfo sl@0: { sl@0: public: sl@0: sl@0: inline TProcessInfo() { Reset(); } sl@0: sl@0: inline TProcessInfo(TUint32 aId, TUint32 aCodeAddress, TUint32 aCodeSize, TUint32 aDataAddress) sl@0: : iId(aId), sl@0: iCodeAddress(aCodeAddress), sl@0: iCodeSize(aCodeSize), sl@0: iDataAddress(aDataAddress) { } sl@0: sl@0: inline void Reset() sl@0: { sl@0: iId = 0; sl@0: iCodeAddress = 0; sl@0: iCodeSize = 0; sl@0: iDataAddress = 0; sl@0: } sl@0: sl@0: public: sl@0: sl@0: TUint32 iId; sl@0: TUint32 iCodeAddress; sl@0: TUint32 iCodeSize; sl@0: TUint32 iDataAddress; sl@0: }; sl@0: sl@0: /* Other functionality may be defined here later */ sl@0: sl@0: /** sl@0: Represents a register id value, in the terms of the Symbian ELF format: sl@0: - bits 0-7 define the class sl@0: - bits 8-15 define the rd_id sl@0: - bits 16-31 define the rd_sub_id sl@0: sl@0: Both the core registers (TFunctionalityRegister type) and the coprocessor registers sl@0: follow this identifier scheme. sl@0: */ sl@0: typedef TUint32 TRegisterInfo; sl@0: sl@0: /** sl@0: Enum representing the status flags which could be returned from a register sl@0: access call. sl@0: */ sl@0: enum TRegisterFlag sl@0: { sl@0: /** sl@0: Default value, a register access call will never return this value sl@0: */ sl@0: ENotSet = 0, sl@0: /** sl@0: Would be returned if the register is supported by the debug driver but the kernel cannot access the register sl@0: */ sl@0: EInValid = 1, sl@0: /** sl@0: Would be returned if the register could be accessed correctly sl@0: */ sl@0: EValid = 2, sl@0: /** sl@0: Would be returned if the register is not supported by the debug driver sl@0: */ sl@0: ENotSupported = 3, sl@0: /** sl@0: Would be returned if a non-4 byte register value was requested sl@0: */ sl@0: EBadSize = 4 sl@0: }; sl@0: sl@0: /** sl@0: Enum representing the different ARM CPU instruction set architectures. sl@0: */ sl@0: enum TArchitectureMode sl@0: { sl@0: /** Represents the ARM CPU architecture. */ sl@0: EArmMode = 1, sl@0: /** Represents the Thumb CPU architecture. */ sl@0: EThumbMode = 2, sl@0: /** sl@0: Represents the Thumb2 CPU architecture. sl@0: @prototype sl@0: */ sl@0: EThumb2EEMode = 3 sl@0: }; sl@0: sl@0: /** sl@0: Used as an identifier for breakpoints set by the RSecuritySvrSession::SetBreak function. sl@0: @see RSecuritySvrSession sl@0: */ sl@0: typedef TInt32 TBreakId; sl@0: sl@0: /** sl@0: Specifies the type of a code segment. sl@0: @see TCodeSegListEntry sl@0: */ sl@0: enum TCodeSegType sl@0: { sl@0: EUnknownCodeSegType = 0, /**< Signifies an unknown code segment type. */ sl@0: EExeCodeSegType = 1, /**< Signifies a code segment belonging to an executable. */ sl@0: EDllCodeSegType = 2 /**< Signifies a code segment belonging to a library. */ sl@0: }; sl@0: sl@0: /** sl@0: Structure used for extracting data from a descriptor returned by a call to sl@0: RSecuritySvrSession::GetList() when GetList() is called with TListId::ECodeSegs sl@0: as the first argument. sl@0: sl@0: @see RSecuritySvrSession::GetList() sl@0: sl@0: @code sl@0: //buffer is a TDesC8 containing 4-byte aligned TCodeSegListEntry objects sl@0: //create a pointer to the start of the data sl@0: TUint8* ptr = (TUint8*)buffer.Ptr(); sl@0: //create a pointer to the end of the data sl@0: const TUint8* ptrEnd = ptr + buffer.Length(); sl@0: while(ptr < ptrEnd) sl@0: { sl@0: //cast the pointer to be a TCodeSegListEntry object sl@0: TCodeSegListEntry& entry = *(TCodeSegListEntry*)ptr; sl@0: //use the TCodeSegListEntry pointer, i.e. sl@0: TUint16 nameLength = entry.iNameLength; sl@0: TPtr name(&(entry.iName[0]), nameLength, nameLength); sl@0: // move ptr on to point to the next TCodeSegListEntry object sl@0: ptr += Align4(entry.GetSize()); sl@0: } sl@0: @endcode sl@0: */ sl@0: class TCodeSegListEntry sl@0: { sl@0: public: sl@0: TInt GetSize() const; sl@0: public: sl@0: /** sl@0: Address of the start of the code segment. sl@0: */ sl@0: TUint32 iCodeBase; sl@0: /** sl@0: Size of the code segment. sl@0: */ sl@0: TUint32 iCodeSize; sl@0: /** sl@0: Size of the const data segment sl@0: */ sl@0: TUint32 iConstDataSize; sl@0: /** sl@0: Address of the initialised data sl@0: */ sl@0: TUint32 iInitialisedDataBase; sl@0: /** sl@0: Size of the initialised data sl@0: */ sl@0: TUint32 iInitialisedDataSize; sl@0: /** sl@0: Size of the uninitialised data sl@0: */ sl@0: TUint32 iUninitialisedDataSize; sl@0: /** sl@0: Boolean indicating whether the code segment is execute in place sl@0: */ sl@0: TBool iIsXip; sl@0: /** sl@0: Indicates whether the code segment is from an executable or a dll, or neither sl@0: */ sl@0: TCodeSegType iCodeSegType; sl@0: /** Uid3 of this segment. */ sl@0: TUint32 iUid3; sl@0: /** Currently unused element. May be used in future to aid maintaining compatibility. */ sl@0: TUint32 iSpare2; sl@0: /** sl@0: Length of the code segment's name sl@0: */ sl@0: TUint16 iNameLength; sl@0: /** sl@0: First two bytes of the code segment's name, the name should be considered to sl@0: extend past the end of the TCodeSegListEntry structure to a length sl@0: corresponding to iNameLength sl@0: */ sl@0: TUint16 iName[1]; sl@0: }; sl@0: sl@0: /** sl@0: Returns the size of the TCodeSegListEntry, including the file name length sl@0: sl@0: @return the size, in bytes, of the TCodeSegListEntry and the code segment's sl@0: file name sl@0: */ sl@0: inline TInt TCodeSegListEntry::GetSize() const sl@0: { sl@0: return sizeof(TCodeSegListEntry) - sizeof(iName) + (2 * iNameLength); sl@0: } sl@0: sl@0: /** sl@0: Structure used for extracting data from a descriptor returned by a call to sl@0: RSecuritySvrSession::GetList() when GetList() is called with TListId::EXipLibraries sl@0: as the first argument. sl@0: sl@0: @see RSecuritySvrSession::GetList() sl@0: sl@0: @code sl@0: //buffer is a TDesC8 containing 4-byte aligned TXipLibraryListEntry objects sl@0: //create a pointer to the start of the data sl@0: TUint8* ptr = (TUint8*)buffer.Ptr(); sl@0: //create a pointer to the end of the data sl@0: const TUint8* ptrEnd = ptr + buffer.Length(); sl@0: while(ptr < ptrEnd) sl@0: { sl@0: //cast the pointer to be a TXipLibraryListEntry object sl@0: TXipLibraryListEntry& entry = *(TXipLibraryListEntry*)ptr; sl@0: //use the TXipLibraryListEntry pointer, i.e. sl@0: TUint16 nameLength = entry.iNameLength; sl@0: TPtr name(&(entry.iName[0]), nameLength, nameLength); sl@0: // move ptr on to point to the next TXipLibraryListEntry object sl@0: ptr += Align4(entry.GetSize()); sl@0: } sl@0: @endcode sl@0: */ sl@0: class TXipLibraryListEntry sl@0: { sl@0: public: sl@0: TInt GetSize() const; sl@0: public: sl@0: /** sl@0: Address of the start of the library's code segment. sl@0: */ sl@0: TUint32 iCodeBase; sl@0: /** sl@0: Size of the code segment. sl@0: */ sl@0: TUint32 iCodeSize; sl@0: /** sl@0: Size of the const data segment sl@0: */ sl@0: TUint32 iConstDataSize; sl@0: /** sl@0: Address of the initialised data sl@0: */ sl@0: TUint32 iInitialisedDataBase; sl@0: /** sl@0: Size of the initialised data sl@0: */ sl@0: TUint32 iInitialisedDataSize; sl@0: /** sl@0: Size of the uninitialised data sl@0: */ sl@0: TUint32 iUninitialisedDataSize; sl@0: /** Currently unused element. May be used in future to aid maintaining compatibility. */ sl@0: TUint32 iSpare1; sl@0: /** Currently unused element. May be used in future to aid maintaining compatibility. */ sl@0: TUint32 iSpare2; sl@0: /** sl@0: Length of the library's name sl@0: */ sl@0: TUint16 iNameLength; sl@0: /** sl@0: First two bytes of the code segment's name, the name should be considered to sl@0: extend past the end of the TXipLibraryListEntry structure to a length sl@0: corresponding to iNameLength sl@0: */ sl@0: TUint16 iName[1]; sl@0: }; sl@0: sl@0: /** sl@0: Returns the size of the TXipLibraryListEntry, including the file name length sl@0: sl@0: @return the size, in bytes, of the TXipLibraryListEntry and the library's sl@0: file name sl@0: */ sl@0: inline TInt TXipLibraryListEntry::GetSize() const sl@0: { sl@0: return sizeof(TXipLibraryListEntry) - sizeof(iName) + (2 * iNameLength); sl@0: } sl@0: sl@0: /** sl@0: Structure used for extracting data from a descriptor returned by a call to sl@0: RSecuritySvrSession::GetList() when GetList() is called with TListId::EExecutables sl@0: as the first argument. sl@0: sl@0: @see RSecuritySvrSession::GetList() sl@0: sl@0: @code sl@0: //buffer is a TDesC8 containing 4-byte aligned TExecutablesListEntry objects sl@0: //create a pointer to the start of the data sl@0: TUint8* ptr = (TUint8*)buffer.Ptr(); sl@0: //create a pointer to the end of the data sl@0: const TUint8* ptrEnd = ptr + buffer.Length(); sl@0: while(ptr < ptrEnd) sl@0: { sl@0: //cast the pointer to be a TExecutablesListEntry object sl@0: TExecutablesListEntry& entry = *(TExecutablesListEntry*)ptr; sl@0: //use the TExecutablesListEntry pointer, i.e. sl@0: TUint16 nameLength = entry.iNameLength; sl@0: TPtr name(&(entry.iName[0]), nameLength, nameLength); sl@0: // move ptr on to point to the next TExecutablesListEntry object sl@0: ptr += Align4(entry.GetSize()); sl@0: } sl@0: @endcode sl@0: */ sl@0: class TExecutablesListEntry sl@0: { sl@0: public: sl@0: TInt GetSize() const; sl@0: public: sl@0: /** sl@0: Indicates whether an agent has registered to actively debug the executable, sl@0: a non-zero value indicates that an agent has attached. sl@0: */ sl@0: TUint8 iIsActivelyDebugged; sl@0: /** sl@0: Indicates whether any agents have registered to passively debug the executable, sl@0: a non-zero value indicates that at least one agent is attached passively sl@0: */ sl@0: TUint8 iIsPassivelyDebugged; sl@0: /** Currently unused element. May be used in future to aid maintaining compatibility. */ sl@0: TUint32 iSpare1; sl@0: /** Currently unused element. May be used in future to aid maintaining compatibility. */ sl@0: TUint32 iSpare2; sl@0: /** sl@0: Length of the executable's name sl@0: */ sl@0: TUint16 iNameLength; sl@0: /** sl@0: First two bytes of the executable's name, the name should be considered to sl@0: extend past the end of the TExecutablesListEntry structure to a length sl@0: corresponding to iNameLength sl@0: */ sl@0: TUint16 iName[1]; sl@0: }; sl@0: sl@0: /** sl@0: Returns the size of the TExecutablesListEntry, including the file name length sl@0: sl@0: @return the size, in bytes, of the TExecutablesListEntry and the executable's sl@0: file name sl@0: */ sl@0: inline TInt TExecutablesListEntry::GetSize() const sl@0: { sl@0: return sizeof(TExecutablesListEntry) - sizeof(iName) + (2*iNameLength); sl@0: } sl@0: sl@0: /** sl@0: Structure used for extracting data from a descriptor returned by a call to sl@0: RSecuritySvrSession::GetList() when GetList() is called with TListId::EProcesses sl@0: as the first argument. sl@0: sl@0: @see RSecuritySvrSession::GetList() sl@0: sl@0: @code sl@0: //buffer is a TDesC8 containing 4-byte aligned TProcessListEntry objects sl@0: //create a pointer to the start of the data sl@0: TUint8* ptr = (TUint8*)buffer.Ptr(); sl@0: //create a pointer to the end of the data sl@0: const TUint8* ptrEnd = ptr + buffer.Length(); sl@0: while(ptr < ptrEnd) sl@0: { sl@0: //cast the pointer to be a TProcessListEntry object sl@0: TProcessListEntry& entry = *(TProcessListEntry*)ptr; sl@0: //use the TProcessListEntry pointer, i.e. sl@0: TUint16 fileNameLength = entry.iFileNameLength; sl@0: TPtr name(&(entry.iNames[0]), fileNameLength, fileNameLength); sl@0: // move ptr on to point to the next TProcessListEntry object sl@0: ptr += Align4(entry.GetSize()); sl@0: } sl@0: @endcode sl@0: */ sl@0: class TProcessListEntry sl@0: { sl@0: public: sl@0: TInt GetSize() const; sl@0: sl@0: public: sl@0: /** Process ID */ sl@0: TUint64 iProcessId; sl@0: sl@0: /** The Uid3 of the process */ sl@0: TUint32 iUid3; sl@0: sl@0: /** sl@0: * Process Attributes sl@0: * @see DProcess::TProcessAttributes sl@0: */ sl@0: TInt iAttributes; sl@0: sl@0: /** sl@0: * Length of fully qualified file name of the process in bytes. Note that this sl@0: * entry may be 0 if the process is in the process of shutting down. sl@0: */ sl@0: TUint16 iFileNameLength; sl@0: sl@0: /** sl@0: * Length of current dynamic name of the process in bytes sl@0: */ sl@0: TUint16 iDynamicNameLength; sl@0: sl@0: /** sl@0: * First two bytes of the process' file name, the name should be considered to sl@0: * extend past the end of the TProcessListEntry structure to a length sl@0: * corresponding to iFileNameLength. Directly after the data corresponding to the sl@0: * file name, the dynamic name is stored with a length of iDynamicNameLength characters. sl@0: * Note that these names are not null terminated and are concatenated directly after each other. sl@0: * sl@0: * @code sl@0: * TProcessListEntry& entry; // entry is a reference to a TProcessListEntry sl@0: * sl@0: * //get the file name.. sl@0: * TPtr fileName(&(entry.iNames[0]), iFileNameLength, iFileNameLength); sl@0: * sl@0: * //get the dynamic name length.. sl@0: * TPtr dynamicName(&(entry.iNames[0]) + iFileNameLength, iDynamicNameLength, iDynamicNameLength); sl@0: * @endcode sl@0: */ sl@0: TUint16 iNames[1]; sl@0: }; sl@0: sl@0: /** sl@0: Returns the size of the TProcessListEntry, including the file name length and the sl@0: dynamic name length sl@0: sl@0: @return the size, in bytes, of the TProcessListEntry and the executable's sl@0: file name file name and dynamic name sl@0: */ sl@0: inline TInt TProcessListEntry::GetSize() const sl@0: { sl@0: return sizeof(TProcessListEntry) - sizeof(iNames) + (2 * (iFileNameLength + iDynamicNameLength)); sl@0: } sl@0: sl@0: /** sl@0: Structure used for extracting data from a descriptor returned by a call to sl@0: RSecuritySvrSession::GetList() when GetList() is called with TListId::EThreads sl@0: as the first argument. sl@0: sl@0: @see RSecuritySvrSession::GetList() sl@0: sl@0: @code sl@0: //buffer is a TDesC8 containing 4-byte aligned TThreadListEntry objects sl@0: //create a pointer to the start of the data sl@0: TUint8* ptr = (TUint8*)buffer.Ptr(); sl@0: //create a pointer to the end of the data sl@0: const TUint8* ptrEnd = ptr + buffer.Length(); sl@0: while(ptr < ptrEnd) sl@0: { sl@0: //cast the pointer to be a TThreadListEntry object sl@0: TThreadListEntry& entry = *(TThreadListEntry*)ptr; sl@0: //use the TThreadListEntry pointer, i.e. sl@0: TUint16 nameLength = entry.iNameLength; sl@0: TPtr name(&(entry.iName[0]), nameLength, nameLength); sl@0: // move ptr on to point to the next TThreadListEntry object sl@0: ptr += Align4(entry.GetSize()); sl@0: } sl@0: @endcode sl@0: */ sl@0: class TThreadListEntry sl@0: { sl@0: public: sl@0: TInt GetSize() const; sl@0: public: sl@0: /** sl@0: Thread ID sl@0: */ sl@0: TUint64 iThreadId; sl@0: /** sl@0: Process ID sl@0: */ sl@0: TUint64 iProcessId; sl@0: /** sl@0: Address of the base of the supervisor stack sl@0: */ sl@0: TUint32 iSupervisorStackBase; sl@0: /** sl@0: Size of the supervisor stack sl@0: */ sl@0: TUint32 iSupervisorStackSize; sl@0: /** sl@0: Non-zero if iSupervisorStackBase has been set correctly sl@0: */ sl@0: TUint8 iSupervisorStackBaseValid; sl@0: /** sl@0: Non-zero if iSupervisorStackSize has been set correctly sl@0: */ sl@0: TUint8 iSupervisorStackSizeValid; sl@0: /** sl@0: Address of the thread's supervisor stack pointer sl@0: */ sl@0: TUint32 iSupervisorStackPtr; sl@0: /** sl@0: Indicator of whether the value returned as iSupervisorStackPtr is valid. sl@0: It is necessary, but not necessarily sufficient, that the thread be suspended sl@0: for a valid value to be returned. This may be removed from the final API and sl@0: the value would be extracted instead via the ReadRegisters type calls. sl@0: */ sl@0: TRegisterFlag iSupervisorStackPtrValid; sl@0: /** Currently unused element. May be used in future to aid maintaining compatibility. */ sl@0: TUint32 iSpare1; sl@0: /** Currently unused element. May be used in future to aid maintaining compatibility. */ sl@0: TUint32 iSpare2; sl@0: /** sl@0: The length of the thread's name sl@0: */ sl@0: TUint16 iNameLength; sl@0: /** sl@0: First two bytes of the thread's name, the name should be considered to sl@0: extend past the end of the TThreadListEntry structure to a length sl@0: corresponding to iNameLength sl@0: */ sl@0: TUint16 iName[1]; sl@0: }; sl@0: sl@0: /** sl@0: Returns the size of the TThreadListEntry, including the name length sl@0: sl@0: @return the size, in bytes, of the TExecutablesListEntry and the thread's name sl@0: */ sl@0: inline TInt TThreadListEntry::GetSize() const sl@0: { sl@0: return sizeof(TThreadListEntry) - sizeof(iName) + (2 * iNameLength); sl@0: } sl@0: sl@0: /** sl@0: Denotes which list type to return from a RSecuritySvrSession::GetList() call sl@0: sl@0: @see RSecuritySvrSession::GetList() sl@0: */ sl@0: enum TListId sl@0: { sl@0: /** sl@0: Indicates that the GetList() call should return a list of the processes in sl@0: the system. The returned buffer will contain an array of 4-byte aligned sl@0: TProcessListEntry objects. sl@0: sl@0: @see TProcessListEntry sl@0: */ sl@0: EProcesses = 0, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the threads in sl@0: the system. The returned buffer will contain an array of 4-byte aligned sl@0: TThreadListEntry objects. sl@0: sl@0: @see TThreadListEntry sl@0: */ sl@0: EThreads = 1, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the code segments in sl@0: the system. The returned buffer will contain an array of 4-byte aligned sl@0: TCodeSegListEntry objects. sl@0: sl@0: @see TCodeSegListEntry sl@0: */ sl@0: ECodeSegs = 2, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the XIP libraries in sl@0: the system. The returned buffer will contain an array of 4-byte aligned sl@0: EXipLibraries objects. sl@0: sl@0: @see EXipLibraries sl@0: */ sl@0: EXipLibraries = 3, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the executables in sl@0: the system. The returned buffer will contain an array of 4-byte aligned sl@0: EExecutables objects. sl@0: sl@0: @see EExecutables sl@0: */ sl@0: EExecutables = 4, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the logical devices in the system. sl@0: */ sl@0: ELogicalDevices = 5, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the mutexes in the system. sl@0: */ sl@0: EMutexes = 6, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the servers in the system. sl@0: */ sl@0: EServers = 7, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the sessions in the system. sl@0: */ sl@0: ESessions = 8, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the semaphores in the system. sl@0: */ sl@0: ESemaphores = 9, sl@0: /** sl@0: Indicates that the GetList() call should return a list of the chunks in the system. sl@0: */ sl@0: EChunks = 10, sl@0: sl@0: /** sl@0: Provides a complete list of all the breakpoints in the system and their sl@0: current state. sl@0: sl@0: @see EBreakpoints sl@0: */ sl@0: EBreakpoints = 11, sl@0: sl@0: /** sl@0: The following are for the possible use of kernel-side debug and SMP breakpoint sl@0: manipulation. sl@0: */ sl@0: ESetBreak = 12, sl@0: ERemoveBreak = 13, sl@0: EModifyBreak = 14, sl@0: sl@0: /** sl@0: * Provides static information of the system sl@0: */ sl@0: EStaticInfo = 15, sl@0: sl@0: /** Last listing enum. */ sl@0: EListLast sl@0: }; sl@0: sl@0: /** sl@0: Bit field values denoting the scope of a listing. sl@0: sl@0: In the debug functionality block, the TTag::iValue element which is returned for a listing tag sl@0: should be considered as a union of the supported values from this enumeration for that listing. sl@0: */ sl@0: enum TListScope sl@0: { sl@0: EScopeNone = 0x0, /**< Corresponds to no scope for a listing. equivalent to not supported */ sl@0: EScopeGlobal= 0x1, /**< Corresponds to a global scope for a listing. */ sl@0: EScopeProcessSpecific = 0x2, /**< Corresponds to a process specific scope for a listing. */ sl@0: EScopeThreadSpecific = 0x4 /**< Corresponds to a thread specific scope for a listing. */ sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: sl@0: Interface constructor for passing IPC data for the GetList call. sl@0: */ sl@0: class TListDetails sl@0: { sl@0: public: sl@0: TListDetails(const TListId aListId, const TListScope aListScope, TUint64 aTargetId=0) sl@0: : iListId(aListId), sl@0: iListScope(aListScope), sl@0: iTargetId(aTargetId) {} sl@0: public: sl@0: TListId iListId; sl@0: TListScope iListScope; sl@0: TUint64 iTargetId; sl@0: }; sl@0: sl@0: /** Debug Security Server Secure ID */ sl@0: const TUid KUidDebugSecurityServer = { 0x102834E2 }; sl@0: sl@0: } // end of Debug namespace declaration sl@0: sl@0: // the remaining functionality in this file is intended for use on user side only sl@0: #ifndef __KERNEL_MODE__ sl@0: sl@0: #include sl@0: sl@0: // API definition for Debug namespace appears elsewhere in this file. sl@0: namespace Debug { sl@0: sl@0: /** The name of the Debug Security Server. */ sl@0: _LIT(KSecurityServerName,"DebugSecurityServer"); sl@0: sl@0: // A version must be specified when creating a session with the server sl@0: /** The Debug Security Server's major version number. */ sl@0: const TUint KDebugServMajorVersionNumber=2; sl@0: /** The Debug Security Server's minor version number. */ sl@0: const TUint KDebugServMinorVersionNumber=4; sl@0: /** The Debug Security Server's patch version number. */ sl@0: const TUint KDebugServPatchVersionNumber=0; sl@0: sl@0: /** sl@0: Denotes how memory should be accessed sl@0: */ sl@0: enum TAccess sl@0: { sl@0: EAccess8 = 1, /**< Currently unsupported, signifies 8 bit access. */ sl@0: EAccess16 = 2, /**< Currently unsupported, signifies 16 bit access. */ sl@0: EAccess32 = 4 /**< Signifies 32 bit access. */ sl@0: }; sl@0: sl@0: /** sl@0: Denotes how data should be interpreted sl@0: */ sl@0: enum TEndianess sl@0: { sl@0: EEndLE8 = 0, /**< Signifies 8 bit little-endian. */ sl@0: EEndBE8 = 1, /**< Currently unsupported, signifies 8 bit big-endian. */ sl@0: EEndBE32 = 2 /**< Currently unsupported, signifies 32 bit big-endian. */ sl@0: }; sl@0: sl@0: /** sl@0: Structure used to store information about a memory operation sl@0: sl@0: @internalComponent sl@0: */ sl@0: class TMemoryInfo sl@0: { sl@0: public: sl@0: sl@0: TMemoryInfo(TUint32 aAddress=0, TUint32 aLength=0, TAccess aAccess=EAccess32, TEndianess aEndianess=EEndLE8) sl@0: : iAddress(aAddress), sl@0: iSize(aLength), sl@0: iAccess(aAccess), sl@0: iEndianess(aEndianess) sl@0: {} sl@0: sl@0: public: sl@0: sl@0: /** sl@0: Address to start reading/writing memory sl@0: */ sl@0: TUint32 iAddress; sl@0: /** sl@0: Number of bytes of memory to read/write sl@0: */ sl@0: TUint32 iSize; sl@0: /** sl@0: Access size for read/write sl@0: @see TAccess sl@0: */ sl@0: TAccess iAccess; sl@0: /** sl@0: Endianess to interpret data as sl@0: @see TEndianess sl@0: */ sl@0: TEndianess iEndianess; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TBreakInfo sl@0: { sl@0: public: sl@0: TUint32 iAddress; sl@0: TArchitectureMode iArchitectureMode; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: sl@0: Function codes (opcodes) used in message passing between client and server sl@0: in this header file and what arguments should be passed with each of these sl@0: */ sl@0: enum TDebugServRqst sl@0: { sl@0: EDebugServOpen = 1, sl@0: EDebugServClose = 2, sl@0: EDebugServSuspendThread = 3, sl@0: EDebugServResumeThread = 4, sl@0: EDebugServReadMemory = 5, sl@0: EDebugServWriteMemory = 6, sl@0: EDebugServSetBreak = 7, sl@0: EDebugServClearBreak = 8, sl@0: EDebugServModifyBreak = 9, sl@0: EDebugServGetEvent = 10, sl@0: EDebugServCancelGetEvent = 11, sl@0: EDebugServAttachExecutable = 12, sl@0: EDebugServDetachExecutable = 13, sl@0: EDebugServGetDebugFunctionalityBufSize = 14, sl@0: EDebugServGetDebugFunctionality = 15, sl@0: EDebugServReadRegisters = 16, sl@0: EDebugServWriteRegisters = 17, sl@0: EDebugServSetEventAction = 18, sl@0: EDebugServBreakInfo = 19, sl@0: EDebugServGetList = 20, sl@0: EDebugServStep = 21, sl@0: EDebugServSetProcessBreak = 22, sl@0: EDebugServProcessBreakInfo = 23, sl@0: EDebugServKillProcess = 24, sl@0: EDebugServModifyProcessBreak = 25, sl@0: EDebugServReadCrashFlash = 26, sl@0: EDebugServWriteCrashFlash = 27, sl@0: EDebugServEraseCrashFlash = 28, sl@0: EDebugServEraseEntireCrashFlash = 29, sl@0: }; sl@0: sl@0: /** sl@0: Client side API to debug security server (DSS). Interaction with the DSS should sl@0: be conducted through this class only. sl@0: */ sl@0: class RSecuritySvrSession : public RSessionBase sl@0: { sl@0: public: sl@0: RSecuritySvrSession(); sl@0: TVersion Version() const; sl@0: sl@0: TInt Close(); sl@0: sl@0: TInt AttachExecutable(const TDesC& aProcessName, TBool aPassive); sl@0: TInt DetachExecutable(const TDesC& aProcessName); sl@0: sl@0: TInt GetDebugFunctionalityBufSize(TUint32* aBufSize); sl@0: TInt GetDebugFunctionality(TDes8& aBuffer); sl@0: sl@0: TInt SuspendThread(const TThreadId aThreadId); sl@0: TInt ResumeThread(const TThreadId aThreadId); sl@0: sl@0: TInt ReadMemory(const TThreadId aThreadId, const TUint32 aAddress, const TUint32 aLength, TDes8 &aData, const TAccess aAccessSize, const TEndianess aEndianess); sl@0: TInt WriteMemory(const TThreadId aThreadId, const TUint32 aAddress, const TUint32 aLength, const TDesC8 &aData, const TAccess aAccessSize, const TEndianess aEndianess); sl@0: sl@0: TInt ReadRegisters(const TThreadId aThreadId, const TDesC8& aRegisterIds, TDes8& aRegisterValues, TDes8& aRegisterFlags); sl@0: TInt WriteRegisters(const TThreadId aThreadId, const TDesC8& aRegisterIds, const TDesC8& aRegisterValues, TDes8& aRegisterFlags); sl@0: sl@0: void GetEvent(const TDesC& aExecutableName, TRequestStatus &aStatus, TDes8& aEventInfo); sl@0: TInt CancelGetEvent(const TDesC& aExecutableName); sl@0: sl@0: TInt SetEventAction(const TDesC& aExecutableName, TEventType aEvent, TKernelEventAction aEventAction); sl@0: sl@0: TInt SetBreak( TBreakId &aId, const TThreadId aThreadId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode); sl@0: TInt ClearBreak(const TBreakId aBreakId); sl@0: TInt ModifyBreak(const TBreakId aBreakId, const TThreadId aThreadId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode); sl@0: TInt BreakInfo(const TBreakId aBreakId, TThreadId& aThreadId, TUint32& aAddress, TArchitectureMode& aMode); sl@0: TInt SetProcessBreak( TBreakId &aId, const TProcessId aProcessId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode); sl@0: TInt ProcessBreakInfo(const TBreakId aBreakId, TProcessId& aProcessId, TUint32& aAddress, TArchitectureMode& aMode); sl@0: TInt ModifyProcessBreak(const TBreakId aBreakId, const TProcessId aProcessId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode); sl@0: sl@0: TInt GetList(const TListId aListId, TDes8& aListData, TUint32& aDataSize); sl@0: TInt GetList(const TThreadId aThreadId, const TListId aListId, TDes8& aListData, TUint32& aDataSize); sl@0: TInt GetList(const TProcessId aProcessId, const TListId aListId, TDes8& aListData, TUint32& aDataSize); sl@0: TInt Step(const TThreadId aThreadId, TUint32 aNumSteps); sl@0: TInt KillProcess(const TProcessId aProcessId, const TInt aReason); sl@0: TInt ReadCrashLog(const TUint32 aPos, TDes8& aData, const TUint32 aDataSize); sl@0: TInt WriteCrashConfig(const TUint32 aPos, const TDesC8& aBuffer, TUint32& aSize); sl@0: TInt EraseCrashLog(const TUint32 aPos, const TUint32 aBlockNumber); sl@0: TInt EraseCrashFlashPartition(); sl@0: sl@0: TInt Connect(const TVersion aVersion); sl@0: private: sl@0: TInt StartServer(void); sl@0: }; sl@0: /** sl@0: Server session constructor sl@0: */ sl@0: inline RSecuritySvrSession::RSecuritySvrSession() sl@0: { sl@0: sl@0: } sl@0: sl@0: /** sl@0: Called by a client to create a session with the DSS. This method starts the sl@0: DSS if it is not running, or connects to it if it already exists. sl@0: sl@0: @param aVersion version of the DSS to connect to sl@0: sl@0: @return KErrNone if a connection was successfully created, or one of the other sl@0: system wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::Connect(const TVersion aVersion) sl@0: { sl@0: // default message slots for the server sl@0: const TUint KDefaultMessageSlots = 4; sl@0: TInt retry=2; sl@0: for (;;) sl@0: { sl@0: TInt r=CreateSession(KSecurityServerName, aVersion, KDefaultMessageSlots); sl@0: if (r!=KErrNotFound && r!=KErrServerTerminated) sl@0: { sl@0: return r; sl@0: } sl@0: if (--retry==0) sl@0: { sl@0: return r; sl@0: } sl@0: r=StartServer(); sl@0: if (r!=KErrNone && r!=KErrAlreadyExists) sl@0: { sl@0: return r; sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Start the server sl@0: sl@0: @return KErrNone on success, or one of the other system wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::StartServer() sl@0: { sl@0: // constants for the server sl@0: _LIT(KSecurityServerProcessName, "rm_debug_svr"); sl@0: const TUidType serverUid(KNullUid, KNullUid, KUidDebugSecurityServer); sl@0: sl@0: RProcess server; sl@0: TInt err = server.Create(KSecurityServerProcessName, KNullDesC, serverUid); sl@0: sl@0: if(KErrNone != err) sl@0: { sl@0: return err; sl@0: } sl@0: sl@0: // Synchronise with the process to make sure it hasn't died straight away sl@0: TRequestStatus stat; sl@0: server.Rendezvous(stat); sl@0: if (stat != KRequestPending) sl@0: { sl@0: // logon failed - server is not yet running, so cannot have terminated sl@0: server.Kill(0); // Abort startup sl@0: } sl@0: else sl@0: { sl@0: // logon OK - start the server sl@0: server.Resume(); sl@0: } sl@0: sl@0: // Wait to synchronise with server - if it dies in the meantime, it sl@0: // also gets completed sl@0: User::WaitForRequest(stat); sl@0: sl@0: // We can't use the 'exit reason' if the server panicked as this sl@0: // is the panic 'reason' and may be '0' which cannot be distinguished sl@0: // from KErrNone sl@0: err = (server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int(); sl@0: server.Close(); sl@0: return err; sl@0: } sl@0: sl@0: /** sl@0: Get version of RSecuritySvrSession sl@0: sl@0: @return a TVersion object specifying the version sl@0: */ sl@0: inline TVersion RSecuritySvrSession::Version(void) const sl@0: { sl@0: return (TVersion(KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServPatchVersionNumber)); sl@0: } sl@0: sl@0: /** sl@0: Suspends execution of the specified thread. sl@0: sl@0: @param aThreadId thread ID of the thread to suspend sl@0: sl@0: @return KErrNone if there were no problems, KErrPermissionDenied if security sl@0: check fails or KErrArgument if the thread does not exist sl@0: */ sl@0: inline TInt RSecuritySvrSession::SuspendThread(const TThreadId aThreadId) sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: TIpcArgs args(&threadIdPckg); sl@0: sl@0: return SendReceive(EDebugServSuspendThread, args); sl@0: } sl@0: sl@0: /** sl@0: Resumes execution of the specified thread. sl@0: sl@0: @param aThreadId thread ID of the thread to resume sl@0: sl@0: @return KErrNone if there were no problems, KErrPermissionDenied if security sl@0: check fails or KErrArgument if the thread does not exist sl@0: */ sl@0: inline TInt RSecuritySvrSession::ResumeThread(const TThreadId aThreadId) sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: TIpcArgs args(&threadIdPckg); sl@0: sl@0: return SendReceive(EDebugServResumeThread, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Set a thread-specific breakpoint in an attached process. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: sl@0: @param aThreadId The thread id to which the breakpoint will apply. sl@0: @param aAddress The virtual memory address at which to place the breakpoint. sl@0: @param aArchitectureMode The kind of breakpoint which is to be set (e.g. ARM/Thumb/Thumb2EE) sl@0: @param aBreakId The address to which the assigned breakpoint ID will be written by this function sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::SetBreak( TBreakId &aBreakId,const TThreadId aThreadId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode) sl@0: { sl@0: TPtr8 breakIdPtr((TUint8*)&aBreakId, sizeof(aBreakId)); sl@0: sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: sl@0: TBreakInfo breakInfo; sl@0: breakInfo.iAddress = aAddress; sl@0: breakInfo.iArchitectureMode = aArchitectureMode; sl@0: TPckgBuf breakInfoPckg(breakInfo); sl@0: sl@0: //call driver to attempt to set break sl@0: TIpcArgs args(&threadIdPckg, &breakInfoPckg, &breakIdPtr); sl@0: return SendReceive(EDebugServSetBreak, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Clears a previously set thread-specific or process-specific breakpoint. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: sl@0: @param aBreakId The TBreakId returned by a prior SetBreak call. Must have been set by the same Debug Agent. sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::ClearBreak(const TBreakId aBreakId) sl@0: { sl@0: TIpcArgs args(aBreakId); sl@0: return SendReceive(EDebugServClearBreak, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Modifies the properties of a previously set breakpoint. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: sl@0: @param aBreakId the TBreakId returned by a prior SetBreak() call. Must have been set by the same Debug Agent. sl@0: @param aThreadId the thread id of the thread to move the breakpoint to sl@0: @param aAddress the virtual memory address at which to place the breakpoint. sl@0: @param aArchitectureMode the kind of breakpoint which is to be set (e.g. ARM/Thumb/Thumb2EE) sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::ModifyBreak(const TBreakId aBreakId, const TThreadId aThreadId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode) sl@0: sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: TIpcArgs args(aBreakId,&threadIdPckg,aAddress,aArchitectureMode); sl@0: return SendReceive(EDebugServModifyBreak, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Modifies the properties of a previously set process breakpoint. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: sl@0: @param aBreakId the TBreakId returned by a prior SetBreak() call. Must have been set by the same Debug Agent. sl@0: @param aProcessId the process id of the process to move the breakpoint to sl@0: @param aAddress the virtual memory address at which to place the breakpoint. sl@0: @param aArchitectureMode the kind of breakpoint which is to be set (e.g. ARM/Thumb/Thumb2EE) sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::ModifyProcessBreak(const TBreakId aBreakId, const TProcessId aProcessId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode) sl@0: sl@0: { sl@0: TPckgBuf processIdPckg(aProcessId); sl@0: TIpcArgs args(aBreakId,&processIdPckg,aAddress,aArchitectureMode); sl@0: return SendReceive(EDebugServModifyProcessBreak, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Returns the properties associated with a given TBreakId. The supplied break id must previously have been allocated sl@0: to the debug agent by a SetBreak() call. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: @pre The aBreakId must have been previously returned by a SetBreak() call and not subsequently cleared by ClearBreak(). sl@0: sl@0: @param aBreakId the TBreakId returned by a prior SetBreak() call. Must have been set by the same Debug Agent. sl@0: @param aAddress on return contains the virtual memory address of the breakpoint sl@0: @param aThreadId on return contains the thread id of the thread that the breakpoint is set in sl@0: @param aMode on return contains the type of this breakpoint (e.g. ARM/Thumb/Thumb2EE) sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::BreakInfo(const TBreakId aBreakId, TThreadId& aThreadId, TUint32& aAddress, TArchitectureMode& aMode) sl@0: { sl@0: // temporary descriptors sl@0: TPtr8 threadId((TUint8*)&aThreadId,0,sizeof(TThreadId)); sl@0: TPtr8 address((TUint8*)&aAddress,0,sizeof(TUint32)); sl@0: TPtr8 mode((TUint8*)&aMode,0,sizeof(TArchitectureMode)); sl@0: sl@0: TIpcArgs args(aBreakId,&threadId,&address,&mode); sl@0: return SendReceive(EDebugServBreakInfo, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Set a process-specific breakpoint in an attached process. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: sl@0: @param aProcessId The process id to which the breakpoint will apply. sl@0: @param aAddress The virtual memory address at which to place the breakpoint. sl@0: @param aArchitectureMode The kind of breakpoint which is to be set (e.g. ARM/Thumb/Thumb2EE) sl@0: @param aBreakId The address to which the assigned breakpoint ID will be written by this function sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::SetProcessBreak( TBreakId &aBreakId, const TProcessId aProcessId, const TUint32 aAddress, const TArchitectureMode aArchitectureMode) sl@0: { sl@0: TPtr8 breakIdPtr((TUint8*)&aBreakId, sizeof(aBreakId)); sl@0: sl@0: TPckgBuf threadIdPckg(aProcessId); sl@0: sl@0: TBreakInfo breakInfo; sl@0: breakInfo.iAddress = aAddress; sl@0: breakInfo.iArchitectureMode = aArchitectureMode; sl@0: TPckgBuf breakInfoPckg(breakInfo); sl@0: sl@0: //call driver to attempt to set break sl@0: TIpcArgs args(&threadIdPckg, &breakInfoPckg, &breakIdPtr); sl@0: return SendReceive(EDebugServSetProcessBreak, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Returns the properties associated with a given TBreakId. The supplied break id must previously have been allocated sl@0: to the debug agent by a SetProcessBreak() call. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: @pre The aBreakId must have been previously returned by a SetProcessBreak() call and not subsequently cleared by ClearBreak(). sl@0: sl@0: @param aBreakId the TBreakId returned by a prior SetBreak() call. Must have been set by the same Debug Agent. sl@0: @param aAddress on return contains the virtual memory address of the breakpoint sl@0: @param aThreadId on return contains the thread id of the thread that the breakpoint is set in sl@0: @param aMode on return contains the type of this breakpoint (e.g. ARM/Thumb/Thumb2EE) sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::ProcessBreakInfo(const TBreakId aBreakId, TProcessId& aProcessId, TUint32& aAddress, TArchitectureMode& aMode) sl@0: { sl@0: // temporary descriptors sl@0: TPtr8 processId((TUint8*)&aProcessId,0,sizeof(TProcessId)); sl@0: TPtr8 address((TUint8*)&aAddress,0,sizeof(TUint32)); sl@0: TPtr8 mode((TUint8*)&aMode,0,sizeof(TArchitectureMode)); sl@0: sl@0: TIpcArgs args(aBreakId,&processId,&address,&mode); sl@0: return SendReceive(EDebugServProcessBreakInfo, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Wait for an event to occur to the target executable being debugged. When an event sl@0: occurs, the TRequestStatus is changed from KRequestPending. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: sl@0: Note 1: Events are reported on a per-executable basis, not per-thread. sl@0: sl@0: Note 2: All the parameters must remain in scope until either CancelGetEvent is called, or sl@0: until TRequestStatus is changed from KRequestPending. In practice, this generally sl@0: means these parameters should not be based on the stack, as they may go out of sl@0: scope before the call completes. sl@0: sl@0: Note 3: TIpcArgs args is allocated on the stack within this function, however, sl@0: all the data containing in args is transferred in the SendReceive() so it can safely sl@0: go out of scope after the call has been made. sl@0: sl@0: @param aExecutableName The name of any executable to which the Debug Agent is attached. sl@0: @param aStatus Debug Agent request status variable. sl@0: @param aEventInfo Descriptor containing a buffer sufficient for Event information. sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline void RSecuritySvrSession::GetEvent(const TDesC& aExecutableName, TRequestStatus &aStatus, TDes8& aEventInfo) sl@0: { sl@0: TIpcArgs args(&aExecutableName, &aEventInfo); sl@0: sl@0: SendReceive(EDebugServGetEvent, args, aStatus ); sl@0: sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Cancel a previously issued asynchronous RSecuritySvrSession::GetEvent call. The previously sl@0: issued call will immediately complete with the TRequestStatus = KErrCancel sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to the process specified by aProcessName sl@0: @pre Debug Agent must have previously issued an RSecuritySvrSession::GetEvent() call. sl@0: sl@0: @param aExecutableName The name of the executable being debugged. sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::CancelGetEvent(const TDesC& aExecutableName) sl@0: { sl@0: TIpcArgs args(&aExecutableName); sl@0: sl@0: return SendReceive(EDebugServCancelGetEvent,args); sl@0: } sl@0: sl@0: /** sl@0: Called by a debug agent to request debug privileges for the executable with sl@0: file name aExecutableName. sl@0: sl@0: @param aExecutableName a fully qualified file name of the executable to attach to sl@0: @param aPassive if true then the agent has reduced debug rights. sl@0: sl@0: @return KErrNone if attached successfully, one of the other system wide error sl@0: codes otherwise sl@0: */ sl@0: inline TInt RSecuritySvrSession::AttachExecutable(const TDesC& aExecutableName, TBool aPassive) sl@0: { sl@0: TIpcArgs args((TInt)aPassive, &aExecutableName); sl@0: return SendReceive(EDebugServAttachExecutable, args); sl@0: } sl@0: sl@0: /** sl@0: Called by a debug agent to detach from the executable with file sl@0: name aExecutableName. sl@0: sl@0: @param aExecutableName the fully qualified file name of the executable to detach from sl@0: sl@0: @return KErrNone if detached successfully, one of the other system wide error sl@0: codes otherwise sl@0: */ sl@0: inline TInt RSecuritySvrSession::DetachExecutable(const TDesC& aExecutableName) sl@0: { sl@0: TIpcArgs args(&aExecutableName); sl@0: return SendReceive(EDebugServDetachExecutable, args); sl@0: } sl@0: sl@0: /** sl@0: Close the session and thread sl@0: sl@0: @return KErrNone if the session is closed successfully, otherwise one of the system wide errors. sl@0: */ sl@0: inline TInt RSecuritySvrSession::Close() sl@0: { sl@0: RSessionBase::Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: Get buffer size required to contain Functionality text block. sl@0: sl@0: @see in-source documentation in rm_debug_api.h sl@0: sl@0: @param aBufSize function will fill this with the required buffer size sl@0: sl@0: @return KErrNone if the call succeeded, or one of the other system wide error sl@0: codes if the call failed sl@0: */ sl@0: inline TInt RSecuritySvrSession::GetDebugFunctionalityBufSize(TUint32 *aBufSize) sl@0: { sl@0: TInt res = KErrNone; sl@0: sl@0: TPtr8 stuff((TUint8*)aBufSize,4, 4); sl@0: sl@0: TIpcArgs args(&stuff); sl@0: sl@0: res = SendReceive(EDebugServGetDebugFunctionalityBufSize, args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: /** sl@0: Get debug functionality text block and place it into aBuffer. sl@0: sl@0: The debug functionality block (DFBlock) is used to provide information about the functionality sl@0: (i.e. features) which are supported by the rm_debug.ldd device driver. sl@0: sl@0: Calling this function with a suitably sized buffer aBuffer will result in the debug sl@0: functionality information being stored in aBuffer. The necessary size of aBuffer can sl@0: be determined by calling DebugFunctionalityBufSize(). sl@0: sl@0: The format of the DFBlock is: sl@0: sl@0: @code sl@0: Sub-block 0 sl@0: Sub-block 1 sl@0: ... sl@0: Sub-block N-1 sl@0: @endcode sl@0: sl@0: The data which will be returned by a call to GetDebugFunctionality() is constant so is sl@0: guaranteed to fit exactly into the aBuffer allocated, assuming that the size of aBuffer sl@0: corresponds to the value returned from GetDebugFunctionalityBufSize(). sl@0: sl@0: Each sub-block is composed of a TTagHeader object followed by a C-style array of TTag objects. sl@0: The sub-block contains information about a particular aspect of the debug sub-system, for example sl@0: information about the manner in which memory can be accessed. sl@0: The TTagHeader is comprised of an identifier which determines the type of data sl@0: it contains, together with the number of TTag elements in the array following the TTagHeader. sl@0: Each TTag in a sub-block has a unique ID, stored in the TTag::iTagId member variable. sl@0: sl@0: The only sub-block that is guaranteed to exist has TTagHeader::iTagHdrId = ETagHeaderIdCore, all other sl@0: sub-blocks are optional. The ETagHeaderIdCore sub-block is the first sub-block within the DFBlock. sl@0: Other sub-blocks may appear in any order after the ETagHeaderIdCore sub-block. sl@0: sl@0: The following is a diagrammatic representation of a sub-block the DFBlock: sl@0: sl@0: @code sl@0: The HHHH represents the tag header ID of a sub-block (TTagHeader::iTagHdrId) sl@0: The NNNN represents the number of TTag elements in the sub-block (TTagHeader::iNumTags) sl@0: The IIIIIIII represents the ID of the TTag (TTag::iTagId) sl@0: The TTTT represents the type of the TTag (TTag::iType) sl@0: The SSSS represents the size of the TTag's associated data (TTag::iSize) sl@0: The VVVVVVVV represents the TTag's value (TTag::iValue) sl@0: sl@0: 0xNNNNHHHH TTagHeader element for first sub-block (has N1 TTag elements) sl@0: 0xIIIIIIII \ sl@0: 0xSSSSTTTT -- TTag 0 sl@0: 0xVVVVVVVV / sl@0: 0xIIIIIIII \ sl@0: 0xSSSSTTTT -- TTag 1 sl@0: 0xVVVVVVVV / sl@0: ... sl@0: 0xIIIIIIII \ sl@0: 0xSSSSTTTT -- TTag N1 - 1 sl@0: 0xVVVVVVVV / sl@0: 0xNNNNHHHH TTagHeader element for second sub-block (has N2 TTag elements) sl@0: 0xIIIIIIII \ sl@0: 0xSSSSTTTT -- TTag 0 sl@0: 0xVVVVVVVV / sl@0: ... sl@0: 0xIIIIIIII \ sl@0: 0xSSSSTTTT -- TTag N2 - 1 sl@0: 0xVVVVVVVV / sl@0: ... sl@0: 0xNNNNHHHH TTagHeader element for last sub-block (has NX TTag elements) sl@0: 0xIIIIIIII \ sl@0: 0xSSSSTTTT -- TTag 0 sl@0: 0xVVVVVVVV / sl@0: ... sl@0: 0xIIIIIIII \ sl@0: 0xSSSSTTTT -- TTag NX - 1 sl@0: 0xVVVVVVVV / sl@0: @endcode sl@0: sl@0: The following example DFBlock contains two sub-blocks (values taken from enums below): sl@0: - ETagHeaderIdCore sl@0: - ETagHeaderIdMemory sl@0: sl@0: @code sl@0: Binary Meaning Value sl@0: sl@0: 0x000A0000 iTagHdrId, iNumTags ETagHeaderIdCore, ECoreLast sl@0: 0x00000000 iTagId ECoreEvents sl@0: 0x00000000 iType, iSize ETagTypeBoolean, 0 sl@0: 0x00000001 iValue ETrue sl@0: 0x00000001 iTagId ECoreStartStop sl@0: 0x00000000 iType, iSize ETagTypeBoolean, 0 sl@0: 0x00000001 iValue ETrue sl@0: ... sl@0: 0x00000008 iTagId ECoreHardware sl@0: 0x00000000 iType, iSize ETagTypeBoolean, 0 sl@0: 0x00000000 iValue EFalse sl@0: 0x00000009 iTagId ECoreApiConstants sl@0: 0x00000000 iType, iSize ETagTypeBoolean, 0 sl@0: 0x00000001 iValue ETrue sl@0: sl@0: 0x000A0001 iTagHdrId, iNumTags ETagHeaderIdMemory, EMemoryLast sl@0: 0x00000000 iTagId EMemoryRead sl@0: 0x00000000 iType, iSize ETagTypeBoolean, 0 sl@0: 0x00000001 iValue ETrue sl@0: 0x00000001 iTagId EMemoryWrite sl@0: 0x00000000 iType, iSize ETagTypeBoolean, 0 sl@0: 0x00000001 iValue ETrue sl@0: ... sl@0: 0x00000008 iTagId EMemoryLE8 sl@0: 0x00000000 iType, iSize ETagTypeBoolean, 0 sl@0: 0x00000001 iValue ETrue sl@0: 0x00000009 iTagId EMemoryMaxBlockSize sl@0: 0x00000001 iType, iSize ETagTypeTUint32, 0 sl@0: 0x00004000 iValue 0x4000 sl@0: @endcode sl@0: sl@0: - Debug Agent DFBlock Processing: sl@0: sl@0: Debug Agents MUST understand and process the ETagHeaderIdCore block. The other sl@0: blocks may be ignored if not recognised. Tags within each block may be ignored if sl@0: not recognised. sl@0: sl@0: @pre aBuffer.MaxLength() >= *aBufSize where aBufSize is set by a call to: sl@0: RSecuritySvrSession::GetDebugFunctionalityBufSize(TUint32 *aBufSize) sl@0: sl@0: @param aBuffer buffer to store functionality block in sl@0: sl@0: @return KErrNone if call succeeded, sl@0: KErrNoMemory if temporary memory could not be allocated, sl@0: KErrGeneral if debug functionality block could not be accessed sl@0: */ sl@0: inline TInt RSecuritySvrSession::GetDebugFunctionality(TDes8& aBuffer) sl@0: { sl@0: TIpcArgs args(&aBuffer); sl@0: sl@0: TInt res = KErrNone; sl@0: sl@0: res = SendReceive(EDebugServGetDebugFunctionality, args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: /** sl@0: Read a block of memory from the target debug thread defined by aThreadId. sl@0: sl@0: @pre the client should attach to the process containing the target thread sl@0: @pre aData.MaxLength() >= aLength sl@0: sl@0: @param aThreadId thread ID of the thread to read memory from sl@0: @param aAddress address to start reading memory from sl@0: @param aLength number of bytes of memory to read sl@0: @param aData descriptor to read memory into sl@0: @param aAccessSize access size for memory reads, default is TAccess::EAccess32 sl@0: @param aEndianess interpretation of endianess of target data, default is sl@0: TEndianess::EEndLE8 sl@0: sl@0: @return KErrNone if memory read successfully, or one of the other system wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::ReadMemory(const TThreadId aThreadId, const TUint32 aAddress, const TUint32 aLength, TDes8 &aData, const TAccess aAccessSize, const TEndianess aEndianess) sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: //set up memory info object sl@0: TMemoryInfo memoryInfo; sl@0: memoryInfo.iAddress = aAddress; sl@0: memoryInfo.iSize = aLength; sl@0: memoryInfo.iAccess = aAccessSize; sl@0: memoryInfo.iEndianess = aEndianess; sl@0: sl@0: TPckgBuf pckg(memoryInfo); sl@0: sl@0: TIpcArgs args(&threadIdPckg, &pckg, &aData); sl@0: sl@0: return SendReceive(EDebugServReadMemory, args); sl@0: } sl@0: sl@0: /** sl@0: Write a block of memory to the target debug thread defined by aThreadId. sl@0: sl@0: @pre the client should attach non-passively to the process containing the sl@0: target thread sl@0: sl@0: @param aThreadId thread ID of the thread to write memory to sl@0: @param aAddress address to start writing memory at sl@0: @param aLength number of bytes of memory to write sl@0: @param aData descriptor to read memory from sl@0: @param aAccessSize access size for memory writes, default is TAccess::EAccess32 sl@0: @param aEndianess interpretation of endianess of target data, default is sl@0: TEndianess::EEndLE8 sl@0: sl@0: @return KErrNone if memory written successfully, or one of the other system wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::WriteMemory(const TThreadId aThreadId, const TUint32 aAddress, const TUint32 aLength, const TDesC8 &aData, const TAccess aAccessSize, const TEndianess aEndianess) sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: //create memory info object sl@0: TMemoryInfo memoryInfo; sl@0: memoryInfo.iAddress = aAddress; sl@0: memoryInfo.iSize = aLength; sl@0: memoryInfo.iAccess = aAccessSize; sl@0: memoryInfo.iEndianess = aEndianess; sl@0: sl@0: TPckgBuf pckg(memoryInfo); sl@0: sl@0: TIpcArgs args(&threadIdPckg, &pckg, &aData); sl@0: sl@0: return SendReceive(EDebugServWriteMemory, args); sl@0: } sl@0: sl@0: /** sl@0: Read register values from the thread with thread ID aThreadId. The IDs of the sl@0: registers to read are stored as an array of TRegisterInfo objects in sl@0: aRegisterIds. If the nth register requested could be read then the value of the sl@0: register will be appended to aRegisterValues and EValid stored at sl@0: offset n in aRegisterFlags. If the register is supported but could not be read sl@0: then EInValid will be stored at offset n in aRegisterFlags and arbitrary data sl@0: appended in aRegisterValues. If reading the specified register is not sl@0: supported by the kernel then ENotSupported will be stored at offset n in sl@0: aRegisterFlags and arbitrary data appended to aRegisterValues. If an unknown sl@0: register is specified then EUnknown will be put in aRegisterFlags and sl@0: arbitrary data placed in aRegisterValues. sl@0: sl@0: @pre the client should attach to the process containing the target thread sl@0: sl@0: @see the register ID format is defined in: sl@0: SGL.TS0028.027 - Symbian Core Dump File Format v1.0.doc sl@0: sl@0: @param aThreadId thread ID of the thread to read register values from sl@0: @param aRegisterIds descriptor containing array of TFunctionalityRegister defined sl@0: register IDs sl@0: @param aRegisterValues descriptor to contain register values sl@0: @param aRegisterFlags descriptor containing array of TUint8 flags, with values sl@0: taken from TRegisterFlag sl@0: sl@0: @return KErrNone if registers were read successfully, or one of the other system wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::ReadRegisters(const TThreadId aThreadId, const TDesC8& aRegisterIds, TDes8& aRegisterValues, TDes8& aRegisterFlags) sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: TIpcArgs args(&threadIdPckg, &aRegisterIds, &aRegisterValues, &aRegisterFlags); sl@0: sl@0: return SendReceive(EDebugServReadRegisters, args); sl@0: } sl@0: sl@0: /** sl@0: Write register values to the thread with thread ID aThreadId. The IDs of the sl@0: registers to write are stored as an array of TRegisterInfo objects in sl@0: aRegisterIds. The values to put in the registers are stored as an array of sl@0: objects in aRegisterValues. If the nth register to write could be sl@0: written then EValid stored at offset n in aRegisterFlags. If the register is sl@0: supported but could not be written then EInValid will be stored at offset n in sl@0: aRegisterFlags. If writing to the specified register is not supported by the sl@0: kernel then ENotSupported will be stored at offset n in aRegisterFlags. If an sl@0: unknown register is specified then EUnknown will be put in aRegisterFlags. sl@0: sl@0: @pre the client should attach non-passively to the process containing the sl@0: target thread sl@0: sl@0: @see the register ID format is defined in: sl@0: SGL.TS0028.027 - Symbian Core Dump File Format v1.0.doc sl@0: sl@0: @param aThreadId thread ID of the thread to write register values to sl@0: @param aRegisterIds descriptor containing array of TFunctionalityRegister defined sl@0: register IDs sl@0: @param aRegisterValues descriptor containing array of register values sl@0: @param aRegisterFlags descriptor containing array of TUint8 flags, with values sl@0: taken from TRegisterFlag sl@0: sl@0: @return KErrNone if registers were written successfully, or one of the other system wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::WriteRegisters(const TThreadId aThreadId, const TDesC8& aRegisterIds, const TDesC8& aRegisterValues, TDes8& aRegisterFlags) sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: TIpcArgs args(&threadIdPckg, &aRegisterIds, &aRegisterValues, &aRegisterFlags); sl@0: sl@0: return SendReceive(EDebugServWriteRegisters, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Set the requisite actions to be taken when a particular event occurs. sl@0: The events are defined in Debug::TEventType and the sl@0: actions are defined in Debug::TKernelEventAction. sl@0: sl@0: The default action for all events is EActionIgnore. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to the executable specified by aExecutableName. sl@0: sl@0: Note: Event actions are on a per-executable basis. This is sl@0: to ensure that events such as EEventStartThread are notified to the Debug sl@0: Agent, even though the debug agent cannot be aware of the existence sl@0: of a new thread at the time the event occurs. sl@0: sl@0: @param aExecutableName The name of the executable to which the Debug Agent is attached. sl@0: @param aEvent A TEventType enum defined in rm_debug_api.h:Debug::TEventType sl@0: @param aEventAction Any TKernelEventAction permitted by the DFBlock. sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::SetEventAction(const TDesC& aExecutableName, TEventType aEvent, TKernelEventAction aEventAction) sl@0: { sl@0: TInt res = KErrNone; sl@0: sl@0: TIpcArgs args(&aExecutableName,aEvent,aEventAction); sl@0: sl@0: res = SendReceive(EDebugServSetEventAction, args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: /** sl@0: Returns a global listing corresponding to the type specified as aListId. The structure sl@0: of the returned data depends on the value of aListId, see TListId for details. sl@0: If aListData is not large enough to contain the listings data then sl@0: the necessary buffer size is stored in aDataSize and the function returns sl@0: KErrTooBig. In this case the contents of aListData will not contain useful data. sl@0: sl@0: Note that if the aListData buffer was too small to hold the data then the value sl@0: returned as aDataSize corresponds to the size of the data at that particular sl@0: instance. The size of the data will vary over time, for example the thread list sl@0: will increase and decrease in size as threads are created and destroyed, so sl@0: re-requesting data with a buffer with max length aDataSize will not necessarily sl@0: succeed if a list has increased in size between the two calls. sl@0: sl@0: @see TListId sl@0: sl@0: @param aListId enum from TListId signifying which type of listing to return sl@0: @param aListData buffer provided by the debug agent in which data can be returned by the debug system sl@0: @param aDataSize if aListData was not large enough to contain the requested sl@0: data then the necessary buffer size is stored in aDataSize. If aListData sl@0: was large enough then the value of aDataSize is the length of aListData sl@0: sl@0: @return KErrNone if data was returned successfully, sl@0: KErrTooBig if aListData is too small to hold the data, sl@0: one of the other system-wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::GetList(const TListId aListId, TDes8& aListData, TUint32& aDataSize) sl@0: { sl@0: //second argument of ETrue implies a global listing sl@0: TListDetails info(aListId, EScopeGlobal); sl@0: TPtr8 infoBuf((TUint8*)&info, sizeof(TListDetails), sizeof(TListDetails)); sl@0: TPtr8 dataSizeBuf((TUint8*)&aDataSize, sizeof(TUint32), sizeof(TUint32)); sl@0: TIpcArgs args(&infoBuf, &aListData, &dataSizeBuf); sl@0: return SendReceive(EDebugServGetList, args); sl@0: } sl@0: sl@0: /** sl@0: Returns a thread-specific listing corresponding to the type specified as aListId. The structure sl@0: of the returned data depends on the value of aListId, see TListId for details. sl@0: If aListData is not large enough to contain the listings data then sl@0: the necessary buffer size is stored in aDataSize and the function returns sl@0: KErrTooBig. In this case the contents of aListData will not contain useful data. sl@0: sl@0: Note that if the aListData buffer is too small to hold the data then the value sl@0: returned as aDataSize corresponds to the size of the data at that particular sl@0: instant. The size of the data will vary over time, for example the thread list sl@0: will increase and decrease in size as threads are created and destroyed, so sl@0: re-requesting data with a buffer with max length aDataSize will not necessarily sl@0: succeed if a list has increased in size between the two calls. sl@0: sl@0: @see TListId sl@0: sl@0: @param aThreadId thread to return the listing for sl@0: @param aListId member of TListId signifying which type of listing to return sl@0: @param aListData buffer provided by the debug agent in which data can be returned by the debug system. sl@0: @param aDataSize if aListData was not large enough to contain the requested sl@0: data then the necessary buffer size is stored in aDataSize. If aListData sl@0: was large enough then the value of aDataSize is the length of aListData sl@0: sl@0: @return KErrNone if data was returned successfully, sl@0: KErrTooBig if aListData is too small to hold the data, sl@0: one of the other system-wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::GetList(const TThreadId aThreadId, const TListId aListId, TDes8& aListData, TUint32& aDataSize) sl@0: { sl@0: TListDetails info(aListId, EScopeThreadSpecific, aThreadId.Id()); sl@0: TPtr8 infoBuf((TUint8*)&info, sizeof(TListDetails), sizeof(TListDetails)); sl@0: TPtr8 dataSizeBuf((TUint8*)&aDataSize, sizeof(TUint32), sizeof(TUint32)); sl@0: TIpcArgs args(&infoBuf, &aListData, &dataSizeBuf); sl@0: return SendReceive(EDebugServGetList, args); sl@0: } sl@0: sl@0: /** sl@0: Returns a process-specific listing corresponding to the type specified as aListId. The structure sl@0: of the returned data depends on the value of aListId, see TListId for details. sl@0: If aListData is not large enough to contain the listings data then sl@0: the necessary buffer size is stored in aDataSize and the function returns sl@0: KErrTooBig. In this case the contents of aListData will not contain useful data. sl@0: sl@0: Note that if the aListData buffer is too small to hold the data then the value sl@0: returned as aDataSize corresponds to the size of the data at that particular sl@0: instant. The size of the data will vary over time, for example the thread list sl@0: will increase and decrease in size as threads are created and destroyed, so sl@0: re-requesting data with a buffer with max length aDataSize will not necessarily sl@0: succeed if a list has increased in size between the two calls. sl@0: sl@0: @see TListId sl@0: sl@0: @param aProcessId process to return the listing for sl@0: @param aListId member of TListId signifying which type of listing to return sl@0: @param aListData buffer provided by the debug agent in which data can be returned by the debug system. sl@0: @param aDataSize if aListData was not large enough to contain the requested sl@0: data then the necessary buffer size is stored in aDataSize. If aListData sl@0: was large enough then the value of aDataSize is the length of aListData sl@0: sl@0: @return KErrNone if data was returned successfully, sl@0: KErrTooBig if aListData is too small to hold the data, sl@0: one of the other system-wide error codes sl@0: */ sl@0: inline TInt RSecuritySvrSession::GetList(const TProcessId aProcessId, const TListId aListId, TDes8& aListData, TUint32& aDataSize) sl@0: { sl@0: TListDetails info(aListId, EScopeProcessSpecific, aProcessId.Id()); sl@0: TPtr8 infoBuf((TUint8*)&info, sizeof(TListDetails), sizeof(TListDetails)); sl@0: TPtr8 dataSizeBuf((TUint8*)&aDataSize, sizeof(TUint32), sizeof(TUint32)); sl@0: TIpcArgs args(&infoBuf, &aListData, &dataSizeBuf); sl@0: return SendReceive(EDebugServGetList, args); sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Step one or more CPU instructions in the specified thread from the current PC. sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: @pre The thread being stepped must be suspended by the Debug Agent. sl@0: sl@0: @param aThreadId the id of the thread which is to be stepped sl@0: @param aNumSteps how many machine-level instructions are to be stepped. sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::Step(const TThreadId aThreadId, const TUint32 aNumSteps) sl@0: { sl@0: TPckgBuf threadIdPckg(aThreadId); sl@0: TInt res = KErrNone; sl@0: sl@0: TIpcArgs args(&threadIdPckg,aNumSteps); sl@0: sl@0: res = SendReceive(EDebugServStep,args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Kill the specified process with the supplied reason. Reason codes are equivalent sl@0: to those in RProcess.Kill(). sl@0: sl@0: @pre Debug Agent must be connected to the debug security server sl@0: @pre Debug Agent must be attached to a process. sl@0: sl@0: @param aProcessId the id of the process which is to be killed sl@0: @param aReason The reason to be associated with the ending of this process sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::KillProcess(const TProcessId aProcessId, const TInt aReason) sl@0: { sl@0: TPckgBuf processIdPckg(aProcessId); sl@0: TInt res = KErrNone; sl@0: sl@0: TIpcArgs args(&processIdPckg,aReason); sl@0: sl@0: res = SendReceive(EDebugServKillProcess,args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: /** sl@0: Purpose sl@0: Method to read data from the crash flash sl@0: sl@0: @pre aData buffer to retrieve the data from the crash flash sl@0: @pre aDataSize Size of the data sl@0: sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::ReadCrashLog(const TUint32 aPos, TDes8& aData, const TUint32 aDataSize) sl@0: { sl@0: TIpcArgs args(aPos, &aData, aDataSize); sl@0: TInt res = SendReceive(EDebugServReadCrashFlash,args); sl@0: return res; sl@0: } sl@0: sl@0: /** sl@0: * @internalTechnology sl@0: * @prototype sl@0: * sl@0: Purpose: sl@0: Method to write the crash flash config sl@0: sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::WriteCrashConfig(const TUint32 aPos, const TDesC8& aBuffer, TUint32& aSize) sl@0: { sl@0: TPtr8 sizePtr((TUint8*)&aSize,4, 4); sl@0: TIpcArgs args(aPos, &aBuffer, &sizePtr); sl@0: TInt res = SendReceive(EDebugServWriteCrashFlash, args); sl@0: return res; sl@0: } sl@0: /** sl@0: Purpose: sl@0: Method to erase a block in the crash flash sl@0: sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::EraseCrashLog(const TUint32 aPos, const TUint32 aBlockNumber) sl@0: { sl@0: TIpcArgs args(aPos, aBlockNumber); sl@0: TInt res = SendReceive(EDebugServEraseCrashFlash, args); sl@0: return res; sl@0: } sl@0: sl@0: /** sl@0: Purpose: sl@0: Method to erase entire flash partition sl@0: sl@0: @return Any error which may be returned by RSessionBase::SendReceive() sl@0: */ sl@0: inline TInt RSecuritySvrSession::EraseCrashFlashPartition() sl@0: { sl@0: TInt res = SendReceive(EDebugServEraseEntireCrashFlash); sl@0: return res; sl@0: } sl@0: sl@0: } // end of Debug namespace declaration sl@0: sl@0: #endif // #ifndef __KERNEL_MODE__ sl@0: sl@0: #endif // RM_DEBUG_API_H sl@0: sl@0: sl@0: