diff options
Diffstat (limited to 'python/src/tcf/services/memory.py')
-rw-r--r-- | python/src/tcf/services/memory.py | 551 |
1 files changed, 396 insertions, 155 deletions
diff --git a/python/src/tcf/services/memory.py b/python/src/tcf/services/memory.py index f6f8aa640..4157bcde2 100644 --- a/python/src/tcf/services/memory.py +++ b/python/src/tcf/services/memory.py @@ -9,95 +9,231 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -""" -Memory service provides basic operations to read/write memory on a target. +"""Memory service provides basic operations to read/write memory on a target. + +.. |fill| replace:: :meth:`~MemoryContext.fill` +.. |get| replace:: :meth:`~MemoryContext.get` +.. |getChildren| replace:: :meth:`~MemoryService.getChildren` +.. |getContext| replace:: :meth:`~MemoryService.getContext` +.. |getMessage| replace:: :meth:`~MemoryError.getMessage` +.. |processes| replace:: :mod:`~tcf.services.processes` +.. |set| replace:: :meth:`~MemoryContext.set` +.. |DoneGetChildren| replace:: :class:`DoneGetChildren` +.. |DoneGetContext| replace:: :class:`DoneGetContext` +.. |DoneMemory| replace:: :class:`DoneMemory` +.. |MemoryContext| replace:: :class:`MemoryContext` +.. |MemoryError| replace:: :class:`MemoryError` +.. |MemoryListener| replace:: :class:`MemoryListener` + +Memory Properties +----------------- +Properties +^^^^^^^^^^ ++-------------------+--------------+------------------------------------------+ +| Name | Type | Description | ++===================+==============+==========================================+ +| PROP_ACCESS_TYPES | |list| | The access types allowed for this | +| | | context. Target system can support | +| | | multiple different memory access types, | +| | | like instruction and data access. | +| | | Different access types can use different | +| | | logic for address translation and memory | +| | | mapping, so they can end up accessing | +| | | different data bits, even if address is | +| | | the same. Each distinct access type | +| | | should be represented by separate memory | +| | | context. A memory context can represent | +| | | multiple access types if they are | +| | | equivalent - all access same memory bits.| +| | | Same data bits can be exposed through | +| | | multiple memory contexts. | +| | | See `Access types`_. | ++-------------------+--------------+------------------------------------------+ +| PROP_ADDRESS_SIZE | |int| | Size of memory address in bytes. | ++-------------------+--------------+------------------------------------------+ +| PROP_BIG_ENDIAN | |bool| | **True** if memory is big-endian. | ++-------------------+--------------+------------------------------------------+ +| PROP_END_BOUND | |int| | Highest address (inclusive) which is | +| | | valid for the context. | ++-------------------+--------------+------------------------------------------+ +| PROP_ID | |basestring| | ID of the context. | ++-------------------+--------------+------------------------------------------+ +| PROP_NAME | |basestring| | Name of the context, can be used for UI | +| | | purposes. | ++-------------------+--------------+------------------------------------------+ +| PROP_PARENT_ID | |basestring| | ID of a parent context. | ++-------------------+--------------+------------------------------------------+ +| PROP_PROCESS_ID | |basestring| | Process ID, see |processes| service. | ++-------------------+--------------+------------------------------------------+ +| PROP_START_BOUND | |int| | Lowest address (inclusive) which is | +| | | valid for the context. | ++-------------------+--------------+------------------------------------------+ + +Access Types +^^^^^^^^^^^^ +All access types are of type |basestring|. + ++--------------------+--------------------------------------------------------+ +| Name | Description | ++====================+========================================================+ +| ACCESS_CACHE | Context is a cache. | ++--------------------+--------------------------------------------------------+ +| ACCESS_DATA | Context represents data access. | ++--------------------+--------------------------------------------------------+ +| ACCESS_HYPERVISOR | Context represents a hypervisor view to memory. | ++--------------------+--------------------------------------------------------+ +| ACCESS_INSTRUCTION | Context represent instructions fetch access. | ++--------------------+--------------------------------------------------------+ +| ACCESS_IO | Context represents IO peripherals. | ++--------------------+--------------------------------------------------------+ +| ACCESS_PHYSICAL | Context uses physical addresses. | ++--------------------+--------------------------------------------------------+ +| ACCESS_SUPERVISOR | Context represents a supervisor (e.g. Linux kernel) | +| | view to memory. | ++--------------------+--------------------------------------------------------+ +| ACCESS_TLB | Context is a TLB memory. | ++--------------------+--------------------------------------------------------+ +| ACCESS_USER | Context represents a user (e.g. application running | +| | in Linux) view to memory. | ++--------------------+--------------------------------------------------------+ +| ACCESS_VIRTUAL | Context uses virtual addresses. | ++--------------------+--------------------------------------------------------+ + +Command Modes +^^^^^^^^^^^^^ +All command modes are of type |int|. For the |get|, |fill| or |set| methods, +the possible modes are: + ++----------------------+------------------------------------------------------+ +| Name | Description | ++======================+======================================================+ +| MODE_CONTINUEONERROR | Carry on when some of the memory cannot be accessed | +| | and return |MemoryError| at the end if any of the | +| | bytes were not processed correctly. | ++----------------------+------------------------------------------------------+ +| MODE_VERIFY | Verify result of memory operations (by reading and | +| | comparing). | ++----------------------+------------------------------------------------------+ + +Service Methods +--------------- +.. autodata:: NAME +.. autoclass:: MemoryService + +addListener +^^^^^^^^^^^ +.. automethod:: MemoryService.addListener + +fill +^^^^ +.. automethod:: MemoryContext.fill + +get +^^^ +.. automethod:: MemoryContext.get + +getChildren +^^^^^^^^^^^ +.. automethod:: MemoryService.getChildren + +getContext +^^^^^^^^^^ +.. automethod:: MemoryService.getContext + +getName +^^^^^^^ +.. automethod:: MemoryService.getName + +removeListener +^^^^^^^^^^^^^^ +.. automethod:: MemoryService.removeListener + +set +^^^ +.. automethod:: MemoryContext.set + +Callback Classes +---------------- +DoneGetChildren +^^^^^^^^^^^^^^^ +.. autoclass:: DoneGetChildren + :members: + +DoneGetContext +^^^^^^^^^^^^^^ +.. autoclass:: DoneGetContext + :members: + +DoneMemory +^^^^^^^^^^ +.. autoclass:: DoneMemory + :members: + +Listener +-------- +MemoryListener +^^^^^^^^^^^^^^ +.. autoclass:: MemoryListener + :members: + +Helper classes +-------------- +ErrorOffset +^^^^^^^^^^^ +.. autoclass:: ErrorOffset + :members: + +MemoryContext +^^^^^^^^^^^^^ +.. autoclass:: MemoryContext + :members: + +MemoryError +^^^^^^^^^^^ +.. autoclass:: MemoryError + :members: + """ from .. import services NAME = "Memory" +"""Memory service name.""" # Context property names. -# String, ID of the context, same as getContext command argument -PROP_ID = "ID" -# String, ID of a parent context +PROP_ID = "ID" PROP_PARENT_ID = "ParentID" - -# String, process ID, see Processes service PROP_PROCESS_ID = "ProcessID" - -# Boolean, True if memory is big-endian PROP_BIG_ENDIAN = "BigEndian" - -# Number, size of memory address in bytes PROP_ADDRESS_SIZE = "AddressSize" - -# String, name of the context, can be used for UI purposes PROP_NAME = "Name" - -# Number, lowest address (inclusive) which is valid for the context PROP_START_BOUND = "StartBound" - -# Number, highest address (inclusive) which is valid for the context PROP_END_BOUND = "EndBound" - -# Array of String, the access types allowed for this context PROP_ACCESS_TYPES = "AccessTypes" -# Values of "AccessTypes". -# Target system can support multiple different memory access types, like -# instruction and data access. Different access types can use different logic -# for address translation and memory mapping, so they can end up accessing -# different data bits, even if address is the same. -# Each distinct access type should be represented by separate memory context. -# A memory context can represent multiple access types if they are -# equivalent - all access same memory bits. -# Same data bits can be exposed through multiple memory contexts. - -# Context represent instructions fetch access ACCESS_INSTRUCTION = "instruction" - -# Context represents data access ACCESS_DATA = "data" - -# Context represents IO peripherals ACCESS_IO = "io" - -# Context represents a user (e.g. application running in Linux) view to memory ACCESS_USER = "user" - -# Context represents a supervisor (e.g. Linux kernel) view to memory ACCESS_SUPERVISOR = "supervisor" - -# Context represents a hypervisor view to memory ACCESS_HYPERVISOR = "hypervisor" - -# Context uses virtual addresses ACCESS_VIRTUAL = "virtual" - -# Context uses physical addresses ACCESS_PHYSICAL = "physical" - -# Context is a cache ACCESS_CACHE = "cache" - -# Context is a TLB memory ACCESS_TLB = "tlb" -# Memory access mode: -# Carry on when some of the memory cannot be accessed and -# return MemoryError at the end if any of the bytes -# were not processed correctly. MODE_CONTINUEONERROR = 0x1 - -# Memory access mode: -# Verify result of memory operations (by reading and comparing). MODE_VERIFY = 0x2 class MemoryContext(object): + """Memory context class. + :param props: Properties to initialise this memory context with. See + `Properties`_. + :type props: |dict| + """ def __init__(self, props): self._props = props or {} @@ -105,122 +241,179 @@ class MemoryContext(object): return "[Memory Context %s]" % self._props def getProperties(self): - """ - Get context properties. See PROP_* definitions for property names. + """Get context properties. See `Properties`_ definitions for property + names. + Context properties are read only, clients should not try to modify them. - @return Map of context properties. + + :returns: A |dict| of context properties. """ return self._props def getID(self): - """ - Retrieve context ID. - Same as getProperties().get('ID') + """Retrieve context ID. + + :returns: A |basestring| representing this memory context ID or + **None**. """ return self._props.get(PROP_ID) def getParentID(self): - """ - Retrieve parent context ID. - Same as getProperties().get('ParentID') + """Retrieve parent context ID. + + :returns: A |basestring| representing this memory context parent ID or + **None**. """ return self._props.get(PROP_PARENT_ID) def getProcessID(self): - """ - Retrieve context process ID. - Same as getProperties().get('ProcessID') + """Retrieve context process ID. + + :returns: A |basestring| representing this memory context process ID or + **None**. """ return self._props.get(PROP_PROCESS_ID) def isBigEndian(self): - """ - Get memory endianness. - @return True if memory is big-endian. + """Get memory endianness. + + :returns: A |bool| stating if memory is big-endian. """ return self._props.get(PROP_BIG_ENDIAN, False) def getAddressSize(self): - """ - Get memory address size. - @return number of bytes used to store memory address value. + """Get memory address size. + + :returns: An |int| representing the number of bytes used to store + memory address value. """ return self._props.get(PROP_ADDRESS_SIZE, 0) def getName(self): - """ - Get memory context name. + """Get memory context name. + The name can be used for UI purposes. - @return context name. + + :returns: A |basestring| representing this context name or **None**. """ return self._props.get(PROP_NAME) def getStartBound(self): - """ - Get lowest address (inclusive) which is valid for the context. - @return lowest address. + """Get lowest address (inclusive) which is valid for the context. + + :returns: An |int| representing the lowest address or **None**. """ return self._props.get(PROP_START_BOUND) def getEndBound(self): - """ - Get highest address (inclusive) which is valid for the context. - @return highest address. + """Get highest address (inclusive) which is valid for the context. + + :returns: An |int| representing the highest address or **None**. """ return self._props.get(PROP_END_BOUND) def getAccessTypes(self): - """ - Get the access types allowed for this context. - @return collection of access type names. + """Get the access types allowed for this context. + + :returns: A |dict| of access type names or **None**. See + `Access Types`_. """ return self._props.get(PROP_ACCESS_TYPES) def set(self, addr, ws, buf, offs, sz, mode, done): # @ReservedAssignment - """ - Set target memory. - If 'ws' is 0 it means client does not care about word size. + """Set target memory. + + If *ws* is 0 it means client does not care about word size. + + :param addr: Address to set for this memory context. + :type addr: |int| + :param ws: Word size (alignement) to use for setting memory. + :type ws: |int| + :param buf: Data to be written in memory. + :type buf: |bytearray| + :param offs: Offset to seek in *buf*. + :type offs: |int| + :param sz: Number of bytes to write in memory. + :type sz: |int| + :param mode: Memory write mode. See `Command Modes`_. + :type mode: |int| + + :returns: pending command handle. """ raise NotImplementedError("Abstract method") def get(self, addr, word_size, buf, offs, size, mode, done): - """ - Read target memory. + """Read target memory. + + :param addr: Address to get from this memory context. + :type addr: |int| + :param ws: word size (alignement) to use for getting memory. + :type ws: |int| + :param buf: read data buffer. + :type buf: |bytearray| + :param offs: Offset to seek in *buf* to write retrieved data. + :type offs: |int| + :param sz: Number of bytes to read in memory. + :type sz: |int| + :param mode: Memory read mode. See `Command Modes`_. + :type mode: |int| + + :returns: pending command handle. """ raise NotImplementedError("Abstract method") def fill(self, addr, word_size, value, size, mode, done): - """ - Fill target memory with given pattern. - 'size' is number of bytes to fill. + """Fill target memory with given pattern. + + :param addr: Address to get from this memory context. + :type addr: |int| + :param word_size: Word size (alignement) to use for filling memory. + :type word_size: |int| + :param buf: Data to be fill memory with. + :type buf: |bytearray| + :param offs: Offset to seek in *buf*. + :type offs: |int| + :param sz: Number of bytes to write in memory. + :type sz: |int| + :param mode: Memory write mode. See `Command Modes`_. + :type mode: |int| + + :returns: pending command handle. """ raise NotImplementedError("Abstract method") class DoneMemory(object): - """ - Client call back interface for set(), get() and fill() commands. - """ + """Client call back interface for |fill|, |get| and |set| commands.""" def doneMemory(self, token, error): + """Called when memory operation command command is done. + + :param token: Command handle. + :param error: Error object or **None**. + """ pass class MemoryError(Exception): # @ReservedAssignment + """Memory errors class. + + Empty class implementing the |Exception| class. + """ pass class ErrorOffset(object): - """ - ErrorOffset may be implemented by MemoryError object, - which is returned by get, set and fill commands. + """Error offset may be implemented by |MemoryError| object, which is + returned by |get|, |set| and |fill| commands. - get/set/fill () returns this exception when reading failed - for some but not all bytes, and MODE_CONTINUEONERROR - has been set in mode. (For example, when only part of the request + The command |get|, |set| and |fill| return this exception when memory + operation failed for some but not all bytes, and **MODE_CONTINUEONERROR** + has been set in *mode*. (For example, when only part of the request translates to valid memory addresses.) - Exception.getMessage can be used for generalized message of the - possible reasons of partial memory operation. + + Method |getMessage| can be used for generalized message of the possible + reasons of partial memory operation. """ # Error may have per byte information BYTE_VALID = 0x00 @@ -235,32 +428,56 @@ class ErrorOffset(object): RANGE_KEY_MSG = "msg" def getStatus(self, offset): + """Get the error status. + + :param offset: offset to get error status for + :type offset: |int| + + :returns: The error status for the error which happened at given + *offset*. + """ raise NotImplementedError("Abstract method") def getMessage(self, offset): + """Get the error message. + + :param offset: Offset to get error message for. + :type offset: |int| + + :returns: The error message for the error which happened at given + *offset*. + """ raise NotImplementedError("Abstract method") class MemoryService(services.Service): + """TCF memory service interface.""" def getName(self): + """Get this service name. + + :returns: The value of string :const:`NAME` + """ return NAME def getContext(self, contextID, done): - """ - Retrieve context info for given context ID. + """Retrieve context info for given context ID. + + :param contextID: ID of the memory context to get. + :type contextID: |basestring| + :param done: Call back interface called when operation is completed. + :type done: |DoneGetContext| - @param contextID - context ID. - @param done - call back interface called when operation is completed. - @return - pending command handle. + :returns: Pending command handle. """ raise NotImplementedError("Abstract method") def getChildren(self, parent_context_id, done): - """ - Retrieve contexts available for memory commands. + """Retrieve contexts available for memory commands. + A context corresponds to an execution thread, process, address space, etc. + A context can belong to a parent context. Contexts hierarchy can be simple plain list or it can form a tree. It is up to target agent developers to choose layout that is most descriptive for a given @@ -269,89 +486,113 @@ class MemoryService(services.Service): each service accesses its own subset of context's attributes and functionality, which is relevant to that service. - @param parent_context_id - parent context ID. Can be None - to retrieve - top level of the hierarchy, or one of - context IDs retrieved by previous - getChildren commands. - @param done - call back interface called when operation is completed. - @return - pending command handle. + :param parent_context_id: parent context ID. Can be **None** - to + retrieve top level of the hierarchy, or one + of context IDs retrieved by previous + |getChildren| commands. + :type parent_context_id: |basestring| + :param done: call back interface called when operation is completed. + :type done: |DoneGetContext| + + :returns: Pending command handle. """ raise NotImplementedError("Abstract method") def addListener(self, listener): - """ - Add memory service event listener. - @param listener - event listener implementation. + """Add memory service event listener. + + :param listener: Event listener implementation. + :type listener: |MemoryListener| """ raise NotImplementedError("Abstract method") def removeListener(self, listener): - """ - Remove memory service event listener. - @param listener - event listener implementation. + """Remove memory service event listener. + + :param listener: Event listener implementation. + :type listener: |MemoryListener| """ raise NotImplementedError("Abstract method") class MemoryListener(object): - """ - Memory event listener is notified when memory context hierarchy - changes, and when memory is modified by memory service commands. + """Memory event listener is notified when memory context hierarchy changes, + and when memory is modified by memory service commands. """ def contextAdded(self, contexts): - """ - Called when a new memory access context(s) is created. + """Called when a new memory access context(s) is created. + + :param contexts: A list of |MemoryContext| properties which have been + added to memory space. + :type contexts: |list| """ pass def contextChanged(self, contexts): - """ - Called when a memory access context(s) properties changed. + """Called when a memory access context(s) properties changed. + + :param contexts: A list of |MemoryContext| properties which have been + changed in memory space. + :type contexts: |list| """ pass def contextRemoved(self, context_ids): - """ - Called when memory access context(s) is removed. + """Called when memory access context(s) is removed. + + :param context_ids: A list of the IDs of memory contexts which have + been removed from memory space. + :type context_ids: |list| """ pass def memoryChanged(self, context_id, addr, size): - """ - Called when target memory content was changed and clients - need to update themselves. Clients, at least, should invalidate - corresponding cached memory data. - Not every change is notified - it is not possible, - only those, which are not caused by normal execution of the debuggee. - 'addr' and 'size' can be None if unknown. + """Called when target memory content was changed and clients need to + update themselves. + + Clients, at least, should invalidate corresponding cached memory data. + + .. note:: Not every change is notified - it is not possible, only + those, which are not caused by normal execution of the + debuggee. + + :param context_id: ID of the changed memory context. + :type context_id: |basestring| + :param addr: Address at which memory has been changed. A value of + **None** means that this address is unknown. + :type addr: |int| + :param size: Size of the changed memory. A value of **None** means that + this size is unknown. + :type size: |int| or **None** """ pass class DoneGetContext(object): - """ - Client call back interface for getContext(). - """ + """Client call back interface for |getContext|.""" def doneGetContext(self, token, error, context): - """ - Called when context data retrieval is done. - @param error - error description if operation failed, None if - succeeded. - @param context - context data. + """Called when memory context retrieval is done. + + :param token: Command handle. + :param error: Error description if operation failed, **None** if + succeeded. + :param context: The so retrieved memory context description. + :type context: |MemoryContext| """ pass class DoneGetChildren(object): - """ - Client call back interface for getChildren(). - """ + """Client call back interface for |getChildren|.""" + def doneGetChildren(self, token, error, context_ids): - """ - Called when context list retrieval is done. - @param error - error description if operation failed, None if - succeeded. - @param context_ids - array of available context IDs. + """Called when memory IDs retrieval is done. + + :param token: Command handle. + :param error: Error description if operation failed, **None** if + succeeded. + :param context_ids: A list of available context IDs. + :type context_ids: |list| """ pass |