mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 426730: [Memory] Support 16 bit addressable size
Change-Id: I1fa5498eebe66cc6febbfaf72c4e433bdfab48ed Signed-off-by: Alvaro Sanchez-Leon <alvsan09@gmail.com> Reviewed-on: https://git.eclipse.org/r/22118 Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com> IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com> Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
This commit is contained in:
parent
0b2adb5223
commit
e49589af70
16 changed files with 590 additions and 280 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, Texas Instruments, Freescale Semiconductor and others.
|
||||
* Copyright (c) 2010, 2014 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
||||
|
||||
|
@ -117,12 +118,12 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
* asynchronous calls to complete before returning.
|
||||
*
|
||||
* @param bigAddress
|
||||
* @param length
|
||||
* @return MemoryByte[]
|
||||
* @param count - The number of addressable units for this block
|
||||
* @return MemoryByte[]
|
||||
* @throws DebugException
|
||||
*/
|
||||
@Override
|
||||
protected MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long length) throws DebugException {
|
||||
protected MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long count) throws DebugException {
|
||||
|
||||
// For the IAddress interface
|
||||
final Addr64 address = new Addr64(bigAddress);
|
||||
|
@ -159,7 +160,7 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.getMemory(
|
||||
context, address, 0, addressableSize, (int) length,
|
||||
context, address, 0, addressableSize, (int) count,
|
||||
//getContext(), address, 0, addressableSize, (int) length,
|
||||
new DataRequestMonitor<MemoryByte[]>(retrieval.getExecutor(), drm) {
|
||||
@Override
|
||||
|
@ -206,6 +207,12 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
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;
|
||||
|
@ -227,7 +234,7 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.setMemory(
|
||||
context, address, offset, addressableSize, bytes.length, bytes,
|
||||
context, address, offset, addressableSize, addressableUnits, bytes,
|
||||
new RequestMonitor(retrieval.getExecutor(), drm));
|
||||
}
|
||||
else {
|
||||
|
@ -293,7 +300,7 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
|||
|
||||
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(ISuspendedDMEvent e) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, 2013 Texas Instruments, Freescale Semiconductor and others.
|
||||
* Copyright (c) 2010, 2014 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* 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)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
||||
|
||||
|
@ -26,6 +27,8 @@ 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.gdb.internal.memory.GdbMemoryBlock.MemorySpaceDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory2;
|
||||
import org.eclipse.cdt.dsf.service.DsfServices;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -181,7 +184,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(), 0, memorySpaceID);
|
||||
return new GdbMemoryBlock(this, memoryDmc, getModelId(), expression, blockAddress, getAddressableSize(memoryDmc, memorySpaceID), 0, memorySpaceID);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -363,7 +366,7 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
}
|
||||
|
||||
BigInteger blockAddress = new BigInteger(address);
|
||||
DsfMemoryBlock block = new GdbMemoryBlock(this, memoryCtx, getModelId(), label, blockAddress, getAddressableSize(), 0, memorySpaceID);
|
||||
DsfMemoryBlock block = new GdbMemoryBlock(this, memoryCtx, getModelId(), label, blockAddress, getAddressableSize(memoryCtx, memorySpaceID), 0, memorySpaceID);
|
||||
blocks.add(block);
|
||||
}
|
||||
}
|
||||
|
@ -383,4 +386,29 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getAddressableSize(IMemoryDMContext aContext, String memorySpaceID) {
|
||||
IGDBMemory2 memoryService = (IGDBMemory2) getServiceTracker()
|
||||
.getService();
|
||||
|
||||
if (memoryService != null && aContext != null) {
|
||||
IMemoryDMContext context = resolveMemSpaceContext(aContext, memorySpaceID);
|
||||
return memoryService.getAddressableSize(context);
|
||||
}
|
||||
|
||||
return super.getAddressableSize();
|
||||
}
|
||||
|
||||
private IMemoryDMContext resolveMemSpaceContext(IMemoryDMContext aContext, String aMemorySpaceID) {
|
||||
IMemoryDMContext context = aContext;
|
||||
if (aMemorySpaceID != null && aMemorySpaceID.length() > 0) {
|
||||
IMemorySpaces memorySpacesService = (IMemorySpaces) getMemorySpaceServiceTracker().getService();
|
||||
if (memorySpacesService != null) {
|
||||
context = new MemorySpaceDMContext(memorySpacesService.getSession().getId(), aMemorySpaceID, aContext);
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Mentor Graphics and others.
|
||||
* Copyright (c) 2013, 2014 Mentor Graphics 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
|
||||
|
@ -9,6 +9,7 @@
|
|||
* Mentor Graphics - Initial API and implementation
|
||||
* John Dallaway - Add methods to get the endianness and address size (Bug 225609)
|
||||
* Philippe Gil (AdaCore) - Switch to c language when getting sizeof(void *) when required (Bug 421541)
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
|
@ -35,6 +36,7 @@ import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
|||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIMemory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressableSizeInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIShowEndianInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataEvaluateExpressionInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowLanguageInfo;
|
||||
|
@ -48,7 +50,7 @@ import org.eclipse.debug.core.model.MemoryByte;
|
|||
/**
|
||||
* @since 4.2
|
||||
*/
|
||||
public class GDBMemory extends MIMemory implements IGDBMemory {
|
||||
public class GDBMemory extends MIMemory implements IGDBMemory2 {
|
||||
|
||||
private IGDBControl fCommandControl;
|
||||
|
||||
|
@ -57,6 +59,11 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
*/
|
||||
private Map<IMemoryDMContext, Integer> fAddressSizes = new HashMap<IMemoryDMContext, Integer>();
|
||||
|
||||
/**
|
||||
* Cache of the addressable sizes for each memory context.
|
||||
*/
|
||||
private Map<IMemoryDMContext, Integer> fAddressableSizes = new HashMap<IMemoryDMContext, Integer>();
|
||||
|
||||
/**
|
||||
* We assume the endianness is the same for all processes because GDB supports only one target.
|
||||
*/
|
||||
|
@ -84,6 +91,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
IMemory.class.getName(),
|
||||
MIMemory.class.getName(),
|
||||
IGDBMemory.class.getName(),
|
||||
IGDBMemory2.class.getName(),
|
||||
GDBMemory.class.getName(),
|
||||
},
|
||||
new Hashtable<String, String>());
|
||||
|
@ -94,19 +102,20 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
public void shutdown(RequestMonitor requestMonitor) {
|
||||
unregister();
|
||||
getSession().removeServiceEventListener(this);
|
||||
fAddressableSizes.clear();
|
||||
fAddressSizes.clear();
|
||||
super.shutdown(requestMonitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readMemoryBlock(final IDMContext dmc, IAddress address,
|
||||
long offset, int word_size, int count, final DataRequestMonitor<MemoryByte[]> drm) {
|
||||
long offset, int word_size, int word_count, final DataRequestMonitor<MemoryByte[]> drm) {
|
||||
super.readMemoryBlock(
|
||||
dmc,
|
||||
address,
|
||||
offset,
|
||||
word_size,
|
||||
count,
|
||||
word_count,
|
||||
new DataRequestMonitor<MemoryByte[]>(ImmediateExecutor.getInstance(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -134,78 +143,88 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
|
||||
// Need a global here as getSteps() can be called more than once.
|
||||
private Step[] steps = null;
|
||||
|
||||
private void determineSteps()
|
||||
{
|
||||
ArrayList<Step> stepsList = new ArrayList<Step>();
|
||||
|
||||
|
||||
if (fAddressSizes.get(memContext) == null) {
|
||||
stepsList.add(
|
||||
new Step() {
|
||||
// store original language
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
fCommandControl.queueCommand(
|
||||
fCommandControl.getCommandFactory().createMIGDBShowLanguage(memContext),
|
||||
new ImmediateDataRequestMonitor<MIGDBShowLanguageInfo>(requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
originalLanguage = getData().getLanguage();
|
||||
} else {
|
||||
abortLanguageSteps = true;
|
||||
}
|
||||
requestMonitor.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
stepsList.add(
|
||||
new Step() {
|
||||
// switch to c language
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
if (abortLanguageSteps) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fCommandControl.queueCommand(
|
||||
fCommandControl.getCommandFactory().createMIGDBSetLanguage(memContext, MIGDBShowLanguageInfo.C),
|
||||
new ImmediateDataRequestMonitor<MIInfo>(requestMonitor) {
|
||||
new Step() {
|
||||
// store original language
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
fCommandControl.queueCommand(
|
||||
fCommandControl.getCommandFactory().createMIGDBShowLanguage(memContext),
|
||||
new ImmediateDataRequestMonitor<MIGDBShowLanguageInfo>(requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
if (isSuccess()) {
|
||||
originalLanguage = getData().getLanguage();
|
||||
} else {
|
||||
abortLanguageSteps = true;
|
||||
}
|
||||
// Accept failure
|
||||
requestMonitor.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
stepsList.add(
|
||||
new Step() {
|
||||
// read address size
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
// Run this step even if the language commands where aborted, but accept failures.
|
||||
readAddressSize(
|
||||
memContext,
|
||||
new ImmediateDataRequestMonitor<Integer>(requestMonitor) {
|
||||
new Step() {
|
||||
// switch to c language
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
if (abortLanguageSteps) {
|
||||
requestMonitor.done();
|
||||
return;
|
||||
}
|
||||
|
||||
fCommandControl.queueCommand(
|
||||
fCommandControl.getCommandFactory().createMIGDBSetLanguage(memContext, MIGDBShowLanguageInfo.C),
|
||||
new ImmediateDataRequestMonitor<MIInfo>(requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
abortLanguageSteps = true;
|
||||
}
|
||||
// Accept failure
|
||||
requestMonitor.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
stepsList.add(new Step() {
|
||||
// Run this step even if the language commands where aborted, but accept failures.
|
||||
// Resolve Addressable and Address size
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
//Read Minimum addressable memory size and actual address size
|
||||
readAddressableSize(memContext, new ImmediateDataRequestMonitor<Integer>(requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
final Integer minAddressableInOctets = getData();
|
||||
//Preserve the addressable size per context
|
||||
fAddressableSizes.put(memContext, minAddressableInOctets);
|
||||
}
|
||||
|
||||
readAddressSize(memContext, new ImmediateDataRequestMonitor<Integer>(requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
//Preserve the address size per context
|
||||
fAddressSizes.put(memContext, getData());
|
||||
}
|
||||
// Accept failure
|
||||
|
||||
// Accept failures
|
||||
requestMonitor.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
stepsList.add(
|
||||
new Step() {
|
||||
// restore original language
|
||||
|
@ -250,8 +269,8 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fIsBigEndian == null) {
|
||||
stepsList.add(
|
||||
|
@ -283,7 +302,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
if (steps == null) {
|
||||
determineSteps();
|
||||
}
|
||||
|
||||
|
||||
return steps;
|
||||
}
|
||||
});
|
||||
|
@ -295,6 +314,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
IMemoryDMContext context = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class);
|
||||
if (context != null) {
|
||||
fAddressSizes.remove(context);
|
||||
fAddressableSizes.remove(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +325,15 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
return (addressSize != null) ? addressSize.intValue() : 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
@Override
|
||||
public int getAddressableSize(IMemoryDMContext context) {
|
||||
Integer addressableSize = fAddressableSizes.get(context);
|
||||
return (addressableSize != null) ? addressableSize.intValue() : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBigEndian(IMemoryDMContext context) {
|
||||
assert fIsBigEndian != null;
|
||||
|
@ -335,6 +364,33 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum addressable size is determined by the space used to store a "char" on a target system
|
||||
* This is then resolved by retrieving a hex representation of -1 casted to the size of a "char"
|
||||
* e.g. from GDB command line
|
||||
* > p/x (char)-1
|
||||
* > $7 = 0xffff
|
||||
*
|
||||
* Since two hex characters are representing one octet, for the above example this method should return 2
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
protected void readAddressableSize(IMemoryDMContext memContext, final DataRequestMonitor<Integer> drm) {
|
||||
//We use a CLI command here instead of the expression services, since the target may not be available
|
||||
//e.g. when using a remote launch.
|
||||
// Using MI directly is a possibility although there is no way to specify the required output format to hex.
|
||||
CommandFactory commandFactory = fCommandControl.getCommandFactory();
|
||||
fCommandControl.queueCommand(
|
||||
commandFactory.createCLIAddressableSize(memContext),
|
||||
new DataRequestMonitor<CLIAddressableSizeInfo>(ImmediateExecutor.getInstance(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
drm.setData(Integer.valueOf(getData().getAddressableSize()));
|
||||
drm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void readEndianness(IMemoryDMContext memContext, final DataRequestMonitor<Boolean> drm) {
|
||||
CommandFactory commandFactory = fCommandControl.getCommandFactory();
|
||||
fCommandControl.queueCommand(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2010 Ericsson and others.
|
||||
* Copyright (c) 2008, 2014 Ericsson 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,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
|
@ -50,6 +51,7 @@ public class GDBMemory_7_0 extends GDBMemory {
|
|||
MIMemory.class.getName(),
|
||||
IMemory.class.getName(),
|
||||
IGDBMemory.class.getName(),
|
||||
IGDBMemory2.class.getName(),
|
||||
GDBMemory.class.getName(),
|
||||
GDBMemory_7_0.class.getName()
|
||||
},
|
||||
|
@ -66,7 +68,7 @@ public class GDBMemory_7_0 extends GDBMemory {
|
|||
|
||||
@Override
|
||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, long offset,
|
||||
int word_size, int count, DataRequestMonitor<MemoryByte[]> drm)
|
||||
int word_size, int word_count, DataRequestMonitor<MemoryByte[]> drm)
|
||||
{
|
||||
IDMContext threadOrMemoryDmc = dmc;
|
||||
|
||||
|
@ -103,12 +105,12 @@ public class GDBMemory_7_0 extends GDBMemory {
|
|||
}
|
||||
}
|
||||
|
||||
super.readMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, drm);
|
||||
super.readMemoryBlock(threadOrMemoryDmc, address, offset, word_size, word_count, drm);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeMemoryBlock(IDMContext dmc, IAddress address, long offset,
|
||||
int word_size, int count, byte[] buffer, RequestMonitor rm)
|
||||
int word_size, int word_count, byte[] buffer, RequestMonitor rm)
|
||||
{
|
||||
IDMContext threadOrMemoryDmc = dmc;
|
||||
|
||||
|
@ -145,6 +147,6 @@ public class GDBMemory_7_0 extends GDBMemory {
|
|||
}
|
||||
}
|
||||
|
||||
super.writeMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, buffer, rm);
|
||||
super.writeMemoryBlock(threadOrMemoryDmc, address, offset, word_size, word_count, buffer, rm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2013 Ericsson and others.
|
||||
* Copyright (c) 2013, 2014 Ericsson 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,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Marc Khouzam (Ericsson) - initial API and implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
|
@ -62,6 +63,7 @@ public class GDBMemory_7_6 extends GDBMemory_7_0 implements IEventListener {
|
|||
register(new String[] { MIMemory.class.getName(),
|
||||
IMemory.class.getName(),
|
||||
IGDBMemory.class.getName(),
|
||||
IGDBMemory2.class.getName(),
|
||||
GDBMemory.class.getName(),
|
||||
GDBMemory_7_0.class.getName(),
|
||||
GDBMemory_7_6.class.getName()},
|
||||
|
@ -140,8 +142,9 @@ public class GDBMemory_7_6 extends GDBMemory_7_0 implements IEventListener {
|
|||
// Now refresh our memory cache, it case it contained this address. Don't have
|
||||
// it send the potential IMemoryChangedEvent as we will send it ourselves (see below).
|
||||
final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(containerDmc, IMemoryDMContext.class);
|
||||
|
||||
final IAddress address = new Addr64(addr);
|
||||
getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, 1, count, false,
|
||||
getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, getAddressableSize(memoryDMC), count, false,
|
||||
new RequestMonitor(getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 Ericsson 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:
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
|
||||
/**
|
||||
* Extension interface to provide access to the addressable size of a memory context
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
public interface IGDBMemory2 extends IGDBMemory {
|
||||
|
||||
/**
|
||||
* Returns the addressable size (in octets) of the memory specified by the given context
|
||||
*/
|
||||
public int getAddressableSize(IMemoryDMContext context);
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2010 Wind River Systems and others.
|
||||
* Copyright (c) 2007, 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
|
||||
|
@ -13,6 +13,7 @@
|
|||
* Vladimir Prus (CodeSourcery) - support for -data-read-memory-bytes (bug 322658)
|
||||
* John Dallaway - support for -data-write-memory-bytes (bug 387793)
|
||||
* John Dallaway - memory cache update fix (bug 387688)
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
|
@ -68,6 +69,8 @@ import org.osgi.framework.BundleContext;
|
|||
public class MIMemory extends AbstractDsfService implements IMemory, ICachingService {
|
||||
|
||||
private static final String READ_MEMORY_BYTES_FEATURE = "data-read-memory-bytes"; //$NON-NLS-1$
|
||||
//data-read-memory write is deprecated, its description could be ambiguous for e.g. 16 bit addressable systems
|
||||
private static final String DATA_WRITE_MEMORY_16_NOT_SUPPORTED = "data-write-memory with word-size != 1 not supported"; //$NON-NLS-1$
|
||||
|
||||
public class MemoryChangedEvent extends AbstractDMEvent<IMemoryDMContext>
|
||||
implements IMemoryChangedEvent
|
||||
|
@ -120,9 +123,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
|
||||
*
|
||||
* This function is called during the launch sequence (where the service is
|
||||
* instantiated). See LaunchSequence.java.
|
||||
*/
|
||||
@Override
|
||||
public void initialize(final RequestMonitor requestMonitor) {
|
||||
|
@ -134,16 +134,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization function:
|
||||
* - Register the service
|
||||
* - Create the command cache
|
||||
* - Register self to service events
|
||||
*
|
||||
* @param requestMonitor
|
||||
*/
|
||||
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||
// Create the command cache
|
||||
IGDBControl commandControl = getServicesTracker().getService(IGDBControl.class);
|
||||
BufferedCommandControl bufferedCommandControl = new BufferedCommandControl(commandControl, getExecutor(), 2);
|
||||
|
||||
|
@ -162,16 +153,12 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
fCommandCache = new CommandCache(getSession(), bufferedCommandControl);
|
||||
fCommandCache.setContextAvailable(commandControl.getContext(), true);
|
||||
|
||||
// Register this service
|
||||
register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
|
||||
|
||||
// Create the memory requests cache
|
||||
fMemoryCaches = new HashMap<IMemoryDMContext, MIMemoryCache>();
|
||||
|
||||
// Register as service event listener
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
||||
// Done
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
|
@ -181,13 +168,10 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
@Override
|
||||
public void shutdown(final RequestMonitor requestMonitor) {
|
||||
|
||||
// Unregister this service
|
||||
unregister();
|
||||
|
||||
// Remove event listener
|
||||
getSession().removeServiceEventListener(this);
|
||||
|
||||
// Complete the shutdown
|
||||
super.shutdown(requestMonitor);
|
||||
}
|
||||
|
||||
|
@ -208,32 +192,27 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
*/
|
||||
@Override
|
||||
public void getMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
|
||||
int word_size, int count, DataRequestMonitor<MemoryByte[]> drm)
|
||||
int word_size, int word_count, DataRequestMonitor<MemoryByte[]> drm)
|
||||
{
|
||||
// Validate the context
|
||||
if (memoryDMC == null) {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the word size
|
||||
// NOTE: We only accept 1 byte words for this implementation
|
||||
if (word_size != 1) {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$
|
||||
if (word_size < 1) {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (< 1)", null)); //$NON-NLS-1$
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the byte count
|
||||
if (count < 0) {
|
||||
if (word_count < 0) {
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// All is clear: go for it
|
||||
getMemoryCache(memoryDMC).getMemory(memoryDMC, address.add(offset), word_size, count, drm);
|
||||
getMemoryCache(memoryDMC).getMemory(memoryDMC, address.add(offset), word_size, word_count, drm);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -241,39 +220,33 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
*/
|
||||
@Override
|
||||
public void setMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
|
||||
int word_size, int count, byte[] buffer, RequestMonitor rm)
|
||||
int word_size, int word_count, byte[] buffer, RequestMonitor rm)
|
||||
{
|
||||
// Validate the context
|
||||
if (memoryDMC == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the word size
|
||||
// NOTE: We only accept 1 byte words for this implementation
|
||||
if (word_size != 1) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$
|
||||
if (word_size < 1) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (< 1)", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the byte count
|
||||
if (count < 0) {
|
||||
if (word_count < 0) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the buffer size
|
||||
if (buffer.length < count) {
|
||||
if (buffer.length < word_count * word_size) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Buffer too short", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// All is clear: go for it
|
||||
getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, count, buffer, rm);
|
||||
getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, word_count, buffer, rm);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -283,29 +256,24 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
public void fillMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
|
||||
int word_size, int count, byte[] pattern, RequestMonitor rm)
|
||||
{
|
||||
// Validate the context
|
||||
if (memoryDMC == null) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the word size
|
||||
// NOTE: We only accept 1 byte words for this implementation
|
||||
if (word_size != 1) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$
|
||||
if (word_size < 1) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (< 1)", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the repeat count
|
||||
if (count < 0) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid repeat count (< 0)", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the pattern
|
||||
if (pattern.length < 1) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Empty pattern", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
|
@ -319,8 +287,13 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
System.arraycopy(pattern, 0, buffer, i * length, length);
|
||||
}
|
||||
|
||||
int word_count = buffer.length / word_size;
|
||||
if (buffer.length % word_size != 0) {
|
||||
word_count ++;
|
||||
}
|
||||
|
||||
// All is clear: go for it
|
||||
getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, count * length, buffer, rm);
|
||||
getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, word_count, buffer, rm);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
@ -332,17 +305,17 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param address
|
||||
* @param offset
|
||||
* @param word_size
|
||||
* @param count
|
||||
* @param word_count in addressable units
|
||||
* @param drm
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
|
||||
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||
final int word_size, final int word_count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||
{
|
||||
if (fDataReadMemoryBytes) {
|
||||
fCommandCache.execute(
|
||||
fCommandFactory.createMIDataReadMemoryBytes(dmc, address.toString(), offset*word_size, count*word_size),
|
||||
fCommandFactory.createMIDataReadMemoryBytes(dmc, address.toString(), offset, word_count, word_size),
|
||||
new DataRequestMonitor<MIDataReadMemoryBytesInfo>(getExecutor(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -352,17 +325,27 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
}
|
||||
@Override
|
||||
protected void handleFailure() {
|
||||
drm.setData(createInvalidBlock(word_size * count));
|
||||
drm.setData(createInvalidBlock(word_size * word_count));
|
||||
drm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (word_size != 1) {
|
||||
//The word-size is specified within the resulting command data-read-memory
|
||||
//The word-size is defined in bytes although in the MI interface it's not clear if the meaning is
|
||||
//octets or system dependent bytes (minimum addressable memory).
|
||||
//As this command is deprecated there is no good reason to augment the support for word sizes != 1
|
||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, DATA_WRITE_MEMORY_16_NOT_SUPPORTED, null));
|
||||
drm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
/* To simplify the parsing of the MI result, we request the output to
|
||||
* be on 1 row of [count] columns, no char interpretation.
|
||||
*/
|
||||
int mode = MIFormat.HEXADECIMAL;
|
||||
int nb_rows = 1;
|
||||
int nb_cols = count;
|
||||
int nb_cols = word_count;
|
||||
Character asChar = null;
|
||||
|
||||
fCommandCache.execute(
|
||||
|
@ -376,7 +359,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
}
|
||||
@Override
|
||||
protected void handleFailure() {
|
||||
drm.setData(createInvalidBlock(word_size * count));
|
||||
drm.setData(createInvalidBlock(word_size * word_count));
|
||||
drm.done();
|
||||
}
|
||||
}
|
||||
|
@ -397,34 +380,44 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param address
|
||||
* @param offset
|
||||
* @param word_size
|
||||
* @param count
|
||||
* @param word_count in addressable units
|
||||
* @param buffer
|
||||
* @param rm
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
|
||||
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
|
||||
final int word_size, final int word_count, final byte[] buffer, final RequestMonitor rm)
|
||||
{
|
||||
if (fDataReadMemoryBytes) {
|
||||
// Use -data-write-memory-bytes for performance
|
||||
// Use -data-write-memory-bytes for performance,
|
||||
fCommandCache.execute(
|
||||
fCommandFactory.createMIDataWriteMemoryBytes(dmc, address.add(offset).toString(),
|
||||
(buffer.length == count) ? buffer : Arrays.copyOf(buffer, count)),
|
||||
(buffer.length == word_count*word_size) ? buffer : Arrays.copyOf(buffer, word_count*word_size)),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm)
|
||||
);
|
||||
} else {
|
||||
if (word_size != 1) {
|
||||
//The word-size is specified within the resulting command data-write-memory
|
||||
//The word-size is defined in bytes although in the MI interface it's not clear if the meaning is
|
||||
//octets or system dependent bytes (minimum addressable memory).
|
||||
//As this command is deprecated there is no good reason to augment the support for word sizes != 1
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, DATA_WRITE_MEMORY_16_NOT_SUPPORTED, null));
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Each byte is written individually (GDB power...)
|
||||
// so we need to keep track of the count
|
||||
final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
|
||||
countingRM.setDoneCount(count);
|
||||
countingRM.setDoneCount(word_count);
|
||||
|
||||
// We will format the individual bytes in decimal
|
||||
int format = MIFormat.DECIMAL;
|
||||
String baseAddress = address.toString();
|
||||
|
||||
// Issue an MI request for each byte to write
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int i = 0; i < word_count; i++) {
|
||||
String value = new Byte(buffer[i]).toString();
|
||||
fCommandCache.execute(
|
||||
fCommandFactory.createMIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
|
||||
|
@ -528,7 +521,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
address = new Addr64(expAddress.getValue());
|
||||
|
||||
final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class);
|
||||
getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, 1, count, true,
|
||||
getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, getAddressableSize(memoryDMC), count, true,
|
||||
new RequestMonitor(getExecutor(), null));
|
||||
}
|
||||
}
|
||||
|
@ -536,6 +529,14 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default addressable size is set to 1 octet, to be overridden by sub-classes supporting different values
|
||||
* @since 4.4
|
||||
*/
|
||||
protected int getAddressableSize(IMemoryDMContext context) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// SortedLinkedlist
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -544,11 +545,16 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
// For simplicity, everything is public.
|
||||
private class MemoryBlock {
|
||||
public IAddress fAddress;
|
||||
public long fLength;
|
||||
public long fLengthInAddressableUnits;
|
||||
public long fLengthInOctets;
|
||||
public MemoryByte[] fBlock;
|
||||
public MemoryBlock(IAddress address, long length, MemoryByte[] block) {
|
||||
public MemoryBlock(IAddress address, long lengthInOctets, long lengthInAddressableUnits, MemoryByte[] block) {
|
||||
// A memory block is expected to be populated with the contents of a defined range of addresses
|
||||
// therefore the number of octets shall be divisible by the number of addresses
|
||||
assert (lengthInOctets % lengthInAddressableUnits == 0);
|
||||
fAddress = address;
|
||||
fLength = length;
|
||||
fLengthInAddressableUnits = lengthInAddressableUnits;
|
||||
fLengthInOctets = lengthInOctets;
|
||||
fBlock = block;
|
||||
}
|
||||
}
|
||||
|
@ -601,14 +607,15 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
// Case where the block is to be merged with the previous block
|
||||
if (index > 0) {
|
||||
MemoryBlock prevBlock = get(index - 1);
|
||||
IAddress endOfPreviousBlock = prevBlock.fAddress.add(prevBlock.fLength);
|
||||
IAddress endOfPreviousBlock = prevBlock.fAddress.add(prevBlock.fLengthInAddressableUnits);
|
||||
if (endOfPreviousBlock.distanceTo(newBlock.fAddress).longValue() == 0) {
|
||||
long newLength = prevBlock.fLength + newBlock.fLength;
|
||||
if (newLength <= Integer.MAX_VALUE) {
|
||||
MemoryByte[] block = new MemoryByte[(int) newLength] ;
|
||||
System.arraycopy(prevBlock.fBlock, 0, block, 0, (int) prevBlock.fLength);
|
||||
System.arraycopy(newBlock.fBlock, 0, block, (int) prevBlock.fLength, (int) newBlock.fLength);
|
||||
newBlock = new MemoryBlock(prevBlock.fAddress, newLength, block);
|
||||
long newLengthInOctets = prevBlock.fLengthInOctets + newBlock.fLengthInOctets;
|
||||
long newLengthInAddressableUnits = prevBlock.fLengthInAddressableUnits + newBlock.fLengthInAddressableUnits;
|
||||
if (newLengthInOctets <= Integer.MAX_VALUE) {
|
||||
MemoryByte[] block = new MemoryByte[(int) newLengthInOctets] ;
|
||||
System.arraycopy(prevBlock.fBlock, 0, block, 0, (int) prevBlock.fLengthInOctets);
|
||||
System.arraycopy(newBlock.fBlock, 0, block, (int) prevBlock.fLengthInOctets, (int) newBlock.fLengthInOctets);
|
||||
newBlock = new MemoryBlock(prevBlock.fAddress, newLengthInOctets, newLengthInAddressableUnits, block);
|
||||
remove(index);
|
||||
index -= 1;
|
||||
set(index, newBlock);
|
||||
|
@ -620,14 +627,15 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
int lastIndex = size() - 1;
|
||||
if (index < lastIndex) {
|
||||
MemoryBlock nextBlock = get(index + 1);
|
||||
IAddress endOfNewBlock = newBlock.fAddress.add(newBlock.fLength);
|
||||
IAddress endOfNewBlock = newBlock.fAddress.add(newBlock.fLengthInAddressableUnits);
|
||||
if (endOfNewBlock.distanceTo(nextBlock.fAddress).longValue() == 0) {
|
||||
long newLength = newBlock.fLength + nextBlock.fLength;
|
||||
long newLength = newBlock.fLengthInOctets + nextBlock.fLengthInOctets;
|
||||
long newAddressesLength = newBlock.fLengthInAddressableUnits + nextBlock.fLengthInAddressableUnits;
|
||||
if (newLength <= Integer.MAX_VALUE) {
|
||||
MemoryByte[] block = new MemoryByte[(int) newLength] ;
|
||||
System.arraycopy(newBlock.fBlock, 0, block, 0, (int) newBlock.fLength);
|
||||
System.arraycopy(nextBlock.fBlock, 0, block, (int) newBlock.fLength, (int) nextBlock.fLength);
|
||||
newBlock = new MemoryBlock(newBlock.fAddress, newLength, block);
|
||||
System.arraycopy(newBlock.fBlock, 0, block, 0, (int) newBlock.fLengthInOctets);
|
||||
System.arraycopy(nextBlock.fBlock, 0, block, (int) newBlock.fLengthInOctets, (int) nextBlock.fLengthInOctets);
|
||||
newBlock = new MemoryBlock(newBlock.fAddress, newLength, newAddressesLength, block);
|
||||
set(index, newBlock);
|
||||
remove(index + 1);
|
||||
}
|
||||
|
@ -712,28 +720,30 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @return A list of the sub-blocks to fetch in order to fill enough gaps in the memory cache
|
||||
* to service the request
|
||||
*/
|
||||
private LinkedList<MemoryBlock> getListOfMissingBlocks(IAddress reqBlockStart, int count) {
|
||||
private LinkedList<MemoryBlock> getListOfMissingBlocks(IAddress reqBlockStart, int word_count, int word_size) {
|
||||
int octetCount = word_count * word_size;
|
||||
|
||||
LinkedList<MemoryBlock> list = new LinkedList<MemoryBlock>();
|
||||
ListIterator<MemoryBlock> it = fMemoryBlockList.listIterator();
|
||||
|
||||
// Look for holes in the list of memory blocks
|
||||
while (it.hasNext() && count > 0) {
|
||||
while (it.hasNext() && octetCount > 0) {
|
||||
MemoryBlock cachedBlock = it.next();
|
||||
IAddress cachedBlockStart = cachedBlock.fAddress;
|
||||
IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength);
|
||||
IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLengthInAddressableUnits);
|
||||
|
||||
// Case where we miss a block before the cached block
|
||||
if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0) {
|
||||
int length = (int) Math.min(reqBlockStart.distanceTo(cachedBlockStart).longValue(), count);
|
||||
int lengthInOctets = (int) Math.min(reqBlockStart.distanceTo(cachedBlockStart).longValue()*word_size, octetCount);
|
||||
// If both blocks start at the same location, no need to create a new cached block
|
||||
if (length > 0) {
|
||||
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, length, new MemoryByte[0]);
|
||||
if (lengthInOctets > 0) {
|
||||
int lengthInAddressableUnits = lengthInOctets / word_size;
|
||||
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, lengthInOctets, lengthInAddressableUnits, new MemoryByte[0]);
|
||||
list.add(newBlock);
|
||||
}
|
||||
// Adjust request block start and length for the next iteration
|
||||
reqBlockStart = cachedBlockEnd;
|
||||
count -= length + cachedBlock.fLength;
|
||||
octetCount -= lengthInOctets + cachedBlock.fLengthInOctets;
|
||||
}
|
||||
|
||||
// Case where the requested block starts somewhere in the cached block
|
||||
|
@ -742,14 +752,15 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
{
|
||||
// Start of the requested block already in cache
|
||||
// Adjust request block start and length for the next iteration
|
||||
count -= reqBlockStart.distanceTo(cachedBlockEnd).longValue();
|
||||
octetCount -= reqBlockStart.distanceTo(cachedBlockEnd).longValue()*word_size;
|
||||
reqBlockStart = cachedBlockEnd;
|
||||
}
|
||||
}
|
||||
|
||||
// Case where we miss a block at the end of the cache
|
||||
if (count > 0) {
|
||||
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, count, new MemoryByte[0]);
|
||||
if (octetCount > 0) {
|
||||
int addressesLength = octetCount / word_size;
|
||||
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, octetCount, addressesLength, new MemoryByte[0]);
|
||||
list.add(newBlock);
|
||||
}
|
||||
|
||||
|
@ -782,22 +793,23 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param count Its length
|
||||
* @return The cached memory content
|
||||
*/
|
||||
private MemoryByte[] getMemoryBlockFromCache(IAddress reqBlockStart, int count) {
|
||||
|
||||
IAddress reqBlockEnd = reqBlockStart.add(count);
|
||||
private MemoryByte[] getMemoryBlockFromCache(IAddress reqBlockStart, int word_count, int word_size) {
|
||||
int count = word_count * word_size;
|
||||
|
||||
IAddress reqBlockEnd = reqBlockStart.add(word_count);
|
||||
MemoryByte[] resultBlock = new MemoryByte[count];
|
||||
ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
MemoryBlock cachedBlock = iter.next();
|
||||
IAddress cachedBlockStart = cachedBlock.fAddress;
|
||||
IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength);
|
||||
IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLengthInAddressableUnits);
|
||||
|
||||
// Case where the cached block overlaps completely the requested memory block
|
||||
if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0
|
||||
&& reqBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
|
||||
{
|
||||
int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue();
|
||||
int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue() * word_size;
|
||||
System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, count);
|
||||
}
|
||||
|
||||
|
@ -805,8 +817,8 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
else if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0
|
||||
&& cachedBlockStart.distanceTo(reqBlockEnd).longValue() > 0)
|
||||
{
|
||||
int pos = (int) reqBlockStart.distanceTo(cachedBlockStart).longValue();
|
||||
int length = (int) Math.min(cachedBlock.fLength, count - pos);
|
||||
int pos = (int) reqBlockStart.distanceTo(cachedBlockStart).longValue() * word_size;
|
||||
int length = (int) Math.min(cachedBlock.fLengthInOctets, count - pos);
|
||||
System.arraycopy(cachedBlock.fBlock, 0, resultBlock, pos, length);
|
||||
}
|
||||
|
||||
|
@ -814,8 +826,8 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0
|
||||
&& reqBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
|
||||
{
|
||||
int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue();
|
||||
int length = (int) Math.min(cachedBlock.fLength - pos, count);
|
||||
int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue() * word_size;
|
||||
int length = (int) Math.min(cachedBlock.fLengthInOctets - pos, count);
|
||||
System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, length);
|
||||
}
|
||||
}
|
||||
|
@ -827,18 +839,19 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* the content with the actual memory just read from the target.
|
||||
*
|
||||
* @param modBlockStart
|
||||
* @param count
|
||||
* @param word_count - Number of addressable units
|
||||
* @param modBlock
|
||||
* @param word_size - Number of octets per addressable unit
|
||||
*/
|
||||
private void updateMemoryCache(IAddress modBlockStart, int count, MemoryByte[] modBlock) {
|
||||
|
||||
IAddress modBlockEnd = modBlockStart.add(count);
|
||||
private void updateMemoryCache(IAddress modBlockStart, int word_count, MemoryByte[] modBlock, int word_size) {
|
||||
IAddress modBlockEnd = modBlockStart.add(word_count);
|
||||
ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
|
||||
int count = word_count * word_size;
|
||||
|
||||
while (iter.hasNext()) {
|
||||
MemoryBlock cachedBlock = iter.next();
|
||||
IAddress cachedBlockStart = cachedBlock.fAddress;
|
||||
IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLength);
|
||||
IAddress cachedBlockEnd = cachedBlock.fAddress.add(cachedBlock.fLengthInAddressableUnits);
|
||||
|
||||
// For now, we only bother to update bytes already cached.
|
||||
// Note: In a better implementation (v1.1), we would augment
|
||||
|
@ -850,7 +863,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0
|
||||
&& modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
|
||||
{
|
||||
int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue();
|
||||
int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue() * word_size;
|
||||
System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, count);
|
||||
}
|
||||
|
||||
|
@ -858,16 +871,16 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
else if (modBlockStart.distanceTo(cachedBlockStart).longValue() >= 0
|
||||
&& cachedBlockEnd.distanceTo(modBlockEnd).longValue() >= 0)
|
||||
{
|
||||
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue();
|
||||
System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, (int) cachedBlock.fLength);
|
||||
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue() * word_size;
|
||||
System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, (int) cachedBlock.fLengthInOctets);
|
||||
}
|
||||
|
||||
// Case where the beginning of the modified block is within the cached block
|
||||
else if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0
|
||||
&& modBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
|
||||
{
|
||||
int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue();
|
||||
int length = (int) modBlockStart.distanceTo(cachedBlockEnd).longValue();
|
||||
int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue() * word_size;
|
||||
int length = (int) modBlockStart.distanceTo(cachedBlockEnd).longValue() * word_size;
|
||||
System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, length);
|
||||
}
|
||||
|
||||
|
@ -875,8 +888,8 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
else if (cachedBlockStart.distanceTo(modBlockEnd).longValue() > 0
|
||||
&& modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
|
||||
{
|
||||
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue();
|
||||
int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue();
|
||||
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue() * word_size;
|
||||
int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue() * word_size;
|
||||
System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, length);
|
||||
}
|
||||
}
|
||||
|
@ -887,14 +900,14 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param memoryDMC
|
||||
* @param address the memory block address (on the target)
|
||||
* @param word_size the size, in bytes, of an addressable item
|
||||
* @param count the number of bytes to read
|
||||
* @param word_count the number of addressable units to read
|
||||
* @param drm the asynchronous data request monitor
|
||||
*/
|
||||
public void getMemory(IMemoryDMContext memoryDMC, final IAddress address, final int word_size,
|
||||
final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||
final int word_count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||
{
|
||||
// Determine the number of read requests to issue
|
||||
LinkedList<MemoryBlock> missingBlocks = getListOfMissingBlocks(address, count);
|
||||
LinkedList<MemoryBlock> missingBlocks = getListOfMissingBlocks(address, word_count, word_size);
|
||||
int numberOfRequests = missingBlocks.size();
|
||||
|
||||
// A read request will be issued for each block needed
|
||||
|
@ -904,7 +917,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
@Override
|
||||
protected void handleSuccess() {
|
||||
// We received everything so read the result from the memory cache
|
||||
drm.setData(getMemoryBlockFromCache(address, count));
|
||||
drm.setData(getMemoryBlockFromCache(address, word_count, word_size));
|
||||
drm.done();
|
||||
}
|
||||
};
|
||||
|
@ -914,14 +927,14 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
for (int i = 0; i < numberOfRequests; i++) {
|
||||
MemoryBlock block = missingBlocks.get(i);
|
||||
final IAddress startAddress = block.fAddress;
|
||||
final int length = (int) block.fLength;
|
||||
final int length = (int) block.fLengthInAddressableUnits;
|
||||
readMemoryBlock(memoryDMC, startAddress, 0, word_size, length,
|
||||
new DataRequestMonitor<MemoryByte[]>(getSession().getExecutor(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
MemoryByte[] block = new MemoryByte[count];
|
||||
block = getData();
|
||||
MemoryBlock memoryBlock = new MemoryBlock(startAddress, length, block);
|
||||
MemoryByte[] block = getData();
|
||||
int lenghtInaddressableUnits = block.length / word_size;
|
||||
MemoryBlock memoryBlock = new MemoryBlock(startAddress, block.length, lenghtInaddressableUnits, block);
|
||||
fMemoryBlockList.add(memoryBlock);
|
||||
countingRM.done();
|
||||
}
|
||||
|
@ -934,16 +947,16 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param address the memory block address (on the target)
|
||||
* @param offset the offset from the start address
|
||||
* @param word_size the size, in bytes, of an addressable item
|
||||
* @param count the number of bytes to write
|
||||
* @param word_count the number of addressable units to write
|
||||
* @param buffer the source buffer
|
||||
* @param rm the asynchronous request monitor
|
||||
*/
|
||||
public void setMemory(final IMemoryDMContext memoryDMC, final IAddress address,
|
||||
final long offset, final int word_size, final int count, final byte[] buffer,
|
||||
final long offset, final int word_size, final int word_count, final byte[] buffer,
|
||||
final RequestMonitor rm)
|
||||
{
|
||||
writeMemoryBlock(
|
||||
memoryDMC, address, offset, word_size, count, buffer,
|
||||
memoryDMC, address, offset, word_size, word_count, buffer,
|
||||
new RequestMonitor(getSession().getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -952,18 +965,17 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
fCommandCache.reset();
|
||||
|
||||
// Re-read the modified memory block to asynchronously update of the memory cache
|
||||
readMemoryBlock(memoryDMC, address, offset, word_size, count,
|
||||
readMemoryBlock(memoryDMC, address, offset, word_size, word_count,
|
||||
new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
updateMemoryCache(address.add(offset), count, getData());
|
||||
updateMemoryCache(address.add(offset), word_count, getData(), word_size);
|
||||
// Send the MemoryChangedEvent
|
||||
IAddress[] addresses = new IAddress[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
IAddress[] addresses = new IAddress[word_count];
|
||||
for (int i = 0; i < word_count; i++) {
|
||||
addresses[i] = address.add(offset + i);
|
||||
}
|
||||
getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties());
|
||||
// Finally...
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
|
@ -976,35 +988,35 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param address
|
||||
* @param offset
|
||||
* @param word_size
|
||||
* @param count
|
||||
* @param word_count
|
||||
* @param sendMemoryEvent Indicates if a IMemoryChangedEvent should be sent if the memory cache has changed.
|
||||
* @param rm
|
||||
*/
|
||||
public void refreshMemory(final IMemoryDMContext memoryDMC, final IAddress address,
|
||||
final long offset, final int word_size, final int count, final boolean sendMemoryEvent,
|
||||
final long offset, final int word_size, final int word_count, final boolean sendMemoryEvent,
|
||||
final RequestMonitor rm)
|
||||
{
|
||||
// Check if we already cache part of this memory area (which means it
|
||||
// is used by a memory service client that will have to be updated)
|
||||
LinkedList<MemoryBlock> list = getListOfMissingBlocks(address, count);
|
||||
LinkedList<MemoryBlock> list = getListOfMissingBlocks(address, word_count, word_size);
|
||||
int sizeToRead = 0;
|
||||
for (MemoryBlock block : list) {
|
||||
sizeToRead += block.fLength;
|
||||
sizeToRead += block.fLengthInAddressableUnits;
|
||||
}
|
||||
|
||||
// If none of the requested memory is in cache, just get out
|
||||
if (sizeToRead == count) {
|
||||
if (sizeToRead == word_count) {
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the corresponding memory block
|
||||
fCommandCache.reset();
|
||||
readMemoryBlock(memoryDMC, address, offset, word_size, count,
|
||||
readMemoryBlock(memoryDMC, address, offset, word_size, word_count,
|
||||
new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
MemoryByte[] oldBlock = getMemoryBlockFromCache(address, count);
|
||||
MemoryByte[] oldBlock = getMemoryBlockFromCache(address, word_count, word_size);
|
||||
MemoryByte[] newBlock = getData();
|
||||
boolean blocksDiffer = false;
|
||||
for (int i = 0; i < oldBlock.length; i++) {
|
||||
|
@ -1014,11 +1026,11 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
}
|
||||
}
|
||||
if (blocksDiffer) {
|
||||
updateMemoryCache(address.add(offset), count, newBlock);
|
||||
updateMemoryCache(address.add(offset), word_count, newBlock, word_size);
|
||||
if (sendMemoryEvent) {
|
||||
// Send the MemoryChangedEvent
|
||||
final IAddress[] addresses = new IAddress[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
final IAddress[] addresses = new IAddress[word_count];
|
||||
for (int i = 0; i < word_count; i++) {
|
||||
addresses[i] = address.add(offset + i);
|
||||
}
|
||||
getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2013 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2014 QNX Software 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
|
||||
|
@ -23,6 +23,7 @@
|
|||
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug (323552)
|
||||
* Philippe Gil (AdaCore) - Add show/set language CLI commands (Bug 421541)
|
||||
* Dmitry Kozlov (Mentor Graphics) - New trace-related methods (Bug 390827)
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command;
|
||||
|
@ -43,6 +44,7 @@ import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMContext;
|
|||
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAddressableSize;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIDetach;
|
||||
|
@ -178,6 +180,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarSetUpdateRange;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowAttributes;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressableSizeInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoBreakInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
|
||||
|
@ -198,11 +201,11 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIDataReadMemoryBytesInfo;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataReadMemoryInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataWriteMemoryInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowExitCodeInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowLanguageInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfoOsInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIListFeaturesInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowLanguageInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIStackInfoDepthInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIStackListArgumentsInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIStackListFramesInfo;
|
||||
|
@ -236,6 +239,13 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIVarUpdateInfo;
|
|||
*/
|
||||
public class CommandFactory {
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public ICommand<CLIAddressableSizeInfo> createCLIAddressableSize(IMemoryDMContext ctx) {
|
||||
return new CLIAddressableSize(ctx);
|
||||
}
|
||||
|
||||
public ICommand<MIInfo> createCLIAttach(IDMContext ctx, int pid) {
|
||||
return new CLIAttach(ctx, pid);
|
||||
}
|
||||
|
@ -475,6 +485,14 @@ public class CommandFactory {
|
|||
return new MIDataReadMemoryBytes(ctx, address, offset, num_bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public ICommand<MIDataReadMemoryBytesInfo> createMIDataReadMemoryBytes(IDMContext ctx, String address,
|
||||
long offset, int word_count, int word_size) {
|
||||
return new MIDataReadMemoryBytes(ctx, address, offset, word_count, word_size);
|
||||
}
|
||||
|
||||
public ICommand<MIDataWriteMemoryInfo> createMIDataWriteMemory(IDMContext ctx, long offset, String address,
|
||||
int wordFormat, int wordSize, String value) {
|
||||
return new MIDataWriteMemory(ctx, offset, address, wordFormat, wordSize, value);
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* 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:
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressableSizeInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
||||
|
||||
/**
|
||||
* <p>CLI command used to resolve the addressable size </p>
|
||||
* The minimum addressable size
|
||||
* is determined by the space used to store a "char" on a target system
|
||||
* <br>
|
||||
* This is
|
||||
* then resolved by retrieving a hex representation of -1 casted to the size of
|
||||
* a "char"
|
||||
* <br>
|
||||
* <br>E.g. from GDB command line
|
||||
* <br>
|
||||
* > p/x (char)-1 <br>
|
||||
* > $7 = 0xffff <br>
|
||||
*
|
||||
* <p>Since two hex characters are representing one octet, for the above example
|
||||
* this method should return 2</p>
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
public class CLIAddressableSize extends MIInterpreterExecConsole<CLIAddressableSizeInfo> {
|
||||
|
||||
private static final String hexOfBitsContainedInChar = "p/x (char)-1"; //$NON-NLS-1$
|
||||
|
||||
public CLIAddressableSize(IMemoryDMContext ctx) {
|
||||
super(ctx, hexOfBitsContainedInChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CLIAddressableSizeInfo getResult(MIOutput miResult) {
|
||||
return new CLIAddressableSizeInfo(miResult);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 CodeSourcery and others.
|
||||
* Copyright (c) 2010, 2014 CodeSourcery 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,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Vladimir Prus (CodeSourcery) - Initial API and implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
@ -26,10 +27,10 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
|||
* be quoted using the C convention.
|
||||
*
|
||||
* `COUNT'
|
||||
* The number of bytes to read. This should be an integer literal.
|
||||
* The number of addressable units to read. This should be an integer literal.
|
||||
*
|
||||
* `BYTE-OFFSET'
|
||||
* The offsets in bytes relative to ADDRESS at which to start
|
||||
* The offset in addressable units relative to ADDRESS at which to start
|
||||
* reading. This should be an integer literal. This option is
|
||||
* provided so that a frontend is not required to first evaluate
|
||||
* address and then perform address arithmetics itself.
|
||||
|
@ -37,23 +38,36 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
|||
*/
|
||||
public class MIDataReadMemoryBytes extends MICommand<MIDataReadMemoryBytesInfo> {
|
||||
|
||||
private int fSize;
|
||||
private static final int DEFAULT_ADDRESSABLE_SIZE = 1;
|
||||
private int fCount;
|
||||
private int fword_size;
|
||||
|
||||
public MIDataReadMemoryBytes(IDMContext ctx, String address, long offset,
|
||||
int num_bytes) {
|
||||
int count) {
|
||||
this(ctx, address, offset, count, DEFAULT_ADDRESSABLE_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param count - The number of addressable units to read from memory
|
||||
* @since 4.4
|
||||
*/
|
||||
public MIDataReadMemoryBytes(IDMContext ctx, String address, long offset,
|
||||
int count, int word_size) {
|
||||
super(ctx, "-data-read-memory-bytes"); //$NON-NLS-1$
|
||||
|
||||
fSize = num_bytes;
|
||||
fCount = count;
|
||||
fword_size = word_size;
|
||||
|
||||
if (offset != 0) {
|
||||
setOptions(new String[] { "-o", Long.toString(offset) }); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
setParameters(new String[] { address, Integer.toString(num_bytes) });
|
||||
setParameters(new String[] { address, Integer.toString(count) });
|
||||
}
|
||||
|
||||
@Override
|
||||
public MIDataReadMemoryBytesInfo getResult(MIOutput out) {
|
||||
return new MIDataReadMemoryBytesInfo(out, fSize);
|
||||
return new MIDataReadMemoryBytesInfo(out, fCount, fword_size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************
|
||||
* 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:
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
/**
|
||||
* This class takes care of parsing and providing the result of the CLI command
|
||||
* <br>"p/x (char)-1"
|
||||
*
|
||||
* <p>E.g. if the response to 'p/x (char)-1' is</p>
|
||||
* $n = 0xffff
|
||||
*
|
||||
* <p>Then we can easily resolve it to 2 octets (e.g. 2 hex characters per octet)</p>
|
||||
* @since 4.4
|
||||
*/
|
||||
public class CLIAddressableSizeInfo extends MIInfo {
|
||||
|
||||
private int fAddressableSize = 1;
|
||||
|
||||
public CLIAddressableSizeInfo(MIOutput record) {
|
||||
super(record);
|
||||
parse();
|
||||
}
|
||||
|
||||
protected void parse() {
|
||||
if (isDone()) {
|
||||
MIOutput out = getMIOutput();
|
||||
for (MIOOBRecord oob : out.getMIOOBRecords()) {
|
||||
if (oob instanceof MIConsoleStreamOutput) {
|
||||
String line = ((MIConsoleStreamOutput)oob).getString().trim();
|
||||
fAddressableSize = hexToOctetCount(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getAddressableSize() {
|
||||
return fAddressableSize;
|
||||
}
|
||||
|
||||
private int hexToOctetCount(String hexString) {
|
||||
//Receiving format is expected in hex form e.g. "$n = 0xffff" or "$n = 0xff"
|
||||
//which shall result in 2 and 1 octets respectively
|
||||
int starts = hexString.indexOf("x"); //$NON-NLS-1$
|
||||
assert(starts > 0);
|
||||
String hexDigits = hexString.substring(starts+1);
|
||||
assert hexDigits.length() > 1;
|
||||
int octets = hexDigits.length()/2;
|
||||
|
||||
return octets;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 CodeSourcery and others.
|
||||
* Copyright (c) 2010, 2014 CodeSourcery 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:
|
||||
* Vladimir Prus (CodeSourcery) - Initial API and implementation
|
||||
* Vladimir Prus (CodeSourcery) - Initial API and implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
@ -25,12 +26,25 @@ import org.eclipse.debug.core.model.MemoryByte;
|
|||
*/
|
||||
public class MIDataReadMemoryBytesInfo extends MIInfo {
|
||||
|
||||
/**
|
||||
* Default Addressable size in octets
|
||||
*/
|
||||
private static final int DEFAULT_WORD_SIZE = 1;
|
||||
/* The cached memory block. */
|
||||
private MemoryByte[] fBlock = null;
|
||||
|
||||
public MIDataReadMemoryBytesInfo(MIOutput output, int size) {
|
||||
this(output, size, DEFAULT_WORD_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param count - Number of Addressable units
|
||||
* @param word_size - Addressable size in octets
|
||||
* @since 4.4
|
||||
*/
|
||||
public MIDataReadMemoryBytesInfo(MIOutput output, int count, int word_size) {
|
||||
super(output);
|
||||
parse(size);
|
||||
parse(count, word_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,11 +54,11 @@ public class MIDataReadMemoryBytesInfo extends MIInfo {
|
|||
return fBlock;
|
||||
}
|
||||
|
||||
private void parse(int size)
|
||||
private void parse(int count, int word_size)
|
||||
{
|
||||
fBlock = new MemoryByte[size];
|
||||
fBlock = new MemoryByte[count*word_size];
|
||||
// Fill the block with invalid bytes, initially.
|
||||
for (int i = 0; i < size; i++)
|
||||
for (int i = 0; i < fBlock.length; i++)
|
||||
fBlock[i] = new MemoryByte((byte) 0, (byte) 0);
|
||||
|
||||
MIResult[] results = getMIOutput().getMIResultRecord().getMIResults();
|
||||
|
@ -72,9 +86,9 @@ public class MIDataReadMemoryBytesInfo extends MIInfo {
|
|||
}
|
||||
}
|
||||
|
||||
if (offset + contents.length()/2 <= size)
|
||||
if (offset*word_size + contents.length()/2 <= count*word_size)
|
||||
for (int k = 0; k < contents.length() / 2; ++k) {
|
||||
fBlock[offset + k] = new MemoryByte(
|
||||
fBlock[offset*word_size + k] = new MemoryByte(
|
||||
(byte) Integer.parseInt(
|
||||
contents.substring(k * 2, k * 2 + 2),
|
||||
16));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2010 Ericsson and others.
|
||||
* Copyright (c) 2007, 2014 Ericsson 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,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson AB - Initial Implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.tests.dsf.gdb.tests;
|
||||
|
||||
|
@ -530,7 +531,7 @@ public class MIMemoryTest extends BaseTestCase {
|
|||
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
||||
|
||||
// Perform the test
|
||||
String expected = "Word size not supported (!= 1)";
|
||||
String expected = "Word size not supported (< 1)";
|
||||
fWait.waitReset();
|
||||
readMemory(fMemoryDmc, fBaseAddress, offset, 0, count);
|
||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
|
@ -538,13 +539,6 @@ public class MIMemoryTest extends BaseTestCase {
|
|||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||
fWait.getMessage().contains(expected));
|
||||
|
||||
fWait.waitReset();
|
||||
readMemory(fMemoryDmc, fBaseAddress, offset, 2, count);
|
||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertFalse(fWait.getMessage(), fWait.isOK());
|
||||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||
fWait.getMessage().contains(expected));
|
||||
|
||||
// Ensure no MemoryChangedEvent event was received
|
||||
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
||||
}
|
||||
|
@ -823,7 +817,7 @@ public class MIMemoryTest extends BaseTestCase {
|
|||
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
||||
|
||||
// Perform the test
|
||||
String expected = "Word size not supported (!= 1)";
|
||||
String expected = "Word size not supported (< 1)";
|
||||
fWait.waitReset();
|
||||
writeMemory(fMemoryDmc, fBaseAddress, offset, 0, count, buffer);
|
||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
|
@ -831,13 +825,6 @@ public class MIMemoryTest extends BaseTestCase {
|
|||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||
fWait.getMessage().contains(expected));
|
||||
|
||||
fWait.waitReset();
|
||||
writeMemory(fMemoryDmc, fBaseAddress, offset, 2, count, buffer);
|
||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertFalse(fWait.getMessage(), fWait.isOK());
|
||||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||
fWait.getMessage().contains(expected));
|
||||
|
||||
// Ensure no MemoryChangedEvent event was received
|
||||
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
||||
}
|
||||
|
@ -1184,7 +1171,7 @@ public class MIMemoryTest extends BaseTestCase {
|
|||
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
||||
|
||||
// Perform the test
|
||||
String expected = "Word size not supported (!= 1)";
|
||||
String expected = "Word size not supported (< 1)";
|
||||
fWait.waitReset();
|
||||
fillMemory(fMemoryDmc, fBaseAddress, offset, 0, count, pattern);
|
||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
|
@ -1192,13 +1179,6 @@ public class MIMemoryTest extends BaseTestCase {
|
|||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||
fWait.getMessage().contains(expected));
|
||||
|
||||
fWait.waitReset();
|
||||
fillMemory(fMemoryDmc, fBaseAddress, offset, 2, count, pattern);
|
||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertFalse(fWait.getMessage(), fWait.isOK());
|
||||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||
fWait.getMessage().contains(expected));
|
||||
|
||||
// Ensure no MemoryChangedEvent event was received
|
||||
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2010 Wind River Systems and others.
|
||||
* Copyright (c) 2007, 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
|
||||
|
@ -11,6 +11,7 @@
|
|||
* Ericsson Communication - added support for 64 bit processors
|
||||
* Ericsson Communication - added support for changed bytes
|
||||
* Ericsson Communication - better management of exceptions
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.debug.model;
|
||||
|
||||
|
@ -325,7 +326,12 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
@Override
|
||||
public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException {
|
||||
|
||||
if (isUseCacheData() && fBlockAddress.compareTo(address) == 0 && units * getAddressableSize() <= fBlock.length)
|
||||
int addressableSize = 1;
|
||||
try {
|
||||
addressableSize = getAddressableSize();
|
||||
} catch (DebugException e) {}
|
||||
|
||||
if (isUseCacheData() && fBlockAddress.compareTo(address) == 0 && units * addressableSize <= fBlock.length)
|
||||
return fBlock;
|
||||
|
||||
MemoryByte[] newBlock = fetchMemoryBlock(address, units);
|
||||
|
@ -378,7 +384,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
// Determine the distance between the cached and the requested block addresses
|
||||
// If the distance does not exceed the length of the cached block, then there
|
||||
// is some overlap between the blocks and we have to mark the changed bytes.
|
||||
BigInteger bigDistance = address.subtract(fBlockAddress);
|
||||
BigInteger bigDistance = address.subtract(fBlockAddress).multiply(BigInteger.valueOf(addressableSize));
|
||||
if (bigDistance.compareTo(BigInteger.valueOf(fLength)) == -1) {
|
||||
// Calculate the length of the data we are going to examine/update
|
||||
int distance = bigDistance.intValue();
|
||||
|
@ -464,7 +470,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
// If the distance does not exceed the length of the new block, then there
|
||||
// is some overlap between the blocks and we have to update the blanks and
|
||||
// possibly note they are changed.
|
||||
BigInteger bigDistance = fBlockAddress.subtract(address);
|
||||
BigInteger bigDistance = fBlockAddress.subtract(address).multiply(BigInteger.valueOf(addressableSize));
|
||||
if (bigDistance.compareTo(BigInteger.valueOf(newLength)) == -1) {
|
||||
// Calculate the length of the data we are going to examine/update
|
||||
int distance = bigDistance.intValue();
|
||||
|
@ -580,7 +586,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
*/
|
||||
@Override
|
||||
public int getAddressableSize() throws DebugException {
|
||||
return fRetrieval.getAddressableSize();
|
||||
return fWordSize;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -593,13 +599,21 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
* asynchronous calls to complete before returning.
|
||||
*
|
||||
* @param bigAddress
|
||||
* @param length
|
||||
* @param count - Number of addressable units for this memory block
|
||||
* @return MemoryByte[]
|
||||
* @throws DebugException
|
||||
* @since 2.1
|
||||
*/
|
||||
protected MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long length) throws DebugException {
|
||||
|
||||
protected MemoryByte[] fetchMemoryBlock(BigInteger bigAddress, final long count) throws DebugException {
|
||||
//resolve the addressable size
|
||||
int aSize;
|
||||
try {
|
||||
aSize = getAddressableSize();
|
||||
} catch (DebugException e) {
|
||||
aSize = 1;
|
||||
}
|
||||
final int addressableSize = aSize;
|
||||
|
||||
// For the IAddress interface
|
||||
final Addr64 address = new Addr64(bigAddress);
|
||||
|
||||
|
@ -611,7 +625,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.getMemory(
|
||||
fContext, address, 0, fWordSize, (int) length,
|
||||
fContext, address, 0, addressableSize, (int) count,
|
||||
new DataRequestMonitor<MemoryByte[]>(fRetrieval.getExecutor(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -645,7 +659,17 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
* @since 2.1
|
||||
*/
|
||||
protected void writeMemoryBlock(final long offset, final byte[] bytes) throws DebugException {
|
||||
|
||||
//resolve the addressable size
|
||||
int aSize;
|
||||
try {
|
||||
aSize = getAddressableSize();
|
||||
} catch (DebugException e) {
|
||||
aSize = 1;
|
||||
}
|
||||
final int addressableSize = aSize;
|
||||
|
||||
final int addressableUnits = bytes.length/addressableSize;
|
||||
|
||||
// For the IAddress interface
|
||||
final Addr64 address = new Addr64(fBaseAddress);
|
||||
|
||||
|
@ -657,7 +681,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
if (memoryService != null) {
|
||||
// Go for it
|
||||
memoryService.setMemory(
|
||||
fContext, address, offset, fWordSize, bytes.length, bytes,
|
||||
fContext, address, offset, addressableSize, addressableUnits, bytes,
|
||||
new RequestMonitor(fRetrieval.getExecutor(), drm));
|
||||
}
|
||||
else {
|
||||
|
@ -711,9 +735,16 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
|||
* @param length
|
||||
*/
|
||||
public void handleMemoryChange(BigInteger address) {
|
||||
int addressableSize;
|
||||
try {
|
||||
addressableSize = getAddressableSize();
|
||||
} catch (DebugException e) {
|
||||
addressableSize = 1;
|
||||
}
|
||||
|
||||
int addressesLength = fLength/addressableSize;
|
||||
// Check if the change affects this particular block (0 is universal)
|
||||
BigInteger fEndAddress = fBlockAddress.add(BigInteger.valueOf(fLength));
|
||||
BigInteger fEndAddress = fBlockAddress.add(BigInteger.valueOf(addressesLength));
|
||||
if (address.equals(BigInteger.ZERO) ||
|
||||
((fBlockAddress.compareTo(address) != 1) && (fEndAddress.compareTo(address) == 1)))
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2014 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.ui.memory.traditional;
|
||||
|
@ -917,8 +918,8 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
{
|
||||
IMemoryBlockExtension memoryBlock = getMemoryBlock();
|
||||
|
||||
BigInteger lengthInBytes = endAddress.subtract(startAddress);
|
||||
BigInteger addressableSize = BigInteger.valueOf(getAddressableSize());
|
||||
final BigInteger addressableSize = BigInteger.valueOf(getAddressableSize());
|
||||
BigInteger lengthInBytes = endAddress.subtract(startAddress).multiply(addressableSize);
|
||||
|
||||
long units = lengthInBytes.divide(addressableSize).add(
|
||||
lengthInBytes.mod(addressableSize).compareTo(BigInteger.ZERO) > 0
|
||||
|
@ -984,15 +985,15 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
BigInteger.valueOf(1));
|
||||
|
||||
BigInteger overlapLength = minEnd
|
||||
.subtract(maxStart);
|
||||
.subtract(maxStart).multiply(addressableSize);
|
||||
if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
|
||||
{
|
||||
// there is overlap
|
||||
|
||||
int offsetIntoOld = maxStart.subtract(
|
||||
fHistoryCache[historyIndex].start).intValue();
|
||||
int offsetIntoOld = (maxStart.subtract(
|
||||
fHistoryCache[historyIndex].start).multiply(addressableSize)).intValue();
|
||||
int offsetIntoNew = maxStart.subtract(
|
||||
startAddress).intValue();
|
||||
startAddress).multiply(addressableSize).intValue();
|
||||
|
||||
for(int i = overlapLength.intValue(); i >= 0; i--)
|
||||
{
|
||||
|
@ -1035,6 +1036,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
||||
.getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
|
||||
|
||||
//calculate the number of units needed for the number of requested bytes
|
||||
int rem = (bytesRequested % getAddressableSize()) > 0 ? 1 : 0;
|
||||
int units = bytesRequested / getAddressableSize() + rem;
|
||||
|
||||
if(containsEditedCell(address)) // cell size cannot be switched during an edit
|
||||
return getEditedMemory(address);
|
||||
|
||||
|
@ -1042,7 +1047,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
if(fCache != null && fCache.start != null)
|
||||
{
|
||||
// see if all of the data requested is in the cache
|
||||
BigInteger dataEnd = address.add(BigInteger.valueOf(bytesRequested));
|
||||
BigInteger dataEnd = address.add(BigInteger.valueOf(units));
|
||||
|
||||
if(fCache.start.compareTo(address) <= 0
|
||||
&& fCache.end.compareTo(dataEnd) >= 0
|
||||
|
@ -1052,7 +1057,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
|||
|
||||
if(contains)
|
||||
{
|
||||
int offset = address.subtract(fCache.start).intValue();
|
||||
int offset = address.subtract(fCache.start).multiply(BigInteger.valueOf(getAddressableSize())).intValue();
|
||||
TraditionalMemoryByte bytes[] = new TraditionalMemoryByte[bytesRequested];
|
||||
for(int i = 0; i < bytes.length; i++)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2014 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
|
||||
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.ui.memory.traditional;
|
||||
|
@ -1616,8 +1617,12 @@ abstract class CopyAction extends Action
|
|||
// : 0);
|
||||
|
||||
final int columns = fRendering.getColumnCount();
|
||||
|
||||
BigInteger lengthToRead = end.subtract(start);
|
||||
int addressableSize = fRendering.getAddressableSize();
|
||||
assert(addressableSize != 0);
|
||||
|
||||
int addressesPerColumn = bytesPerColumn/addressableSize;
|
||||
|
||||
BigInteger lengthToRead = end.subtract(start).multiply(BigInteger.valueOf(addressableSize));
|
||||
|
||||
int rows = lengthToRead.divide(
|
||||
BigInteger.valueOf(columns * bytesPerColumn)).intValue();
|
||||
|
@ -1630,7 +1635,7 @@ abstract class CopyAction extends Action
|
|||
for(int row = 0; row < rows; row++)
|
||||
{
|
||||
BigInteger rowAddress = start.add(BigInteger.valueOf(row
|
||||
* columns * bytesPerColumn));
|
||||
* columns * addressesPerColumn));
|
||||
|
||||
if(copyAddress)
|
||||
{
|
||||
|
@ -1643,7 +1648,7 @@ abstract class CopyAction extends Action
|
|||
for(int col = 0; col < columns; col++)
|
||||
{
|
||||
BigInteger cellAddress = rowAddress.add(BigInteger
|
||||
.valueOf(col * bytesPerColumn));
|
||||
.valueOf(col * addressesPerColumn));
|
||||
|
||||
if(cellAddress.compareTo(end) < 0)
|
||||
{
|
||||
|
@ -1685,7 +1690,7 @@ abstract class CopyAction extends Action
|
|||
for(int col = 0; col < columns; col++)
|
||||
{
|
||||
BigInteger cellAddress = rowAddress.add(BigInteger
|
||||
.valueOf(col * fRendering.getBytesPerColumn()));
|
||||
.valueOf(col * addressesPerColumn));
|
||||
|
||||
if(cellAddress.compareTo(end) < 0)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue