mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 09:46:02 +02:00
Bug 322658: Support for new GDB MI command -data-read-memory-bytes. It is already supported in GDB HEAD and will be officialy available with GDB 7.3
This commit is contained in:
parent
c31e996fc2
commit
fa9a41f13a
9 changed files with 386 additions and 19 deletions
|
@ -8,13 +8,16 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Wind River Systems - initial API and implementation
|
* Wind River Systems - initial API and implementation
|
||||||
* Ericsson - Modified for additional features in DSF Reference implementation
|
* Ericsson - Modified for additional features in DSF Reference implementation
|
||||||
* Nokia - create and use backend service.
|
* Nokia - create and use backend service.
|
||||||
|
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
package org.eclipse.cdt.dsf.gdb.service.command;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -597,4 +600,15 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GDBControl is only used for GDB earlier that 7.0. Although -list-features
|
||||||
|
* is available in 6.8, it does not report anything we care about, so
|
||||||
|
* return empty list.
|
||||||
|
*/
|
||||||
|
private final List<String> fFeatures = new ArrayList<String>();
|
||||||
|
/** @since 4.0 */
|
||||||
|
public List<String> getFeatures() {
|
||||||
|
return fFeatures;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,15 @@
|
||||||
* Wind River Systems - initial API and implementation
|
* Wind River Systems - initial API and implementation
|
||||||
* Ericsson - Modified for additional features in DSF Reference implementation
|
* Ericsson - Modified for additional features in DSF Reference implementation
|
||||||
* Ericsson - New version for 7_0
|
* Ericsson - New version for 7_0
|
||||||
|
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
package org.eclipse.cdt.dsf.gdb.service.command;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -61,6 +64,7 @@ import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor_7_0;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
|
||||||
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.MIListFeaturesInfo;
|
||||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.cdt.utils.pty.PTY;
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
|
@ -116,6 +120,7 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
private MIInferiorProcess fInferiorProcess = null;
|
private MIInferiorProcess fInferiorProcess = null;
|
||||||
|
|
||||||
private PTY fPty;
|
private PTY fPty;
|
||||||
|
private List<String> fFeatures = new ArrayList<String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -150,6 +155,7 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
new CommandMonitoringStep(InitializationShutdownStep.Direction.INITIALIZING),
|
new CommandMonitoringStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||||
new InferiorInputOutputInitStep(InitializationShutdownStep.Direction.INITIALIZING),
|
new InferiorInputOutputInitStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||||
new CommandProcessorsStep(InitializationShutdownStep.Direction.INITIALIZING),
|
new CommandProcessorsStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||||
|
new ListFeaturesStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||||
new RegisterStep(InitializationShutdownStep.Direction.INITIALIZING),
|
new RegisterStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -163,6 +169,7 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
public void shutdown(final RequestMonitor requestMonitor) {
|
public void shutdown(final RequestMonitor requestMonitor) {
|
||||||
final Sequence.Step[] shutdownSteps = new Sequence.Step[] {
|
final Sequence.Step[] shutdownSteps = new Sequence.Step[] {
|
||||||
new RegisterStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
new RegisterStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||||
|
new ListFeaturesStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||||
new CommandProcessorsStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
new CommandProcessorsStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||||
new InferiorInputOutputInitStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
new InferiorInputOutputInitStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||||
new CommandMonitoringStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
new CommandMonitoringStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||||
|
@ -238,6 +245,18 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void listFeatures(final RequestMonitor requestMonitor) {
|
||||||
|
queueCommand(
|
||||||
|
getCommandFactory().createMIListFeatures(fControlDmc),
|
||||||
|
new DataRequestMonitor<MIListFeaturesInfo>(getExecutor(), requestMonitor) {
|
||||||
|
@Override
|
||||||
|
public void handleSuccess() {
|
||||||
|
fFeatures = getData().getFeatures();
|
||||||
|
super.handleSuccess();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method does the necessary work to setup the input/output streams for the
|
* This method does the necessary work to setup the input/output streams for the
|
||||||
* inferior process, by either preparing the PTY to be used, to simply leaving
|
* inferior process, by either preparing the PTY to be used, to simply leaving
|
||||||
|
@ -572,6 +591,11 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
countingRm.setDoneCount(count);
|
countingRm.setDoneCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**@since 4.0 */
|
||||||
|
public List<String> getFeatures() {
|
||||||
|
return fFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
public void eventDispatched(ICommandControlShutdownDMEvent e) {
|
public void eventDispatched(ICommandControlShutdownDMEvent e) {
|
||||||
// Handle our "GDB Exited" event and stop processing commands.
|
// Handle our "GDB Exited" event and stop processing commands.
|
||||||
|
@ -723,6 +747,21 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
protected class ListFeaturesStep extends InitializationShutdownStep {
|
||||||
|
ListFeaturesStep(Direction direction) { super(direction); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initialize(final RequestMonitor requestMonitor) {
|
||||||
|
listFeatures(requestMonitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutdown(RequestMonitor requestMonitor) {
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class RegisterStep extends InitializationShutdownStep {
|
protected class RegisterStep extends InitializationShutdownStep {
|
||||||
RegisterStep(Direction direction) { super(direction); }
|
RegisterStep(Direction direction) { super(direction); }
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2010 Ericsson and others.
|
* Copyright (c) 2008, 2010 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 License v1.0
|
* are made available under the terms of the Eclipse License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,10 +7,12 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Ericsson - initial API and implementation
|
* Ericsson - initial API and implementation
|
||||||
|
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
package org.eclipse.cdt.dsf.gdb.service.command;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
@ -53,4 +55,15 @@ public interface IGDBControl extends IMICommandControl {
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
void setEnvironment(Properties props, boolean clear, RequestMonitor requestMonitor);
|
void setEnvironment(Properties props, boolean clear, RequestMonitor requestMonitor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all the target-independent MI features
|
||||||
|
* supported by the GDB that is being used. Consult the GDB MI documentation
|
||||||
|
* for the MI -list-features command for the possible names of features.
|
||||||
|
*
|
||||||
|
* The return value is never null but may be an empty list.
|
||||||
|
*
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
List<String> getFeatures();
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
* Ericsson AB - expanded from initial stub
|
* Ericsson AB - expanded from initial stub
|
||||||
* Ericsson AB - added support for event handling
|
* Ericsson AB - added support for event handling
|
||||||
* Ericsson AB - added memory cache
|
* Ericsson AB - added memory cache
|
||||||
|
* Vladimir Prus (CodeSourcery) - support for -data-read-memory-bytes (bug 322658)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.mi.service;
|
package org.eclipse.cdt.dsf.mi.service;
|
||||||
|
|
||||||
|
@ -29,9 +30,9 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.ICachingService;
|
import org.eclipse.cdt.dsf.debug.service.ICachingService;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IMemory;
|
|
||||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
|
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IMemory;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||||
|
@ -39,10 +40,11 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.BufferedCommandControl;
|
import org.eclipse.cdt.dsf.debug.service.command.BufferedCommandControl;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
|
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIExpressions.ExpressionChangedEvent;
|
import org.eclipse.cdt.dsf.mi.service.MIExpressions.ExpressionChangedEvent;
|
||||||
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.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.service.AbstractDsfService;
|
import org.eclipse.cdt.dsf.service.AbstractDsfService;
|
||||||
|
@ -59,6 +61,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$
|
||||||
|
|
||||||
public class MemoryChangedEvent extends AbstractDMEvent<IMemoryDMContext>
|
public class MemoryChangedEvent extends AbstractDMEvent<IMemoryDMContext>
|
||||||
implements IMemoryChangedEvent
|
implements IMemoryChangedEvent
|
||||||
{
|
{
|
||||||
|
@ -91,6 +95,10 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Whether the -data-read-memory-bytes should be used
|
||||||
|
// instead of -data-read-memory
|
||||||
|
private boolean fDataReadMemoryBytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
@ -128,9 +136,11 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
*/
|
*/
|
||||||
private void doInitialize(final RequestMonitor requestMonitor) {
|
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||||
// Create the command cache
|
// Create the command cache
|
||||||
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
|
IGDBControl commandControl = getServicesTracker().getService(IGDBControl.class);
|
||||||
BufferedCommandControl bufferedCommandControl = new BufferedCommandControl(commandControl, getExecutor(), 2);
|
BufferedCommandControl bufferedCommandControl = new BufferedCommandControl(commandControl, getExecutor(), 2);
|
||||||
|
|
||||||
|
fDataReadMemoryBytes = commandControl.getFeatures().contains(READ_MEMORY_BYTES_FEATURE);
|
||||||
|
|
||||||
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
||||||
|
|
||||||
// This cache stores the result of a command when received; also, this cache
|
// This cache stores the result of a command when received; also, this cache
|
||||||
|
@ -319,15 +329,32 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
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 count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||||
{
|
{
|
||||||
/* To simplify the parsing of the MI result, we request the output to
|
if (fDataReadMemoryBytes) {
|
||||||
* be on 1 row of [count] columns, no char interpretation.
|
fCommandCache.execute(
|
||||||
*/
|
fCommandFactory.createMIDataReadMemoryBytes(dmc, address.toString(), offset*word_size, count*word_size),
|
||||||
int mode = MIFormat.HEXADECIMAL;
|
new DataRequestMonitor<MIDataReadMemoryBytesInfo>(getExecutor(), drm) {
|
||||||
int nb_rows = 1;
|
@Override
|
||||||
int nb_cols = count;
|
protected void handleSuccess() {
|
||||||
Character asChar = null;
|
// Retrieve the memory block
|
||||||
|
drm.setData(getData().getMIMemoryBlock());
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void handleFailure() {
|
||||||
|
drm.setData(createInvalidBlock(word_size * count));
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
/* To simplify the parsing of the MI result, we request the output to
|
||||||
|
* be on 1 row of [count] columns, no char interpretation.
|
||||||
|
*/
|
||||||
|
int mode = MIFormat.HEXADECIMAL;
|
||||||
|
int nb_rows = 1;
|
||||||
|
int nb_cols = count;
|
||||||
|
Character asChar = null;
|
||||||
|
|
||||||
fCommandCache.execute(
|
fCommandCache.execute(
|
||||||
fCommandFactory.createMIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
|
fCommandFactory.createMIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
|
||||||
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
|
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -338,16 +365,21 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void handleFailure() {
|
protected void handleFailure() {
|
||||||
// Bug234289: If memory read fails, return a block marked as invalid
|
drm.setData(createInvalidBlock(word_size * count));
|
||||||
MemoryByte[] block = new MemoryByte[word_size * count];
|
|
||||||
for (int i = 0; i < block.length; i++)
|
|
||||||
block[i] = new MemoryByte((byte) 0, (byte) 0);
|
|
||||||
drm.setData(block);
|
|
||||||
drm.done();
|
drm.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MemoryByte[] createInvalidBlock(int size) {
|
||||||
|
// Bug234289: If memory read fails, return a block marked as invalid
|
||||||
|
MemoryByte[] block = new MemoryByte[size];
|
||||||
|
for (int i = 0; i < block.length; i++)
|
||||||
|
block[i] = new MemoryByte((byte) 0, (byte) 0);
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param memoryDMC
|
* @param memoryDMC
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
* ENEA Software AB - CLI command extension - fix for bug 190277
|
* ENEA Software AB - CLI command extension - fix for bug 190277
|
||||||
* Ericsson - Implementation for DSF-GDB
|
* Ericsson - Implementation for DSF-GDB
|
||||||
* Anna Dushistova (Mentor Graphics) - [318322] Add set solib-absolute-prefix
|
* Anna Dushistova (Mentor Graphics) - [318322] Add set solib-absolute-prefix
|
||||||
|
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.dsf.mi.service.command;
|
package org.eclipse.cdt.dsf.mi.service.command;
|
||||||
|
@ -57,6 +58,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataEvaluateExpression;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataListRegisterNames;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataListRegisterNames;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataListRegisterValues;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataListRegisterValues;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataReadMemory;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataReadMemory;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataReadMemoryBytes;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataWriteMemory;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataWriteMemory;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentCD;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentCD;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentDirectory;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentDirectory;
|
||||||
|
@ -94,6 +96,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBShowExitCode;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExec;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExec;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListFeatures;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListThreadGroups;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListThreadGroups;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIRemoveInferior;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIRemoveInferior;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackInfoDepth;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackInfoDepth;
|
||||||
|
@ -145,10 +148,12 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIDataDisassembleInfo;
|
||||||
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.MIDataListRegisterNamesInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataListRegisterNamesInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataListRegisterValuesInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataListRegisterValuesInfo;
|
||||||
|
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.MIInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||||
|
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.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;
|
||||||
|
@ -358,6 +363,12 @@ public class CommandFactory {
|
||||||
return new MIDataReadMemory(ctx, offset, address, word_format, word_size, rows, cols, asChar);
|
return new MIDataReadMemory(ctx, offset, address, word_format, word_size, rows, cols, asChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public ICommand<MIDataReadMemoryBytesInfo> createMIDataReadMemoryBytes(IDMContext ctx, String address,
|
||||||
|
long offset, int num_bytes) {
|
||||||
|
return new MIDataReadMemoryBytes(ctx, address, offset, num_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -588,6 +599,11 @@ public class CommandFactory {
|
||||||
return new MIInterpreterExecConsole<MIInfo>(ctx, cmd);
|
return new MIInterpreterExecConsole<MIInfo>(ctx, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public ICommand<MIListFeaturesInfo> createMIListFeatures(ICommandControlDMContext ctx) {
|
||||||
|
return new MIListFeatures(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
public ICommand<MIListThreadGroupsInfo> createMIListThreadGroups(ICommandControlDMContext ctx) {
|
public ICommand<MIListThreadGroupsInfo> createMIListThreadGroups(ICommandControlDMContext ctx) {
|
||||||
return new MIListThreadGroups(ctx);
|
return new MIListThreadGroups(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 CodeSourcery and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Vladimir Prus (CodeSourcery) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataReadMemoryBytesInfo;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -data-read-memory-bytes [ -o BYTE-OFFSET ]
|
||||||
|
* ADDRESS COUNT
|
||||||
|
* where:
|
||||||
|
*
|
||||||
|
* `ADDRESS'
|
||||||
|
* An expression specifying the address of the first memory word to be
|
||||||
|
* read. Complex expressions containing embedded white space should
|
||||||
|
* be quoted using the C convention.
|
||||||
|
*
|
||||||
|
* `COUNT'
|
||||||
|
* The number of bytes to read. This should be an integer literal.
|
||||||
|
*
|
||||||
|
* `BYTE-OFFSET'
|
||||||
|
* The offsets in bytes relative to ADDRESS at which to start
|
||||||
|
* reading. This should be an integer literal. This option is
|
||||||
|
* provided so that a frontend is not required to first evaluate
|
||||||
|
* address and then perform address arithmetics itself.
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public class MIDataReadMemoryBytes extends MICommand<MIDataReadMemoryBytesInfo> {
|
||||||
|
|
||||||
|
private int fSize;
|
||||||
|
|
||||||
|
public MIDataReadMemoryBytes(IDMContext ctx, String address, long offset,
|
||||||
|
int num_bytes) {
|
||||||
|
super(ctx, "-data-read-memory-bytes"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
fSize = num_bytes;
|
||||||
|
|
||||||
|
if (offset != 0) {
|
||||||
|
setOptions(new String[] { "-o", Long.toString(offset) }); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
setParameters(new String[] { address, Integer.toString(num_bytes) });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MIDataReadMemoryBytesInfo getResult(MIOutput out) {
|
||||||
|
return new MIDataReadMemoryBytesInfo(out, fSize);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 CodeSourcery and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Vladimir Prus (CodeSourcery) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIListFeaturesInfo;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -list-features
|
||||||
|
*
|
||||||
|
* Returns a list of particular features of the MI protocol that this
|
||||||
|
* version of gdb implements. A feature can be a command, or a new field
|
||||||
|
* in an output of some command, or even an important bugfix. While a
|
||||||
|
* frontend can sometimes detect presence of a feature at runtime, it is
|
||||||
|
* easier to perform detection at debugger startup.
|
||||||
|
*
|
||||||
|
* The command returns a list of strings, with each string naming an
|
||||||
|
* available feature. Each returned string is just a name, it does not
|
||||||
|
* have any internal structure.
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public class MIListFeatures extends MICommand<MIListFeaturesInfo> {
|
||||||
|
|
||||||
|
public MIListFeatures(ICommandControlDMContext ctx) {
|
||||||
|
super(ctx, "-list-features"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MIListFeaturesInfo getResult(MIOutput out) {
|
||||||
|
return new MIListFeaturesInfo(out);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 CodeSourcery and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Vladimir Prus (CodeSourcery) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||||
|
|
||||||
|
import org.eclipse.debug.core.model.MemoryByte;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example output is:
|
||||||
|
*
|
||||||
|
* (gdb)
|
||||||
|
* -data-read-memory-bytes &a 10
|
||||||
|
* ^done,memory=[{begin="0xbffff154",offset="0x00000000",
|
||||||
|
* end="0xbffff15e",
|
||||||
|
* contents="01000000020000000300"}]
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public class MIDataReadMemoryBytesInfo extends MIInfo {
|
||||||
|
|
||||||
|
/* The cached memory block. */
|
||||||
|
private MemoryByte[] fBlock = null;
|
||||||
|
|
||||||
|
public MIDataReadMemoryBytesInfo(MIOutput output, int size) {
|
||||||
|
super(output);
|
||||||
|
parse(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the memory block
|
||||||
|
*/
|
||||||
|
public MemoryByte[] getMIMemoryBlock() {
|
||||||
|
return fBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parse(int size)
|
||||||
|
{
|
||||||
|
fBlock = new MemoryByte[size];
|
||||||
|
// Fill the block with invalid bytes, initially.
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
fBlock[i] = new MemoryByte((byte) 0, (byte) 0);
|
||||||
|
|
||||||
|
MIResult[] results = getMIOutput().getMIResultRecord().getMIResults();
|
||||||
|
|
||||||
|
for (int i = 0; i < results.length; i++) {
|
||||||
|
|
||||||
|
if (results[i].getVariable().equals("memory")) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
MIList v = (MIList) (results[i].getMIValue());
|
||||||
|
try {
|
||||||
|
for (int j = 0; j < v.getMIValues().length; ++j) {
|
||||||
|
MITuple b = (MITuple) (v.getMIValues()[j]);
|
||||||
|
int offset = 0;
|
||||||
|
String contents = ""; //$NON-NLS-1$
|
||||||
|
for (int k = 0; k < b.getMIResults().length; ++k) {
|
||||||
|
MIResult r = b.getMIResults()[k];
|
||||||
|
if (r.getVariable().equals("offset")) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
String offset_s = ((MIConst) r.getMIValue())
|
||||||
|
.getCString();
|
||||||
|
offset = Integer.decode(offset_s);
|
||||||
|
} else if (r.getVariable().equals("contents")) //$NON-NLS-1$
|
||||||
|
{
|
||||||
|
contents = ((MIConst) r.getMIValue()).getCString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset + contents.length()/2 <= size)
|
||||||
|
for (int k = 0; k < contents.length() / 2; ++k) {
|
||||||
|
fBlock[offset + k] = new MemoryByte(
|
||||||
|
(byte) Integer.parseInt(
|
||||||
|
contents.substring(k * 2, k * 2 + 2),
|
||||||
|
16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(NumberFormatException e)
|
||||||
|
{
|
||||||
|
// Something went wrong. Stop processing this memory range.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 CodeSourcery and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Vladimir Prus (CodeSourcery) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example output is:
|
||||||
|
*
|
||||||
|
* (gdb) -list-features
|
||||||
|
* ^done,result=["feature1","feature2"]
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public class MIListFeaturesInfo extends MIInfo {
|
||||||
|
|
||||||
|
private List<String> fFeatures = new ArrayList<String>();
|
||||||
|
|
||||||
|
public MIListFeaturesInfo(MIOutput out) {
|
||||||
|
super(out);
|
||||||
|
parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFeatures() {
|
||||||
|
return fFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parse() {
|
||||||
|
if (isDone()) {
|
||||||
|
MIOutput out = getMIOutput();
|
||||||
|
MIResultRecord rr = out.getMIResultRecord();
|
||||||
|
if (rr != null) {
|
||||||
|
MIResult[] results = rr.getMIResults();
|
||||||
|
for (int i = 0; i < results.length; i++) {
|
||||||
|
String var = results[i].getVariable();
|
||||||
|
if (var.equals("features")) { //$NON-NLS-1$
|
||||||
|
MIValue val = results[i].getMIValue();
|
||||||
|
if (val instanceof MIList) {
|
||||||
|
MIList list = (MIList) val;
|
||||||
|
for (int j = 0; j < list.getMIValues().length; ++j) {
|
||||||
|
MIValue feature = list.getMIValues()[j];
|
||||||
|
if (feature instanceof MIConst)
|
||||||
|
fFeatures.add(((MIConst) feature).getString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue