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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||||
|
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
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.
|
* asynchronous calls to complete before returning.
|
||||||
*
|
*
|
||||||
* @param bigAddress
|
* @param bigAddress
|
||||||
* @param length
|
* @param count - The number of addressable units for this block
|
||||||
* @return MemoryByte[]
|
* @return MemoryByte[]
|
||||||
* @throws DebugException
|
* @throws DebugException
|
||||||
*/
|
*/
|
||||||
@Override
|
@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
|
// For the IAddress interface
|
||||||
final Addr64 address = new Addr64(bigAddress);
|
final Addr64 address = new Addr64(bigAddress);
|
||||||
|
@ -159,7 +160,7 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
||||||
if (memoryService != null) {
|
if (memoryService != null) {
|
||||||
// Go for it
|
// Go for it
|
||||||
memoryService.getMemory(
|
memoryService.getMemory(
|
||||||
context, address, 0, addressableSize, (int) length,
|
context, address, 0, addressableSize, (int) count,
|
||||||
//getContext(), address, 0, addressableSize, (int) length,
|
//getContext(), address, 0, addressableSize, (int) length,
|
||||||
new DataRequestMonitor<MemoryByte[]>(retrieval.getExecutor(), drm) {
|
new DataRequestMonitor<MemoryByte[]>(retrieval.getExecutor(), drm) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -206,6 +207,12 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
||||||
protected void execute(final DataRequestMonitor<MemoryByte[]> drm) {
|
protected void execute(final DataRequestMonitor<MemoryByte[]> drm) {
|
||||||
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
GdbMemoryBlockRetrieval retrieval = (GdbMemoryBlockRetrieval)getMemoryBlockRetrieval();
|
||||||
int addressableSize = 1;
|
int addressableSize = 1;
|
||||||
|
try {
|
||||||
|
addressableSize = getAddressableSize();
|
||||||
|
} catch (DebugException e) {}
|
||||||
|
|
||||||
|
int addressableUnits = bytes.length/addressableSize;
|
||||||
|
|
||||||
// If this block was created with a memory space qualification,
|
// If this block was created with a memory space qualification,
|
||||||
// we need to create an enhanced context
|
// we need to create an enhanced context
|
||||||
IMemoryDMContext context = null;
|
IMemoryDMContext context = null;
|
||||||
|
@ -227,7 +234,7 @@ public class GdbMemoryBlock extends DsfMemoryBlock implements IMemorySpaceAwareM
|
||||||
if (memoryService != null) {
|
if (memoryService != null) {
|
||||||
// Go for it
|
// Go for it
|
||||||
memoryService.setMemory(
|
memoryService.setMemory(
|
||||||
context, address, offset, addressableSize, bytes.length, bytes,
|
context, address, offset, addressableSize, addressableUnits, bytes,
|
||||||
new RequestMonitor(retrieval.getExecutor(), drm));
|
new RequestMonitor(retrieval.getExecutor(), drm));
|
||||||
}
|
}
|
||||||
else {
|
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));
|
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.REQUEST_FAILED, Messages.Err_MemoryServiceNotAvailable, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
public void eventDispatched(ISuspendedDMEvent e) {
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
* Texas Instruments, Freescale Semiconductor - initial API and implementation
|
||||||
* Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323)
|
* Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323)
|
||||||
|
* Alvaro Sanchez-Leon (Ericsson AB) - [Memory] Support 16 bit addressable size (Bug 426730)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
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.IMemory.IMemoryDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces;
|
import org.eclipse.cdt.dsf.debug.service.IMemorySpaces;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlock.MemorySpaceDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory2;
|
||||||
import org.eclipse.cdt.dsf.service.DsfServices;
|
import org.eclipse.cdt.dsf.service.DsfServices;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
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,
|
* same memory block, a trip to the target could result. However,
|
||||||
* the memory request cache should save the day.
|
* the memory request cache should save the day.
|
||||||
*/
|
*/
|
||||||
return new GdbMemoryBlock(this, memoryDmc, getModelId(), expression, blockAddress, getAddressableSize(), 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);
|
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);
|
blocks.add(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,4 +386,29 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements
|
||||||
}
|
}
|
||||||
return false;
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
* Mentor Graphics - Initial API and implementation
|
* Mentor Graphics - Initial API and implementation
|
||||||
* John Dallaway - Add methods to get the endianness and address size (Bug 225609)
|
* 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)
|
* 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;
|
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.gdb.service.command.IGDBControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIMemory;
|
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.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.CLIShowEndianInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataEvaluateExpressionInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataEvaluateExpressionInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowLanguageInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowLanguageInfo;
|
||||||
|
@ -48,7 +50,7 @@ import org.eclipse.debug.core.model.MemoryByte;
|
||||||
/**
|
/**
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
public class GDBMemory extends MIMemory implements IGDBMemory {
|
public class GDBMemory extends MIMemory implements IGDBMemory2 {
|
||||||
|
|
||||||
private IGDBControl fCommandControl;
|
private IGDBControl fCommandControl;
|
||||||
|
|
||||||
|
@ -57,6 +59,11 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
||||||
*/
|
*/
|
||||||
private Map<IMemoryDMContext, Integer> fAddressSizes = new HashMap<IMemoryDMContext, Integer>();
|
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.
|
* 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(),
|
IMemory.class.getName(),
|
||||||
MIMemory.class.getName(),
|
MIMemory.class.getName(),
|
||||||
IGDBMemory.class.getName(),
|
IGDBMemory.class.getName(),
|
||||||
|
IGDBMemory2.class.getName(),
|
||||||
GDBMemory.class.getName(),
|
GDBMemory.class.getName(),
|
||||||
},
|
},
|
||||||
new Hashtable<String, String>());
|
new Hashtable<String, String>());
|
||||||
|
@ -94,19 +102,20 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
||||||
public void shutdown(RequestMonitor requestMonitor) {
|
public void shutdown(RequestMonitor requestMonitor) {
|
||||||
unregister();
|
unregister();
|
||||||
getSession().removeServiceEventListener(this);
|
getSession().removeServiceEventListener(this);
|
||||||
|
fAddressableSizes.clear();
|
||||||
fAddressSizes.clear();
|
fAddressSizes.clear();
|
||||||
super.shutdown(requestMonitor);
|
super.shutdown(requestMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readMemoryBlock(final IDMContext dmc, IAddress address,
|
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(
|
super.readMemoryBlock(
|
||||||
dmc,
|
dmc,
|
||||||
address,
|
address,
|
||||||
offset,
|
offset,
|
||||||
word_size,
|
word_size,
|
||||||
count,
|
word_count,
|
||||||
new DataRequestMonitor<MemoryByte[]>(ImmediateExecutor.getInstance(), drm) {
|
new DataRequestMonitor<MemoryByte[]>(ImmediateExecutor.getInstance(), drm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
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.
|
// Need a global here as getSteps() can be called more than once.
|
||||||
private Step[] steps = null;
|
private Step[] steps = null;
|
||||||
|
|
||||||
private void determineSteps()
|
private void determineSteps()
|
||||||
{
|
{
|
||||||
ArrayList<Step> stepsList = new ArrayList<Step>();
|
ArrayList<Step> stepsList = new ArrayList<Step>();
|
||||||
|
|
||||||
if (fAddressSizes.get(memContext) == null) {
|
if (fAddressSizes.get(memContext) == null) {
|
||||||
stepsList.add(
|
stepsList.add(
|
||||||
new Step() {
|
new Step() {
|
||||||
// store original language
|
// store original language
|
||||||
@Override
|
@Override
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void execute(final RequestMonitor requestMonitor) {
|
||||||
fCommandControl.queueCommand(
|
fCommandControl.queueCommand(
|
||||||
fCommandControl.getCommandFactory().createMIGDBShowLanguage(memContext),
|
fCommandControl.getCommandFactory().createMIGDBShowLanguage(memContext),
|
||||||
new ImmediateDataRequestMonitor<MIGDBShowLanguageInfo>(requestMonitor) {
|
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) {
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleCompleted() {
|
protected void handleCompleted() {
|
||||||
if (!isSuccess()) {
|
if (isSuccess()) {
|
||||||
|
originalLanguage = getData().getLanguage();
|
||||||
|
} else {
|
||||||
abortLanguageSteps = true;
|
abortLanguageSteps = true;
|
||||||
}
|
}
|
||||||
// Accept failure
|
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
stepsList.add(
|
stepsList.add(
|
||||||
new Step() {
|
new Step() {
|
||||||
// read address size
|
// switch to c language
|
||||||
@Override
|
@Override
|
||||||
public void execute(final RequestMonitor requestMonitor) {
|
public void execute(final RequestMonitor requestMonitor) {
|
||||||
// Run this step even if the language commands where aborted, but accept failures.
|
if (abortLanguageSteps) {
|
||||||
readAddressSize(
|
requestMonitor.done();
|
||||||
memContext,
|
return;
|
||||||
new ImmediateDataRequestMonitor<Integer>(requestMonitor) {
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
protected void handleCompleted() {
|
protected void handleCompleted() {
|
||||||
if (isSuccess()) {
|
if (isSuccess()) {
|
||||||
|
//Preserve the address size per context
|
||||||
fAddressSizes.put(memContext, getData());
|
fAddressSizes.put(memContext, getData());
|
||||||
}
|
}
|
||||||
// Accept failure
|
|
||||||
|
// Accept failures
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
stepsList.add(
|
stepsList.add(
|
||||||
new Step() {
|
new Step() {
|
||||||
// restore original language
|
// restore original language
|
||||||
|
@ -250,8 +269,8 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fIsBigEndian == null) {
|
if (fIsBigEndian == null) {
|
||||||
stepsList.add(
|
stepsList.add(
|
||||||
|
@ -283,7 +302,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
||||||
if (steps == null) {
|
if (steps == null) {
|
||||||
determineSteps();
|
determineSteps();
|
||||||
}
|
}
|
||||||
|
|
||||||
return steps;
|
return steps;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -295,6 +314,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
||||||
IMemoryDMContext context = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class);
|
IMemoryDMContext context = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class);
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
fAddressSizes.remove(context);
|
fAddressSizes.remove(context);
|
||||||
|
fAddressableSizes.remove(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,6 +325,15 @@ public class GDBMemory extends MIMemory implements IGDBMemory {
|
||||||
return (addressSize != null) ? addressSize.intValue() : 8;
|
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
|
@Override
|
||||||
public boolean isBigEndian(IMemoryDMContext context) {
|
public boolean isBigEndian(IMemoryDMContext context) {
|
||||||
assert fIsBigEndian != null;
|
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) {
|
protected void readEndianness(IMemoryDMContext memContext, final DataRequestMonitor<Boolean> drm) {
|
||||||
CommandFactory commandFactory = fCommandControl.getCommandFactory();
|
CommandFactory commandFactory = fCommandControl.getCommandFactory();
|
||||||
fCommandControl.queueCommand(
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Ericsson - initial API and implementation
|
* 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;
|
package org.eclipse.cdt.dsf.gdb.service;
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ public class GDBMemory_7_0 extends GDBMemory {
|
||||||
MIMemory.class.getName(),
|
MIMemory.class.getName(),
|
||||||
IMemory.class.getName(),
|
IMemory.class.getName(),
|
||||||
IGDBMemory.class.getName(),
|
IGDBMemory.class.getName(),
|
||||||
|
IGDBMemory2.class.getName(),
|
||||||
GDBMemory.class.getName(),
|
GDBMemory.class.getName(),
|
||||||
GDBMemory_7_0.class.getName()
|
GDBMemory_7_0.class.getName()
|
||||||
},
|
},
|
||||||
|
@ -66,7 +68,7 @@ public class GDBMemory_7_0 extends GDBMemory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, long offset,
|
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;
|
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
|
@Override
|
||||||
protected void writeMemoryBlock(IDMContext dmc, IAddress address, long offset,
|
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;
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Marc Khouzam (Ericsson) - initial API and implementation
|
* 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;
|
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(),
|
register(new String[] { MIMemory.class.getName(),
|
||||||
IMemory.class.getName(),
|
IMemory.class.getName(),
|
||||||
IGDBMemory.class.getName(),
|
IGDBMemory.class.getName(),
|
||||||
|
IGDBMemory2.class.getName(),
|
||||||
GDBMemory.class.getName(),
|
GDBMemory.class.getName(),
|
||||||
GDBMemory_7_0.class.getName(),
|
GDBMemory_7_0.class.getName(),
|
||||||
GDBMemory_7_6.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
|
// 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).
|
// it send the potential IMemoryChangedEvent as we will send it ourselves (see below).
|
||||||
final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(containerDmc, IMemoryDMContext.class);
|
final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(containerDmc, IMemoryDMContext.class);
|
||||||
|
|
||||||
final IAddress address = new Addr64(addr);
|
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) {
|
new RequestMonitor(getExecutor(), null) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleCompleted() {
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
* Vladimir Prus (CodeSourcery) - support for -data-read-memory-bytes (bug 322658)
|
* Vladimir Prus (CodeSourcery) - support for -data-read-memory-bytes (bug 322658)
|
||||||
* John Dallaway - support for -data-write-memory-bytes (bug 387793)
|
* John Dallaway - support for -data-write-memory-bytes (bug 387793)
|
||||||
* John Dallaway - memory cache update fix (bug 387688)
|
* 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;
|
package org.eclipse.cdt.dsf.mi.service;
|
||||||
|
|
||||||
|
@ -68,6 +69,8 @@ import org.osgi.framework.BundleContext;
|
||||||
public class MIMemory extends AbstractDsfService implements IMemory, ICachingService {
|
public class MIMemory extends AbstractDsfService implements IMemory, ICachingService {
|
||||||
|
|
||||||
private static final String READ_MEMORY_BYTES_FEATURE = "data-read-memory-bytes"; //$NON-NLS-1$
|
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>
|
public class MemoryChangedEvent extends AbstractDMEvent<IMemoryDMContext>
|
||||||
implements IMemoryChangedEvent
|
implements IMemoryChangedEvent
|
||||||
|
@ -120,9 +123,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
|
* @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
|
@Override
|
||||||
public void initialize(final RequestMonitor requestMonitor) {
|
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) {
|
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||||
// Create the command cache
|
|
||||||
IGDBControl commandControl = getServicesTracker().getService(IGDBControl.class);
|
IGDBControl commandControl = getServicesTracker().getService(IGDBControl.class);
|
||||||
BufferedCommandControl bufferedCommandControl = new BufferedCommandControl(commandControl, getExecutor(), 2);
|
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 = new CommandCache(getSession(), bufferedCommandControl);
|
||||||
fCommandCache.setContextAvailable(commandControl.getContext(), true);
|
fCommandCache.setContextAvailable(commandControl.getContext(), true);
|
||||||
|
|
||||||
// Register this service
|
|
||||||
register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
|
register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
|
||||||
|
|
||||||
// Create the memory requests cache
|
|
||||||
fMemoryCaches = new HashMap<IMemoryDMContext, MIMemoryCache>();
|
fMemoryCaches = new HashMap<IMemoryDMContext, MIMemoryCache>();
|
||||||
|
|
||||||
// Register as service event listener
|
|
||||||
getSession().addServiceEventListener(this, null);
|
getSession().addServiceEventListener(this, null);
|
||||||
|
|
||||||
// Done
|
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,13 +168,10 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
@Override
|
@Override
|
||||||
public void shutdown(final RequestMonitor requestMonitor) {
|
public void shutdown(final RequestMonitor requestMonitor) {
|
||||||
|
|
||||||
// Unregister this service
|
|
||||||
unregister();
|
unregister();
|
||||||
|
|
||||||
// Remove event listener
|
|
||||||
getSession().removeServiceEventListener(this);
|
getSession().removeServiceEventListener(this);
|
||||||
|
|
||||||
// Complete the shutdown
|
|
||||||
super.shutdown(requestMonitor);
|
super.shutdown(requestMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,32 +192,27 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void getMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
|
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) {
|
if (memoryDMC == null) {
|
||||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
||||||
drm.done();
|
drm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the word size
|
if (word_size < 1) {
|
||||||
// NOTE: We only accept 1 byte words for this implementation
|
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();
|
drm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the byte count
|
if (word_count < 0) {
|
||||||
if (count < 0) {
|
|
||||||
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
|
drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
|
||||||
drm.done();
|
drm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All is clear: go for it
|
getMemoryCache(memoryDMC).getMemory(memoryDMC, address.add(offset), word_size, word_count, drm);
|
||||||
getMemoryCache(memoryDMC).getMemory(memoryDMC, address.add(offset), word_size, count, drm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -241,39 +220,33 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
|
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) {
|
if (memoryDMC == null) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
||||||
rm.done();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the word size
|
if (word_size < 1) {
|
||||||
// NOTE: We only accept 1 byte words for this implementation
|
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();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the byte count
|
if (word_count < 0) {
|
||||||
if (count < 0) {
|
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the buffer size
|
if (buffer.length < word_count * word_size) {
|
||||||
if (buffer.length < count) {
|
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Buffer too short", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Buffer too short", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All is clear: go for it
|
getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, word_count, buffer, rm);
|
||||||
getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, count, buffer, rm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -283,29 +256,24 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
public void fillMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
|
public void fillMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
|
||||||
int word_size, int count, byte[] pattern, RequestMonitor rm)
|
int word_size, int count, byte[] pattern, RequestMonitor rm)
|
||||||
{
|
{
|
||||||
// Validate the context
|
|
||||||
if (memoryDMC == null) {
|
if (memoryDMC == null) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
|
||||||
rm.done();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the word size
|
if (word_size < 1) {
|
||||||
// NOTE: We only accept 1 byte words for this implementation
|
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();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the repeat count
|
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid repeat count (< 0)", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid repeat count (< 0)", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the pattern
|
|
||||||
if (pattern.length < 1) {
|
if (pattern.length < 1) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Empty pattern", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Empty pattern", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
|
@ -319,8 +287,13 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
System.arraycopy(pattern, 0, buffer, i * length, length);
|
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
|
// 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 address
|
||||||
* @param offset
|
* @param offset
|
||||||
* @param word_size
|
* @param word_size
|
||||||
* @param count
|
* @param word_count in addressable units
|
||||||
* @param drm
|
* @param drm
|
||||||
*
|
*
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
|
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) {
|
if (fDataReadMemoryBytes) {
|
||||||
fCommandCache.execute(
|
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) {
|
new DataRequestMonitor<MIDataReadMemoryBytesInfo>(getExecutor(), drm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
|
@ -352,17 +325,27 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void handleFailure() {
|
protected void handleFailure() {
|
||||||
drm.setData(createInvalidBlock(word_size * count));
|
drm.setData(createInvalidBlock(word_size * word_count));
|
||||||
drm.done();
|
drm.done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} 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
|
/* To simplify the parsing of the MI result, we request the output to
|
||||||
* be on 1 row of [count] columns, no char interpretation.
|
* be on 1 row of [count] columns, no char interpretation.
|
||||||
*/
|
*/
|
||||||
int mode = MIFormat.HEXADECIMAL;
|
int mode = MIFormat.HEXADECIMAL;
|
||||||
int nb_rows = 1;
|
int nb_rows = 1;
|
||||||
int nb_cols = count;
|
int nb_cols = word_count;
|
||||||
Character asChar = null;
|
Character asChar = null;
|
||||||
|
|
||||||
fCommandCache.execute(
|
fCommandCache.execute(
|
||||||
|
@ -376,7 +359,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void handleFailure() {
|
protected void handleFailure() {
|
||||||
drm.setData(createInvalidBlock(word_size * count));
|
drm.setData(createInvalidBlock(word_size * word_count));
|
||||||
drm.done();
|
drm.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,34 +380,44 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
* @param address
|
* @param address
|
||||||
* @param offset
|
* @param offset
|
||||||
* @param word_size
|
* @param word_size
|
||||||
* @param count
|
* @param word_count in addressable units
|
||||||
* @param buffer
|
* @param buffer
|
||||||
* @param rm
|
* @param rm
|
||||||
*
|
*
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
|
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) {
|
if (fDataReadMemoryBytes) {
|
||||||
// Use -data-write-memory-bytes for performance
|
// Use -data-write-memory-bytes for performance,
|
||||||
fCommandCache.execute(
|
fCommandCache.execute(
|
||||||
fCommandFactory.createMIDataWriteMemoryBytes(dmc, address.add(offset).toString(),
|
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)
|
new DataRequestMonitor<MIInfo>(getExecutor(), rm)
|
||||||
);
|
);
|
||||||
} else {
|
} 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...)
|
// Each byte is written individually (GDB power...)
|
||||||
// so we need to keep track of the count
|
// so we need to keep track of the count
|
||||||
final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
|
final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
|
||||||
countingRM.setDoneCount(count);
|
countingRM.setDoneCount(word_count);
|
||||||
|
|
||||||
// We will format the individual bytes in decimal
|
// We will format the individual bytes in decimal
|
||||||
int format = MIFormat.DECIMAL;
|
int format = MIFormat.DECIMAL;
|
||||||
String baseAddress = address.toString();
|
String baseAddress = address.toString();
|
||||||
|
|
||||||
// Issue an MI request for each byte to write
|
// 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();
|
String value = new Byte(buffer[i]).toString();
|
||||||
fCommandCache.execute(
|
fCommandCache.execute(
|
||||||
fCommandFactory.createMIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
|
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());
|
address = new Addr64(expAddress.getValue());
|
||||||
|
|
||||||
final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class);
|
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));
|
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
|
// SortedLinkedlist
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -544,11 +545,16 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
// For simplicity, everything is public.
|
// For simplicity, everything is public.
|
||||||
private class MemoryBlock {
|
private class MemoryBlock {
|
||||||
public IAddress fAddress;
|
public IAddress fAddress;
|
||||||
public long fLength;
|
public long fLengthInAddressableUnits;
|
||||||
|
public long fLengthInOctets;
|
||||||
public MemoryByte[] fBlock;
|
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;
|
fAddress = address;
|
||||||
fLength = length;
|
fLengthInAddressableUnits = lengthInAddressableUnits;
|
||||||
|
fLengthInOctets = lengthInOctets;
|
||||||
fBlock = block;
|
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
|
// Case where the block is to be merged with the previous block
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
MemoryBlock prevBlock = get(index - 1);
|
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) {
|
if (endOfPreviousBlock.distanceTo(newBlock.fAddress).longValue() == 0) {
|
||||||
long newLength = prevBlock.fLength + newBlock.fLength;
|
long newLengthInOctets = prevBlock.fLengthInOctets + newBlock.fLengthInOctets;
|
||||||
if (newLength <= Integer.MAX_VALUE) {
|
long newLengthInAddressableUnits = prevBlock.fLengthInAddressableUnits + newBlock.fLengthInAddressableUnits;
|
||||||
MemoryByte[] block = new MemoryByte[(int) newLength] ;
|
if (newLengthInOctets <= Integer.MAX_VALUE) {
|
||||||
System.arraycopy(prevBlock.fBlock, 0, block, 0, (int) prevBlock.fLength);
|
MemoryByte[] block = new MemoryByte[(int) newLengthInOctets] ;
|
||||||
System.arraycopy(newBlock.fBlock, 0, block, (int) prevBlock.fLength, (int) newBlock.fLength);
|
System.arraycopy(prevBlock.fBlock, 0, block, 0, (int) prevBlock.fLengthInOctets);
|
||||||
newBlock = new MemoryBlock(prevBlock.fAddress, newLength, block);
|
System.arraycopy(newBlock.fBlock, 0, block, (int) prevBlock.fLengthInOctets, (int) newBlock.fLengthInOctets);
|
||||||
|
newBlock = new MemoryBlock(prevBlock.fAddress, newLengthInOctets, newLengthInAddressableUnits, block);
|
||||||
remove(index);
|
remove(index);
|
||||||
index -= 1;
|
index -= 1;
|
||||||
set(index, newBlock);
|
set(index, newBlock);
|
||||||
|
@ -620,14 +627,15 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
int lastIndex = size() - 1;
|
int lastIndex = size() - 1;
|
||||||
if (index < lastIndex) {
|
if (index < lastIndex) {
|
||||||
MemoryBlock nextBlock = get(index + 1);
|
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) {
|
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) {
|
if (newLength <= Integer.MAX_VALUE) {
|
||||||
MemoryByte[] block = new MemoryByte[(int) newLength] ;
|
MemoryByte[] block = new MemoryByte[(int) newLength] ;
|
||||||
System.arraycopy(newBlock.fBlock, 0, block, 0, (int) newBlock.fLength);
|
System.arraycopy(newBlock.fBlock, 0, block, 0, (int) newBlock.fLengthInOctets);
|
||||||
System.arraycopy(nextBlock.fBlock, 0, block, (int) newBlock.fLength, (int) nextBlock.fLength);
|
System.arraycopy(nextBlock.fBlock, 0, block, (int) newBlock.fLengthInOctets, (int) nextBlock.fLengthInOctets);
|
||||||
newBlock = new MemoryBlock(newBlock.fAddress, newLength, block);
|
newBlock = new MemoryBlock(newBlock.fAddress, newLength, newAddressesLength, block);
|
||||||
set(index, newBlock);
|
set(index, newBlock);
|
||||||
remove(index + 1);
|
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
|
* @return A list of the sub-blocks to fetch in order to fill enough gaps in the memory cache
|
||||||
* to service the request
|
* 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>();
|
LinkedList<MemoryBlock> list = new LinkedList<MemoryBlock>();
|
||||||
ListIterator<MemoryBlock> it = fMemoryBlockList.listIterator();
|
ListIterator<MemoryBlock> it = fMemoryBlockList.listIterator();
|
||||||
|
|
||||||
// Look for holes in the list of memory blocks
|
// Look for holes in the list of memory blocks
|
||||||
while (it.hasNext() && count > 0) {
|
while (it.hasNext() && octetCount > 0) {
|
||||||
MemoryBlock cachedBlock = it.next();
|
MemoryBlock cachedBlock = it.next();
|
||||||
IAddress cachedBlockStart = cachedBlock.fAddress;
|
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
|
// Case where we miss a block before the cached block
|
||||||
if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0) {
|
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 both blocks start at the same location, no need to create a new cached block
|
||||||
if (length > 0) {
|
if (lengthInOctets > 0) {
|
||||||
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, length, new MemoryByte[0]);
|
int lengthInAddressableUnits = lengthInOctets / word_size;
|
||||||
|
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, lengthInOctets, lengthInAddressableUnits, new MemoryByte[0]);
|
||||||
list.add(newBlock);
|
list.add(newBlock);
|
||||||
}
|
}
|
||||||
// Adjust request block start and length for the next iteration
|
// Adjust request block start and length for the next iteration
|
||||||
reqBlockStart = cachedBlockEnd;
|
reqBlockStart = cachedBlockEnd;
|
||||||
count -= length + cachedBlock.fLength;
|
octetCount -= lengthInOctets + cachedBlock.fLengthInOctets;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case where the requested block starts somewhere in the cached block
|
// 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
|
// Start of the requested block already in cache
|
||||||
// Adjust request block start and length for the next iteration
|
// Adjust request block start and length for the next iteration
|
||||||
count -= reqBlockStart.distanceTo(cachedBlockEnd).longValue();
|
octetCount -= reqBlockStart.distanceTo(cachedBlockEnd).longValue()*word_size;
|
||||||
reqBlockStart = cachedBlockEnd;
|
reqBlockStart = cachedBlockEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case where we miss a block at the end of the cache
|
// Case where we miss a block at the end of the cache
|
||||||
if (count > 0) {
|
if (octetCount > 0) {
|
||||||
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, count, new MemoryByte[0]);
|
int addressesLength = octetCount / word_size;
|
||||||
|
MemoryBlock newBlock = new MemoryBlock(reqBlockStart, octetCount, addressesLength, new MemoryByte[0]);
|
||||||
list.add(newBlock);
|
list.add(newBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,22 +793,23 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
* @param count Its length
|
* @param count Its length
|
||||||
* @return The cached memory content
|
* @return The cached memory content
|
||||||
*/
|
*/
|
||||||
private MemoryByte[] getMemoryBlockFromCache(IAddress reqBlockStart, int count) {
|
private MemoryByte[] getMemoryBlockFromCache(IAddress reqBlockStart, int word_count, int word_size) {
|
||||||
|
int count = word_count * word_size;
|
||||||
IAddress reqBlockEnd = reqBlockStart.add(count);
|
|
||||||
|
IAddress reqBlockEnd = reqBlockStart.add(word_count);
|
||||||
MemoryByte[] resultBlock = new MemoryByte[count];
|
MemoryByte[] resultBlock = new MemoryByte[count];
|
||||||
ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
|
ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
MemoryBlock cachedBlock = iter.next();
|
MemoryBlock cachedBlock = iter.next();
|
||||||
IAddress cachedBlockStart = cachedBlock.fAddress;
|
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
|
// Case where the cached block overlaps completely the requested memory block
|
||||||
if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0
|
if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0
|
||||||
&& reqBlockEnd.distanceTo(cachedBlockEnd).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);
|
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
|
else if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0
|
||||||
&& cachedBlockStart.distanceTo(reqBlockEnd).longValue() > 0)
|
&& cachedBlockStart.distanceTo(reqBlockEnd).longValue() > 0)
|
||||||
{
|
{
|
||||||
int pos = (int) reqBlockStart.distanceTo(cachedBlockStart).longValue();
|
int pos = (int) reqBlockStart.distanceTo(cachedBlockStart).longValue() * word_size;
|
||||||
int length = (int) Math.min(cachedBlock.fLength, count - pos);
|
int length = (int) Math.min(cachedBlock.fLengthInOctets, count - pos);
|
||||||
System.arraycopy(cachedBlock.fBlock, 0, resultBlock, pos, length);
|
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
|
else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0
|
||||||
&& reqBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
|
&& reqBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
|
||||||
{
|
{
|
||||||
int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue();
|
int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue() * word_size;
|
||||||
int length = (int) Math.min(cachedBlock.fLength - pos, count);
|
int length = (int) Math.min(cachedBlock.fLengthInOctets - pos, count);
|
||||||
System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, length);
|
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.
|
* the content with the actual memory just read from the target.
|
||||||
*
|
*
|
||||||
* @param modBlockStart
|
* @param modBlockStart
|
||||||
* @param count
|
* @param word_count - Number of addressable units
|
||||||
* @param modBlock
|
* @param modBlock
|
||||||
|
* @param word_size - Number of octets per addressable unit
|
||||||
*/
|
*/
|
||||||
private void updateMemoryCache(IAddress modBlockStart, int count, MemoryByte[] modBlock) {
|
private void updateMemoryCache(IAddress modBlockStart, int word_count, MemoryByte[] modBlock, int word_size) {
|
||||||
|
IAddress modBlockEnd = modBlockStart.add(word_count);
|
||||||
IAddress modBlockEnd = modBlockStart.add(count);
|
|
||||||
ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
|
ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
|
||||||
|
int count = word_count * word_size;
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
MemoryBlock cachedBlock = iter.next();
|
MemoryBlock cachedBlock = iter.next();
|
||||||
IAddress cachedBlockStart = cachedBlock.fAddress;
|
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.
|
// For now, we only bother to update bytes already cached.
|
||||||
// Note: In a better implementation (v1.1), we would augment
|
// 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
|
if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0
|
||||||
&& modBlockEnd.distanceTo(cachedBlockEnd).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);
|
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
|
else if (modBlockStart.distanceTo(cachedBlockStart).longValue() >= 0
|
||||||
&& cachedBlockEnd.distanceTo(modBlockEnd).longValue() >= 0)
|
&& cachedBlockEnd.distanceTo(modBlockEnd).longValue() >= 0)
|
||||||
{
|
{
|
||||||
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue();
|
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue() * word_size;
|
||||||
System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, (int) cachedBlock.fLength);
|
System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, (int) cachedBlock.fLengthInOctets);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case where the beginning of the modified block is within the cached block
|
// Case where the beginning of the modified block is within the cached block
|
||||||
else if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0
|
else if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0
|
||||||
&& modBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
|
&& modBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
|
||||||
{
|
{
|
||||||
int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue();
|
int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue() * word_size;
|
||||||
int length = (int) modBlockStart.distanceTo(cachedBlockEnd).longValue();
|
int length = (int) modBlockStart.distanceTo(cachedBlockEnd).longValue() * word_size;
|
||||||
System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, length);
|
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
|
else if (cachedBlockStart.distanceTo(modBlockEnd).longValue() > 0
|
||||||
&& modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
|
&& modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
|
||||||
{
|
{
|
||||||
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue();
|
int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue() * word_size;
|
||||||
int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue();
|
int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue() * word_size;
|
||||||
System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, length);
|
System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,14 +900,14 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
* @param memoryDMC
|
* @param memoryDMC
|
||||||
* @param address the memory block address (on the target)
|
* @param address the memory block address (on the target)
|
||||||
* @param word_size the size, in bytes, of an addressable item
|
* @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
|
* @param drm the asynchronous data request monitor
|
||||||
*/
|
*/
|
||||||
public void getMemory(IMemoryDMContext memoryDMC, final IAddress address, final int word_size,
|
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
|
// 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();
|
int numberOfRequests = missingBlocks.size();
|
||||||
|
|
||||||
// A read request will be issued for each block needed
|
// A read request will be issued for each block needed
|
||||||
|
@ -904,7 +917,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
// We received everything so read the result from the memory cache
|
// 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();
|
drm.done();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -914,14 +927,14 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
for (int i = 0; i < numberOfRequests; i++) {
|
for (int i = 0; i < numberOfRequests; i++) {
|
||||||
MemoryBlock block = missingBlocks.get(i);
|
MemoryBlock block = missingBlocks.get(i);
|
||||||
final IAddress startAddress = block.fAddress;
|
final IAddress startAddress = block.fAddress;
|
||||||
final int length = (int) block.fLength;
|
final int length = (int) block.fLengthInAddressableUnits;
|
||||||
readMemoryBlock(memoryDMC, startAddress, 0, word_size, length,
|
readMemoryBlock(memoryDMC, startAddress, 0, word_size, length,
|
||||||
new DataRequestMonitor<MemoryByte[]>(getSession().getExecutor(), drm) {
|
new DataRequestMonitor<MemoryByte[]>(getSession().getExecutor(), drm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
MemoryByte[] block = new MemoryByte[count];
|
MemoryByte[] block = getData();
|
||||||
block = getData();
|
int lenghtInaddressableUnits = block.length / word_size;
|
||||||
MemoryBlock memoryBlock = new MemoryBlock(startAddress, length, block);
|
MemoryBlock memoryBlock = new MemoryBlock(startAddress, block.length, lenghtInaddressableUnits, block);
|
||||||
fMemoryBlockList.add(memoryBlock);
|
fMemoryBlockList.add(memoryBlock);
|
||||||
countingRM.done();
|
countingRM.done();
|
||||||
}
|
}
|
||||||
|
@ -934,16 +947,16 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
* @param address the memory block address (on the target)
|
* @param address the memory block address (on the target)
|
||||||
* @param offset the offset from the start address
|
* @param offset the offset from the start address
|
||||||
* @param word_size the size, in bytes, of an addressable item
|
* @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 buffer the source buffer
|
||||||
* @param rm the asynchronous request monitor
|
* @param rm the asynchronous request monitor
|
||||||
*/
|
*/
|
||||||
public void setMemory(final IMemoryDMContext memoryDMC, final IAddress address,
|
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)
|
final RequestMonitor rm)
|
||||||
{
|
{
|
||||||
writeMemoryBlock(
|
writeMemoryBlock(
|
||||||
memoryDMC, address, offset, word_size, count, buffer,
|
memoryDMC, address, offset, word_size, word_count, buffer,
|
||||||
new RequestMonitor(getSession().getExecutor(), rm) {
|
new RequestMonitor(getSession().getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
|
@ -952,18 +965,17 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
fCommandCache.reset();
|
fCommandCache.reset();
|
||||||
|
|
||||||
// Re-read the modified memory block to asynchronously update of the memory cache
|
// 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) {
|
new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
updateMemoryCache(address.add(offset), count, getData());
|
updateMemoryCache(address.add(offset), word_count, getData(), word_size);
|
||||||
// Send the MemoryChangedEvent
|
// Send the MemoryChangedEvent
|
||||||
IAddress[] addresses = new IAddress[count];
|
IAddress[] addresses = new IAddress[word_count];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < word_count; i++) {
|
||||||
addresses[i] = address.add(offset + i);
|
addresses[i] = address.add(offset + i);
|
||||||
}
|
}
|
||||||
getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties());
|
getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties());
|
||||||
// Finally...
|
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -976,35 +988,35 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
* @param address
|
* @param address
|
||||||
* @param offset
|
* @param offset
|
||||||
* @param word_size
|
* @param word_size
|
||||||
* @param count
|
* @param word_count
|
||||||
* @param sendMemoryEvent Indicates if a IMemoryChangedEvent should be sent if the memory cache has changed.
|
* @param sendMemoryEvent Indicates if a IMemoryChangedEvent should be sent if the memory cache has changed.
|
||||||
* @param rm
|
* @param rm
|
||||||
*/
|
*/
|
||||||
public void refreshMemory(final IMemoryDMContext memoryDMC, final IAddress address,
|
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)
|
final RequestMonitor rm)
|
||||||
{
|
{
|
||||||
// Check if we already cache part of this memory area (which means it
|
// 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)
|
// 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;
|
int sizeToRead = 0;
|
||||||
for (MemoryBlock block : list) {
|
for (MemoryBlock block : list) {
|
||||||
sizeToRead += block.fLength;
|
sizeToRead += block.fLengthInAddressableUnits;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If none of the requested memory is in cache, just get out
|
// If none of the requested memory is in cache, just get out
|
||||||
if (sizeToRead == count) {
|
if (sizeToRead == word_count) {
|
||||||
rm.done();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the corresponding memory block
|
// Read the corresponding memory block
|
||||||
fCommandCache.reset();
|
fCommandCache.reset();
|
||||||
readMemoryBlock(memoryDMC, address, offset, word_size, count,
|
readMemoryBlock(memoryDMC, address, offset, word_size, word_count,
|
||||||
new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) {
|
new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
MemoryByte[] oldBlock = getMemoryBlockFromCache(address, count);
|
MemoryByte[] oldBlock = getMemoryBlockFromCache(address, word_count, word_size);
|
||||||
MemoryByte[] newBlock = getData();
|
MemoryByte[] newBlock = getData();
|
||||||
boolean blocksDiffer = false;
|
boolean blocksDiffer = false;
|
||||||
for (int i = 0; i < oldBlock.length; i++) {
|
for (int i = 0; i < oldBlock.length; i++) {
|
||||||
|
@ -1014,11 +1026,11 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (blocksDiffer) {
|
if (blocksDiffer) {
|
||||||
updateMemoryCache(address.add(offset), count, newBlock);
|
updateMemoryCache(address.add(offset), word_count, newBlock, word_size);
|
||||||
if (sendMemoryEvent) {
|
if (sendMemoryEvent) {
|
||||||
// Send the MemoryChangedEvent
|
// Send the MemoryChangedEvent
|
||||||
final IAddress[] addresses = new IAddress[count];
|
final IAddress[] addresses = new IAddress[word_count];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < word_count; i++) {
|
||||||
addresses[i] = address.add(offset + i);
|
addresses[i] = address.add(offset + i);
|
||||||
}
|
}
|
||||||
getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties());
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug (323552)
|
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug (323552)
|
||||||
* Philippe Gil (AdaCore) - Add show/set language CLI commands (Bug 421541)
|
* Philippe Gil (AdaCore) - Add show/set language CLI commands (Bug 421541)
|
||||||
* Dmitry Kozlov (Mentor Graphics) - New trace-related methods (Bug 390827)
|
* 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;
|
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.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
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.CLIAttach;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIDetach;
|
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.MIVarShowAttributes;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
|
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.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.CLICatchInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoBreakInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoBreakInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
|
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.MIDataReadMemoryInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataWriteMemoryInfo;
|
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.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.MIInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfoOsInfo;
|
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.MIListFeaturesInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo;
|
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.MIStackInfoDepthInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIStackListArgumentsInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIStackListArgumentsInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIStackListFramesInfo;
|
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 {
|
public class CommandFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.4
|
||||||
|
*/
|
||||||
|
public ICommand<CLIAddressableSizeInfo> createCLIAddressableSize(IMemoryDMContext ctx) {
|
||||||
|
return new CLIAddressableSize(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
public ICommand<MIInfo> createCLIAttach(IDMContext ctx, int pid) {
|
public ICommand<MIInfo> createCLIAttach(IDMContext ctx, int pid) {
|
||||||
return new CLIAttach(ctx, pid);
|
return new CLIAttach(ctx, pid);
|
||||||
}
|
}
|
||||||
|
@ -475,6 +485,14 @@ public class CommandFactory {
|
||||||
return new MIDataReadMemoryBytes(ctx, address, offset, num_bytes);
|
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,
|
public ICommand<MIDataWriteMemoryInfo> createMIDataWriteMemory(IDMContext ctx, long offset, String address,
|
||||||
int wordFormat, int wordSize, String value) {
|
int wordFormat, int wordSize, String value) {
|
||||||
return new MIDataWriteMemory(ctx, offset, address, wordFormat, wordSize, 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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* 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.commands;
|
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.
|
* be quoted using the C convention.
|
||||||
*
|
*
|
||||||
* `COUNT'
|
* `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'
|
* `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
|
* reading. This should be an integer literal. This option is
|
||||||
* provided so that a frontend is not required to first evaluate
|
* provided so that a frontend is not required to first evaluate
|
||||||
* address and then perform address arithmetics itself.
|
* 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> {
|
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,
|
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$
|
super(ctx, "-data-read-memory-bytes"); //$NON-NLS-1$
|
||||||
|
|
||||||
fSize = num_bytes;
|
fCount = count;
|
||||||
|
fword_size = word_size;
|
||||||
|
|
||||||
if (offset != 0) {
|
if (offset != 0) {
|
||||||
setOptions(new String[] { "-o", Long.toString(offset) }); //$NON-NLS-1$
|
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
|
@Override
|
||||||
public MIDataReadMemoryBytesInfo getResult(MIOutput out) {
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* 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;
|
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 {
|
public class MIDataReadMemoryBytesInfo extends MIInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Addressable size in octets
|
||||||
|
*/
|
||||||
|
private static final int DEFAULT_WORD_SIZE = 1;
|
||||||
/* The cached memory block. */
|
/* The cached memory block. */
|
||||||
private MemoryByte[] fBlock = null;
|
private MemoryByte[] fBlock = null;
|
||||||
|
|
||||||
public MIDataReadMemoryBytesInfo(MIOutput output, int size) {
|
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);
|
super(output);
|
||||||
parse(size);
|
parse(count, word_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,11 +54,11 @@ public class MIDataReadMemoryBytesInfo extends MIInfo {
|
||||||
return fBlock;
|
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.
|
// 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);
|
fBlock[i] = new MemoryByte((byte) 0, (byte) 0);
|
||||||
|
|
||||||
MIResult[] results = getMIOutput().getMIResultRecord().getMIResults();
|
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) {
|
for (int k = 0; k < contents.length() / 2; ++k) {
|
||||||
fBlock[offset + k] = new MemoryByte(
|
fBlock[offset*word_size + k] = new MemoryByte(
|
||||||
(byte) Integer.parseInt(
|
(byte) Integer.parseInt(
|
||||||
contents.substring(k * 2, k * 2 + 2),
|
contents.substring(k * 2, k * 2 + 2),
|
||||||
16));
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Ericsson AB - Initial Implementation
|
* 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;
|
package org.eclipse.cdt.tests.dsf.gdb.tests;
|
||||||
|
|
||||||
|
@ -530,7 +531,7 @@ public class MIMemoryTest extends BaseTestCase {
|
||||||
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
||||||
|
|
||||||
// Perform the test
|
// Perform the test
|
||||||
String expected = "Word size not supported (!= 1)";
|
String expected = "Word size not supported (< 1)";
|
||||||
fWait.waitReset();
|
fWait.waitReset();
|
||||||
readMemory(fMemoryDmc, fBaseAddress, offset, 0, count);
|
readMemory(fMemoryDmc, fBaseAddress, offset, 0, count);
|
||||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||||
|
@ -538,13 +539,6 @@ public class MIMemoryTest extends BaseTestCase {
|
||||||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||||
fWait.getMessage().contains(expected));
|
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
|
// Ensure no MemoryChangedEvent event was received
|
||||||
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
||||||
}
|
}
|
||||||
|
@ -823,7 +817,7 @@ public class MIMemoryTest extends BaseTestCase {
|
||||||
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
||||||
|
|
||||||
// Perform the test
|
// Perform the test
|
||||||
String expected = "Word size not supported (!= 1)";
|
String expected = "Word size not supported (< 1)";
|
||||||
fWait.waitReset();
|
fWait.waitReset();
|
||||||
writeMemory(fMemoryDmc, fBaseAddress, offset, 0, count, buffer);
|
writeMemory(fMemoryDmc, fBaseAddress, offset, 0, count, buffer);
|
||||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||||
|
@ -831,13 +825,6 @@ public class MIMemoryTest extends BaseTestCase {
|
||||||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||||
fWait.getMessage().contains(expected));
|
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
|
// Ensure no MemoryChangedEvent event was received
|
||||||
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
||||||
}
|
}
|
||||||
|
@ -1184,7 +1171,7 @@ public class MIMemoryTest extends BaseTestCase {
|
||||||
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
fBaseAddress = evaluateExpression(frameDmc, "&charBlock");
|
||||||
|
|
||||||
// Perform the test
|
// Perform the test
|
||||||
String expected = "Word size not supported (!= 1)";
|
String expected = "Word size not supported (< 1)";
|
||||||
fWait.waitReset();
|
fWait.waitReset();
|
||||||
fillMemory(fMemoryDmc, fBaseAddress, offset, 0, count, pattern);
|
fillMemory(fMemoryDmc, fBaseAddress, offset, 0, count, pattern);
|
||||||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||||
|
@ -1192,13 +1179,6 @@ public class MIMemoryTest extends BaseTestCase {
|
||||||
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
assertTrue("Wrong error message: expected '" + expected + "', received '" + fWait.getMessage() + "'",
|
||||||
fWait.getMessage().contains(expected));
|
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
|
// Ensure no MemoryChangedEvent event was received
|
||||||
assertTrue("MemoryChangedEvent problem: expected " + 0 + ", received " + getEventCount(), getEventCount() == 0);
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -11,6 +11,7 @@
|
||||||
* Ericsson Communication - added support for 64 bit processors
|
* Ericsson Communication - added support for 64 bit processors
|
||||||
* Ericsson Communication - added support for changed bytes
|
* Ericsson Communication - added support for changed bytes
|
||||||
* Ericsson Communication - better management of exceptions
|
* 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;
|
package org.eclipse.cdt.dsf.debug.model;
|
||||||
|
|
||||||
|
@ -325,7 +326,12 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
||||||
@Override
|
@Override
|
||||||
public MemoryByte[] getBytesFromAddress(BigInteger address, long units) throws DebugException {
|
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;
|
return fBlock;
|
||||||
|
|
||||||
MemoryByte[] newBlock = fetchMemoryBlock(address, units);
|
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
|
// 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
|
// 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.
|
// 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) {
|
if (bigDistance.compareTo(BigInteger.valueOf(fLength)) == -1) {
|
||||||
// Calculate the length of the data we are going to examine/update
|
// Calculate the length of the data we are going to examine/update
|
||||||
int distance = bigDistance.intValue();
|
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
|
// 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
|
// is some overlap between the blocks and we have to update the blanks and
|
||||||
// possibly note they are changed.
|
// 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) {
|
if (bigDistance.compareTo(BigInteger.valueOf(newLength)) == -1) {
|
||||||
// Calculate the length of the data we are going to examine/update
|
// Calculate the length of the data we are going to examine/update
|
||||||
int distance = bigDistance.intValue();
|
int distance = bigDistance.intValue();
|
||||||
|
@ -580,7 +586,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int getAddressableSize() throws DebugException {
|
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.
|
* asynchronous calls to complete before returning.
|
||||||
*
|
*
|
||||||
* @param bigAddress
|
* @param bigAddress
|
||||||
* @param length
|
* @param count - Number of addressable units for this memory block
|
||||||
* @return MemoryByte[]
|
* @return MemoryByte[]
|
||||||
* @throws DebugException
|
* @throws DebugException
|
||||||
* @since 2.1
|
* @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
|
// For the IAddress interface
|
||||||
final Addr64 address = new Addr64(bigAddress);
|
final Addr64 address = new Addr64(bigAddress);
|
||||||
|
|
||||||
|
@ -611,7 +625,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
||||||
if (memoryService != null) {
|
if (memoryService != null) {
|
||||||
// Go for it
|
// Go for it
|
||||||
memoryService.getMemory(
|
memoryService.getMemory(
|
||||||
fContext, address, 0, fWordSize, (int) length,
|
fContext, address, 0, addressableSize, (int) count,
|
||||||
new DataRequestMonitor<MemoryByte[]>(fRetrieval.getExecutor(), drm) {
|
new DataRequestMonitor<MemoryByte[]>(fRetrieval.getExecutor(), drm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
|
@ -645,7 +659,17 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
protected void writeMemoryBlock(final long offset, final byte[] bytes) throws DebugException {
|
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
|
// For the IAddress interface
|
||||||
final Addr64 address = new Addr64(fBaseAddress);
|
final Addr64 address = new Addr64(fBaseAddress);
|
||||||
|
|
||||||
|
@ -657,7 +681,7 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
||||||
if (memoryService != null) {
|
if (memoryService != null) {
|
||||||
// Go for it
|
// Go for it
|
||||||
memoryService.setMemory(
|
memoryService.setMemory(
|
||||||
fContext, address, offset, fWordSize, bytes.length, bytes,
|
fContext, address, offset, addressableSize, addressableUnits, bytes,
|
||||||
new RequestMonitor(fRetrieval.getExecutor(), drm));
|
new RequestMonitor(fRetrieval.getExecutor(), drm));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -711,9 +735,16 @@ public class DsfMemoryBlock extends PlatformObject implements IMemoryBlockExtens
|
||||||
* @param length
|
* @param length
|
||||||
*/
|
*/
|
||||||
public void handleMemoryChange(BigInteger address) {
|
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)
|
// 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) ||
|
if (address.equals(BigInteger.ZERO) ||
|
||||||
((fBlockAddress.compareTo(address) != 1) && (fEndAddress.compareTo(address) == 1)))
|
((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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
|
* 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;
|
package org.eclipse.cdt.debug.ui.memory.traditional;
|
||||||
|
@ -917,8 +918,8 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
{
|
{
|
||||||
IMemoryBlockExtension memoryBlock = getMemoryBlock();
|
IMemoryBlockExtension memoryBlock = getMemoryBlock();
|
||||||
|
|
||||||
BigInteger lengthInBytes = endAddress.subtract(startAddress);
|
final BigInteger addressableSize = BigInteger.valueOf(getAddressableSize());
|
||||||
BigInteger addressableSize = BigInteger.valueOf(getAddressableSize());
|
BigInteger lengthInBytes = endAddress.subtract(startAddress).multiply(addressableSize);
|
||||||
|
|
||||||
long units = lengthInBytes.divide(addressableSize).add(
|
long units = lengthInBytes.divide(addressableSize).add(
|
||||||
lengthInBytes.mod(addressableSize).compareTo(BigInteger.ZERO) > 0
|
lengthInBytes.mod(addressableSize).compareTo(BigInteger.ZERO) > 0
|
||||||
|
@ -984,15 +985,15 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
BigInteger.valueOf(1));
|
BigInteger.valueOf(1));
|
||||||
|
|
||||||
BigInteger overlapLength = minEnd
|
BigInteger overlapLength = minEnd
|
||||||
.subtract(maxStart);
|
.subtract(maxStart).multiply(addressableSize);
|
||||||
if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
|
if(overlapLength.compareTo(BigInteger.valueOf(0)) > 0)
|
||||||
{
|
{
|
||||||
// there is overlap
|
// there is overlap
|
||||||
|
|
||||||
int offsetIntoOld = maxStart.subtract(
|
int offsetIntoOld = (maxStart.subtract(
|
||||||
fHistoryCache[historyIndex].start).intValue();
|
fHistoryCache[historyIndex].start).multiply(addressableSize)).intValue();
|
||||||
int offsetIntoNew = maxStart.subtract(
|
int offsetIntoNew = maxStart.subtract(
|
||||||
startAddress).intValue();
|
startAddress).multiply(addressableSize).intValue();
|
||||||
|
|
||||||
for(int i = overlapLength.intValue(); i >= 0; i--)
|
for(int i = overlapLength.intValue(); i >= 0; i--)
|
||||||
{
|
{
|
||||||
|
@ -1035,6 +1036,10 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
Display.getDefault().getThread()) : TraditionalRenderingMessages
|
||||||
.getString("TraditionalRendering.CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$
|
.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
|
if(containsEditedCell(address)) // cell size cannot be switched during an edit
|
||||||
return getEditedMemory(address);
|
return getEditedMemory(address);
|
||||||
|
|
||||||
|
@ -1042,7 +1047,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
if(fCache != null && fCache.start != null)
|
if(fCache != null && fCache.start != null)
|
||||||
{
|
{
|
||||||
// see if all of the data requested is in the cache
|
// 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
|
if(fCache.start.compareTo(address) <= 0
|
||||||
&& fCache.end.compareTo(dataEnd) >= 0
|
&& fCache.end.compareTo(dataEnd) >= 0
|
||||||
|
@ -1052,7 +1057,7 @@ public class Rendering extends Composite implements IDebugEventSetListener
|
||||||
|
|
||||||
if(contains)
|
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];
|
TraditionalMemoryByte bytes[] = new TraditionalMemoryByte[bytesRequested];
|
||||||
for(int i = 0; i < bytes.length; i++)
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
|
* 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;
|
package org.eclipse.cdt.debug.ui.memory.traditional;
|
||||||
|
@ -1616,8 +1617,12 @@ abstract class CopyAction extends Action
|
||||||
// : 0);
|
// : 0);
|
||||||
|
|
||||||
final int columns = fRendering.getColumnCount();
|
final int columns = fRendering.getColumnCount();
|
||||||
|
int addressableSize = fRendering.getAddressableSize();
|
||||||
BigInteger lengthToRead = end.subtract(start);
|
assert(addressableSize != 0);
|
||||||
|
|
||||||
|
int addressesPerColumn = bytesPerColumn/addressableSize;
|
||||||
|
|
||||||
|
BigInteger lengthToRead = end.subtract(start).multiply(BigInteger.valueOf(addressableSize));
|
||||||
|
|
||||||
int rows = lengthToRead.divide(
|
int rows = lengthToRead.divide(
|
||||||
BigInteger.valueOf(columns * bytesPerColumn)).intValue();
|
BigInteger.valueOf(columns * bytesPerColumn)).intValue();
|
||||||
|
@ -1630,7 +1635,7 @@ abstract class CopyAction extends Action
|
||||||
for(int row = 0; row < rows; row++)
|
for(int row = 0; row < rows; row++)
|
||||||
{
|
{
|
||||||
BigInteger rowAddress = start.add(BigInteger.valueOf(row
|
BigInteger rowAddress = start.add(BigInteger.valueOf(row
|
||||||
* columns * bytesPerColumn));
|
* columns * addressesPerColumn));
|
||||||
|
|
||||||
if(copyAddress)
|
if(copyAddress)
|
||||||
{
|
{
|
||||||
|
@ -1643,7 +1648,7 @@ abstract class CopyAction extends Action
|
||||||
for(int col = 0; col < columns; col++)
|
for(int col = 0; col < columns; col++)
|
||||||
{
|
{
|
||||||
BigInteger cellAddress = rowAddress.add(BigInteger
|
BigInteger cellAddress = rowAddress.add(BigInteger
|
||||||
.valueOf(col * bytesPerColumn));
|
.valueOf(col * addressesPerColumn));
|
||||||
|
|
||||||
if(cellAddress.compareTo(end) < 0)
|
if(cellAddress.compareTo(end) < 0)
|
||||||
{
|
{
|
||||||
|
@ -1685,7 +1690,7 @@ abstract class CopyAction extends Action
|
||||||
for(int col = 0; col < columns; col++)
|
for(int col = 0; col < columns; col++)
|
||||||
{
|
{
|
||||||
BigInteger cellAddress = rowAddress.add(BigInteger
|
BigInteger cellAddress = rowAddress.add(BigInteger
|
||||||
.valueOf(col * fRendering.getBytesPerColumn()));
|
.valueOf(col * addressesPerColumn));
|
||||||
|
|
||||||
if(cellAddress.compareTo(end) < 0)
|
if(cellAddress.compareTo(end) < 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue