mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +02:00
Bug 431627 - [mem] Need additional API to extend support for memory
spaces Change-Id: I775f443927ddd326e5aab5c0e9243cd818edde41 Signed-off-by: Alvaro Sanchez-Leon <alvsan09@gmail.com> Reviewed-on: https://git.eclipse.org/r/24994 Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com> Tested-by: Hudson CI Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
This commit is contained in:
parent
fa5de3be3b
commit
ddb8ab8708
6 changed files with 209 additions and 215 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Wind River Systems and others.
|
||||
* Copyright (c) 2010, 2014 Wind River Systems 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
|
||||
|
@ -7,6 +7,8 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial implementation
|
||||
* Anders Dahlberg (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
* Alvaro Sanchez-Leon (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb;
|
||||
|
||||
|
@ -136,7 +138,7 @@ public class GDBTypeParser {
|
|||
}
|
||||
} else {
|
||||
sb.insert(0, ' ');
|
||||
sb.insert(0, gdbType.nameType);
|
||||
sb.insert(0, gdbType.getTypeName());
|
||||
gdbType = null;
|
||||
}
|
||||
}
|
||||
|
@ -279,9 +281,12 @@ public class GDBTypeParser {
|
|||
insertingChild(kind, 0);
|
||||
}
|
||||
|
||||
void insertingChild(int kind, int d) {
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
protected void insertingChild(int kind, int d) {
|
||||
if (gdbDerivedType == null) {
|
||||
gdbDerivedType = new GDBDerivedType(genericType, kind, d);
|
||||
gdbDerivedType = createGDBDerivedType(genericType, kind, d);
|
||||
} else {
|
||||
GDBDerivedType dType = gdbDerivedType;
|
||||
GDBType gdbType = gdbDerivedType.getChild();
|
||||
|
@ -289,7 +294,7 @@ public class GDBTypeParser {
|
|||
dType = (GDBDerivedType)gdbType;
|
||||
gdbType = dType.getChild();
|
||||
}
|
||||
gdbType = new GDBDerivedType(gdbType, kind, d);
|
||||
gdbType = createGDBDerivedType(gdbType, kind, d);
|
||||
dType.setChild(gdbType);
|
||||
}
|
||||
}
|
||||
|
@ -459,6 +464,13 @@ public class GDBTypeParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
protected GDBDerivedType createGDBDerivedType(GDBType c, int t, int dim) {
|
||||
return new GDBDerivedType(c, t, dim);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
|
|
@ -8,37 +8,31 @@
|
|||
* Contributors:
|
||||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
* Anders Dahlberg (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
*******************************************************************************/
|
||||
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.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory;
|
||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.cdt.utils.Addr64;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.DebugEvent;
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.model.MemoryByte;
|
||||
|
||||
/**
|
||||
* A specialization of the DSF memory block implementation supporting memory
|
||||
|
@ -59,6 +53,18 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
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
|
||||
|
||||
//TODO: remove the memorySpaceID parameter from this method
|
||||
//after making sure it's not used in earlier implementations
|
||||
//in the mean time check for consistency
|
||||
if(memorySpaceID != null) {
|
||||
assert(context instanceof IMemorySpaceDMContext);
|
||||
assert memorySpaceID.equals(((IMemorySpaceDMContext) context).getMemorySpaceId());
|
||||
} else {
|
||||
if (context instanceof IMemorySpaceDMContext) {
|
||||
assert ((IMemorySpaceDMContext) context).getMemorySpaceId() == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +77,10 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
|
||||
public MemorySpaceDMContext(String sessionId, String memorySpaceId, IDMContext parent) {
|
||||
super(sessionId, new IDMContext[] {parent});
|
||||
fMemorySpaceId = memorySpaceId;
|
||||
// A memorySpaceDMContext should not be created if the memorySpaceId is not valid.
|
||||
// However we need the id to calculate the hash, therefore we can not leave it as null
|
||||
assert(memorySpaceId != null);
|
||||
fMemorySpaceId = memorySpaceId == null ? "": memorySpaceId; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -111,150 +120,6 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
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 count - The number of addressable units for this block
|
||||
* @return MemoryByte[]
|
||||
* @throws DebugException
|
||||
*/
|
||||
@Override
|
||||
protected MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long count) 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 = 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 = retrieval.getServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.getMemory(
|
||||
context, address, 0, addressableSize, (int) count,
|
||||
//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;
|
||||
try {
|
||||
addressableSize = getAddressableSize();
|
||||
} catch (DebugException e) {}
|
||||
|
||||
int addressableUnits = bytes.length/addressableSize;
|
||||
|
||||
// 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 = 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 = retrieval.getServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.setMemory(
|
||||
context, address, offset, addressableSize, addressableUnits, 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()
|
||||
|
@ -283,19 +148,10 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
@Override
|
||||
public int getAddressSize() throws DebugException {
|
||||
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
||||
IMemoryDMContext context = null;
|
||||
if (fMemorySpaceID != null) {
|
||||
IMemorySpaces memorySpacesService = retrieval.getMemorySpaceServiceTracker().getService();
|
||||
if (memorySpacesService != null) {
|
||||
context = new MemorySpaceDMContext(memorySpacesService.getSession().getId(), fMemorySpaceID, getContext());
|
||||
}
|
||||
}
|
||||
else {
|
||||
context = getContext();
|
||||
}
|
||||
|
||||
IGDBMemory memoryService = (IGDBMemory)retrieval.getServiceTracker().getService();
|
||||
if (memoryService != null) {
|
||||
return memoryService.getAddressSize(context);
|
||||
return memoryService.getAddressSize(getContext());
|
||||
}
|
||||
|
||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
|
||||
|
|
|
@ -9,24 +9,30 @@
|
|||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323)
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
* Anders Dahlberg (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
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.DsfRunnable;
|
||||
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.debug.service.IMemorySpaces.IMemorySpaceDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces2;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlock.MemorySpaceDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory;
|
||||
|
@ -105,11 +111,26 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
*/
|
||||
@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);
|
||||
|
||||
String memorySpaceID = null;
|
||||
|
||||
// Determine if the expression has memory space information
|
||||
IDMContext dmc = null;
|
||||
if (context instanceof IDMContext) {
|
||||
dmc = (IDMContext) context;
|
||||
} else {
|
||||
if (context instanceof IAdaptable) {
|
||||
dmc = (IDMContext)((IAdaptable)context).getAdapter(IDMContext.class);
|
||||
}
|
||||
}
|
||||
|
||||
if (dmc != null) {
|
||||
DecodeResult result = decodeMemorySpaceExpression(dmc, expression);
|
||||
expression = result.getExpression();
|
||||
memorySpaceID = result.getMemorySpaceId();
|
||||
}
|
||||
|
||||
return getMemoryBlock(expression, context, memorySpaceID);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -131,6 +152,17 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
return null;
|
||||
}
|
||||
|
||||
//Adjust the memory context to use memory spaces when available
|
||||
if (memoryDmc instanceof IMemorySpaceDMContext) {
|
||||
// The memory space ids should match
|
||||
assert(memorySpaceID != null);
|
||||
assert(memorySpaceID.equals(((IMemorySpaceDMContext)memoryDmc).getMemorySpaceId()));
|
||||
} else {
|
||||
if (memorySpaceID != null && memorySpaceID.length() > 0) {
|
||||
memoryDmc = new MemorySpaceDMContext(getSession().getId(), memorySpaceID, memoryDmc);
|
||||
}
|
||||
}
|
||||
|
||||
// The block start address (supports 64-bit processors)
|
||||
BigInteger blockAddress;
|
||||
|
||||
|
@ -177,7 +209,7 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
}
|
||||
|
||||
// check for block address exceeding maximum allowed address value
|
||||
int addressSize = getAddressSize(memoryDmc, memorySpaceID);
|
||||
int addressSize = getAddressSize(memoryDmc);
|
||||
BigInteger endAddress = BigInteger.ONE.shiftLeft(addressSize*8).subtract(BigInteger.ONE);
|
||||
if (endAddress.compareTo(blockAddress) < 0) {
|
||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1,
|
||||
|
@ -196,7 +228,7 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
* 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(memoryDmc, memorySpaceID), 0, memorySpaceID);
|
||||
return new GdbMemoryBlock(this, memoryDmc, getModelId(), expression, blockAddress, getAddressableSize(memoryDmc), 0, memorySpaceID);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -283,13 +315,18 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
}
|
||||
|
||||
// default decoding
|
||||
final String memorySpaceID;
|
||||
final String expression;
|
||||
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$
|
||||
//Unknown parsing, may not use memory spaces
|
||||
memorySpaceID = null;
|
||||
expression = str;
|
||||
} else {
|
||||
memorySpaceID = str.substring(0, index);
|
||||
expression = (index < str.length()-1) ? str.substring(index+1) : ""; //$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() {
|
||||
@Override
|
||||
public String getMemorySpaceId() { return memorySpaceID; }
|
||||
|
@ -298,7 +335,68 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the received expression by
|
||||
* First, decoding the string directly
|
||||
* Second, if the memory space is not found in the expression string, use the Memory service to use some help from gdb
|
||||
*/
|
||||
private DecodeResult decodeMemorySpaceExpression(final IDMContext dmc, final String expression) throws DebugException {
|
||||
DecodeResult decodeResult;
|
||||
try {
|
||||
decodeResult = decodeAddress(expression);
|
||||
} catch (CoreException e1) {
|
||||
throw new DebugException(e1.getStatus());
|
||||
}
|
||||
|
||||
if (decodeResult.getMemorySpaceId() != null) {
|
||||
//memory space found in expression
|
||||
return decodeResult;
|
||||
}
|
||||
|
||||
//
|
||||
final IMemorySpaces service = fMemorySpaceServiceTracker.getService();
|
||||
if (service instanceof IMemorySpaces2) {
|
||||
final IMemorySpaces2 memSpaceService = (IMemorySpaces2) service;
|
||||
|
||||
Query<IMemorySpaces.DecodeResult> query = new Query<IMemorySpaces.DecodeResult>() {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<IMemorySpaces.DecodeResult> drm) {
|
||||
memSpaceService.decodeExpression(dmc, expression, drm);
|
||||
}
|
||||
};
|
||||
|
||||
getExecutor().execute(query);
|
||||
try {
|
||||
final IMemorySpaces.DecodeResult result = query.get();
|
||||
decodeResult = new DecodeResult() {
|
||||
@Override
|
||||
public String getMemorySpaceId() {
|
||||
return result.getMemorySpaceId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return result.getExpression();
|
||||
}
|
||||
};
|
||||
} catch (InterruptedException e) {
|
||||
throw new DebugException(new Status(IStatus.ERROR,
|
||||
GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
|
||||
"Error evaluating memory space expression (InterruptedException).", e)); //$NON-NLS-1$
|
||||
|
||||
} catch (ExecutionException e) {
|
||||
throw new DebugException(new Status(IStatus.ERROR,
|
||||
GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR,
|
||||
"Error evaluating memory space expression (ExecutionException).", e)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return decodeResult;
|
||||
}
|
||||
|
||||
|
||||
ServiceTracker<IMemorySpaces, IMemorySpaces> getMemorySpaceServiceTracker() {
|
||||
return fMemorySpaceServiceTracker;
|
||||
}
|
||||
|
@ -377,11 +475,19 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
if (memorySpaceID.length() == 0) {
|
||||
memorySpaceID = null;
|
||||
assert false : "should have either no memory space or a valid (non-empty) ID"; //$NON-NLS-1$
|
||||
} else {
|
||||
if (memoryCtx instanceof IMemorySpaceDMContext) {
|
||||
//The context is already a memory space context, make sure the ids are consistent
|
||||
assert(((IMemorySpaceDMContext) memoryCtx).getMemorySpaceId().equals(memorySpaceID));
|
||||
} else {
|
||||
//Use a memory space context if the memory space id is valid
|
||||
memoryCtx = new MemorySpaceDMContext(getSession().getId(), memorySpaceID, memoryCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger blockAddress = new BigInteger(address);
|
||||
DsfMemoryBlock block = new GdbMemoryBlock(this, memoryCtx, getModelId(), label, blockAddress, getAddressableSize(memoryCtx, memorySpaceID), 0, memorySpaceID);
|
||||
DsfMemoryBlock block = new GdbMemoryBlock(this, memoryCtx, getModelId(), label, blockAddress, getAddressableSize(memoryCtx), 0, memorySpaceID);
|
||||
blocks.add(block);
|
||||
}
|
||||
}
|
||||
|
@ -402,38 +508,22 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
return false;
|
||||
}
|
||||
|
||||
private int getAddressableSize(IMemoryDMContext aContext, String memorySpaceID) {
|
||||
private int getAddressableSize(IMemoryDMContext context) {
|
||||
IGDBMemory2 memoryService = (IGDBMemory2) getServiceTracker()
|
||||
.getService();
|
||||
|
||||
if (memoryService != null && aContext != null) {
|
||||
IMemoryDMContext context = resolveMemSpaceContext(aContext, memorySpaceID);
|
||||
if (memoryService != null && context != null) {
|
||||
return memoryService.getAddressableSize(context);
|
||||
}
|
||||
|
||||
return super.getAddressableSize();
|
||||
}
|
||||
|
||||
|
||||
private int getAddressSize(IMemoryDMContext aContext, String memorySpaceID) {
|
||||
private int getAddressSize(IMemoryDMContext context) {
|
||||
IGDBMemory memoryService = (IGDBMemory)getServiceTracker().getService();
|
||||
if (memoryService != null && aContext != null) {
|
||||
IMemoryDMContext context = resolveMemSpaceContext(aContext, memorySpaceID);
|
||||
if (memoryService != null && context != null) {
|
||||
return memoryService.getAddressSize(context);
|
||||
}
|
||||
return super.getAddressSize();
|
||||
}
|
||||
|
||||
private IMemoryDMContext resolveMemSpaceContext(IMemoryDMContext aContext, String aMemorySpaceID) {
|
||||
IMemoryDMContext context = aContext;
|
||||
if (aMemorySpaceID != null && aMemorySpaceID.length() > 0) {
|
||||
IMemorySpaces memorySpacesService = getMemorySpaceServiceTracker().getService();
|
||||
if (memorySpacesService != null) {
|
||||
context = new MemorySpaceDMContext(memorySpacesService.getSession().getId(), aMemorySpaceID, aContext);
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -430,11 +430,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// Event handlers
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @nooverride This method is not intended to be re-implemented or extended by clients.
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IResumedDMEvent e) {
|
||||
if (e instanceof IContainerResumedDMEvent) {
|
||||
|
@ -459,10 +454,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @nooverride This method is not intended to be re-implemented or extended by clients.
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(ISuspendedDMEvent e) {
|
||||
if (e instanceof IContainerSuspendedDMEvent) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2013 Monta Vista and others.
|
||||
* Copyright (c) 2008, 2014 Monta Vista 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
|
||||
|
@ -14,6 +14,8 @@
|
|||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
* Axel Mueller - Workaround for GDB bug where -var-info-path-expression gives invalid result (Bug 320277)
|
||||
* Anton Gorenkov - DSF-GDB should properly handle variable type change (based on RTTI) (Bug 376901)
|
||||
* Anders Dahlberg (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
* Alvaro Sanchez-Leon (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
|
@ -586,7 +588,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
*/
|
||||
public void setType(String newTypeName) {
|
||||
type = newTypeName;
|
||||
gdbType = fGDBTypeParser.parse(newTypeName);
|
||||
gdbType = getGDBTypeParser().parse(newTypeName);
|
||||
}
|
||||
|
||||
public void setValue(String format, String val) { valueMap.put(format, val); }
|
||||
|
@ -2542,10 +2544,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
*/
|
||||
private static final GDBTypeParser fGDBTypeParser = new GDBTypeParser();
|
||||
private GDBTypeParser fGDBTypeParser = null;
|
||||
|
||||
private final DsfSession fSession;
|
||||
|
||||
|
@ -2620,6 +2619,13 @@ public class MIVariableManager implements ICommandControl {
|
|||
return lruVariableList;
|
||||
}
|
||||
|
||||
private GDBTypeParser getGDBTypeParser() {
|
||||
if (fGDBTypeParser == null) {
|
||||
fGDBTypeParser = createGDBTypeParser();
|
||||
}
|
||||
return fGDBTypeParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a variable object based on the specified
|
||||
* ExpressionDMC, creating it in GDB if it was not created already.
|
||||
|
@ -3172,4 +3178,12 @@ public class MIVariableManager implements ICommandControl {
|
|||
protected boolean needFixForGDBBug320277() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
protected GDBTypeParser createGDBTypeParser() {
|
||||
return new GDBTypeParser();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 Ericsson AB 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:
|
||||
* Anders Dahlberg (Ericsson) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - Need additional API to extend support for memory spaces (Bug 431627)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.service;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
|
||||
/**
|
||||
* This extension allows the decoding of an expression with the help of the external debugger
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public interface IMemorySpaces2 extends IMemorySpaces {
|
||||
|
||||
/**
|
||||
* Provides the means to use the debugger backend to help with asynchronous
|
||||
* resolution of memory space, expression pair from a single string expression
|
||||
*
|
||||
*/
|
||||
public void decodeExpression(IDMContext context, String expression, DataRequestMonitor<DecodeResult> rm);
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue