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:
|
||||
* Wind River Systems - initial API and 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -597,4 +600,15 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
|||
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
|
||||
* Ericsson - Modified for additional features in DSF Reference implementation
|
||||
* 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
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.MIBreakpoint;
|
||||
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.DsfSession;
|
||||
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 PTY fPty;
|
||||
private List<String> fFeatures = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
|
@ -150,6 +155,7 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
|||
new CommandMonitoringStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||
new InferiorInputOutputInitStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||
new CommandProcessorsStep(InitializationShutdownStep.Direction.INITIALIZING),
|
||||
new ListFeaturesStep(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) {
|
||||
final Sequence.Step[] shutdownSteps = new Sequence.Step[] {
|
||||
new RegisterStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||
new ListFeaturesStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||
new CommandProcessorsStep(InitializationShutdownStep.Direction.SHUTTING_DOWN),
|
||||
new InferiorInputOutputInitStep(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
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**@since 4.0 */
|
||||
public List<String> getFeatures() {
|
||||
return fFeatures;
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(ICommandControlShutdownDMEvent e) {
|
||||
// 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 {
|
||||
RegisterStep(Direction direction) { super(direction); }
|
||||
@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
|
||||
* are made available under the terms of the Eclipse License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -7,10 +7,12 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
|
@ -53,4 +55,15 @@ public interface IGDBControl extends IMICommandControl {
|
|||
* @since 3.0
|
||||
*/
|
||||
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 - added support for event handling
|
||||
* Ericsson AB - added memory cache
|
||||
* Vladimir Prus (CodeSourcery) - support for -data-read-memory-bytes (bug 322658)
|
||||
*******************************************************************************/
|
||||
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.debug.service.ICachingService;
|
||||
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.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.IContainerSuspendedDMEvent;
|
||||
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.command.BufferedCommandControl;
|
||||
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.service.command.IGDBControl;
|
||||
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.output.MIDataReadMemoryBytesInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataReadMemoryInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataWriteMemoryInfo;
|
||||
import org.eclipse.cdt.dsf.service.AbstractDsfService;
|
||||
|
@ -59,6 +61,8 @@ import org.osgi.framework.BundleContext;
|
|||
*/
|
||||
public class MIMemory extends AbstractDsfService implements IMemory, ICachingService {
|
||||
|
||||
private static final String READ_MEMORY_BYTES_FEATURE = "data-read-memory-bytes"; //$NON-NLS-1$
|
||||
|
||||
public class MemoryChangedEvent extends AbstractDMEvent<IMemoryDMContext>
|
||||
implements IMemoryChangedEvent
|
||||
{
|
||||
|
@ -91,6 +95,10 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
return cache;
|
||||
}
|
||||
|
||||
// Whether the -data-read-memory-bytes should be used
|
||||
// instead of -data-read-memory
|
||||
private boolean fDataReadMemoryBytes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -128,9 +136,11 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
*/
|
||||
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||
// Create the command cache
|
||||
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
|
||||
IGDBControl commandControl = getServicesTracker().getService(IGDBControl.class);
|
||||
BufferedCommandControl bufferedCommandControl = new BufferedCommandControl(commandControl, getExecutor(), 2);
|
||||
|
||||
fDataReadMemoryBytes = commandControl.getFeatures().contains(READ_MEMORY_BYTES_FEATURE);
|
||||
|
||||
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
||||
|
||||
// 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,
|
||||
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||
{
|
||||
/* 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;
|
||||
if (fDataReadMemoryBytes) {
|
||||
fCommandCache.execute(
|
||||
fCommandFactory.createMIDataReadMemoryBytes(dmc, address.toString(), offset*word_size, count*word_size),
|
||||
new DataRequestMonitor<MIDataReadMemoryBytesInfo>(getExecutor(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// 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),
|
||||
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
|
||||
@Override
|
||||
|
@ -338,16 +365,21 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
}
|
||||
@Override
|
||||
protected void handleFailure() {
|
||||
// Bug234289: If memory read fails, return a block marked as invalid
|
||||
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.setData(createInvalidBlock(word_size * count));
|
||||
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
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* ENEA Software AB - CLI command extension - fix for bug 190277
|
||||
* Ericsson - Implementation for DSF-GDB
|
||||
* 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;
|
||||
|
@ -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.MIDataListRegisterValues;
|
||||
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.MIEnvironmentCD;
|
||||
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.MIInterpreterExec;
|
||||
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.MIRemoveInferior;
|
||||
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.MIDataListRegisterNamesInfo;
|
||||
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.MIDataWriteMemoryInfo;
|
||||
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.MIListFeaturesInfo;
|
||||
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.MIStackListArgumentsInfo;
|
||||
|
@ -358,6 +363,12 @@ public class CommandFactory {
|
|||
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,
|
||||
int wordFormat, int wordSize, String value) {
|
||||
return new MIDataWriteMemory(ctx, offset, address, wordFormat, wordSize, value);
|
||||
|
@ -588,6 +599,11 @@ public class CommandFactory {
|
|||
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) {
|
||||
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