diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java index 3ed3d8aa36c..16d92780259 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java @@ -10,6 +10,7 @@ * Freescale Semiconductor - refactoring * Patrick Chuong (Texas Instruments) - Bug 323279 * Patrick Chuong (Texas Instruments) - Bug fix (329682) + * Patrick Chuong (Texas Instruments) - Bug 328168 *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; @@ -36,6 +37,7 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IDisassembly; import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext; +import org.eclipse.cdt.dsf.debug.service.IDisassembly2; import org.eclipse.cdt.dsf.debug.service.IExpressions; import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress; import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; @@ -478,7 +480,7 @@ public class DisassemblyBackendDsf extends AbstractDisassemblyBackend implements /* (non-Javadoc) * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, int, int, boolean, boolean, boolean, int) */ - public void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final String file, final int lineNumber, final int lines, boolean mixed, final boolean showSymbols, final boolean showDisassembly, final int linesHint) { + public void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final String file, final int lineNumber, final int lines, final boolean mixed, final boolean showSymbols, final boolean showDisassembly, final int linesHint) { // make sure address range is no less than 32 bytes // this is an attempt to get better a response from the backend (bug 302505) final BigInteger finalEndAddress= startAddress.add(BigInteger.valueOf(32)).max(endAddress); @@ -491,108 +493,121 @@ public class DisassemblyBackendDsf extends AbstractDisassemblyBackend implements final DsfExecutor executor= session.getExecutor(); final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class); - if (mixed) { - final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { - @Override - public void handleCompleted() { - final IMixedInstruction[] data= getData(); - if (!isCanceled() && data != null) { - fCallback.asyncExec(new Runnable() { - public void run() { - if (!insertDisassembly(startAddress, finalEndAddress, data, showSymbols, showDisassembly)) { - // retry in non-mixed mode - fCallback.retrieveDisassembly(startAddress, finalEndAddress, linesHint, false, true); - } - }}); - } else { - final IStatus status= getStatus(); - if (status != null && !status.isOK()) { - if( file != null ) { - fCallback.asyncExec(new Runnable() { - public void run() { - fCallback.retrieveDisassembly(startAddress, finalEndAddress, linesHint, true, true); - }}); - } - else { - fCallback.asyncExec(new Runnable() { - public void run() { - fCallback.doScrollLocked(new Runnable() { + + // align the start address first (bug 328168) + executor.execute(new Runnable() { + public void run() { + alignOpCodeAddress(startAddress, new DataRequestMonitor(executor, null) { + + @Override + public void handleCompleted() { + final BigInteger finalStartAddress = getData(); + if (mixed) { + final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { + @Override + public void handleCompleted() { + final IMixedInstruction[] data= getData(); + if (!isCanceled() && data != null) { + fCallback.asyncExec(new Runnable() { public void run() { - fCallback.insertError(startAddress, status.getMessage()); + if (!insertDisassembly(finalStartAddress, finalEndAddress, data, showSymbols, showDisassembly)) { + // retry in non-mixed mode + fCallback.retrieveDisassembly(finalStartAddress, finalEndAddress, linesHint, false, true); + } + }}); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + if( file != null ) { + fCallback.asyncExec(new Runnable() { + public void run() { + fCallback.retrieveDisassembly(finalStartAddress, finalEndAddress, linesHint, true, true); + }}); } - }); + else { + fCallback.asyncExec(new Runnable() { + public void run() { + fCallback.doScrollLocked(new Runnable() { + public void run() { + fCallback.insertError(finalStartAddress, status.getMessage()); + } + }); + }}); + } + } + fCallback.setUpdatePending(false); + } + } + }; + if (file != null) { + executor.execute(new Runnable() { + public void run() { + final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); + if (disassembly == null) { + disassemblyRequest.cancel(); + disassemblyRequest.done(); + return; + } + disassembly.getMixedInstructions(context, file, lineNumber, lines*2, disassemblyRequest); + }}); + } else { + executor.execute(new Runnable() { + public void run() { + final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); + if (disassembly == null) { + disassemblyRequest.cancel(); + disassemblyRequest.done(); + return; + } + disassembly.getMixedInstructions(context, finalStartAddress, finalEndAddress, disassemblyRequest); }}); } - } - fCallback.setUpdatePending(false); - } - } - }; - if (file != null) { - executor.execute(new Runnable() { - public void run() { - final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); - if (disassembly == null) { - disassemblyRequest.cancel(); - disassemblyRequest.done(); - return; - } - disassembly.getMixedInstructions(context, file, lineNumber, lines*2, disassemblyRequest); - }}); - } else { - executor.execute(new Runnable() { - public void run() { - final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); - if (disassembly == null) { - disassemblyRequest.cancel(); - disassemblyRequest.done(); - return; - } - disassembly.getMixedInstructions(context, startAddress, finalEndAddress, disassemblyRequest); - }}); - } - } else { - final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { - @Override - public void handleCompleted() { - if (!isCanceled() && getData() != null) { - fCallback.asyncExec(new Runnable() { - public void run() { - if (!insertDisassembly(startAddress, finalEndAddress, getData(), showSymbols, showDisassembly)) { - fCallback.doScrollLocked(new Runnable() { - public void run() { - fCallback.insertError(startAddress, DisassemblyMessages.DisassemblyBackendDsf_error_UnableToRetrieveData); + } else { + final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { + @Override + public void handleCompleted() { + if (!isCanceled() && getData() != null) { + fCallback.asyncExec(new Runnable() { + public void run() { + if (!insertDisassembly(finalStartAddress, finalEndAddress, getData(), showSymbols, showDisassembly)) { + fCallback.doScrollLocked(new Runnable() { + public void run() { + fCallback.insertError(finalStartAddress, DisassemblyMessages.DisassemblyBackendDsf_error_UnableToRetrieveData); + } + }); + } + }}); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + fCallback.asyncExec(new Runnable() { + public void run() { + fCallback.doScrollLocked(new Runnable() { + public void run() { + fCallback.insertError(finalStartAddress, status.getMessage()); + } + }); + }}); } - }); + fCallback.setUpdatePending(false); + } } - }}); - } else { - final IStatus status= getStatus(); - if (status != null && !status.isOK()) { - fCallback.asyncExec(new Runnable() { + }; + executor.execute(new Runnable() { public void run() { - fCallback.doScrollLocked(new Runnable() { - public void run() { - fCallback.insertError(startAddress, status.getMessage()); - } - }); + final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); + if (disassembly == null) { + disassemblyRequest.cancel(); + disassemblyRequest.done(); + return; + } + disassembly.getInstructions(context, finalStartAddress, finalEndAddress, disassemblyRequest); }}); } - fCallback.setUpdatePending(false); } - } - }; - executor.execute(new Runnable() { - public void run() { - final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class); - if (disassembly == null) { - disassemblyRequest.cancel(); - disassemblyRequest.done(); - return; - } - disassembly.getInstructions(context, startAddress, finalEndAddress, disassemblyRequest); - }}); - } + }); + } + }); } private boolean insertDisassembly(BigInteger startAddress, BigInteger endAddress, IInstruction[] instructions, boolean showSymbols, boolean showDisassembly) { @@ -1090,4 +1105,34 @@ public class DisassemblyBackendDsf extends AbstractDisassemblyBackend implements return null; } + + /** + * Align the opCode of an address. + * + * @param addr the address + * @param rm the data request monitor + */ + void alignOpCodeAddress(final BigInteger addr, final DataRequestMonitor rm) { + IDisassembly2 disassembly = getService(IDisassembly2.class); + if (disassembly == null) { + rm.setData(addr); + rm.done(); + return; + } + + final DsfExecutor executor= DsfSession.getSession(fDsfSessionId).getExecutor(); + final IDisassemblyDMContext context = DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class); + disassembly.alignOpCodeAddress(context, addr, new DataRequestMonitor(executor, rm) { + @Override + protected void handleFailure() { + rm.setData(addr); + rm.done(); + } + @Override + protected void handleSuccess() { + rm.setData(getData()); + rm.done(); + } + }); + } } \ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly2.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly2.java new file mode 100644 index 00000000000..d386f510101 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IDisassembly2.java @@ -0,0 +1,37 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments 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: + * Patrick Chuong (Texas Instruments) - Bug 328168 + *****************************************************************/ +package org.eclipse.cdt.dsf.debug.service; + +import java.math.BigInteger; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; + +/** + * This interface extends the disassembly service with support for + * address alignment extension request. + * + * @since 2.2 + */ +public interface IDisassembly2 extends IDisassembly { + /** + * Aligns the given opCode address. This method will be call for each + * disassembly request, the service should try to resolve + * the given address and align it to a valid opCode address. + * + * @param context context of the disassembly code + * @param address the address to align + * @param drm aligned address + */ + void alignOpCodeAddress( + IDisassemblyDMContext context, + BigInteger address, + DataRequestMonitor drm); +}