mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-30 20:35:38 +02:00
Bug 309032: Need APIs to support memory pages (or memory spaces)
This commit is contained in:
parent
8fcc98e15c
commit
e1dfb2e746
10 changed files with 825 additions and 16 deletions
|
@ -21,10 +21,11 @@ Export-Package: org.eclipse.cdt.dsf.gdb,
|
|||
org.eclipse.cdt.dsf.gdb.actions,
|
||||
org.eclipse.cdt.dsf.gdb.breakpoints,
|
||||
org.eclipse.cdt.dsf.gdb.internal.commands,
|
||||
org.eclipse.cdt.dsf.gdb.internal.memory;x-internal:=true,
|
||||
org.eclipse.cdt.dsf.gdb.internal.tracepointactions,
|
||||
org.eclipse.cdt.dsf.gdb.launching,
|
||||
org.eclipse.cdt.dsf.gdb.service,
|
||||
org.eclipse.cdt.dsf.gdb.service.command,
|
||||
org.eclipse.cdt.dsf.gdb.internal.tracepointactions,
|
||||
org.eclipse.cdt.dsf.mi.service,
|
||||
org.eclipse.cdt.dsf.mi.service.command,
|
||||
org.eclipse.cdt.dsf.mi.service.command.commands,
|
||||
|
|
|
@ -0,0 +1,267 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, Texas Instruments, Freescale Semiconductor 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:
|
||||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlock;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.cdt.dsf.concurrent.Query;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock;
|
||||
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces.IMemorySpaceDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.utils.Addr64;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.model.MemoryByte;
|
||||
|
||||
/**
|
||||
* A specialization of the DSF memory block implementation supporting memory
|
||||
* spaces. The memory space support is provisional, thus this class is internal.
|
||||
*
|
||||
* @author Alain Lee and John Cortell
|
||||
*/
|
||||
public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareMemoryBlock {
|
||||
|
||||
private final String fMemorySpaceID;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
GdbMemoryBlock(DsfMemoryBlockRetrieval retrieval, IMemoryDMContext context,
|
||||
String modelId, String expression, BigInteger address,
|
||||
int word_size, long length, String memorySpaceID) {
|
||||
super(retrieval, context, modelId, expression, address, word_size, length);
|
||||
fMemorySpaceID = (memorySpaceID != null && memorySpaceID.length() > 0) ? memorySpaceID : null;
|
||||
assert memorySpaceID == null || memorySpaceID.length() > 0; // callers shouldn't be passing in an empty string
|
||||
}
|
||||
|
||||
/**
|
||||
* A memory space qualified context for the IMemory methods. Used if
|
||||
* required, otherwise the more basic IMemoryDMContext is used
|
||||
*/
|
||||
public static class MemorySpaceDMContext extends AbstractDMContext implements IMemorySpaceDMContext {
|
||||
|
||||
private final String fMemorySpaceId;
|
||||
|
||||
public MemorySpaceDMContext(String sessionId, String memorySpaceId, IDMContext parent) {
|
||||
super(sessionId, new IDMContext[] {parent});
|
||||
fMemorySpaceId = memorySpaceId;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.service.IMemorySpaces.IMemorySpaceDMContext#getMemorySpaceId()
|
||||
*/
|
||||
public String getMemorySpaceId() {
|
||||
return fMemorySpaceId;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof MemorySpaceDMContext) {
|
||||
MemorySpaceDMContext dmc = (MemorySpaceDMContext) other;
|
||||
return (super.baseEquals(other)) && (dmc.fMemorySpaceId.equals(fMemorySpaceId));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.baseHashCode() + fMemorySpaceId.hashCode();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return baseToString() + ".memoryspace[" + fMemorySpaceId + ']'; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The real thing. Since the original call is synchronous (from a platform
|
||||
* Job), we use a Query that will patiently wait for the underlying
|
||||
* asynchronous calls to complete before returning.
|
||||
*
|
||||
* @param bigAddress
|
||||
* @param length
|
||||
* @return MemoryByte[]
|
||||
* @throws DebugException
|
||||
*/
|
||||
@Override
|
||||
protected MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long length) throws DebugException {
|
||||
|
||||
// For the IAddress interface
|
||||
final Addr64 address = new Addr64(bigAddress);
|
||||
|
||||
// Use a Query to synchronize the downstream calls
|
||||
Query<MemoryByte[]> query = new Query<MemoryByte[]>() {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<MemoryByte[]> drm) {
|
||||
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
||||
int addressableSize = 1;
|
||||
try {
|
||||
addressableSize = getAddressableSize();
|
||||
} catch (DebugException e) {}
|
||||
|
||||
// If this block was created with a memory space qualification,
|
||||
// we need to create an enhanced context
|
||||
IMemoryDMContext context = null;
|
||||
if (fMemorySpaceID != null) {
|
||||
IMemorySpaces memoryService = (IMemorySpaces) retrieval.getMemorySpaceServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
context = new MemorySpaceDMContext(memoryService.getSession().getId(), fMemorySpaceID, getContext());
|
||||
}
|
||||
else {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
context = getContext();
|
||||
}
|
||||
|
||||
IMemory memoryService = (IMemory) retrieval.getServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.getMemory(
|
||||
context, address, 0, addressableSize, (int) length,
|
||||
//getContext(), address, 0, addressableSize, (int) length,
|
||||
new DataRequestMonitor<MemoryByte[]>(retrieval.getExecutor(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
drm.setData(getData());
|
||||
drm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
||||
retrieval.getExecutor().execute(query);
|
||||
|
||||
try {
|
||||
return query.get();
|
||||
} catch (InterruptedException e) {
|
||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, Messages.Err_MemoryReadFailed, e));
|
||||
} catch (ExecutionException e) {
|
||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, Messages.Err_MemoryReadFailed, e));
|
||||
}
|
||||
}
|
||||
|
||||
/* Writes an array of bytes to memory.
|
||||
*
|
||||
* @param offset
|
||||
* @param bytes
|
||||
* @throws DebugException
|
||||
*/
|
||||
@Override
|
||||
protected void writeMemoryBlock(final long offset, final byte[] bytes) throws DebugException {
|
||||
|
||||
// For the IAddress interface
|
||||
final Addr64 address = new Addr64(getBigBaseAddress());
|
||||
|
||||
// Use a Query to synchronize the downstream calls
|
||||
Query<MemoryByte[]> query = new Query<MemoryByte[]>() {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<MemoryByte[]> drm) {
|
||||
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
||||
int addressableSize = 1;
|
||||
// If this block was created with a memory space qualification,
|
||||
// we need to create an enhanced context
|
||||
IMemoryDMContext context = null;
|
||||
if (fMemorySpaceID != null) {
|
||||
IMemorySpaces memoryService = (IMemorySpaces) retrieval.getMemorySpaceServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
context = new MemorySpaceDMContext(memoryService.getSession().getId(), fMemorySpaceID, getContext());
|
||||
}
|
||||
else {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
context = getContext();
|
||||
}
|
||||
IMemory memoryService = (IMemory) retrieval.getServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.setMemory(
|
||||
context, address, offset, addressableSize, bytes.length, bytes,
|
||||
new RequestMonitor(retrieval.getExecutor(), drm));
|
||||
}
|
||||
else {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
||||
retrieval.getExecutor().execute(query);
|
||||
|
||||
try {
|
||||
query.get();
|
||||
} catch (InterruptedException e) {
|
||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, Messages.Err_MemoryWriteFailed, e));
|
||||
} catch (ExecutionException e) {
|
||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, Messages.Err_MemoryWriteFailed, e));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.model.provisional.IMemorySpaceAwareMemoryBlock#getMemorySpaceID()
|
||||
*/
|
||||
public String getMemorySpaceID() {
|
||||
return fMemorySpaceID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to qualify the expression with the memory space, if
|
||||
* applicable.
|
||||
*
|
||||
* @see org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock#getExpression()
|
||||
*/
|
||||
@Override
|
||||
public String getExpression() {
|
||||
if (fMemorySpaceID != null) {
|
||||
assert fMemorySpaceID.length() > 0;
|
||||
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
||||
return retrieval.encodeAddress(super.getExpression(), fMemorySpaceID);
|
||||
}
|
||||
return super.getExpression();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,365 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, Texas Instruments, Freescale Semiconductor 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:
|
||||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlock;
|
||||
import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.Query;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock;
|
||||
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.service.DsfServices;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.model.IMemoryBlock;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockExtension;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* A specialization of the DSF memory block retrieval implementation supporting
|
||||
* memory spaces. The memory space support is provisional, thus this class is
|
||||
* internal.
|
||||
*
|
||||
* @author Alain Lee and John Cortell
|
||||
*/
|
||||
public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
||||
IMemorySpaceAwareMemoryBlockRetrieval {
|
||||
|
||||
private final ServiceTracker fMemorySpaceServiceTracker;
|
||||
|
||||
// No need to use the constants in our base class. Serializing and
|
||||
// recreating the blocks is done entirely by us
|
||||
private static final String MEMORY_BLOCK_EXPRESSION_LIST = "memoryBlockExpressionList"; //$NON-NLS-1$
|
||||
private static final String ATTR_EXPRESSION_LIST_CONTEXT = "context"; //$NON-NLS-1$
|
||||
private static final String MEMORY_BLOCK_EXPRESSION = "gdbmemoryBlockExpression"; //$NON-NLS-1$
|
||||
private static final String ATTR_MEMORY_BLOCK_EXPR_LABEL = "label"; //$NON-NLS-1$
|
||||
private static final String ATTR_MEMORY_BLOCK_EXPR_ADDRESS = "address"; //$NON-NLS-1$
|
||||
private static final String ATTR_MEMORY_BLOCK_MEMORY_SPACE_ID = "memorySpaceID"; //$NON-NLS-1$
|
||||
|
||||
/** see comment in base class */
|
||||
private static final String CONTEXT_RESERVED = "reserved-for-future-use"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public GdbMemoryBlockRetrieval(String modelId, ILaunchConfiguration config,
|
||||
DsfSession session) throws DebugException {
|
||||
super(modelId, config, session);
|
||||
|
||||
|
||||
BundleContext bundle = GdbPlugin.getBundleContext();
|
||||
|
||||
// Create a tracker for the MemoryPageService
|
||||
String memoryPageServiceFilter = DsfServices.createServiceFilter(IMemorySpaces.class, session.getId());
|
||||
|
||||
try {
|
||||
fMemorySpaceServiceTracker = new ServiceTracker(
|
||||
bundle, bundle.createFilter(memoryPageServiceFilter), null);
|
||||
} catch (InvalidSyntaxException e) {
|
||||
throw new DebugException(new Status(IStatus.ERROR,
|
||||
GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
|
||||
"Error creating service filter.", e)); //$NON-NLS-1$
|
||||
}
|
||||
fMemorySpaceServiceTracker.open();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval#getExtendedMemoryBlock(java.lang.String, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException {
|
||||
// Technically, we don't need to override this method. Letting our base
|
||||
// class create a DsfMemoryBlock would work just fine. But, for the
|
||||
// sake of consistency, lets have this retrieval class always return a
|
||||
// GdbMemoryBlock.
|
||||
return getMemoryBlock(expression, context, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval#getExtendedMemoryBlock(java.lang.String, java.lang.Object, java.lang.String)
|
||||
*/
|
||||
public IMemorySpaceAwareMemoryBlock getMemoryBlock(String expression, Object context, String memorySpaceID) throws DebugException {
|
||||
// Drill for the actual DMC
|
||||
IMemoryDMContext memoryDmc = null;
|
||||
IDMContext dmc = null;
|
||||
if (context instanceof IAdaptable) {
|
||||
dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class);
|
||||
if (dmc != null) {
|
||||
memoryDmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class);
|
||||
}
|
||||
}
|
||||
|
||||
if (memoryDmc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The block start address (supports 64-bit processors)
|
||||
BigInteger blockAddress;
|
||||
|
||||
/*
|
||||
* See if the expression is a simple numeric value; if it is, we can
|
||||
* avoid some costly processing (calling the back-end to resolve the
|
||||
* expression and obtain an address)
|
||||
*/
|
||||
try {
|
||||
// First, assume a decimal address
|
||||
int base = 10;
|
||||
int offset = 0;
|
||||
|
||||
// Check for "hexadecimality"
|
||||
if (expression.startsWith("0x") || expression.startsWith("0X")) { //$NON-NLS-1$//$NON-NLS-2$
|
||||
base = 16;
|
||||
offset = 2;
|
||||
}
|
||||
// Check for "binarity"
|
||||
else if (expression.startsWith("0b")) { //$NON-NLS-1$
|
||||
base = 2;
|
||||
offset = 2;
|
||||
}
|
||||
// Check for "octality"
|
||||
else if (expression.startsWith("0")) { //$NON-NLS-1$
|
||||
base = 8;
|
||||
offset = 1;
|
||||
}
|
||||
// Now, try to parse the expression. If a NumberFormatException is
|
||||
// thrown, then it wasn't a simple numerical expression and we go
|
||||
// to plan B (attempt an expression evaluation)
|
||||
blockAddress = new BigInteger(expression.substring(offset), base);
|
||||
|
||||
} catch (NumberFormatException nfexc) {
|
||||
// OK, expression is not a simple, absolute numeric value;
|
||||
// try to resolve as an expression.
|
||||
// In case of failure, simply return 'null'
|
||||
|
||||
// Resolve the expression
|
||||
blockAddress = resolveMemoryAddress(dmc, expression);
|
||||
if (blockAddress == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we only resolved the requested memory block
|
||||
* start address and we have no idea of the block's length.
|
||||
*
|
||||
* The renderer will provide this information when it calls
|
||||
* getBytesFromAddress() i.e. after the memory block holder has
|
||||
* been instantiated.
|
||||
*
|
||||
* The down side is that every time we switch renderer, for the
|
||||
* same memory block, a trip to the target could result. However,
|
||||
* the memory request cache should save the day.
|
||||
*/
|
||||
return new GdbMemoryBlock(this, memoryDmc, getModelId(), expression, blockAddress, getAddressableSize(), 0, memorySpaceID);
|
||||
}
|
||||
|
||||
/*
|
||||
* implementation of
|
||||
* @see org.eclipse.cdt.debug.internal.core.model.provisional.IMemorySpaceManagement#getMemorySpaces(Object context)
|
||||
*/
|
||||
public void getMemorySpaces(final Object context, final GetMemorySpacesRequest request) {
|
||||
Query<String[]> query = new Query<String[]>() {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<String[]> drm) {
|
||||
IDMContext dmc = null;
|
||||
if (context instanceof IAdaptable) {
|
||||
dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class);
|
||||
if (dmc != null) {
|
||||
IMemorySpaces memoryPageService = (IMemorySpaces)fMemorySpaceServiceTracker.getService();
|
||||
if (memoryPageService != null) {
|
||||
memoryPageService.getMemorySpaces(
|
||||
dmc,
|
||||
new DataRequestMonitor<String[]>(getExecutor(), drm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
// Store the result
|
||||
if (isSuccess()) {
|
||||
request.setMemorySpaces(getData());
|
||||
}
|
||||
else {
|
||||
request.setStatus(getStatus());
|
||||
}
|
||||
request.done();
|
||||
drm.done(); // don't bother with status; we don't check it below
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
request.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, Messages.Err_MemoryServiceNotAvailable, null));
|
||||
request.done();
|
||||
drm.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
getExecutor().execute(query);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval#encodeAddress(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public String encodeAddress(String expression, String memorySpaceID) {
|
||||
String result = null;
|
||||
IMemorySpaces service = (IMemorySpaces)fMemorySpaceServiceTracker.getService();
|
||||
if (service != null) {
|
||||
// the service can tell us to use our default encoding by returning null
|
||||
result = service.encodeAddress(expression, memorySpaceID);
|
||||
}
|
||||
if (result == null) {
|
||||
// default encoding
|
||||
result = memorySpaceID + ':' + expression;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.internal.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval#decodeAddress(java.lang.String)
|
||||
*/
|
||||
public DecodeResult decodeAddress(String str) throws CoreException {
|
||||
IMemorySpaces memoryPageService = (IMemorySpaces)fMemorySpaceServiceTracker.getService();
|
||||
if (memoryPageService != null) {
|
||||
final IMemorySpaces.DecodeResult result = memoryPageService.decodeAddress(str);
|
||||
if (result != null) { // service can return null to tell use to use default decoding
|
||||
return new DecodeResult() {
|
||||
public String getMemorySpaceId() { return result.getMemorySpaceId(); }
|
||||
public String getExpression() { return result.getExpression(); }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// default decoding
|
||||
int index = str.indexOf(':');
|
||||
if (index == -1) {
|
||||
throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, Messages.Err_InvalidEncodedAddress + ": " + str , null)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
final String memorySpaceID = str.substring(0, index);
|
||||
final String expression = (index < str.length()-1) ? str.substring(index+1) : ""; //$NON-NLS-1$
|
||||
return new DecodeResult() {
|
||||
public String getMemorySpaceId() { return memorySpaceID; }
|
||||
public String getExpression() { return expression; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
ServiceTracker getMemorySpaceServiceTracker() {
|
||||
return fMemorySpaceServiceTracker;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval#getMemento()
|
||||
*/
|
||||
@Override
|
||||
public String getMemento() throws CoreException {
|
||||
IMemoryBlock[] blocks = DebugPlugin.getDefault().getMemoryBlockManager().getMemoryBlocks(this);
|
||||
Document document = DebugPlugin.newDocument();
|
||||
Element expressionList = document.createElement(MEMORY_BLOCK_EXPRESSION_LIST);
|
||||
expressionList.setAttribute(ATTR_EXPRESSION_LIST_CONTEXT, CONTEXT_RESERVED);
|
||||
for (IMemoryBlock block : blocks) {
|
||||
if (block instanceof IMemoryBlockExtension) {
|
||||
IMemoryBlockExtension memoryBlock = (IMemoryBlockExtension) block;
|
||||
Element expression = document.createElement(MEMORY_BLOCK_EXPRESSION);
|
||||
expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_ADDRESS, memoryBlock.getBigBaseAddress().toString());
|
||||
if (block instanceof IMemorySpaceAwareMemoryBlock) {
|
||||
String memorySpaceID = ((IMemorySpaceAwareMemoryBlock)memoryBlock).getMemorySpaceID();
|
||||
if (memorySpaceID != null) {
|
||||
expression.setAttribute(ATTR_MEMORY_BLOCK_MEMORY_SPACE_ID, memorySpaceID);
|
||||
|
||||
// What we return from GdbMemoryBlock#getExpression()
|
||||
// is the encoded representation. We need to decode it
|
||||
// to get the original expression used to create the block
|
||||
DecodeResult result = ((IMemorySpaceAwareMemoryBlockRetrieval)memoryBlock.getMemoryBlockRetrieval()).decodeAddress(memoryBlock.getExpression());
|
||||
expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL, result.getExpression());
|
||||
}
|
||||
else {
|
||||
expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL, memoryBlock.getExpression());
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert false; // should never happen (see getExtendedMemoryBlock()), but we can handle it.
|
||||
expression.setAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL, memoryBlock.getExpression());
|
||||
}
|
||||
expressionList.appendChild(expression);
|
||||
}
|
||||
}
|
||||
document.appendChild(expressionList);
|
||||
return DebugPlugin.serializeDocument(document);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval#createBlocksFromConfiguration(org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected void createBlocksFromConfiguration(IMemoryDMContext memoryCtx, String memento) throws CoreException {
|
||||
|
||||
// Parse the memento and validate its type
|
||||
Element root = DebugPlugin.parseDocument(memento);
|
||||
if (!root.getNodeName().equalsIgnoreCase(MEMORY_BLOCK_EXPRESSION_LIST)) {
|
||||
IStatus status = new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugPlugin.INTERNAL_ERROR,
|
||||
"Memory monitor initialization: invalid memento", null);//$NON-NLS-1$
|
||||
throw new CoreException(status);
|
||||
}
|
||||
|
||||
// Process the block list specific to this memory context
|
||||
// FIXME: (Bug228573) We only process the first entry...
|
||||
if (root.getAttribute(ATTR_EXPRESSION_LIST_CONTEXT).equals(CONTEXT_RESERVED)) {
|
||||
List<IMemoryBlock> blocks = new ArrayList<IMemoryBlock>();
|
||||
NodeList expressionList = root.getChildNodes();
|
||||
int length = expressionList.getLength();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
Node node = expressionList.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element entry = (Element) node;
|
||||
if (entry.getNodeName().equalsIgnoreCase(MEMORY_BLOCK_EXPRESSION)) {
|
||||
String label = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_LABEL);
|
||||
String address = entry.getAttribute(ATTR_MEMORY_BLOCK_EXPR_ADDRESS);
|
||||
|
||||
String memorySpaceID = null;
|
||||
if (entry.hasAttribute(ATTR_MEMORY_BLOCK_MEMORY_SPACE_ID)) {
|
||||
memorySpaceID = entry.getAttribute(ATTR_MEMORY_BLOCK_MEMORY_SPACE_ID);
|
||||
if (memorySpaceID.length() == 0) {
|
||||
memorySpaceID = null;
|
||||
assert false : "should have either no memory space or a valid (non-empty) ID"; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger blockAddress = new BigInteger(address);
|
||||
DsfMemoryBlock block = new GdbMemoryBlock(this, memoryCtx, getModelId(), label, blockAddress, getAddressableSize(), 0, memorySpaceID);
|
||||
blocks.add(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
DebugPlugin.getDefault().getMemoryBlockManager().addMemoryBlocks( blocks.toArray(new IMemoryBlock[blocks.size()]));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Freescale Semiconductor 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:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
||||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
* @noinstantiate This class is not intended to be instantiated by clients.
|
||||
*/
|
||||
public class Messages extends NLS {
|
||||
static {
|
||||
NLS.initializeMessages("org.eclipse.cdt.dsf.gdb.internal.memory.messages", Messages.class); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public static String Err_MemoryServiceNotAvailable;
|
||||
public static String Err_MemoryReadFailed;
|
||||
public static String Err_MemoryWriteFailed;
|
||||
public static String Err_InvalidEncodedAddress;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2010 Freescale Semiconductor 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:
|
||||
# Freescale Semiconductor - initial API and implementation
|
||||
###############################################################################
|
||||
|
||||
Err_MemoryServiceNotAvailable=The required DSF memory service is not available.
|
||||
Err_MemoryReadFailed=Error reading memory block
|
||||
Err_MemoryWriteFailed=Error writing memory block
|
||||
Err_InvalidEncodedAddress=Encoded address has unexpected format
|
|
@ -32,6 +32,7 @@ import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
|||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlockRetrieval;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
||||
|
@ -117,7 +118,7 @@ public class GdbLaunch extends DsfLaunch
|
|||
ICommandControlService commandControl = fTracker.getService(ICommandControlService.class);
|
||||
IMIProcesses procService = fTracker.getService(IMIProcesses.class);
|
||||
if (commandControl != null && procService != null) {
|
||||
fMemRetrieval = new DsfMemoryBlockRetrieval(
|
||||
fMemRetrieval = new GdbMemoryBlockRetrieval(
|
||||
GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, getLaunchConfiguration(), fSession);
|
||||
fSession.registerModelAdapter(IMemoryBlockRetrieval.class, fMemRetrieval);
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
|||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces.IMemorySpaceDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlock.MemorySpaceDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIMemory;
|
||||
|
@ -68,6 +70,12 @@ public class GDBMemory_7_0 extends MIMemory {
|
|||
// Return any thread... let's take the first one.
|
||||
if (execCtxs != null && execCtxs.length > 0) {
|
||||
threadOrMemoryDmc = execCtxs[0];
|
||||
|
||||
// Not so fast, Charlie. The context we were given may have
|
||||
// a memory space qualifier. We need to preserve it.
|
||||
if (dmc instanceof IMemorySpaceDMContext) {
|
||||
threadOrMemoryDmc = new MemorySpaceDMContext(getSession().getId(), ((IMemorySpaceDMContext)dmc).getMemorySpaceId(), threadOrMemoryDmc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +98,12 @@ public class GDBMemory_7_0 extends MIMemory {
|
|||
// Return any thread... let's take the first one.
|
||||
if (execCtxs != null && execCtxs.length > 0) {
|
||||
threadOrMemoryDmc = execCtxs[0];
|
||||
|
||||
// Not so fast, Charlie. The context we were given may have
|
||||
// a memory space qualifier. We need to preserve it.
|
||||
if (dmc instanceof IMemorySpaceDMContext) {
|
||||
threadOrMemoryDmc = new MemorySpaceDMContext(getSession().getId(), ((IMemorySpaceDMContext)dmc).getMemorySpaceId(), threadOrMemoryDmc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,8 +87,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
* @param address - the actual memory block start address
|
||||
* @param word_size - the number of bytes per address
|
||||
* @param length - the requested block length (could be 0)
|
||||
* @since 2.1
|
||||
*/
|
||||
DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, IMemoryDMContext context, String modelId, String expression, BigInteger address, int word_size, long length) {
|
||||
protected DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, IMemoryDMContext context, String modelId, String expression, BigInteger address, int word_size, long length) {
|
||||
fLaunch = retrieval.getLaunch();
|
||||
fDebugTarget = retrieval.getDebugTarget();
|
||||
fRetrieval = retrieval;
|
||||
|
@ -121,7 +122,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (adapter.isAssignableFrom(DsfMemoryBlockRetrieval.class)) {
|
||||
|
@ -557,7 +558,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
// Helper functions
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
/**
|
||||
* The real thing. Since the original call is synchronous (from a platform
|
||||
* Job), we use a Query that will patiently wait for the underlying
|
||||
* asynchronous calls to complete before returning.
|
||||
|
@ -566,8 +567,9 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
* @param length
|
||||
* @return MemoryByte[]
|
||||
* @throws DebugException
|
||||
* @since 2.1
|
||||
*/
|
||||
private MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long length) throws DebugException {
|
||||
protected MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long length) throws DebugException {
|
||||
|
||||
// For the IAddress interface
|
||||
final Addr64 address = new Addr64(bigAddress);
|
||||
|
@ -605,13 +607,15 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
}
|
||||
}
|
||||
|
||||
/* Writes an array of bytes to memory.
|
||||
/**
|
||||
* Writes an array of bytes to memory.
|
||||
*
|
||||
* @param offset
|
||||
* @param bytes
|
||||
* @throws DebugException
|
||||
*/
|
||||
private void writeMemoryBlock(final long offset, final byte[] bytes) throws DebugException {
|
||||
* @since 2.1
|
||||
*/
|
||||
protected void writeMemoryBlock(final long offset, final byte[] bytes) throws DebugException {
|
||||
|
||||
// For the IAddress interface
|
||||
final Addr64 address = new Addr64(fBaseAddress);
|
||||
|
@ -707,4 +711,13 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
public String getUpdatePolicyDescription(String id) {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context specified at construction.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected IMemoryDMContext getContext() {
|
||||
return fContext;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,7 +230,14 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
|
|||
}
|
||||
}
|
||||
|
||||
private void createBlocksFromConfiguration(IMemoryDMContext memoryCtx, String memento) throws CoreException {
|
||||
/**
|
||||
* Create memory blocks based on the given memento (obtained from the launch
|
||||
* configuration) and add them to the platform's IMemoryBlockManager. The
|
||||
* memento was previously created by {@link #getMemento()}
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected void createBlocksFromConfiguration(IMemoryDMContext memoryCtx, String memento) throws CoreException {
|
||||
|
||||
// Parse the memento and validate its type
|
||||
Element root = DebugPlugin.parseDocument(memento);
|
||||
|
@ -280,6 +287,15 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a memento to represent all active blocks created by this retrieval
|
||||
* object (blocks currently registered with the platform's
|
||||
* IMemoryBlockManager). We will be expected to recreate the blocks in
|
||||
* {@link #createBlocksFromConfiguration(IMemoryDMContext, String)}.
|
||||
*
|
||||
* @return a string memento
|
||||
* @throws CoreException
|
||||
*/
|
||||
public String getMemento() throws CoreException {
|
||||
IMemoryBlock[] blocks = DebugPlugin.getDefault().getMemoryBlockManager().getMemoryBlocks(this);
|
||||
Document document = DebugPlugin.newDocument();
|
||||
|
@ -355,11 +371,8 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long,
|
||||
* long)
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long)
|
||||
*/
|
||||
public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException {
|
||||
throw new DebugException(new Status(
|
||||
|
@ -457,7 +470,10 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
|
|||
// Helper functions
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private BigInteger resolveMemoryAddress(final IDMContext dmc, final String expression) throws DebugException {
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
protected BigInteger resolveMemoryAddress(final IDMContext dmc, final String expression) throws DebugException {
|
||||
|
||||
// Use a Query to "synchronize" the downstream calls
|
||||
Query<BigInteger> query = new Query<BigInteger>() {
|
||||
|
@ -502,5 +518,15 @@ public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBl
|
|||
"Error evaluating memory address (ExecutionException).", e)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the model ID specified at construction
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected String getModelId() {
|
||||
return fModelId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, Texas Instruments, Freescale Semiconductor 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:
|
||||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.service;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||
import org.eclipse.cdt.dsf.service.IDsfService;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* A memory service that is memory space aware.
|
||||
*
|
||||
* <p>
|
||||
* Memory contexts are not meant to be represented in tree or table views, so it
|
||||
* doesn't need to implement IDMService interface.
|
||||
*
|
||||
* @author Alain Lee and John Cortell
|
||||
* @since 2.1
|
||||
*/
|
||||
public interface IMemorySpaces extends IDsfService{
|
||||
|
||||
public interface IMemorySpaceDMContext extends IMemoryDMContext {
|
||||
public String getMemorySpaceId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally provides the string encoding of a memory space qualified
|
||||
* address. CDT provides a default encoding of
|
||||
* [memory-space-id]:[expression]. If this is adequate, the client can
|
||||
* return null from this method. This method is called when having to
|
||||
* represent a memory-space qualified address as a single string.
|
||||
*
|
||||
* @param expression
|
||||
* the expression representing a location within a memory space.
|
||||
* This can be a simple numeric expression like "0x10000" or
|
||||
* something more complex "$EAX+(gCustomerCount*100)".
|
||||
* @param memorySpaceID
|
||||
* a string which represents the memory space
|
||||
* @return the encoded string representation of the address, or null to
|
||||
* indicate no custom encoding is required
|
||||
*/
|
||||
String encodeAddress(String expression, String memorySpaceID);
|
||||
|
||||
/**
|
||||
* The inverse of {@link #encodeAddress(String, String)}. Client should
|
||||
* provide decoding if it provides encoding. Conversely, it should not
|
||||
* provide decoding if it doesn't provide encoding.
|
||||
*
|
||||
* @param str
|
||||
* the encoded string
|
||||
* @return the result of decoding the string into its components, or null to
|
||||
* indicate no custom decoding is required
|
||||
* @throws CoreException
|
||||
* if decoding and string is not in the expected format
|
||||
*/
|
||||
DecodeResult decodeAddress(String str) throws CoreException;
|
||||
|
||||
interface DecodeResult {
|
||||
String getMemorySpaceId();
|
||||
String getExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the memory spaces available in the given context.
|
||||
*
|
||||
* @param ctx a DM context
|
||||
* @param rm the asynchronous data request monitor
|
||||
*/
|
||||
void getMemorySpaces(IDMContext context, final DataRequestMonitor<String[]> rm);
|
||||
}
|
Loading…
Add table
Reference in a new issue