mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-03 23:25:26 +02:00
Committed patch to enable IMemoryBlockExtension support (from bug 160046).
This commit is contained in:
parent
453c1f7013
commit
4ea1ca7350
3 changed files with 493 additions and 83 deletions
|
@ -7,64 +7,64 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
* Ericsson Communication - upgrade IF from IMemoryBlock to IMemoryBlockExtension
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.model;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.cdt.utils.Addr32;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.debug.DsfDebugPlugin;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.Query;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.debug.service.IMemory;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.model.IDebugTarget;
|
||||
import org.eclipse.debug.core.model.IMemoryBlock;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockExtension;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
|
||||
import org.eclipse.debug.core.model.MemoryByte;
|
||||
|
||||
public class DsfMemoryBlock extends PlatformObject implements IMemoryBlock
|
||||
/**
|
||||
* This class holds the memory block retrieved from the target as a result of
|
||||
* a getBytes() or getBytesFromAddress() call from the platform.
|
||||
*/
|
||||
public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtension
|
||||
{
|
||||
private final DsfMemoryBlockRetrieval fRetrieval;
|
||||
private final String fModelId;
|
||||
private final String fExpression;
|
||||
private final long fStartAddress;
|
||||
private final byte[] fBytes;
|
||||
private final long fLength;
|
||||
private final BigInteger fBaseAddress;
|
||||
|
||||
DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, long startAddress, byte[] bytes) {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param retrieval
|
||||
* @param modelId
|
||||
* @param expression
|
||||
* @param startAddress
|
||||
* @param length
|
||||
*/
|
||||
DsfMemoryBlock(DsfMemoryBlockRetrieval retrieval, String modelId, String expression, long startAddress, long length) {
|
||||
fRetrieval = retrieval;
|
||||
fModelId = modelId;
|
||||
fExpression = expression;
|
||||
fStartAddress = startAddress;
|
||||
fBytes = bytes;
|
||||
}
|
||||
|
||||
public byte[] getBytes() throws DebugException {
|
||||
return fBytes;
|
||||
fBaseAddress = new BigInteger(Long.toString(startAddress));
|
||||
fLength = length;
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return fBytes.length;
|
||||
}
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// IAdaptable
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public long getStartAddress() {
|
||||
return fStartAddress;
|
||||
}
|
||||
|
||||
public void setValue(long offset, byte[] bytes) throws DebugException {
|
||||
throw new DebugException(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, DebugException.NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public boolean supportsValueModification() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public IDebugTarget getDebugTarget() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ILaunch getLaunch() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getModelIdentifier() {
|
||||
return fModelId;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (adapter.isAssignableFrom(DsfMemoryBlockRetrieval.class)) {
|
||||
|
@ -72,4 +72,266 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlock
|
|||
}
|
||||
return super.getAdapter(adapter);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// IDebugElement
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
|
||||
*/
|
||||
public IDebugTarget getDebugTarget() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier()
|
||||
*/
|
||||
public String getModelIdentifier() {
|
||||
return fModelId;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
|
||||
*/
|
||||
public ILaunch getLaunch() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// IMemoryBock interface - obsoleted by IMemoryBlockExtension
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlock#getStartAddress()
|
||||
*/
|
||||
public long getStartAddress() {
|
||||
return fStartAddress;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlock#getLength()
|
||||
*/
|
||||
public long getLength() {
|
||||
return fLength;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlock#getBytes()
|
||||
*/
|
||||
public byte[] getBytes() throws DebugException {
|
||||
MemoryByte[] block = fetchMemoryBlock(fStartAddress, fLength);
|
||||
int length = block.length;
|
||||
byte[] bytes = new byte[length];
|
||||
// Extract bytes from MemoryBytes
|
||||
for (int i = 0; i < length; i++)
|
||||
bytes[i] = block[i].getValue();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlock#supportsValueModification()
|
||||
*/
|
||||
public boolean supportsValueModification() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlock#setValue(long, byte[])
|
||||
*/
|
||||
public void setValue(long offset, byte[] bytes) throws DebugException {
|
||||
setValue(BigInteger.valueOf(offset), bytes);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// IMemoryBlockExtension interface
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getExpression()
|
||||
*/
|
||||
public String getExpression() {
|
||||
return fExpression;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBigBaseAddress()
|
||||
*/
|
||||
public BigInteger getBigBaseAddress() throws DebugException {
|
||||
return fBaseAddress;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockStartAddress()
|
||||
*/
|
||||
public BigInteger getMemoryBlockStartAddress() throws DebugException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockEndAddress()
|
||||
*/
|
||||
public BigInteger getMemoryBlockEndAddress() throws DebugException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBigLength()
|
||||
*/
|
||||
public BigInteger getBigLength() throws DebugException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressSize()
|
||||
*/
|
||||
public int getAddressSize() throws DebugException {
|
||||
// TODO: Have the service make a trip to the back-end and
|
||||
// retrieve/store that information for us
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportBaseAddressModification()
|
||||
*/
|
||||
public boolean supportBaseAddressModification() throws DebugException {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#supportsChangeManagement()
|
||||
*/
|
||||
public boolean supportsChangeManagement() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#setBaseAddress(java.math.BigInteger)
|
||||
*/
|
||||
public void setBaseAddress(BigInteger address) throws DebugException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromOffset(java.math.BigInteger, long)
|
||||
*/
|
||||
public MemoryByte[] getBytesFromOffset(BigInteger unitOffset, long addressableUnits) throws DebugException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getBytesFromAddress(java.math.BigInteger, long)
|
||||
*/
|
||||
public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException {
|
||||
return fetchMemoryBlock(address.longValue(), units);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#setValue(java.math.BigInteger, byte[])
|
||||
*/
|
||||
public void setValue(BigInteger offset, byte[] bytes) throws DebugException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#connect(java.lang.Object)
|
||||
*/
|
||||
public void connect(Object client) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#disconnect(java.lang.Object)
|
||||
*/
|
||||
public void disconnect(Object client) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getConnections()
|
||||
*/
|
||||
public Object[] getConnections() {
|
||||
// TODO Auto-generated method stub
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#dispose()
|
||||
*/
|
||||
public void dispose() throws DebugException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getMemoryBlockRetrieval()
|
||||
*/
|
||||
public IMemoryBlockRetrieval getMemoryBlockRetrieval() {
|
||||
return fRetrieval;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getAddressableSize()
|
||||
*/
|
||||
public int getAddressableSize() throws DebugException {
|
||||
// TODO: Have the service make a trip to the back-end and
|
||||
// retrieve/store that information for us
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// 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.
|
||||
*
|
||||
* @param address
|
||||
* @param length
|
||||
* @return MemoryBytes[]
|
||||
* @throws DebugException
|
||||
*/
|
||||
private MemoryByte[] fetchMemoryBlock(final long address, final long length) throws DebugException {
|
||||
|
||||
/* For this first implementation, we make a few simplifying assumptions:
|
||||
* - word_size = 1 (we want to read individual bytes)
|
||||
* - offset = 0
|
||||
* - mode = hexadecimal (will be overridden in getMemory() anyway)
|
||||
*/
|
||||
final int word_size = 1;
|
||||
final int offset = 0;
|
||||
final int mode = 0; // TODO: Add a constant for hexadecimal mode
|
||||
|
||||
// Use a Query to "synchronize" the inherently asynchronous downstream calls
|
||||
Query<MemoryByte[]> query = new Query<MemoryByte[]>() {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<MemoryByte[]> rm) {
|
||||
IMemory memoryService = (IMemory) fRetrieval.getServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
// Place holder for the result
|
||||
final MemoryByte[] buffer = new MemoryByte[(int) length];
|
||||
// Go for it
|
||||
memoryService.getMemory(
|
||||
fRetrieval.getContext(), new Addr32(address), word_size, buffer, offset, (int) length, mode,
|
||||
new RequestMonitor(fRetrieval.getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
rm.setData(buffer);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
fRetrieval.getExecutor().execute(query);
|
||||
try {
|
||||
return query.get();
|
||||
} catch (InterruptedException e) {
|
||||
} catch (ExecutionException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,19 +7,14 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
* Ericsson Communication - upgrade IF from IMemoryBlockRetrieval to IMemoryBlockRetrievalExtension
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.model;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.cdt.utils.Addr32;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Query;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.DsfDebugPlugin;
|
||||
import org.eclipse.dd.dsf.debug.service.IMemory;
|
||||
|
@ -27,24 +22,40 @@ import org.eclipse.dd.dsf.service.DsfSession;
|
|||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.model.IMemoryBlock;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockExtension;
|
||||
import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
* Implementation of memory access API of the Eclipse standard debug model.
|
||||
* <br/>Note: This is only a sample implementation intended as a starting point.
|
||||
*
|
||||
* The IMemoryBlockRetrievalExtension is implemented for the reference
|
||||
* application. This will result in getExtendedMemoryBlock() being called
|
||||
* when a memory block is selected from the memory pane.
|
||||
*
|
||||
* However, if the 'simpler' IMemoryBlockRetrieval is to be implemented, the
|
||||
* code will still be functional after trivial adjustments. In that case, the
|
||||
* platform will call getMemoryBlock() instead. Note that DsfMemoryBlock will
|
||||
* have to be 'downgraded' to implement IMemoryBlock (instead of IMemoryBlockExtension)
|
||||
*
|
||||
*/
|
||||
public class DsfMemoryBlockRetrieval extends PlatformObject
|
||||
implements IMemoryBlockRetrieval
|
||||
public class DsfMemoryBlockRetrieval extends PlatformObject implements IMemoryBlockRetrievalExtension
|
||||
{
|
||||
private final String fModelId;
|
||||
private final DsfSession fSession;
|
||||
private final DsfExecutor fExecutor;
|
||||
private final IDMContext<?> fContext;
|
||||
private final ServiceTracker fServiceTracker;
|
||||
private final String fModelId;
|
||||
private final DsfSession fSession;
|
||||
private final DsfExecutor fExecutor;
|
||||
private final IDMContext<?> fContext;
|
||||
private final ServiceTracker fServiceTracker;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param modelId
|
||||
* @param dmc
|
||||
* @throws DebugException
|
||||
*/
|
||||
public DsfMemoryBlockRetrieval(String modelId, IDMContext<?> dmc) throws DebugException {
|
||||
fModelId = modelId;
|
||||
fContext = dmc;
|
||||
|
@ -66,37 +77,154 @@ public class DsfMemoryBlockRetrieval extends PlatformObject
|
|||
}
|
||||
fServiceTracker.open();
|
||||
}
|
||||
|
||||
public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException {
|
||||
Query<DsfMemoryBlock> query = new Query<DsfMemoryBlock>() {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<DsfMemoryBlock> rm) {
|
||||
IMemory memoryService = (IMemory)fServiceTracker.getService();
|
||||
if (memoryService != null) {
|
||||
final byte[] buf = new byte[(int)length];
|
||||
memoryService.getMemory(
|
||||
fContext, new Addr32(startAddress), 32, buf, 0, (int)length, 0,
|
||||
new RequestMonitor(fExecutor, rm) {
|
||||
@Override
|
||||
protected void handleOK() {
|
||||
rm.setData(new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, startAddress, buf));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
fExecutor.execute(query);
|
||||
try {
|
||||
return query.get();
|
||||
} catch (InterruptedException e) {
|
||||
} catch (ExecutionException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// Accessors
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getModelId() {
|
||||
return fModelId;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public DsfSession getSession() {
|
||||
return fSession;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public DsfExecutor getExecutor() {
|
||||
return fExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IDMContext<?> getContext() {
|
||||
return fContext;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ServiceTracker getServiceTracker() {
|
||||
return fServiceTracker;
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// IMemoryBlockRetrieval - obsoleted by IMemoryBlockRetrievalExtension
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval()
|
||||
*/
|
||||
public boolean supportsStorageRetrieval() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long)
|
||||
*/
|
||||
public IMemoryBlock getMemoryBlock(final long startAddress, final long length) throws DebugException {
|
||||
// The expression to display in the rendering tab
|
||||
// Put here for the sake of completeness (not used with IMemoryBlock)
|
||||
String expression = "0x" + Long.toHexString(startAddress); //$NON-NLS-1$
|
||||
return new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, expression, startAddress, length);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// IMemoryBlockRetrievalExtension
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension#getExtendedMemoryBlock(java.lang.String, java.lang.Object)
|
||||
*/
|
||||
public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException {
|
||||
|
||||
boolean validAddress = false;
|
||||
long address = 0;
|
||||
|
||||
/* 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 (not too realistic but bear with us :-)
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
address = Long.parseLong(expression.substring(offset), base);
|
||||
|
||||
// All right! We saved a trip to the back-end.
|
||||
validAddress = true;
|
||||
|
||||
} catch (NumberFormatException nfexc) {
|
||||
// OK, expression is not a simple, absolute numeric value; try to resolve as expression
|
||||
}
|
||||
|
||||
// We have to ask the debugger to resolve the address for us
|
||||
if (!validAddress) {
|
||||
// [frch] Code removed until we properly hook the ExpressionService
|
||||
// [frch] Code saved in lmcfrch-memory-070625.PATCH
|
||||
return null;
|
||||
}
|
||||
|
||||
/* At this point, we only know the requested address and we have no
|
||||
* idea of the memory block length. The renderer will provide this
|
||||
* information when it calls getBytesFromAddress() i.e. after the
|
||||
* memory block holder has been instantiated...
|
||||
*
|
||||
* We could try to out-smart the renderer and do some educated guess
|
||||
* about the start address it will select and the length it will
|
||||
* request.
|
||||
*
|
||||
* This would 'work' for the standard debug renderers: start address
|
||||
* on a 16-byte boundary, length of 320 bytes (20 lines of 16 bytes).
|
||||
* However, this is not such a great idea: a given renderer might ask
|
||||
* for a block starting at any address adn length it sees fit. Therefore
|
||||
* we can't make any assumption.
|
||||
*
|
||||
* The only safe approach is to just instantiate the IMemoryBlockExtension
|
||||
* and postpone the actual memory fetch until the renderer explicitly
|
||||
* asks for it (i.e. calls getBytesFromAddress()).
|
||||
*
|
||||
* The down side is that every time we switch renderer, for the same block,
|
||||
* a trip to the target could result.
|
||||
*
|
||||
* However, we have an ace in our sleeve: the memory request cache should
|
||||
* save us a trip to the back-end.
|
||||
*/
|
||||
|
||||
return new DsfMemoryBlock(DsfMemoryBlockRetrieval.this, fModelId, expression, address, 0);
|
||||
}
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// Helper functions
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// [frch] Code removed until we properly hook the ExpressionService
|
||||
// [frch] Code saved in lmcfrch-memory-070625.PATCH
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
* Ericsson Communication - extended the API for IMemoryBlockExtension
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.debug.service;
|
||||
|
||||
|
@ -14,6 +15,7 @@ import org.eclipse.cdt.core.IAddress;
|
|||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.service.IDsfService;
|
||||
import org.eclipse.debug.core.model.MemoryByte;
|
||||
|
||||
/**
|
||||
* Service for accessing memory. Memory contexts are not meant to be
|
||||
|
@ -38,5 +40,23 @@ public interface IMemory extends IDsfService {
|
|||
*/
|
||||
public void fillMemory(IDMContext<?> ctx, IAddress addr,
|
||||
int word_size, byte[] value, int size, int mode, RequestMonitor requestMonitor);
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// Replicated the base functions to support IMemoryBlockExtension
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Writes the given value to the given memory location. */
|
||||
public void setMemory(IDMContext<?> ctx, IAddress addr,
|
||||
int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor);
|
||||
|
||||
/** Reads memory at the given location */
|
||||
public void getMemory(IDMContext<?> ctx, IAddress addr,
|
||||
int word_size, MemoryByte[] buf, int offs, int size, int mode, RequestMonitor requestMonitor);
|
||||
|
||||
public void fillMemory(IDMContext<?> ctx, IAddress addr,
|
||||
int word_size, MemoryByte[] value, int size, int mode, RequestMonitor requestMonitor);
|
||||
|
||||
// /** Reads memory at the given location */
|
||||
// public void resolveMemoryAddress(IDMContext<?> ctx, String expression, BigInteger[] address, RequestMonitor requestMonitor);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue