/*******************************************************************************
* Copyright (c) 2006, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Ericsson - Modified for additional features in DSF Reference Implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
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.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
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.mi.service.command.CommandFactory;
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.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIRegisterValue;
import org.eclipse.cdt.dsf.service.AbstractDsfService;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
/**
*
* <p>
* Implementation note:
* This class implements event handlers for the events that are generated by
* this service itself. When the event is dispatched, these handlers will
* be called first, before any of the clients. These handlers update the
* service's internal state information to make them consistent with the
* events being issued. Doing this in the handlers as opposed to when
* the events are generated, guarantees that the state of the service will
* always be consistent with the events.
*/
public class MIRegisters extends AbstractDsfService implements IRegisters, ICachingService {
private static final String BLANK_STRING = ""; //$NON-NLS-1$
/*
* Support class used to construct Register Group DMCs.
*/
public static class MIRegisterGroupDMC extends AbstractDMContext implements IRegisterGroupDMContext {
private int fGroupNo;
private String fGroupName;
public MIRegisterGroupDMC(MIRegisters service, IContainerDMContext contDmc, int groupNo, String groupName) {
super(service.getSession().getId(), new IDMContext[] { contDmc });
fGroupNo = groupNo;
fGroupName = groupName;
}
public int getGroupNo() { return fGroupNo; }
public String getName() { return fGroupName; }
@Override
public boolean equals(Object other) {
return ((super.baseEquals(other)) && (((MIRegisterGroupDMC) other).fGroupNo == fGroupNo) &&
(((MIRegisterGroupDMC) other).fGroupName.equals(fGroupName)));
}
@Override
public int hashCode() { return super.baseHashCode() ^ fGroupNo; }
@Override
public String toString() { return baseToString() + ".group[" + fGroupNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
}
/*
* Support class used to construct Register DMCs.
*/
public static class MIRegisterDMC extends AbstractDMContext implements IRegisterDMContext {
private int fRegNo;
private String fRegName;
public MIRegisterDMC(MIRegisters service, MIRegisterGroupDMC group, int regNo, String regName) {
super(service.getSession().getId(),
new IDMContext[] { group });
fRegNo = regNo;
fRegName = regName;
}
public MIRegisterDMC(MIRegisters service, MIRegisterGroupDMC group, IMIExecutionDMContext execDmc, int regNo, String regName) {
super(service.getSession().getId(),
new IDMContext[] { execDmc, group });
fRegNo = regNo;
fRegName = regName;
}
public int getRegNo() { return fRegNo; }
public String getName() { return fRegName; }
@Override
public boolean equals(Object other) {
return ((super.baseEquals(other)) && (((MIRegisterDMC) other).fRegNo == fRegNo) &&
(((MIRegisterDMC) other).fRegName.equals(fRegName)));
}
@Override
public int hashCode() { return super.baseHashCode() ^ fRegNo; }
@Override
public String toString() { return baseToString() + ".register[" + fRegNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
}
/*
* Event class to notify register value is changed
*/
public static class RegisterChangedDMEvent implements IRegisters.IRegisterChangedDMEvent {
private final IRegisterDMContext fRegisterDmc;
RegisterChangedDMEvent(IRegisterDMContext registerDMC) {
fRegisterDmc = registerDMC;
}
public IRegisterDMContext getDMContext() {
return fRegisterDmc;
}
}
/*
* Internal control variables.
*/
private CommandFactory fCommandFactory;
private MIRegisterGroupDMC fGeneralRegistersGroupDMC;
private CommandCache fRegisterNameCache; // Cache for holding the Register Names in the single Group
private CommandCache fRegisterValueCache; // Cache for holding the Register Values
public MIRegisters(DsfSession session)
{
super(session);
}
@Override
protected BundleContext getBundleContext()
{
return GdbPlugin.getBundleContext();
}
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(
new RequestMonitor(ImmediateExecutor.getInstance(), requestMonitor) {
@Override
protected void handleSuccess() {
doInitialize(requestMonitor);
}});
}
private void doInitialize(RequestMonitor requestMonitor) {
/*
* Create the lower level register cache.
*/
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
BufferedCommandControl bufferedCommandControl = new BufferedCommandControl(commandControl, getExecutor(), 2);
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
// This cache stores the result of a command when received; also, this cache
// is manipulated when receiving events. Currently, events are received after
// three scheduling of the executor, while command results after only one. This
// can cause problems because command results might be processed before an event
// that actually arrived before the command result.
// To solve this, we use a bufferedCommandControl that will delay the command
// result by two scheduling of the executor.
// See bug 280461
fRegisterValueCache = new CommandCache(getSession(), bufferedCommandControl);
fRegisterValueCache.setContextAvailable(commandControl.getContext(), true);
// This cache is not affected by events so does not need the bufferedCommandControl
fRegisterNameCache = new CommandCache(getSession(), commandControl);
fRegisterNameCache.setContextAvailable(commandControl.getContext(), true);
/*
* Sign up so we see events. We use these events to decide how to manage
* any local caches we are providing as well as the lower level register
* cache we create to get/set registers on the target.
*/
getSession().addServiceEventListener(this, null);
/*
* Make ourselves known so clients can use us.
*/
register(new String[]{IRegisters.class.getName(), MIRegisters.class.getName()}, new Hashtable<String,String>());
requestMonitor.done();
}
@Override
public void shutdown(RequestMonitor requestMonitor)
{
unregister();
getSession().removeServiceEventListener(this);
super.shutdown(requestMonitor);
}
public boolean isValid() { return true; }
public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor<FormattedValueDMData> rm) {
if (dmc.getParents().length == 1 && dmc.getParents()[0] instanceof MIRegisterDMC) {
getRegisterDataValue( (MIRegisterDMC) dmc.getParents()[0], dmc.getFormatID(), rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
public void getRegisterGroupData(IRegisterGroupDMContext regGroupDmc, DataRequestMonitor<IRegisterGroupDMData> rm) {
/**
* For the GDB GDBMI implementation there is only on group. The GPR and FPU registers are grouped into
* one set. We are going to hard wire this set as the "General Registers".
*/
class RegisterGroupData implements IRegisterGroupDMData {
public String getName() { return "General Registers"; } //$NON-NLS-1$
public String getDescription() { return "General Purpose and FPU Register Group"; } //$NON-NLS-1$
}
rm.setData( new RegisterGroupData() ) ;
rm.done();
}
public void getBitFieldData(IBitFieldDMContext dmc, DataRequestMonitor<IBitFieldDMData> rm) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Bit fields not yet supported", null)); //$NON-NLS-1$
rm.done();
}
/**
* For the GDB GDBMI implementation there is only on group. We represent
* this group as a single list we maintain within this service. So we
* need to search this list to see if we have a current value.
*/
public void getRegisterData(IRegisterDMContext regDmc , final DataRequestMonitor<IRegisterDMData> rm) {
if (regDmc instanceof MIRegisterDMC) {
final MIRegisterDMC miRegDmc = (MIRegisterDMC)regDmc;
IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(regDmc, IMIExecutionDMContext.class);
// Create register DMC with name if execution DMC is not present.
if(execDmc == null){
rm.setData(new RegisterData(miRegDmc.getName(), BLANK_STRING, false));
rm.done();
return;
}
int[] regnos = {miRegDmc.getRegNo()};
fRegisterValueCache.execute(
fCommandFactory.createMIDataListRegisterValues(execDmc, MIFormat.HEXADECIMAL, regnos),
new DataRequestMonitor<MIDataListRegisterValuesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Retrieve the register value.
MIRegisterValue[] regValue = getData().getMIRegisterValues();
// If the list is empty just return empty handed.
if (regValue.length == 0) {
assert false : "Backend protocol error"; //$NON-NLS-1$
//done.setStatus(new Status(IStatus.ERROR, IDsfStatusConstants.INTERNAL_ERROR ,));
rm.done();
return;
}
// the request was for only one register
assert regValue.length == 1;
// We can determine if the register is floating point because
// GDB returns this additional information as part of the value.
MIRegisterValue reg = regValue[0];
boolean isFloat = false;
if ( reg.getValue().contains("float")) { //$NON-NLS-1$
isFloat = true;
}
// Return the new register attributes.
rm.setData(new RegisterData(miRegDmc.getName(), BLANK_STRING, isFloat));
rm.done();
}
});
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown DMC type", null)); //$NON-NLS-1$
rm.done();
}
}
private void getRegisterDataValue( final MIRegisterDMC regDmc, final String formatId, final DataRequestMonitor<FormattedValueDMData> rm) {
IMIExecutionDMContext miExecDmc = DMContexts.getAncestorOfType(regDmc, IMIExecutionDMContext.class);
if(miExecDmc == null){
// Set value to blank if execution dmc is not present
rm.setData( new FormattedValueDMData( BLANK_STRING ) );
rm.done();
return;
}
// Select the format to be shown
int NumberFormat = MIFormat.HEXADECIMAL;
if ( HEX_FORMAT.equals ( formatId ) ) { NumberFormat = MIFormat.HEXADECIMAL; }
if ( OCTAL_FORMAT.equals ( formatId ) ) { NumberFormat = MIFormat.OCTAL; }
if ( NATURAL_FORMAT.equals( formatId ) ) { NumberFormat = MIFormat.NATURAL; }
if ( BINARY_FORMAT.equals ( formatId ) ) { NumberFormat = MIFormat.BINARY; }
if ( DECIMAL_FORMAT.equals( formatId ) ) { NumberFormat = MIFormat.DECIMAL; }
int[] regnos = {regDmc.getRegNo()};
fRegisterValueCache.execute(
fCommandFactory.createMIDataListRegisterValues(miExecDmc, NumberFormat, regnos),
new DataRequestMonitor<MIDataListRegisterValuesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Retrieve the register value.
MIRegisterValue[] regValue = getData().getMIRegisterValues();
// If the list is empty just return empty handed.
if (regValue.length == 0) {
assert false : "Backend protocol error"; //$NON-NLS-1$
//done.setStatus(new Status(IStatus.ERROR, IDsfStatusConstants.INTERNAL_ERROR ,));
rm.done();
return;
}
MIRegisterValue reg = regValue[0];
// Return the new register value.
rm.setData( new FormattedValueDMData( reg.getValue() ) );
rm.done();
}
});
}
static class RegisterData implements IRegisterDMData {
final private String fRegName;
final private String fRegDesc;
final private boolean fIsFloat;
public RegisterData(String regName, String regDesc, boolean isFloat ) {
fRegName = regName;
fRegDesc = regDesc;
fIsFloat = isFloat;
}
public boolean isReadable() { return true; }
public boolean isReadOnce() { return false; }
public boolean isWriteable() { return true; }
public boolean isWriteOnce() { return false; }
public boolean hasSideEffects() { return false; }
public boolean isVolatile() { return true; }
public boolean isFloat() { return fIsFloat; }
public String getName() { return fRegName; }
public String getDescription() { return fRegDesc; }
}
// Wraps a list of registers in DMContexts.
private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, String[] regNames) {
return makeRegisterDMCs(groupDmc, null, regNames);
}
// Wraps a list of registers in DMContexts.
private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, IMIExecutionDMContext execDmc, String[] regNames) {
List<MIRegisterDMC> regDmcList = new ArrayList<MIRegisters.MIRegisterDMC>( regNames.length );
int regNo = 0;
for (String regName : regNames) {
if(regName != null && regName.length() > 0) {
if(execDmc != null)
regDmcList.add(new MIRegisterDMC(this, groupDmc, execDmc, regNo, regName));
else
regDmcList.add(new MIRegisterDMC(this, groupDmc, regNo, regName));
}
regNo++;
}
return regDmcList.toArray(new MIRegisterDMC[regDmcList.size()]);
}
/*
* Event handling section. These event handlers control the caching state of the
* register caches. This service creates several cache objects. Not all of which
* need to be flushed. These handlers maintain the state of the caches.
*/
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.
* @noreference This method is not intended to be referenced by clients.
*/
@DsfServiceEventHandler
public void eventDispatched(IRunControl.IResumedDMEvent e) {
fRegisterValueCache.setContextAvailable(e.getDMContext(), false);
if (e.getReason() != StateChangeReason.STEP) {
fRegisterValueCache.reset();
}
}
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.
* @noreference This method is not intended to be referenced by clients.
*/
@DsfServiceEventHandler
public void eventDispatched(
IRunControl.ISuspendedDMEvent e) {
fRegisterValueCache.setContextAvailable(e.getDMContext(), true);
fRegisterValueCache.reset();
}
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.
* @noreference This method is not intended to be referenced by clients.
*/
@DsfServiceEventHandler
public void eventDispatched(final IRegisters.IRegisterChangedDMEvent e) {
fRegisterValueCache.reset();
}
private void generateRegisterChangedEvent(IRegisterDMContext dmc ) {
getSession().dispatchEvent(new RegisterChangedDMEvent(dmc), getProperties());
}
/*
* These are the public interfaces for this service.
*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#getRegisterGroups(org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
public void getRegisterGroups(IDMContext ctx, DataRequestMonitor<IRegisterGroupDMContext[]> rm ) {
IContainerDMContext contDmc = DMContexts.getAncestorOfType(ctx, IContainerDMContext.class);
if (contDmc == null) {
rm.setStatus( new Status( IStatus.ERROR , GdbPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found", null ) ) ; //$NON-NLS-1$
rm.done();
return;
}
if (fGeneralRegistersGroupDMC == null) {
fGeneralRegistersGroupDMC = new MIRegisterGroupDMC( this , contDmc, 0 , "General Registers" ) ; //$NON-NLS-1$
}
MIRegisterGroupDMC[] groupDMCs = new MIRegisterGroupDMC[] { fGeneralRegistersGroupDMC };
rm.setData(groupDMCs) ;
rm.done() ;
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#getRegisters(org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
public void getRegisters(final IDMContext dmc, final DataRequestMonitor<IRegisterDMContext[]> rm) {
final MIRegisterGroupDMC groupDmc = DMContexts.getAncestorOfType(dmc, MIRegisterGroupDMC.class);
if ( groupDmc == null ) {
rm.setStatus( new Status( IStatus.ERROR , GdbPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found", null ) ) ; //$NON-NLS-1$
rm.done();
return;
}
final IContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class);
if ( containerDmc == null ) {
rm.setStatus( new Status( IStatus.ERROR , GdbPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found" , null ) ) ; //$NON-NLS-1$
rm.done();
return;
}
// There is only one group and its number must be 0.
if ( groupDmc.getGroupNo() == 0 ) {
final IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class);
fRegisterNameCache.execute(
fCommandFactory.createMIDataListRegisterNames(containerDmc),
new DataRequestMonitor<MIDataListRegisterNamesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Retrieve the register names.
String[] regNames = getData().getRegisterNames() ;
// If the list is empty just return empty handed.
if ( regNames.length == 0 ) {
rm.done();
return;
}
// Create DMContexts for each of the register names.
if(executionDmc == null)
rm.setData(makeRegisterDMCs(groupDmc, regNames));
else
rm.setData(makeRegisterDMCs(groupDmc, executionDmc, regNames));
rm.done();
}
});
} else {
rm.setStatus(new Status(IStatus.ERROR , GdbPlugin.PLUGIN_ID , INTERNAL_ERROR , "Invalid group = " + groupDmc , null)); //$NON-NLS-1$
rm.done();
}
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#getBitFields(org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
public void getBitFields( IDMContext regDmc , DataRequestMonitor<IBitFieldDMContext[]> rm ) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "BitField not supported", null)); //$NON-NLS-1$
rm.done();
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#writeRegister(org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext, java.lang.String, java.lang.String, org.eclipse.cdt.dsf.concurrent.RequestMonitor)
*/
public void writeRegister(IRegisterDMContext regCtx, final String regValue, final String formatId, final RequestMonitor rm) {
MIRegisterGroupDMC grpDmc = DMContexts.getAncestorOfType(regCtx, MIRegisterGroupDMC.class);
if ( grpDmc == null ) {
rm.setStatus( new Status( IStatus.ERROR , GdbPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found" , null ) ) ; //$NON-NLS-1$
rm.done();
return;
}
final MIRegisterDMC regDmc = (MIRegisterDMC)regCtx;
// There is only one group and its number must be 0.
if ( grpDmc.getGroupNo() == 0 ) {
final IExpressions exprService = getServicesTracker().getService(IExpressions.class);
String regName = regDmc.getName();
final IExpressionDMContext exprCtxt = exprService.createExpression(regCtx, "$" + regName); //$NON-NLS-1$
final FormattedValueDMContext valueDmc = exprService.getFormattedValueContext(exprCtxt, formatId);
exprService.getFormattedExpressionValue(
valueDmc,
new DataRequestMonitor<FormattedValueDMData>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
if(! regValue.equals(getData().getFormattedValue()) || ! valueDmc.getFormatID().equals(formatId)){
exprService.writeExpression(exprCtxt, regValue, formatId, new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
generateRegisterChangedEvent(regDmc);
rm.done();
}
});
}//if
else {
rm.done();
}
}//handleSuccess
}
);
}
else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Invalid group = " + grpDmc, null)); //$NON-NLS-1$
rm.done();
}
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#writeBitField(org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMContext, java.lang.String, java.lang.String, org.eclipse.cdt.dsf.concurrent.RequestMonitor)
*/
public void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$
rm.done();
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#writeBitField(org.eclipse.cdt.dsf.debug.service.IRegisters.IBitFieldDMContext, org.eclipse.cdt.dsf.debug.service.IRegisters.IMnemonic, org.eclipse.cdt.dsf.concurrent.RequestMonitor)
*/
public void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$
rm.done();
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IFormattedValues#getAvailableFormats(org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
rm.setData(new String[] { HEX_FORMAT, DECIMAL_FORMAT, OCTAL_FORMAT, BINARY_FORMAT, NATURAL_FORMAT });
rm.done();
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IFormattedValues#getFormattedValueContext(org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, java.lang.String)
*/
public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) {
if ( dmc instanceof MIRegisterDMC ) {
MIRegisterDMC regDmc = (MIRegisterDMC) dmc;
return( new FormattedValueDMContext( this, regDmc, formatId));
}
return null;
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#findRegisterGroup(org.eclipse.cdt.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
public void findRegisterGroup(IDMContext ctx, String name, DataRequestMonitor<IRegisterGroupDMContext> rm) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$
rm.done();
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#findRegister(org.eclipse.cdt.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
public void findRegister(IDMContext ctx, String name, DataRequestMonitor<IRegisterDMContext> rm) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register context not supported", null)); //$NON-NLS-1$
rm.done();
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#findBitField(org.eclipse.cdt.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
public void findBitField(IDMContext ctx, String name, DataRequestMonitor<IBitFieldDMContext> rm) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$
rm.done();
}
/**
* {@inheritDoc}
* @since 1.1
*/
public void flushCache(IDMContext context) {
fRegisterNameCache.reset(context);
fRegisterValueCache.reset(context);
}
}