diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java index 735b9919348..7eea1d8d106 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java @@ -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 fFeatures = new ArrayList(); + /** @since 4.0 */ + public List getFeatures() { + return fFeatures; + } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java index f4e8af804b6..dd65e6a3c8f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java @@ -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 fFeatures = new ArrayList(); /** * @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(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 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 diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java index 58f525af9fb..02ecee9aa84 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java @@ -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 getFeatures(); } \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java index 975f7591b49..89420ea042b 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java @@ -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 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 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(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(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 diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java index d1bb9e1b796..942195a4bb4 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java @@ -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 createMIDataReadMemoryBytes(IDMContext ctx, String address, + long offset, int num_bytes) { + return new MIDataReadMemoryBytes(ctx, address, offset, num_bytes); + } + public ICommand 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(ctx, cmd); } + /** @since 4.0 */ + public ICommand createMIListFeatures(ICommandControlDMContext ctx) { + return new MIListFeatures(ctx); + } + public ICommand createMIListThreadGroups(ICommandControlDMContext ctx) { return new MIListThreadGroups(ctx); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIDataReadMemoryBytes.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIDataReadMemoryBytes.java new file mode 100644 index 00000000000..a5a4579cb97 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIDataReadMemoryBytes.java @@ -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 { + + 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); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListFeatures.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListFeatures.java new file mode 100644 index 00000000000..01b4931ea77 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListFeatures.java @@ -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 { + + public MIListFeatures(ICommandControlDMContext ctx) { + super(ctx, "-list-features"); //$NON-NLS-1$ + } + + @Override + public MIListFeaturesInfo getResult(MIOutput out) { + return new MIListFeaturesInfo(out); + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIDataReadMemoryBytesInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIDataReadMemoryBytesInfo.java new file mode 100644 index 00000000000..afe9f8c6234 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIDataReadMemoryBytesInfo.java @@ -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. + } + } + } + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListFeaturesInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListFeaturesInfo.java new file mode 100644 index 00000000000..a11eaa9d31b --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListFeaturesInfo.java @@ -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 fFeatures = new ArrayList(); + + public MIListFeaturesInfo(MIOutput out) { + super(out); + parse(); + } + + public List 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()); + } + } + } + } + } + } + } +}