Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java')
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java307
1 files changed, 307 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java
new file mode 100644
index 000000000..cf40d6a4b
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFMemory.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.tm.internal.tcf.dsf.services;
+
+import java.util.Hashtable;
+
+import org.eclipse.cdt.core.IAddress;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.dd.dsf.concurrent.RequestMonitor;
+import org.eclipse.dd.dsf.datamodel.IDMContext;
+import org.eclipse.dd.dsf.service.AbstractDsfService;
+import org.eclipse.dd.dsf.service.DsfSession;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.tm.internal.tcf.dsf.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IMemory.MemoryContext;
+import org.eclipse.tm.tcf.services.IMemory.MemoryError;
+import org.osgi.framework.BundleContext;
+
+
+public class TCFDSFMemory extends AbstractDsfService implements org.eclipse.dd.dsf.debug.service.IMemory {
+
+ private class MemoryCache implements TCFDSFExecutionDMC.DataCache {
+
+ final TCFDataCache<org.eclipse.tm.tcf.services.IMemory.MemoryContext> context;
+
+ MemoryCache(final IChannel channel, final TCFDSFExecutionDMC exe) {
+ context = new TCFDataCache<org.eclipse.tm.tcf.services.IMemory.MemoryContext>(channel) {
+ @Override
+ public boolean startDataRetrieval() {
+ assert command == null;
+ String id = exe.getTcfContextId();
+ if (id == null || tcf_mem_service == null) {
+ data = null;
+ valid = true;
+ return true;
+ }
+ command = tcf_mem_service.getContext(id,
+ new org.eclipse.tm.tcf.services.IMemory.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception err,
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext ctx) {
+ if (command != token) return;
+ command = null;
+ if (err != null) {
+ error = err;
+ }
+ else {
+ data = ctx;
+ }
+ valid = true;
+ validate();
+ }
+ });
+ return false;
+ }
+ };
+ }
+ }
+
+ private final org.eclipse.tm.tcf.services.IMemory.MemoryListener mem_listener =
+ new org.eclipse.tm.tcf.services.IMemory.MemoryListener() {
+
+ public void contextAdded(MemoryContext[] contexts) {
+ }
+
+ public void contextChanged(MemoryContext[] contexts) {
+ }
+
+ public void contextRemoved(String[] context_ids) {
+ }
+
+ public void memoryChanged(String context_id, Number[] addr, long[] size) {
+ TCFDSFRunControl rc = getServicesTracker().getService(TCFDSFRunControl.class);
+ TCFDSFExecutionDMC exe = rc.getContext(context_id);
+ if (exe == null || exe.memory_cache == null) return;
+ for (int n = 0; n < addr.length; n++) {
+ long count = size[n];
+ // TODO: DSF does not support address ranges
+ if (count > 256) count = 256;
+ IAddress[] addresses = new IAddress[(int)count];
+ for (int i = 0; i < (int)count; i++) {
+ addresses[i] = new TCFAddress(addr[n]).add(i);
+ }
+ getSession().dispatchEvent(new MemoryChangedEvent(exe, addresses), getProperties());
+ }
+ }
+ };
+
+ private final IChannel channel;
+ private final org.eclipse.tm.tcf.services.IMemory tcf_mem_service;
+
+ public TCFDSFMemory(DsfSession session, IChannel channel, final RequestMonitor monitor) {
+ super(session);
+ this.channel = channel;
+ tcf_mem_service = channel.getRemoteService(org.eclipse.tm.tcf.services.IMemory.class);
+ if (tcf_mem_service != null) tcf_mem_service.addListener(mem_listener);
+ initialize(new RequestMonitor(getExecutor(), monitor) {
+ @Override
+ protected void handleOK() {
+ String[] class_names = {
+ org.eclipse.dd.dsf.debug.service.IMemory.class.getName(),
+ TCFDSFMemory.class.getName()
+ };
+ register(class_names, new Hashtable<String,String>());
+ monitor.done();
+ }
+ });
+ }
+
+ @Override
+ public void shutdown(RequestMonitor monitor) {
+ unregister();
+ super.shutdown(monitor);
+ }
+
+ @Override
+ protected BundleContext getBundleContext() {
+ return Activator.getBundleContext();
+ }
+
+ public void fillMemory(final IDMContext dmc, final IAddress address, final long offset,
+ final int word_size, final int count, final byte[] pattern, final RequestMonitor rm) {
+ if (tcf_mem_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Memory access service is not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc;
+ if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx);
+ MemoryCache cache = (MemoryCache)ctx.memory_cache;
+ if (!cache.context.validate()) {
+ cache.context.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ fillMemory(dmc, address, offset, word_size, count, pattern, rm);
+ }
+ });
+ return;
+ }
+ if (cache.context.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData();
+ if (mem == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ mem.fill(address.add(offset).getValue(), word_size, pattern, count * word_size, 0,
+ new org.eclipse.tm.tcf.services.IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void getMemory(final IDMContext dmc, final IAddress address, final long offset,
+ final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> rm) {
+ if (tcf_mem_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Memory access service is not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc;
+ if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx);
+ MemoryCache cache = (MemoryCache)ctx.memory_cache;
+ if (!cache.context.validate()) {
+ cache.context.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ getMemory(dmc, address, offset, word_size, count, rm);
+ }
+ });
+ return;
+ }
+ if (cache.context.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData();
+ if (mem == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ final byte[] buffer = new byte[word_size * count];
+ mem.get(address.add(offset).getValue(), word_size, buffer, 0, count * word_size, 0,
+ new org.eclipse.tm.tcf.services.IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ MemoryByte[] res = new MemoryByte[buffer.length];
+ for (int i = 0; i < buffer.length; i++) {
+ res[i] = new MemoryByte(buffer[i]);
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+
+ public void setMemory(final IDMContext dmc, final IAddress address, final long offset,
+ final int word_size, final int count, final byte[] buffer, final RequestMonitor rm) {
+ if (tcf_mem_service == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Memory access service is not available", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ else if (dmc instanceof TCFDSFExecutionDMC) {
+ final TCFDSFExecutionDMC ctx = (TCFDSFExecutionDMC)dmc;
+ if (ctx.memory_cache == null) ctx.memory_cache = new MemoryCache(channel, ctx);
+ MemoryCache cache = (MemoryCache)ctx.memory_cache;
+ if (!cache.context.validate()) {
+ cache.context.addWaitingRequest(new IDataRequest() {
+ public void cancel() {
+ rm.setStatus(new Status(IStatus.CANCEL, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Canceled", null)); //$NON-NLS-1$
+ rm.setCanceled(true);
+ rm.done();
+ }
+ public void done() {
+ setMemory(dmc, address, offset, word_size, count, buffer, rm);
+ }
+ });
+ return;
+ }
+ if (cache.context.getError() != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Data error", cache.context.getError())); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ org.eclipse.tm.tcf.services.IMemory.MemoryContext mem = cache.context.getData();
+ if (mem == null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Invalid DMC", null)); //$NON-NLS-1$
+ rm.done();
+ return;
+ }
+ mem.set(address.add(offset).getValue(), word_size, buffer, 0, count * word_size, 0,
+ new org.eclipse.tm.tcf.services.IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (rm.isCanceled()) return;
+ if (error != null) {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ REQUEST_FAILED, "Command error", error)); //$NON-NLS-1$
+ }
+ rm.done();
+ }
+ });
+ }
+ else {
+ rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
+ rm.done();
+ }
+ }
+}

Back to the top