/******************************************************************************* * Copyright (c) 2008, 2015 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Ericsson - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; import java.math.BigInteger; import java.util.Hashtable; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.debug.service.IDisassembly; import org.eclipse.cdt.dsf.debug.service.IInstruction; import org.eclipse.cdt.dsf.debug.service.IMixedInstruction; import org.eclipse.cdt.dsf.debug.service.command.ICommandControl; 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.commands.MIDataDisassemble; import org.eclipse.cdt.dsf.mi.service.command.output.MIDataDisassembleInfo; import org.eclipse.cdt.dsf.service.AbstractDsfService; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.osgi.framework.BundleContext; public class MIDisassembly extends AbstractDsfService implements IDisassembly { // Services ICommandControl fConnection; private CommandFactory fCommandFactory; /////////////////////////////////////////////////////////////////////////// // AbstractDsfService /////////////////////////////////////////////////////////////////////////// /** * The service constructor * * @param session The debugging session */ public MIDisassembly(DsfSession session) { super(session); } /** * @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor) */ @Override public void initialize(final RequestMonitor rm) { super.initialize(new ImmediateRequestMonitor(rm) { @Override protected void handleSuccess() { doInitialize(rm); } }); } private void doInitialize(final RequestMonitor rm) { fConnection = getServicesTracker().getService(ICommandControl.class); fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory(); register(new String[] { IDisassembly.class.getName(), MIDisassembly.class.getName() }, new Hashtable<String, String>()); rm.done(); } /** * @see org.eclipse.cdt.dsf.service.AbstractDsfService#shutdown(org.eclipse.cdt.dsf.concurrent.RequestMonitor) */ @Override public void shutdown(RequestMonitor rm) { unregister(); super.shutdown(rm); } /** * @see org.eclipse.cdt.dsf.service.AbstractDsfService#getBundleContext() */ @Override protected BundleContext getBundleContext() { return GdbPlugin.getBundleContext(); } /////////////////////////////////////////////////////////////////////////// // IDisassembly /////////////////////////////////////////////////////////////////////////// /** * @see org.eclipse.cdt.dsf.debug.service.IDisassembly#getInstructions(org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.math.BigInteger, java.math.BigInteger, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) */ @Override public void getInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, DataRequestMonitor<IInstruction[]> drm) { getInstructions(context, startAddress, endAddress, MIDataDisassemble.DATA_DISASSEMBLE_MODE_DISASSEMBLY, drm); } /** * Helper method to allow getting disassembly instructions not in mixed mode. * @since 4.4 */ protected void getInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, int mode, final DataRequestMonitor<IInstruction[]> drm) { // Checking what we don't support instead of what we do support allows // others to extend the 'mode' field with new values. assert mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_MIXED || mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_MIXED_OPCODES; if (context == null) { drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$ drm.done(); return; } String start = (startAddress != null) ? startAddress.toString() : "$pc"; //$NON-NLS-1$ String end = (endAddress != null) ? endAddress.toString() : start + " + 100"; //$NON-NLS-1$ fConnection.queueCommand(fCommandFactory.createMIDataDisassemble(context, start, end, mode), new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) { @Override protected void handleSuccess() { IInstruction[] result = getData().getMIAssemblyCode(); drm.setData(result); drm.done(); } }); } /** * @see org.eclipse.cdt.dsf.debug.service.IDisassembly#getInstructions(org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.lang.String, int, int, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) */ @Override public void getInstructions(IDisassemblyDMContext context, String filename, int linenum, int lines, DataRequestMonitor<IInstruction[]> drm) { getInstructions(context, filename, linenum, lines, MIDataDisassemble.DATA_DISASSEMBLE_MODE_DISASSEMBLY, drm); } /** * Helper method to allow getting disassembly instructions not in mixed mode. * @since 4.4 */ protected void getInstructions(IDisassemblyDMContext context, String filename, int linenum, int lines, int mode, final DataRequestMonitor<IInstruction[]> drm) { // Checking what we don't support instead of what we do support allows // others to extend the 'mode' field with new values. assert mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_MIXED || mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_MIXED_OPCODES; if (context == null) { drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$ drm.done(); return; } fConnection.queueCommand(fCommandFactory.createMIDataDisassemble(context, filename, linenum, lines, mode), new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) { @Override protected void handleSuccess() { IInstruction[] result = getData().getMIAssemblyCode(); drm.setData(result); drm.done(); } }); } /** * @see org.eclipse.cdt.dsf.debug.service.IDisassembly#getMixedInstructions(org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.math.BigInteger, java.math.BigInteger, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) */ @Override public void getMixedInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, final DataRequestMonitor<IMixedInstruction[]> drm) { getMixedInstructions(context, startAddress, endAddress, MIDataDisassemble.DATA_DISASSEMBLE_MODE_MIXED, drm); } /** * Helper method to allow getting disassembly instructions in mixed mode. * @since 4.4 */ protected void getMixedInstructions(IDisassemblyDMContext context, BigInteger startAddress, BigInteger endAddress, int mode, final DataRequestMonitor<IMixedInstruction[]> drm) { // Checking what we don't support instead of what we do support allows // others to extend the 'mode' field with new values. assert mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_DISASSEMBLY || mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_DISASSEMBLY_OPCODES; if (context == null) { drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$ drm.done(); return; } String start = (startAddress != null) ? startAddress.toString() : "$pc"; //$NON-NLS-1$ String end = (endAddress != null) ? endAddress.toString() : start + " + 100"; //$NON-NLS-1$ fConnection.queueCommand(fCommandFactory.createMIDataDisassemble(context, start, end, mode), new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) { @Override protected void handleSuccess() { IMixedInstruction[] result = getData().getMIMixedCode(); drm.setData(result); drm.done(); } }); } /** * @see org.eclipse.cdt.dsf.debug.service.IDisassembly#getMixedInstructions(org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext, java.lang.String, int, int, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor) */ @Override public void getMixedInstructions(IDisassemblyDMContext context, String filename, int linenum, int lines, final DataRequestMonitor<IMixedInstruction[]> drm) { getMixedInstructions(context, filename, linenum, lines, MIDataDisassemble.DATA_DISASSEMBLE_MODE_MIXED, drm); } /** * Helper method to allow getting disassembly instructions in mixed mode. * @since 4.4 */ protected void getMixedInstructions(IDisassemblyDMContext context, String filename, int linenum, int lines, int mode, final DataRequestMonitor<IMixedInstruction[]> drm) { // Checking what we don't support instead of what we do support allows // others to extend the 'mode' field with new values. assert mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_DISASSEMBLY || mode != MIDataDisassemble.DATA_DISASSEMBLE_MODE_DISASSEMBLY_OPCODES; if (context == null) { drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$ drm.done(); return; } fConnection.queueCommand(fCommandFactory.createMIDataDisassemble(context, filename, linenum, lines, mode), new DataRequestMonitor<MIDataDisassembleInfo>(getExecutor(), drm) { @Override protected void handleSuccess() { IMixedInstruction[] result = getData().getMIMixedCode(); drm.setData(result); drm.done(); } }); } }