Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: abf60962b119976a140aef47732250b26f550cf5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*******************************************************************************
 * Copyright (c) 2014 Wind River Systems, Inc. and others. All rights reserved.
 * This program and the accompanying materials are made available under the terms
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.tcf.services;

import java.util.Collection;
import java.util.Map;

import org.eclipse.tcf.protocol.IService;
import org.eclipse.tcf.protocol.IToken;


/**
 * IMemory service provides basic operations to read/write memory on a target.
 *
 * @noimplement This interface is not intended to be implemented by clients.
 */
public interface IMemory extends IService {

    static final String NAME = "Memory";

    /**
     * Context property names.
     */
    static final String
        PROP_ID = "ID",                         /** String, ID of the context, same as getContext command argument */
        PROP_PARENT_ID = "ParentID",            /** String, ID of a parent context */
        PROP_PROCESS_ID = "ProcessID",          /** String, process ID, see Processes service */
        PROP_BIG_ENDIAN = "BigEndian",          /** Boolean, true if memory is big-endian */
        PROP_ADDRESS_SIZE = "AddressSize",      /** Number, size of memory address in bytes */
        PROP_NAME = "Name",                     /** String, name of the context, can be used for UI purposes */
        PROP_START_BOUND = "StartBound",        /** Number, lowest address (inclusive) which is valid for the context */
        PROP_END_BOUND = "EndBound",            /** Number, highest address (inclusive) which is valid for the context */
        PROP_ACCESS_TYPES = "AccessTypes";      /** Array of String, the access types allowed for this context */

    /**
     * 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.
     */
    static final String
        ACCESS_INSTRUCTION = "instruction",     /** Context represent instructions fetch access */
        ACCESS_DATA = "data",                   /** Context represents data access */
        ACCESS_IO = "io",                       /** Context represents IO peripherals */
        ACCESS_USER = "user",                   /** Context represents a user (e.g. application running in Linux) view to memory */
        ACCESS_SUPERVISOR = "supervisor",       /** Context represents a supervisor (e.g. Linux kernel) view to memory */
        ACCESS_HYPERVISOR = "hypervisor",       /** Context represents a hypervisor view to memory */
        ACCESS_VIRTUAL = "virtual",             /** Context uses virtual addresses */
        ACCESS_PHYSICAL = "physical",           /** Context uses physical addresses */
        ACCESS_CACHE = "cache",                 /** Context is a cache */
        ACCESS_TLB = "tlb";                     /** Context is a TLB memory */

    /**
     * Retrieve context info for given context ID.
     *
     * @param id - context ID.
     * @param done - call back interface called when operation is completed.
     * @return - pending command handle.
     */
    IToken getContext(String id, DoneGetContext done);

    /**
     * Client call back interface for getContext().
     */
    interface DoneGetContext {
        /**
         * Called when context data retrieval is done.
         * @param error - error description if operation failed, null if succeeded.
         * @param context - context data.
         */
        void doneGetContext(IToken token, Exception error, MemoryContext context);
    }

    /**
     * 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 target. Context IDs are valid across
     * all services. In other words, all services access same hierarchy of contexts,
     * with same IDs, however, 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 null -
     * 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.
     */
    IToken getChildren(String parent_context_id, DoneGetChildren done);

    /**
     * Client call back interface for getChildren().
     */
    interface DoneGetChildren {
        /**
         * Called when context list retrieval is done.
         * @param error - error description if operation failed, null if succeeded.
         * @param context_ids - array of available context IDs.
         */
        void doneGetChildren(IToken token, Exception error, String[] context_ids);
    }

    /**
     * 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.
     */
    final static int MODE_CONTINUEONERROR = 0x1;

    /**
     * Memory access mode:
     * Verify result of memory operations (by reading and comparing).
     */
    final static int MODE_VERIFY = 0x2;

    interface MemoryContext {

        /**
         * Get context ID.
         * @return context ID.
         */
        String getID();

        /**
         * Get parent context ID.
         * @return parent ID.
         */
        String getParentID();

        /**
         * Get process ID, if applicable.
         * @return process ID.
         */
        String getProcessID();

        /**
         * Get memory endianness.
         * @return true if memory is big-endian.
         */
        boolean isBigEndian();

        /**
         * Get memory address size.
         * @return number of bytes used to store memory address value.
         */
        int getAddressSize();

        /**
         * Get memory context name.
         * The name can be used for UI purposes.
         * @return context name.
         */
        String getName();

        /**
         * Get lowest address (inclusive) which is valid for the context.
         * @return lowest address.
         */
        Number getStartBound();

        /**
         * Get highest address (inclusive) which is valid for the context.
         * @return highest address.
         */
        Number getEndBound();

        /**
         * Get the access types allowed for this context.
         * @return collection of access type names.
         */
        Collection<String> getAccessTypes();

        /**
         * Get context properties.
         * @return all available context properties.
         */
        Map<String,Object> getProperties();

        /**
         * Set target memory.
         * If 'word_size' is 0 it means client does not care about word size.
         */
        IToken set(Number addr, int word_size, byte[] buf,
                int offs, int size, int mode, DoneMemory done);

        /**
         * Read target memory.
         */
        IToken get(Number addr, int word_size, byte[] buf,
                int offs, int size, int mode, DoneMemory done);

        /**
         * Fill target memory with given pattern.
         * 'size' is number of bytes to fill.
         */
        IToken fill(Number addr, int word_size, byte[] value,
                int size, int mode, DoneMemory done);
    }

    /**
     * Client call back interface for set(), get() and fill() commands.
     */
    interface DoneMemory {
        public void doneMemory(IToken token, MemoryError error);
    }

    class MemoryError extends Exception {

        private static final long serialVersionUID = 1L;

        public MemoryError(String msg) {
            super(msg);
        }
    }

    /**
     * ErrorOffset interface can 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
     * translates to valid memory addresses.)
     * Exception.getMessage can be used for generalized message of the
     * possible reasons of partial memory operation.
     */
    interface ErrorOffset {

        // Error may have per byte information
        final static int
            BYTE_VALID        = 0x00,
            BYTE_UNKNOWN      = 0x01, // e.g. out of range
            BYTE_INVALID      = 0x02,
            BYTE_CANNOT_READ  = 0x04,
            BYTE_CANNOT_WRITE = 0x08;

        final static String
            RANGE_KEY_ADDR  = "addr",
            RANGE_KEY_SIZE  = "size",
            RANGE_KEY_STAT  = "stat",
            RANGE_KEY_MSG   = "msg";

        int getStatus(int offset);

        /**
         * Returns the detail message string about the
         * byte associated with specified location.
         * @return  the detail error message string.
         */
        String getMessage(int offset);

    }

    /**
     * Add memory service event listener.
     * @param listener - event listener implementation.
     */
    void addListener(MemoryListener listener);

    /**
     * Remove memory service event listener.
     * @param listener - event listener implementation.
     */
    void removeListener(MemoryListener listener);

    /**
     * Memory event listener is notified when memory context hierarchy
     * changes, and when memory is modified by memory service commands.
     */
    interface MemoryListener {

        /**
         * Called when a new memory access context(s) is created.
         */
        void contextAdded(MemoryContext[] contexts);

        /**
         * Called when a memory access context(s) properties changed.
         */
        void contextChanged(MemoryContext[] contexts);

        /**
         * Called when memory access context(s) is removed.
         */
        void contextRemoved(String[] context_ids);

        /**
         * 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 null if unknown.
         */
        void memoryChanged(String context_id, Number[] addr, long[] size);
    }
}

Back to the top