1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 06:02:11 +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:
Alvaro Sanchez-Leon 2014-04-24 20:48:31 +02:00 committed by Marc Khouzam
parent fa5de3be3b
commit ddb8ab8708
6 changed files with 209 additions and 215 deletions

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,8 @@
* *
* Contributors: * Contributors:
* Wind River Systems - initial implementation * 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; package org.eclipse.cdt.dsf.gdb;
@ -136,7 +138,7 @@ public class GDBTypeParser {
} }
} else { } else {
sb.insert(0, ' '); sb.insert(0, ' ');
sb.insert(0, gdbType.nameType); sb.insert(0, gdbType.getTypeName());
gdbType = null; gdbType = null;
} }
} }
@ -279,9 +281,12 @@ public class GDBTypeParser {
insertingChild(kind, 0); insertingChild(kind, 0);
} }
void insertingChild(int kind, int d) { /**
* @since 4.4
*/
protected void insertingChild(int kind, int d) {
if (gdbDerivedType == null) { if (gdbDerivedType == null) {
gdbDerivedType = new GDBDerivedType(genericType, kind, d); gdbDerivedType = createGDBDerivedType(genericType, kind, d);
} else { } else {
GDBDerivedType dType = gdbDerivedType; GDBDerivedType dType = gdbDerivedType;
GDBType gdbType = gdbDerivedType.getChild(); GDBType gdbType = gdbDerivedType.getChild();
@ -289,7 +294,7 @@ public class GDBTypeParser {
dType = (GDBDerivedType)gdbType; dType = (GDBDerivedType)gdbType;
gdbType = dType.getChild(); gdbType = dType.getChild();
} }
gdbType = new GDBDerivedType(gdbType, kind, d); gdbType = createGDBDerivedType(gdbType, kind, d);
dType.setChild(gdbType); dType.setChild(gdbType);
} }
} }
@ -460,6 +465,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) { public static void main(String[] args) {
GDBTypeParser parser = new GDBTypeParser(); GDBTypeParser parser = new GDBTypeParser();

View file

@ -8,37 +8,31 @@
* Contributors: * Contributors:
* Texas Instruments, Freescale Semiconductor - initial API and implementation * Texas Instruments, Freescale Semiconductor - initial API and implementation
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730) * 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; package org.eclipse.cdt.dsf.gdb.internal.memory;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.concurrent.ExecutionException;
import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlock; 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.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.AbstractDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock; import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock;
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval; 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.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.IMemorySpaces.IMemorySpaceDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory; import org.eclipse.cdt.dsf.gdb.service.IGDBMemory;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.utils.Addr64;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.MemoryByte;
/** /**
* A specialization of the DSF memory block implementation supporting memory * 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); super(retrieval, context, modelId, expression, address, word_size, length);
fMemorySpaceID = (memorySpaceID != null && memorySpaceID.length() > 0) ? memorySpaceID : null; fMemorySpaceID = (memorySpaceID != null && memorySpaceID.length() > 0) ? memorySpaceID : null;
assert memorySpaceID == null || memorySpaceID.length() > 0; // callers shouldn't be passing in an empty string 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) { public MemorySpaceDMContext(String sessionId, String memorySpaceId, IDMContext parent) {
super(sessionId, new 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) /* (non-Javadoc)
@ -112,150 +121,6 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
} }
} }
/*
* 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) /* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.core.model.provisional.IMemorySpaceAwareMemoryBlock#getMemorySpaceID() * @see org.eclipse.cdt.debug.internal.core.model.provisional.IMemorySpaceAwareMemoryBlock#getMemorySpaceID()
*/ */
@ -283,19 +148,10 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
@Override @Override
public int getAddressSize() throws DebugException { public int getAddressSize() throws DebugException {
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval(); 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(); IGDBMemory memoryService = (IGDBMemory)retrieval.getServiceTracker().getService();
if (memoryService != null) { 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)); throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));

View file

@ -9,24 +9,30 @@
* Texas Instruments, Freescale Semiconductor - initial API and implementation * 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) - Each memory context needs a different MemoryRetrieval (Bug 250323)
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730) * 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; package org.eclipse.cdt.dsf.gdb.internal.memory;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlock; import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlock;
import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval; import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlockRetrieval;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable; 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.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock; import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock;
import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; 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;
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.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlock.MemorySpaceDMContext; import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlock.MemorySpaceDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory; import org.eclipse.cdt.dsf.gdb.service.IGDBMemory;
@ -105,11 +111,26 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
*/ */
@Override @Override
public IMemoryBlockExtension getExtendedMemoryBlock(String expression, Object context) throws DebugException { 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 String memorySpaceID = null;
// sake of consistency, lets have this retrieval class always return a
// GdbMemoryBlock. // Determine if the expression has memory space information
return getMemoryBlock(expression, context, null); 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) /* (non-Javadoc)
@ -131,6 +152,17 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
return null; 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) // The block start address (supports 64-bit processors)
BigInteger blockAddress; BigInteger blockAddress;
@ -177,7 +209,7 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
} }
// check for block address exceeding maximum allowed address value // 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); BigInteger endAddress = BigInteger.ONE.shiftLeft(addressSize*8).subtract(BigInteger.ONE);
if (endAddress.compareTo(blockAddress) < 0) { if (endAddress.compareTo(blockAddress) < 0) {
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, 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, * same memory block, a trip to the target could result. However,
* the memory request cache should save the day. * 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 // default decoding
final String memorySpaceID;
final String expression;
int index = str.indexOf(':'); int index = str.indexOf(':');
if (index == -1) { 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() { return new DecodeResult() {
@Override @Override
public String getMemorySpaceId() { return memorySpaceID; } public String getMemorySpaceId() { return memorySpaceID; }
@ -299,6 +336,67 @@ 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() { ServiceTracker<IMemorySpaces, IMemorySpaces> getMemorySpaceServiceTracker() {
return fMemorySpaceServiceTracker; return fMemorySpaceServiceTracker;
} }
@ -377,11 +475,19 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
if (memorySpaceID.length() == 0) { if (memorySpaceID.length() == 0) {
memorySpaceID = null; memorySpaceID = null;
assert false : "should have either no memory space or a valid (non-empty) ID"; //$NON-NLS-1$ 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); 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); blocks.add(block);
} }
} }
@ -402,38 +508,22 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
return false; return false;
} }
private int getAddressableSize(IMemoryDMContext aContext, String memorySpaceID) { private int getAddressableSize(IMemoryDMContext context) {
IGDBMemory2 memoryService = (IGDBMemory2) getServiceTracker() IGDBMemory2 memoryService = (IGDBMemory2) getServiceTracker()
.getService(); .getService();
if (memoryService != null && aContext != null) { if (memoryService != null && context != null) {
IMemoryDMContext context = resolveMemSpaceContext(aContext, memorySpaceID);
return memoryService.getAddressableSize(context); return memoryService.getAddressableSize(context);
} }
return super.getAddressableSize(); return super.getAddressableSize();
} }
private int getAddressSize(IMemoryDMContext context) {
private int getAddressSize(IMemoryDMContext aContext, String memorySpaceID) {
IGDBMemory memoryService = (IGDBMemory)getServiceTracker().getService(); IGDBMemory memoryService = (IGDBMemory)getServiceTracker().getService();
if (memoryService != null && aContext != null) { if (memoryService != null && context != null) {
IMemoryDMContext context = resolveMemSpaceContext(aContext, memorySpaceID);
return memoryService.getAddressSize(context); return memoryService.getAddressSize(context);
} }
return super.getAddressSize(); 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;
}
} }

View file

@ -430,11 +430,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Event handlers // 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 @DsfServiceEventHandler
public void eventDispatched(IResumedDMEvent e) { public void eventDispatched(IResumedDMEvent e) {
if (e instanceof IContainerResumedDMEvent) { 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 @DsfServiceEventHandler
public void eventDispatched(ISuspendedDMEvent e) { public void eventDispatched(ISuspendedDMEvent e) {
if (e instanceof IContainerSuspendedDMEvent) { if (e instanceof IContainerSuspendedDMEvent) {

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -14,6 +14,8 @@
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121) * 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) * 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) * 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; package org.eclipse.cdt.dsf.mi.service;
@ -586,7 +588,7 @@ public class MIVariableManager implements ICommandControl {
*/ */
public void setType(String newTypeName) { public void setType(String newTypeName) {
type = newTypeName; type = newTypeName;
gdbType = fGDBTypeParser.parse(newTypeName); gdbType = getGDBTypeParser().parse(newTypeName);
} }
public void setValue(String format, String val) { valueMap.put(format, val); } public void setValue(String format, String val) { valueMap.put(format, val); }
@ -2542,10 +2544,7 @@ public class MIVariableManager implements ICommandControl {
} }
} }
/** private GDBTypeParser fGDBTypeParser = null;
* @since 3.0
*/
private static final GDBTypeParser fGDBTypeParser = new GDBTypeParser();
private final DsfSession fSession; private final DsfSession fSession;
@ -2620,6 +2619,13 @@ public class MIVariableManager implements ICommandControl {
return lruVariableList; return lruVariableList;
} }
private GDBTypeParser getGDBTypeParser() {
if (fGDBTypeParser == null) {
fGDBTypeParser = createGDBTypeParser();
}
return fGDBTypeParser;
}
/** /**
* This method returns a variable object based on the specified * This method returns a variable object based on the specified
* ExpressionDMC, creating it in GDB if it was not created already. * ExpressionDMC, creating it in GDB if it was not created already.
@ -3172,4 +3178,12 @@ public class MIVariableManager implements ICommandControl {
protected boolean needFixForGDBBug320277() { protected boolean needFixForGDBBug320277() {
return true; return true;
} }
/**
* @since 4.4
*/
protected GDBTypeParser createGDBTypeParser() {
return new GDBTypeParser();
}
} }

View file

@ -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);
}