From eddb05898660bada8ed8f206c27b78c4b389c1e7 Mon Sep 17 00:00:00 2001 From: John Cortell Date: Mon, 15 Feb 2010 15:34:31 +0000 Subject: [PATCH] [302772] Refactor DSF Disassembly view to support CDI --- .../META-INF/MANIFEST.MF | 1 + .../internal/ui/CDebugUIMessages.properties | 7 +- .../dsf}/AddressRangePosition.java | 15 +- .../dsf/CDIDisassemblyRetrieval.java | 105 ++ .../dsf/DisassemblyBackendCdi.java | 555 ++++++++ .../dsf/DisassemblyBackendCdiFactory.java | 40 + .../disassembly/dsf}/DisassemblyPosition.java | 11 +- .../ui/disassembly/dsf/DisassemblyUtils.java | 53 + .../ui/disassembly/dsf}/ErrorPosition.java | 12 +- .../disassembly/dsf/IDisassemblyBackend.java | 178 +++ .../disassembly/dsf/IDisassemblyDocument.java | 33 + .../dsf/IDisassemblyPartCallback.java | 73 + .../dsf/IDisassemblyRetrieval.java | 119 ++ .../ui/disassembly/dsf}/LabelPosition.java | 13 +- .../eclipse/cdt/debug/ui/CDebugUIPlugin.java | 7 +- .../.settings/.api_filters | 11 + .../ui/disassembly/AddressRulerColumn.java | 5 +- .../ui/disassembly/DisassemblyBackendDsf.java | 960 +++++++++++++ .../DisassemblyBackendDsfFactory.java | 37 + .../ui/disassembly/DisassemblyPart.java | 1191 +++++------------ .../ui/disassembly/DisassemblyTextHover.java | 66 +- .../ui/disassembly/EditionFinderJob.java | 5 +- .../FunctionOffsetRulerColumn.java | 6 +- .../{model => }/SourcePosition.java | 15 +- .../actions/ActionGotoAddress.java | 9 +- .../actions/JumpToAddressAction.java | 5 +- .../model/BreakpointsAnnotationModel.java | 2 + .../model/DisassemblyDocument.java | 180 ++- .../model/DisassemblyWithSourcePosition.java | 12 +- .../provisional/DisassemblySelection.java | 6 +- .../cdt/dsf/internal/ui/DsfUIPlugin.java | 8 +- 31 files changed, 2742 insertions(+), 998 deletions(-) rename {dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model => debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf}/AddressRangePosition.java (77%) create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdiFactory.java rename {dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model => debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf}/DisassemblyPosition.java (80%) create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyUtils.java rename {dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model => debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf}/ErrorPosition.java (74%) create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyBackend.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyDocument.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyPartCallback.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java rename {dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model => debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf}/LabelPosition.java (71%) create mode 100644 dsf/org.eclipse.cdt.dsf.ui/.settings/.api_filters create mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java create mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsfFactory.java rename dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/{model => }/SourcePosition.java (71%) diff --git a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF index 63deaff592c..41f3dfa391c 100644 --- a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF @@ -10,6 +10,7 @@ Export-Package: org.eclipse.cdt.debug.internal.ui;x-internal:=true, org.eclipse.cdt.debug.internal.ui.actions;x-internal:=true, org.eclipse.cdt.debug.internal.ui.dialogfields;x-internal:=true, + org.eclipse.cdt.debug.internal.ui.disassembly.dsf;x-friends:="org.eclipse.cdt.dsf.ui", org.eclipse.cdt.debug.internal.ui.editors;x-internal:=true, org.eclipse.cdt.debug.internal.ui.preferences;x-internal:=true, org.eclipse.cdt.debug.internal.ui.propertypages;x-internal:=true, diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugUIMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugUIMessages.properties index d66555e2593..d2daff37156 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugUIMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugUIMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2003, 2009 QNX Software Systems and others. +# Copyright (c) 2003, 2010 QNX Software 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 @@ -40,4 +40,7 @@ CDTDebugModelPresentation.24=-Infinity CDTDebugModelPresentation.25=(disabled) CBreakpointWorkbenchAdapterFactory.0=C/C++ breakpoint CBreakpointWorkbenchAdapterFactory.1=C/C++ watchpoint -ErrorStatusHandler.1=Error \ No newline at end of file +ErrorStatusHandler.1=Error +DisassemblyBackendCdi_Symbol_Evaluation_Unusable=Expression \"{0}\" evaluated to an unusable value. +DisassemblyBackendCdi_Symbol_Didnt_Evaluate=Expression \"{0}\" could not be evaluated. +DisassemblyBackendCdi_Error_Dlg_Title=Error \ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/AddressRangePosition.java similarity index 77% rename from dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java rename to debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/AddressRangePosition.java index 7f4b865fdf0..b4552a551d6 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/AddressRangePosition.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; import java.math.BigInteger; @@ -63,4 +63,15 @@ public class AddressRangePosition extends Position { // identity comparison return this == other; } + + /* (non-Javadoc) + * @see org.eclipse.jface.text.Position#toString() + */ + @Override + public String toString() { + return getClass().getSimpleName() + '@' + Integer.toHexString(System.identityHashCode(this)) + + (fValid ? "" : "[INVALID]") //$NON-NLS-1$ //$NON-NLS-2$ + + '[' + offset + ':' + length + "]->[" + fAddressOffset //$NON-NLS-1$ + + ':' + fAddressLength + ']'; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java new file mode 100644 index 00000000000..a2853192d72 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/CDIDisassemblyRetrieval.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + * Freescale Semiconductor - refactoring + *******************************************************************************/ + +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction; +import org.eclipse.cdt.debug.core.cdi.model.ICDIMixedInstruction; +import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; +import org.eclipse.cdt.debug.core.model.ICDebugTarget; +import org.eclipse.cdt.debug.core.model.ICStackFrame; +import org.eclipse.cdt.debug.core.model.IDisassemblyBlock; +import org.eclipse.cdt.debug.internal.core.model.DisassemblyBlock; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.swt.widgets.Display; + + +/** + */ +public class CDIDisassemblyRetrieval implements IDisassemblyRetrieval { + + private ICDebugTarget fDebugTarget; + + /** + * Constructor + */ + public CDIDisassemblyRetrieval(ICDebugTarget debugTarget) { + fDebugTarget= debugTarget; + } + + /* + * @see org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval#asyncGetDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, int, org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval.DisassemblyRequest) + */ + public void asyncGetDisassembly(final BigInteger startAddress, final BigInteger endAddress, final String file, final int lineNumber, final int lines, final DisassemblyRequest disassemblyRequest) { + Runnable op= new Runnable() { + public void run() { + ICDITarget cdiTarget= (ICDITarget) fDebugTarget.getAdapter(ICDITarget.class); + try { + ICDIMixedInstruction[] mixedInstructions= null; + ICDIInstruction[] asmInstructions= null; + if (file != null) { + mixedInstructions= cdiTarget.getMixedInstructions(file, lineNumber, lines); + } + else if (startAddress != null) { + mixedInstructions= cdiTarget.getMixedInstructions(startAddress, endAddress); + if (mixedInstructions.length == 0) { + mixedInstructions= null; + asmInstructions= cdiTarget.getInstructions(startAddress, endAddress); + } else if (mixedInstructions.length == 1 && mixedInstructions[0].getInstructions().length == 0) { + mixedInstructions= null; + asmInstructions= cdiTarget.getInstructions(startAddress, endAddress); + } + } + if (mixedInstructions != null) { + IDisassemblyBlock block= DisassemblyBlock.create(fDebugTarget.getDisassembly(), mixedInstructions); + disassemblyRequest.setDisassemblyBlock(block); + } else if (asmInstructions != null) { + IDisassemblyBlock block= DisassemblyBlock.create(fDebugTarget.getDisassembly(), asmInstructions); + disassemblyRequest.setDisassemblyBlock(block); + } + } catch (CDIException exc) { + disassemblyRequest.setStatus(new Status(IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), exc.getDetailMessage(), exc)); + } catch (DebugException exc) { + disassemblyRequest.setStatus(new Status(IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), exc.getMessage(), exc)); + } finally { + disassemblyRequest.done(); + } + + } + }; + Display.getDefault().asyncExec(op); + } + + /* + * @see org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval#asyncGetFrameAddress(org.eclipse.debug.core.model.IStackFrame, org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval.AddressRequest) + */ + public void asyncGetFrameAddress(final IStackFrame stackFrame, final AddressRequest addressRequest) { + Runnable op= new Runnable() { + public void run() { + if (stackFrame instanceof ICStackFrame) { + addressRequest.setAddress(((ICStackFrame)stackFrame).getAddress().getValue()); + } else { + addressRequest.cancel(); + } + addressRequest.done(); + } + }; + Display.getDefault().asyncExec(op); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java new file mode 100644 index 00000000000..41aab067eda --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdi.java @@ -0,0 +1,555 @@ +/******************************************************************************* + * Copyright (c) 2010 Wind River Systems, Inc. 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 + * Freescale Semiconductor - refactoring + *******************************************************************************/ + +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.model.ICDIExpression; +import org.eclipse.cdt.debug.core.model.IAsmInstruction; +import org.eclipse.cdt.debug.core.model.IAsmSourceLine; +import org.eclipse.cdt.debug.core.model.ICDebugElement; +import org.eclipse.cdt.debug.core.model.ICDebugTarget; +import org.eclipse.cdt.debug.core.model.ICStackFrame; +import org.eclipse.cdt.debug.core.model.ICThread; +import org.eclipse.cdt.debug.core.model.ICType; +import org.eclipse.cdt.debug.core.model.ICValue; +import org.eclipse.cdt.debug.core.model.IDisassemblyBlock; +import org.eclipse.cdt.debug.internal.core.model.CDebugTarget; +import org.eclipse.cdt.debug.internal.core.model.CExpression; +import org.eclipse.cdt.debug.internal.core.model.CStackFrame; +import org.eclipse.cdt.debug.internal.ui.CDebugUIMessages; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.model.ISourceLocator; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Position; + +import com.ibm.icu.text.MessageFormat; + +/** + * The CDI backend to the DSF disassembly view. + * + */ +public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSetListener { + + private IDisassemblyPartCallback fCallback; + private ICThread fTargetContext; + private String fCdiSessionId; + private ICStackFrame fTargetFrameContext; + private CDIDisassemblyRetrieval fDisassemblyRetrieval; + + public DisassemblyBackendCdi() { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#init(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback) + */ + public void init(IDisassemblyPartCallback callback) { + assert callback != null; + fCallback = callback; + DebugPlugin.getDefault().addDebugEventListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasDebugContext() + */ + public boolean hasDebugContext() { + return fTargetContext != null; + } + + /** + * Unlike DSF, CDI sessions don't have an ID. But to appease the DSF + * Disassembly view, we fabricate one. + * + * @param debugElement + * the debug element which represents the process being debugged + * @return the session ID + */ + private String getSessionId(ICDebugElement debugElement) { + return "cdi-" + System.identityHashCode(debugElement.getDebugTarget()); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#setDebugContext(org.eclipse.core.runtime.IAdaptable) + */ + public SetDebugContextResult setDebugContext(IAdaptable context) { + assert supportsDebugContext(context) : "caller should not have invoked us"; //$NON-NLS-1$ + + SetDebugContextResult result = new SetDebugContextResult(); + result.sessionId = fCdiSessionId; // initial value; may change + + ICDebugTarget cdiDebugTarget = (ICDebugTarget)((ICDebugElement)context).getDebugTarget(); + String cdiSessionId = getSessionId(cdiDebugTarget); + + fDisassemblyRetrieval = new CDIDisassemblyRetrieval(cdiDebugTarget); + + if (!cdiSessionId.equals(fCdiSessionId)) { + fTargetContext = null; + + if (context instanceof ICStackFrame) { + fTargetFrameContext = (ICStackFrame)context; + fTargetContext = (ICThread)fTargetFrameContext.getThread(); + try { + // CDI frame levels are ordered opposite of DSF. Frame 0 is the + // root frame of the thread where in DSF it's the topmost frame + // (where the PC is). Do a little math to flip reverse the value + result.frameLevel = ((CStackFrame)((fTargetContext.getTopStackFrame()))).getLevel() - fTargetFrameContext.getLevel(); + } catch (DebugException e) { + } + } + + if (fTargetContext != null) { + result.sessionId = fCdiSessionId = cdiSessionId; + result.contextChanged = true; + } + } + else if (context instanceof ICStackFrame) { + if (context instanceof ICStackFrame) { + fTargetFrameContext = (ICStackFrame)context; + fTargetContext = (ICThread)fTargetFrameContext.getThread(); + try { + // CDI frame levels are ordered opposite of DSF. Frame 0 is the + // root frame of the thread where in DSF it's the topmost frame + // (where the PC is). Do a little math to flip reverse the value + result.frameLevel = ((CStackFrame)((fTargetContext.getTopStackFrame()))).getLevel() - fTargetFrameContext.getLevel(); + } catch (DebugException e) { + } + fCallback.gotoFrame(result.frameLevel); + } + } + + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#supportsDebugContext(org.eclipse.core.runtime.IAdaptable) + */ + public boolean supportsDebugContext(IAdaptable context) { + return supportsDebugContext_(context); + } + + /** + * @param context + * @return + */ + public static boolean supportsDebugContext_(IAdaptable context) { + return (context != null) && (context.getAdapter(ICDebugElement.class) != null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#clearDebugContext() + */ + public void clearDebugContext() { + fTargetContext= null; + fCdiSessionId = null; + fTargetFrameContext = null; + fDisassemblyRetrieval = null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveFrameAddress(int) + */ + public void retrieveFrameAddress(final int targetFrame) { + try { + IStackFrame stackFrame= fTargetContext.getStackFrames()[targetFrame]; + fDisassemblyRetrieval.asyncGetFrameAddress(stackFrame, new IDisassemblyRetrieval.AddressRequest() { + @Override + public void done() { + fCallback.setUpdatePending(false); + if (!isCanceled()) { + BigInteger address= getAddress(); + if (targetFrame == 0) { + fCallback.updatePC(address); + } else { + fCallback.gotoFrame(targetFrame, address); + } + } + } + }); + + } catch (DebugException exc) { + DisassemblyUtils.internalError(exc); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLevel() + */ + public int getFrameLevel() { + return fTargetFrameContext.getLevel(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#isSuspended() + */ + public boolean isSuspended() { + return fTargetContext != null && fTargetContext.isSuspended(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameFile() + */ + public String getFrameFile() { + return fTargetFrameContext != null ? fTargetFrameContext.getFile() : null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLine() + */ + public int getFrameLine() { + return fTargetFrameContext.getFrameLineNumber(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, boolean, boolean, boolean, int, int, int) + */ + public void retrieveDisassembly(final BigInteger startAddress, + BigInteger endAddress, String file, int lineNumber, int lines, final boolean mixed, + final boolean showSymbols, final boolean showDisassembly, int linesHint) { + + if (fTargetContext == null || fTargetContext.isTerminated()) { + return; + } + final BigInteger addressLength= BigInteger.valueOf(lines * 4); + if (endAddress.subtract(startAddress).compareTo(addressLength) > 0) { + endAddress= startAddress.add(addressLength); + } + final BigInteger finalEndAddress= endAddress; + final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() { + @Override + public void done() { + if (!isCanceled() && getDisassemblyBlock() != null) { + insertDisassembly(startAddress, getDisassemblyBlock(), mixed, showSymbols, showDisassembly); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + if (startAddress != null) { + fCallback.doScrollLocked(new Runnable() { + public void run() { + fCallback.insertError(startAddress, status.getMessage()); + } + }); + } + } + fCallback.setUpdatePending(false); + } + } + }; + fDisassemblyRetrieval.asyncGetDisassembly(startAddress, finalEndAddress, file, lineNumber, lines, disassemblyRequest); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#insertSource(org.eclipse.jface.text.Position, java.math.BigInteger, java.lang.String, int) + */ + public Object insertSource(Position pos, BigInteger address, + String file, int lineNumber) { + ISourceLocator locator = fTargetContext.getLaunch().getSourceLocator(); + if (locator instanceof ISourceLookupDirector) { + return ((ISourceLookupDirector)locator).getSourceElement(file); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasFrameContext() + */ + public boolean hasFrameContext() { + return fTargetFrameContext != null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#gotoSymbol(java.lang.String) + */ + public void gotoSymbol(String symbol) { + if (fTargetFrameContext != null) { + try { + // This logic was lifted from CMemoryBlockRetrievalExtension.getExtendedMemoryBlock(String, Object) + CStackFrame cstackFrame = (CStackFrame)fTargetFrameContext; + ICDIExpression cdiExpression = cstackFrame.getCDITarget().createExpression(symbol); + CExpression cdtExpression = new CExpression(cstackFrame, cdiExpression, null); + IValue value = cdtExpression.getValue(); + if (value instanceof ICValue) { + ICType type = ((ICValue)value).getType(); + if (type != null) { + // get the address for the expression, allow all types + String rawExpr = cdtExpression.getExpressionString(); + String voidExpr = "(void *)(" + rawExpr + ')'; //$NON-NLS-1$ + String attempts[] = { rawExpr, voidExpr }; + for (int i = 0; i < attempts.length; i++) { + String expr = attempts[i]; + String addressStr = cstackFrame.evaluateExpressionToString(expr); + if (addressStr != null) { + try { + final BigInteger address = (addressStr.startsWith("0x")) ? new BigInteger(addressStr.substring(2), 16) : new BigInteger(addressStr); //$NON-NLS-1$ + fCallback.asyncExec(new Runnable() { + public void run() { + fCallback.gotoAddress(address); + }}); + + } catch (NumberFormatException e) { + if (i >= attempts.length) { + throw new DebugException(new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID, + MessageFormat.format(CDebugUIMessages.getString("DisassemblyBackendCdi_Symbol_Evaluation_Unusable"), new String[]{symbol}))); //$NON-NLS-1$ + } + } + } + } + } + } + else { + throw new DebugException(new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID, + MessageFormat.format(CDebugUIMessages.getString("DisassemblyBackendCdi_Symbol_Didnt_Evaluate"), new String[]{symbol}))); //$NON-NLS-1$ + } + } + catch (final CDIException exc) { + fCallback.asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(fCallback.getSite().getShell(), + CDebugUIMessages.getString("DisassemblyBackendCdi_Error_Dlg_Title"), //$NON-NLS-1$ + null, new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID, exc.getLocalizedMessage())); + }}); + } + catch (final DebugException exc) { + fCallback.asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(fCallback.getSite().getShell(), + CDebugUIMessages.getString("DisassemblyBackendCdi_Error_Dlg_Title"), //$NON-NLS-1$ + null, exc.getStatus()); + }}); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.lang.String, int, java.math.BigInteger, boolean, boolean, boolean) + */ + public void retrieveDisassembly(String file, int lines, + BigInteger endAddress, final boolean mixed, final boolean showSymbols, + final boolean showDisassembly) { + final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() { + @Override + public void done() { + if (!isCanceled() && getDisassemblyBlock() != null) { + insertDisassembly(null, getDisassemblyBlock(), mixed, showSymbols, showDisassembly); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + fCallback.asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ + } + }); + } + fCallback.setUpdatePending(false); + } + } + }; + + assert !fCallback.getUpdatePending(); + fCallback.setUpdatePending(true); + fDisassemblyRetrieval.asyncGetDisassembly(null, endAddress, file, 1, lines, disassemblyRequest); + } + + private void insertDisassembly(BigInteger startAddress, IDisassemblyBlock disassemblyBlock, boolean mixed, boolean showSymbols, boolean showDisassembly) { + if (!fCallback.hasViewer() || fCdiSessionId == null) { + return; + } + + if (!fCallback.getUpdatePending()) { + assert false; + return; + } + try { + fCallback.lockScroller(); + + final IDisassemblyDocument document = fCallback.getDocument(); // for convenience + IAsmSourceLine[] srcLines= disassemblyBlock.getSourceLines(); + AddressRangePosition p = null; + Object srcElement= disassemblyBlock.getSourceElement(); + for (int i = 0; i < srcLines.length; i++) { + IAsmSourceLine srcLine= srcLines[i]; + + // If the caller doesn't want mixed, set line number to -1 so we + // create a pure disassembly position object + int lineNumber= mixed ? srcLine.getLineNumber() - 1 : -1; + + IAsmInstruction[] instructions= srcLine.getInstructions(); + for (int j = 0; j < instructions.length; j++) { + IAsmInstruction instruction = instructions[j]; + BigInteger address= instruction.getAdress().getValue(); + if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) { + startAddress = address; + fCallback.setGotoAddressPending(address); + } + if (p == null || !p.containsAddress(address)) { + p = fCallback.getPositionOfAddress(address); + } + if (p instanceof ErrorPosition && p.fValid) { + p.fValid = false; + document.addInvalidAddressRange(p); + } else if (p == null) { + return; + } else if (p.fValid) { + if (srcElement != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) { + // override probably unaligned disassembly + p.fValid = false; + document.addInvalidAddressRange(p); + } else { + return; + } + } + boolean hasSource= false; + String compilationPath= null; + if (srcElement != null && lineNumber >= 0) { + if (srcElement instanceof LocalFileStorage) { + compilationPath = ((LocalFileStorage)srcElement).getFullPath().toString(); + } + else if (srcElement instanceof IFile) { + compilationPath = ((IFile)srcElement).getLocation().toString(); + } + else { + assert false : "missing support for source element of type " + srcElement.getClass().toString(); //$NON-NLS-1$ + } + if (compilationPath != null) { + p = fCallback.insertSource(p, address, compilationPath, lineNumber); + hasSource = fCallback.getStorageForFile(compilationPath) != null; + } + else { + hasSource = false; + } + } + // insert symbol label + final String functionName= instruction.getFunctionName(); + if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) { + p = document.insertLabel(p, address, functionName, showSymbols && (!hasSource || showDisassembly)); + } + // determine instruction byte length + BigInteger instrLength= null; + if (j < instructions.length - 1) { + instrLength= instructions[j+1].getAdress().distanceTo(instruction.getAdress()).abs(); + } else if (i < srcLines.length - 1) { + int nextSrcLineIdx= i+1; + while (nextSrcLineIdx < srcLines.length) { + IAsmInstruction[] nextInstrs= srcLines[nextSrcLineIdx].getInstructions(); + if (nextInstrs.length > 0) { + instrLength= nextInstrs[0].getAdress().distanceTo(instruction.getAdress()).abs(); + break; + } + ++nextSrcLineIdx; + } + if (nextSrcLineIdx >= srcLines.length) { + break; + } + } else { + if (instructions.length == 1 && srcLines.length == 1) { + instrLength= p.fAddressLength; + } + } + if (instrLength == null) { + // cannot determine length of last instruction + break; + } + final String opCode; + // insert function name+offset instead of opcode bytes + if (functionName != null && functionName.length() > 0) { + opCode= functionName + '+' + instruction.getOffset(); + } else { + opCode= ""; //$NON-NLS-1$ + } + if (!showDisassembly && hasSource) { + p = document.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, "", compilationPath, lineNumber); //$NON-NLS-1$ + } else { + p = document.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstructionText(), compilationPath, lineNumber); //$NON-NLS-1 + } + if (p == null) { + break; + } + } + } + + + } catch (BadLocationException e) { + // should not happen + DisassemblyUtils.internalError(e); + } finally { + fCallback.setUpdatePending(false); + fCallback.updateInvalidSource(); + fCallback.unlockScroller(); + fCallback.doPending(); + fCallback.updateVisibleArea(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[]) + */ + public void handleDebugEvents(DebugEvent[] events) { + for (DebugEvent event : events) { + if (event.getKind() == DebugEvent.TERMINATE) { + Object eventSource = event.getSource(); + if ((eventSource instanceof CDebugTarget) && (getSessionId((CDebugTarget)eventSource).equals(fCdiSessionId))) { + fCallback.handleTargetEnded(); + return; + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#dispose() + */ + public void dispose() { + DebugPlugin.getDefault().removeDebugEventListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#evaluateExpression(java.lang.String) + */ + public String evaluateExpression(String expression) { + // This is called to service text hovering. We either resolve the + // expression or we don't. No error reporting needed. + if (fTargetFrameContext != null) { + try { + // This logic was lifted from CMemoryBlockRetrievalExtension.getExtendedMemoryBlock(String, Object) + CStackFrame cstackFrame = (CStackFrame)fTargetFrameContext; + ICDIExpression cdiExpression = cstackFrame.getCDITarget().createExpression(expression); + CExpression cdtExpression = new CExpression(cstackFrame, cdiExpression, null); + IValue value = cdtExpression.getValue(); + if (value instanceof ICValue) { + ICType type = ((ICValue)value).getType(); + if (type != null) { + return cstackFrame.evaluateExpressionToString(cdtExpression.getExpressionString()); + } + } + } + catch (Exception exc) { + + } + } + return ""; //$NON-NLS-1$ + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdiFactory.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdiFactory.java new file mode 100644 index 00000000000..96d67f6f827 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyBackendCdiFactory.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2010 Freescale Semiconductor, Inc. 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: + * Freescale Semiconductor - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IAdapterFactory; + +public class DisassemblyBackendCdiFactory implements IAdapterFactory { + + private static final Class[] ADAPTERS = { IDisassemblyBackend.class }; + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class) + */ + @SuppressWarnings("rawtypes") + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (IDisassemblyBackend.class.equals(adapterType)) { + if (adaptableObject instanceof IAdaptable && DisassemblyBackendCdi.supportsDebugContext_((IAdaptable)adaptableObject)) { + return new DisassemblyBackendCdi(); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList() + */ + @SuppressWarnings("rawtypes") + public Class[] getAdapterList() { + return ADAPTERS; + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyPosition.java similarity index 80% rename from dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java rename to debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyPosition.java index d07f699353a..b1d3f728172 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyPosition.java @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; import java.math.BigInteger; @@ -45,5 +45,12 @@ public class DisassemblyPosition extends AddressRangePosition { public int getLine() { return -1; } - + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString() + */ + @Override + public String toString() { + return super.toString() + "->[" + new String(fFunction) + ']'; //$NON-NLS-1$ + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyUtils.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyUtils.java new file mode 100644 index 00000000000..de51911dd21 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/DisassemblyUtils.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2010 Wind River Systems, Inc. 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 + * Freescale Semiconductor - refactoring + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.Platform; + +/** + * Some general utilities used by the DSF Disassembly view and its backends + */ +public class DisassemblyUtils { + + /** + * Trace option. The view started out and continues to be in DSF but + * backends can be non-DSF. + */ + public final static boolean DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug/disassembly")); //$NON-NLS-1$//$NON-NLS-2$ + + public static String getAddressText(BigInteger address) { + if (address == null) { + return ""; //$NON-NLS-1$ + } + if (address.compareTo(BigInteger.ZERO) < 0) { + return address.toString(); + } + String hex = address.toString(16); + return "0x" + "0000000000000000".substring(hex.length() + (address.bitLength() <= 32 ? 8 : 0)) + hex; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public static void internalError(Throwable e) { + if (DEBUG) { + System.err.println("Disassembly: Internal error"); //$NON-NLS-1$ + CDebugUIPlugin.log(e); + } + } + public static BigInteger decodeAddress(String string) { + if (string.startsWith("0x")) { //$NON-NLS-1$ + return new BigInteger(string.substring(2), 16); + } + return new BigInteger(string); + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/ErrorPosition.java similarity index 74% rename from dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java rename to debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/ErrorPosition.java index 3e47f0783c9..13954123838 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/ErrorPosition.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; import java.math.BigInteger; @@ -37,4 +37,12 @@ public class ErrorPosition extends AddressRangePosition { public int hashCode() { return fHashCode; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString() + */ + @Override + public String toString() { + return super.toString() + "->[" + fHashCode + ']'; //$NON-NLS-1$ + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyBackend.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyBackend.java new file mode 100644 index 00000000000..ca8bcc61b33 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyBackend.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2010 Wind River Systems, Inc. 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 + * Freescale Semiconductor - refactoring + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.text.Position; + +/** + * This is the main interface that connects the DSF Disassembly view to CDI and + * DSF backends. This interface is obtained through IAdaptable. A new instance + * is provided every time the adapter is requested. The caller must invoke + * {@link #dispose()} when it has no further use for the instance. + */ +public interface IDisassemblyBackend { + + /** + * Used to return muliple results from + * {@link IDisassemblyBackend#setDebugContext(IAdaptable)} + */ + public class SetDebugContextResult { + /** + * The ID of the session associated with the context + */ + public String sessionId; + + /** + * The frame represented by the context. 0 is the topmost frame (where + * the PC is) + */ + public int frameLevel; + + /** + * Whether the context changed to another execution context (the parent + * elements of a thread, typically a process) + */ + public boolean contextChanged; + } + + /** + * Called after instantiation + * @param callback + */ + void init(IDisassemblyPartCallback callback); + + /** + * Indicates whether this backend support the provided debug context, + * + * @param context + * the debug context + * @return true if it is supported. Caller should invoke + * {@link #setDebugContext(IAdaptable)} with [context] only after + * first checking with this method + */ + boolean supportsDebugContext(IAdaptable context); + + /** + * @return whether the backend has a debug context + */ + boolean hasDebugContext(); + + /** + * Called by the view when there has been a change to the active debug + * context. Should be called only if + * {@link #supportsDebugContext(IAdaptable)} first returns true. + * + * @param context + * the active debug context; must not be null + * @return information about the new context + */ + SetDebugContextResult setDebugContext(IAdaptable context); + + /** + * Clear any knowledge of the current debug context. + */ + void clearDebugContext(); + + /** + * The implementation should end up calling DisassemblyPart.gotoFrame() if + * targetFrame > 0, or DisassemblyPart.gotoPC() otherwise. + * + * @param targetFrame + * the frame level to retrieve. Level 0 is the topmost frame + * (where the PC is) + */ + void retrieveFrameAddress(int targetFrame); + + /** + * Get the frame of the current context + * + * @return the frame's level; 0 is the topmost frame (i.e., where the PC + * is). -1 if no frame context has been set. + */ + int getFrameLevel(); + + /** + * Indicates whether the current context is suspended. + */ + boolean isSuspended(); + + /** + * Indicates whether the current context is a frame. + */ + boolean hasFrameContext(); + + /** + * Returns the file associated with the current frame context, or null if + * the current context is not a frame or if the frame has no file + * association. + */ + String getFrameFile(); + + /** + * Returns the line number associated with the current frame context, or -1 + * if current context is not a frame or if the frame has no file and line + * association. + */ + int getFrameLine(); + + /** + * Retrieves disassembly based on either (a) start and end address range, or + * (b) file, line number, and line count. If the caller specifies both sets + * of information, the implementation should honor (b) and ignore (a). + * + * @param startAddress + * @param endAddress + * @param file + * @param lineNumber + * @param lines + * @param mixed + * @param showSymbols + * @param showDisassembly + * @param linesHint + */ + void retrieveDisassembly(BigInteger startAddress, BigInteger endAddress, String file, int lineNumber, int lines, boolean mixed, boolean showSymbols, boolean showDisassembly, int linesHint); + + Object insertSource(Position pos, BigInteger address, final String file, int lineNumber); + + void gotoSymbol(String symbol); + + /** + * Retrieves disassembly of the code generated by a source file, starting at + * the first line. Caller specifies the maximum number of disassembly lines + * that should result and a maximum address. + * + * @param file + * @param lines + * @param endAddress + * @param mixed + * @param showSymbols + * @param showDisassembly + */ + void retrieveDisassembly(String file, int lines, BigInteger endAddress, boolean mixed, boolean showSymbols, boolean showDisassembly); + + /** + * Evaluate an expression for text hover + * + * @param expression + * the expression to be evaluated + * @return the result, or "" if it doesn't resolve, for whatever reason + */ + String evaluateExpression(String expression); + + /** + * Called when the Disassembly view has no further use for this backend. + */ + void dispose(); +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyDocument.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyDocument.java new file mode 100644 index 00000000000..f954594b7af --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyDocument.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2010 Wind River Systems, Inc. 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 + * Freescale Semiconductor - refactoring + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import java.math.BigInteger; + +import org.eclipse.jface.text.BadLocationException; + +/** + * DSF Disassembly view backends (CDI and DSF) need this limited access to the + * editor/view Document. + */ +public interface IDisassemblyDocument { + + void addInvalidAddressRange(AddressRangePosition p); + + AddressRangePosition insertLabel(AddressRangePosition pos, + BigInteger address, String label, boolean showLabels) + throws BadLocationException; + + AddressRangePosition insertDisassemblyLine(AddressRangePosition p, + BigInteger address, int intValue, String opCode, String string, + String compilationPath, int lineNumber) throws BadLocationException; +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyPartCallback.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyPartCallback.java new file mode 100644 index 00000000000..1c8e908a0f6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyPartCallback.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2010 Wind River Systems, Inc. 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 + * Freescale Semiconductor - refactoring + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import java.math.BigInteger; + +import org.eclipse.ui.IWorkbenchPartSite; + +/** + * Implementations of {@link IDisassemblyBackend} are given this access back + * into the part (editor/view) that created them. Except where noted, methods + * must be invoked on the GUI thread. A disassembly backend has to call back + * into the editor/view to carry out its duties. + * + *

+ * This interface was born of the refactoring which allowed the DSF Disassembly + * view to work with both DSF and CDI. Before that, the functionality of + * IDisasssemblyBackend was built into DisassemblyPart and thus there was no + * need for this interface. This interface merely exposes model (DSF/CDI) + * agnostic access to DisassemblyPart. It exposes methods that have been in + * DisassemblyPart all along. Documentation for those methods were sparse, and + * thus this interface is likewise. See the DisassemblyPart for any available + * documentation. + */ +public interface IDisassemblyPartCallback { + void gotoFrame(int frame); + void gotoFrameIfActive(int frame); + void updateVisibleArea(); + void updateInvalidSource(); + void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final int linesHint, boolean mixed, boolean ignoreFile); + void insertError(BigInteger address, String message); + int getAddressSize(); + void addressSizeChanged(int addressSize); + AddressRangePosition getPositionOfAddress(BigInteger address); + void gotoFrame(int frame, BigInteger address); + void updatePC(BigInteger pc); + void doPending(); + void doScrollLocked(final Runnable doit); + void lockScroller(); + void unlockScroller(); + void insertSource(AddressRangePosition pos); + AddressRangePosition insertSource(AddressRangePosition pos, BigInteger address, final String file, int lineNumber); + void setUpdatePending(boolean pending); + boolean getUpdatePending(); + void setGotoAddressPending(BigInteger address); + BigInteger getGotoAddressPending(); + IDisassemblyDocument getDocument(); + Object getStorageForFile(String file); + void gotoAddress(BigInteger address); + IWorkbenchPartSite getSite(); + boolean hasViewer(); + + /** Thread-safe */ + void handleTargetSuspended(); + + /** Thread-safe */ + void handleTargetResumed(); + + /** Thread-safe */ + void handleTargetEnded(); + + /** Thread-safe */ + void asyncExec(Runnable runnable); +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java new file mode 100644 index 00000000000..82eaa04689c --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/IDisassemblyRetrieval.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; + +import java.math.BigInteger; + +import org.eclipse.cdt.debug.core.model.IDisassemblyBlock; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.debug.core.IRequest; +import org.eclipse.debug.core.model.IStackFrame; + +/** + */ +public interface IDisassemblyRetrieval { + /** + */ + public static class Request implements IRequest { + private IStatus fStatus; + private boolean fCanceled; + /* + * @see org.eclipse.debug.core.IRequest#cancel() + */ + public void cancel() { + fCanceled= true; + } + + /* + * @see org.eclipse.debug.core.IRequest#done() + */ + public void done() { + } + + /* + * @see org.eclipse.debug.core.IRequest#getStatus() + */ + public IStatus getStatus() { + return fStatus; + } + + /* + * @see org.eclipse.debug.core.IRequest#isCanceled() + */ + public boolean isCanceled() { + return fCanceled; + } + + /* + * @see org.eclipse.debug.core.IRequest#setStatus(org.eclipse.core.runtime.IStatus) + */ + public void setStatus(IStatus status) { + fStatus= status; + } + + } + + /** + */ + public static class AddressRequest extends Request { + private BigInteger fAddress; + /** + * @return the address + */ + public BigInteger getAddress() { + return fAddress; + } + + /** + * @param address the address to set + */ + public void setAddress(BigInteger address) { + fAddress= address; + } + } + + public static class DisassemblyRequest extends Request { + IDisassemblyBlock fDisassemblyBlock; + + /** + * @return the disassemblyBlock + */ + public IDisassemblyBlock getDisassemblyBlock() { + return fDisassemblyBlock; + } + + /** + * @param disassemblyBlock the disassemblyBlock to set + */ + public void setDisassemblyBlock(IDisassemblyBlock disassemblyBlock) { + fDisassemblyBlock= disassemblyBlock; + } + } + + /** + * @param stackFrame + * @param addressRequest + */ + void asyncGetFrameAddress(IStackFrame stackFrame, AddressRequest addressRequest); + + /** + * @param startAddress + * @param endAddress + * @param file + * @param lines + * @param disassemblyRequest + */ + void asyncGetDisassembly(BigInteger startAddress, BigInteger endAddress, String file, int fileNumber, int lines, + DisassemblyRequest disassemblyRequest); + +} + diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/LabelPosition.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/LabelPosition.java similarity index 71% rename from dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/LabelPosition.java rename to debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/LabelPosition.java index 5dbaea989c0..451acb3bf2a 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/LabelPosition.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/disassembly/dsf/LabelPosition.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -8,7 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; +package org.eclipse.cdt.debug.internal.ui.disassembly.dsf; import java.math.BigInteger; @@ -28,5 +28,12 @@ public class LabelPosition extends AddressRangePosition { super(offset, length, addressOffset, BigInteger.ZERO); fLabel = label; } - + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString() + */ + @Override + public String toString() { + return super.toString() + "->[" + fLabel + ']'; //$NON-NLS-1$ + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java index 368e9fdc79e..05803dab60a 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/CDebugUIPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 QNX Software Systems and others. + * Copyright (c) 2004, 2010 QNX Software 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 @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.Map; import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.model.ICDebugElement; import org.eclipse.cdt.debug.internal.ui.CBreakpointUpdater; import org.eclipse.cdt.debug.internal.ui.CDebugImageDescriptorRegistry; import org.eclipse.cdt.debug.internal.ui.CDebugModelPresentation; @@ -23,6 +24,7 @@ import org.eclipse.cdt.debug.internal.ui.CDebuggerPageAdapter; import org.eclipse.cdt.debug.internal.ui.ColorManager; import org.eclipse.cdt.debug.internal.ui.EvaluationContextManager; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyBackendCdiFactory; import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorManager; import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator; @@ -289,6 +291,9 @@ public class CDebugUIPlugin extends AbstractUIPlugin { EvaluationContextManager.startup(); CDebugCorePlugin.getDefault().addCBreakpointListener( CBreakpointUpdater.getInstance() ); + // Register the CDI backend for DSF's disassembly view + Platform.getAdapterManager().registerAdapters(new DisassemblyBackendCdiFactory(), ICDebugElement.class); + // We contribute actions to the platform's Variables view with a // criteria to enable only when this plugin is loaded. This can lead to // some edge cases with broken behavior (273306). The solution is to diff --git a/dsf/org.eclipse.cdt.dsf.ui/.settings/.api_filters b/dsf/org.eclipse.cdt.dsf.ui/.settings/.api_filters new file mode 100644 index 00000000000..9dd163b85df --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/.settings/.api_filters @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java index 54a4c31bc87..d5cfa50889a 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/AddressRulerColumn.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -12,10 +12,9 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; import java.math.BigInteger; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.source.IAnnotationHover; import org.eclipse.jface.text.source.IAnnotationModel; 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 new file mode 100644 index 00000000000..691abe99f6a --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java @@ -0,0 +1,960 @@ +/******************************************************************************* + * Copyright (c) 2010 Wind River Systems, Inc. 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 + * Freescale Semiconductor - refactoring + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; + +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.DEBUG; +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.internalError; + +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.ErrorPosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.Query; +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.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.debug.service.IInstruction; +import org.eclipse.cdt.dsf.debug.service.IMixedInstruction; +import org.eclipse.cdt.dsf.debug.service.IRunControl; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup; +import org.eclipse.cdt.dsf.debug.service.IStack; +import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData; +import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Position; + +public class DisassemblyBackendDsf implements IDisassemblyBackend, SessionEndedListener { + + private volatile IExecutionDMContext fTargetContext; + private DsfServicesTracker fServicesTracker; + private IFrameDMContext fTargetFrameContext; + protected IFrameDMData fTargetFrameData; + + private String fDsfSessionId; + + private IDisassemblyPartCallback fCallback; + + /** + * Constructor + */ + public DisassemblyBackendDsf() { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#init(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback) + */ + public void init(IDisassemblyPartCallback callback) { + assert callback != null; + fCallback = callback; + DsfSession.addSessionEndedListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#dispose() + */ + public void dispose() { + DsfSession.removeSessionEndedListener(this); + } + + public static boolean supportsDebugContext_(IAdaptable context) { + return context.getAdapter(IDMVMContext.class) != null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#supportsDebugContext(org.eclipse.core.runtime.IAdaptable) + */ + public boolean supportsDebugContext(IAdaptable context) { + return supportsDebugContext_(context); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasDebugContext() + */ + public boolean hasDebugContext() { + return fTargetContext != null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#setDebugContext(org.eclipse.core.runtime.IAdaptable) + */ + public SetDebugContextResult setDebugContext(IAdaptable context) { + assert supportsDebugContext(context) : "caller should not have invoked us"; //$NON-NLS-1$ + IDMVMContext vmContext = (IDMVMContext) context.getAdapter(IDMVMContext.class); + IDMContext dmContext = vmContext.getDMContext(); + + SetDebugContextResult result = new SetDebugContextResult(); + result.sessionId = fDsfSessionId; // initial value; may change + + String dsfSessionId = dmContext.getSessionId(); + + + if (!dsfSessionId.equals(fDsfSessionId)) { + // switch to different session or initiate session + if (DEBUG) System.out.println("DisassemblyBackendDsf() " + dsfSessionId); //$NON-NLS-1$ + fTargetContext= null; + if (dmContext instanceof IFrameDMContext) { + IFrameDMContext frame= (IFrameDMContext) dmContext; + IExecutionDMContext executionContext= DMContexts.getAncestorOfType(frame, IExecutionDMContext.class); + if (executionContext != null) { + fTargetContext= executionContext; + fTargetFrameContext= frame; + result.frameLevel = frame.getLevel(); + } + } + if (fTargetContext != null) { + + // remove ourselves as a listener with the previous session (context) + if (fDsfSessionId != null) { + final DsfSession prevSession = DsfSession.getSession(fDsfSessionId); + if (prevSession != null) { + try { + prevSession.getExecutor().execute(new DsfRunnable() { + public void run() { + prevSession.removeServiceEventListener(this); + } + }); + } catch (RejectedExecutionException e) { + // Session is shut down. + } + } + } + + result.sessionId = fDsfSessionId = dsfSessionId; + if (fServicesTracker != null) { + fServicesTracker.dispose(); + } + fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), fDsfSessionId); + result.contextChanged = true; + + // add ourselves as a listener with the new session (context) + final DsfSession newSession = DsfSession.getSession(dsfSessionId); + if (newSession != null) { + try { + newSession.getExecutor().execute(new DsfRunnable() { + public void run() { + newSession.removeServiceEventListener(this); + } + }); + } catch (RejectedExecutionException e) { + // Session is shut down. + } + } + } + } else if (dmContext instanceof IFrameDMContext) { + // switch to different frame + IFrameDMContext frame= (IFrameDMContext) dmContext; + final IDMContext[] parents= frame.getParents(); + for (IDMContext parent : parents) { + if (parent instanceof IExecutionDMContext) { + fTargetContext= (IExecutionDMContext) parent; + fTargetFrameContext= frame; + fCallback.gotoFrameIfActive(frame.getLevel()); + result.frameLevel = getFrameLevel(); + break; + } + } + } + + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#clearDebugContext() + */ + public void clearDebugContext() { + final DsfSession session = DsfSession.getSession(fDsfSessionId); + if (session != null) { + try { + session.getExecutor().execute(new DsfRunnable() { + public void run() { + session.removeServiceEventListener(this); + } + }); + } catch (RejectedExecutionException e) { + // Session is shut down. + } + } + fTargetContext= null; + if (fServicesTracker != null) { + fServicesTracker.dispose(); + fServicesTracker= null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveFrameAddress(int) + */ + public void retrieveFrameAddress(final int frame) { + final DsfExecutor executor= getSession().getExecutor(); + executor.execute(new DsfRunnable() { + public void run() { + retrieveFrameAddressInSessionThread(frame); + }}); + } + + void retrieveFrameAddressInSessionThread(final int frame) { + final IStack stack= fServicesTracker.getService(IStack.class); + final DsfExecutor executor= getSession().getExecutor(); + + // Our frame context is currently either un-set or it's set to the frame + // our caller is specifying. If un-set, then set it and reinvoke this + // method. + if (fTargetFrameContext == null) { + if (frame == 0) { + stack.getTopFrame(fTargetContext, new DataRequestMonitor(executor, null) { + @Override + protected void handleCompleted() { + fCallback.setUpdatePending(false); + fTargetFrameContext= getData(); + if (fTargetFrameContext != null) { + retrieveFrameAddressInSessionThread(frame); + } + } + }); + } else { + // TODO retrieve other stack frame + } + return; + } + else { + assert frame == fTargetFrameContext.getLevel(); + } + + stack.getFrameData(fTargetFrameContext, new DataRequestMonitor(executor, null) { + @Override + protected void handleCompleted() { + fCallback.setUpdatePending(false); + IFrameDMData frameData= getData(); + fTargetFrameData= frameData; + if (!isCanceled() && frameData != null) { + final IAddress address= frameData.getAddress(); + final BigInteger addressValue= address.getValue(); + if (DEBUG) System.out.println("retrieveFrameAddress done "+ DisassemblyUtils.getAddressText(addressValue)); //$NON-NLS-1$ + fCallback.asyncExec(new Runnable() { + public void run() { + if (address.getSize() * 4 > fCallback.getAddressSize()) { + fCallback.addressSizeChanged(address.getSize() * 4); + } + if (frame == 0) { + fCallback.updatePC(addressValue); + } else { + fCallback.gotoFrame(frame, addressValue); + } + } + + }); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + fCallback.asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ + } + }); + } + } + } + }); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#isSuspended() + */ + public boolean isSuspended() { + DsfSession session = getSession(); + if (session == null || !session.isActive()) { + return false; + } + if (session.getExecutor().isInExecutorThread()) { + IRunControl runControl = getRunControl(); + if (runControl == null) { + return false; + } else { + return runControl.isSuspended(fTargetContext); + } + } + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + try { + IRunControl runControl = getRunControl(); + if (runControl == null) { + rm.setData(false); + } else { + rm.setData(runControl.isSuspended(fTargetContext)); + } + } finally { + rm.done(); + } + } + }; + session.getExecutor().execute(query); + try { + return query.get(); + } catch (InterruptedException exc) { + } catch (ExecutionException exc) { + } + + return false; + } + + private DsfSession getSession() { + return DsfSession.getSession(fDsfSessionId); + } + + private IRunControl getRunControl() { + return getService(IRunControl.class); + } + + private V getService(Class serviceClass) { + if (fServicesTracker != null) { + return fServicesTracker.getService(serviceClass); + } + return null; + } + + + + @DsfServiceEventHandler + public void handleEvent(IExitedDMEvent event) { + if (fTargetContext == null) { + return; + } + final IExecutionDMContext context= event.getDMContext(); + if (context.equals(fTargetContext) + || DMContexts.isAncestorOf(fTargetContext, context)) { + fCallback.asyncExec(new Runnable() { + public void run() { + fCallback.handleTargetEnded(); + }}); + } + } + + @DsfServiceEventHandler + public void handleEvent(ISuspendedDMEvent event) { + if (fTargetContext == null) { + return; + } + final IExecutionDMContext context= event.getDMContext(); + if (context.equals(fTargetContext) + || DMContexts.isAncestorOf(fTargetContext, context)) { + fCallback.handleTargetSuspended(); + } + } + + @DsfServiceEventHandler + public void handleEvent(IResumedDMEvent event) { + if (fTargetContext == null) { + return; + } + final IExecutionDMContext context= event.getDMContext(); + if (context.equals(fTargetContext) + || DMContexts.isAncestorOf(fTargetContext, context)) { + fCallback.handleTargetResumed(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener#sessionEnded(org.eclipse.cdt.dsf.service.DsfSession) + */ + public void sessionEnded(DsfSession session) { + if (session.getId().equals(fDsfSessionId)) { + clearDebugContext(); + fCallback.handleTargetEnded(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLevel() + */ + public int getFrameLevel() { + if (fTargetFrameContext != null) { + return fTargetFrameContext.getLevel(); + } + return -1; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasFrameContext() + */ + public boolean hasFrameContext() { + return fTargetFrameContext != null; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameFile() + */ + public String getFrameFile() { + return fTargetFrameData.getFile(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLine() + */ + public int getFrameLine() { + return fTargetFrameData.getLine(); + } + + /* (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) { + final BigInteger finalEndAddress= endAddress; + + DsfSession session = getSession(); + if (session == null) { + return; // can happen during session termination + } + + 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, false); + } + }}); + } 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() { + public void run() { + fCallback.insertError(startAddress, 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, 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() { + insertDisassembly(startAddress, finalEndAddress, getData(), showSymbols, showDisassembly); + }}); + } 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(startAddress, 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.getInstructions(context, file, lineNumber, lines, 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.getInstructions(context, startAddress, finalEndAddress, disassemblyRequest); + }}); + } + } + + + } + + private void insertDisassembly(BigInteger startAddress, BigInteger endAddress, IInstruction[] instructions, boolean showSymbols, boolean showDisassembly) { + if (!fCallback.hasViewer() || fDsfSessionId == null) { + return; + } + if (DEBUG) System.out.println("insertDisassembly "+ DisassemblyUtils.getAddressText(startAddress)); //$NON-NLS-1$ + assert fCallback.getUpdatePending(); + if (!fCallback.getUpdatePending()) { + // safe-guard in case something weird is going on + return; + } + try { + fCallback.lockScroller(); + + AddressRangePosition p= null; + for (int j = 0; j < instructions.length; j++) { + IInstruction instruction = instructions[j]; + BigInteger address= instruction.getAdress(); + if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) { + startAddress = address; + fCallback.setGotoAddressPending(address); + } + if (p == null || !p.containsAddress(address)) { + p = fCallback.getPositionOfAddress(address); + } + if (p instanceof ErrorPosition && p.fValid) { + p.fValid = false; + fCallback.getDocument().addInvalidAddressRange(p); + } else if (p == null || p.fValid || address.compareTo(endAddress) > 0) { + if (DEBUG) System.out.println("Excess disassembly lines at " + DisassemblyUtils.getAddressText(address)); //$NON-NLS-1$ + return; + } + boolean hasSource= false; + String compilationPath= null; + // insert symbol label + final String functionName= instruction.getFuntionName(); + if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) { + p = fCallback.getDocument().insertLabel(p, address, functionName, showSymbols && (!hasSource || showDisassembly)); + } + // determine instruction byte length + BigInteger instrLength= null; + if (j < instructions.length - 1) { + instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); + } else if (instructions.length == 1) { + if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) { + instrLength= p.fAddressLength; + } + } + if (instrLength == null) { + // cannot determine length of last instruction + break; + } + final String opCode; + // insert function name+offset instead of opcode bytes + if (functionName != null && functionName.length() > 0) { + opCode= functionName + '+' + instruction.getOffset(); + } else { + opCode= ""; //$NON-NLS-1$ + } + p = fCallback.getDocument().insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), compilationPath, -1); + if (p == null) { + break; + } + } + } catch (BadLocationException e) { + // should not happen + DisassemblyUtils.internalError(e); + } finally { + fCallback.setUpdatePending(false); + fCallback.updateInvalidSource(); + fCallback.unlockScroller(); + fCallback.doPending(); + fCallback.updateVisibleArea(); + } + } + + /** + * @param startAddress + * an address the caller is hoping will be covered by this + * insertion. I.e., [mixedInstructions] may or may not contain + * that address; the caller wants to know if it does, and so we + * indicate that via our return value. Can be null or + * BigInteger(-1) to indicate n/a, in which case we return true + * as long as any instruction was inserted + * @param endAddress + * cut-off address. Any elements in [mixedInstructions] that + * extend beyond this address are ignored. + * @param mixedInstructions + * @param showSymbols + * @param showDisassembly + * @return whether [startAddress] was inserted + */ + private boolean insertDisassembly(BigInteger startAddress, BigInteger endAddress, IMixedInstruction[] mixedInstructions, boolean showSymbols, boolean showDisassembly) { + if (!fCallback.hasViewer() || fDsfSessionId == null) { + return true; + } + if (DEBUG) System.out.println("insertDisassembly "+ DisassemblyUtils.getAddressText(startAddress)); //$NON-NLS-1$ + boolean updatePending = fCallback.getUpdatePending(); + assert updatePending; + if (!updatePending) { + // safe-guard in case something weird is going on + return true; + } + // indicates whether [startAddress] was inserted + boolean insertedStartAddress = false; + try { + fCallback.lockScroller(); + + AddressRangePosition p= null; + for (int i = 0; i < mixedInstructions.length; ++i) { + IMixedInstruction mixedInstruction= mixedInstructions[i]; + final String file= mixedInstruction.getFileName(); + int lineNumber= mixedInstruction.getLineNumber() - 1; + IInstruction[] instructions= mixedInstruction.getInstructions(); + for (int j = 0; j < instructions.length; ++j) { + IInstruction instruction = instructions[j]; + BigInteger address= instruction.getAdress(); + if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) { + startAddress = address; + fCallback.setGotoAddressPending(address); + } + if (p == null || !p.containsAddress(address)) { + p = fCallback.getPositionOfAddress(address); + } + if (p instanceof ErrorPosition && p.fValid) { + p.fValid = false; + fCallback.getDocument().addInvalidAddressRange(p); + } else if (p == null || address.compareTo(endAddress) > 0) { + if (DEBUG) System.out.println("Excess disassembly lines at " + DisassemblyUtils.getAddressText(address)); //$NON-NLS-1$ + return insertedStartAddress; + } else if (p.fValid) { + if (DEBUG) System.out.println("Excess disassembly lines at " + DisassemblyUtils.getAddressText(address)); //$NON-NLS-1$ + if (file != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) { + // override probably unaligned disassembly + p.fValid = false; + fCallback.getDocument().addInvalidAddressRange(p); + } else { + return insertedStartAddress; + } + } + boolean hasSource= false; + if (file != null && lineNumber >= 0) { + p = fCallback.insertSource(p, address, file, lineNumber); + hasSource = fCallback.getStorageForFile(file) != null; + } + // insert symbol label + final String functionName= instruction.getFuntionName(); + if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) { + p = fCallback.getDocument().insertLabel(p, address, functionName, showSymbols && (!hasSource || showDisassembly)); + } + // determine instruction byte length + BigInteger instrLength= null; + if (j < instructions.length - 1) { + instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); + } else if (i < mixedInstructions.length - 1) { + int nextSrcLineIdx= i+1; + while (nextSrcLineIdx < mixedInstructions.length) { + IInstruction[] nextInstrs= mixedInstructions[nextSrcLineIdx].getInstructions(); + if (nextInstrs.length > 0) { + instrLength= nextInstrs[0].getAdress().subtract(instruction.getAdress()).abs(); + break; + } + ++nextSrcLineIdx; + } + if (nextSrcLineIdx >= mixedInstructions.length) { + break; + } + } else if (instructions.length == 1) { + if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) { + instrLength= p.fAddressLength; + } + } + if (instrLength == null) { + // cannot determine length of last instruction + break; + } + final String opCode; + // insert function name+offset instead of opcode bytes + if (functionName != null && functionName.length() > 0) { + opCode= functionName + '+' + instruction.getOffset(); + } else { + opCode= ""; //$NON-NLS-1$ + } + insertedStartAddress= insertedStartAddress || address.compareTo(startAddress) == 0; + p = fCallback.getDocument().insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), file, lineNumber); + if (p == null && insertedStartAddress) { + break; + } + } + } + + } catch (BadLocationException e) { + // should not happen + DisassemblyUtils.internalError(e); + } finally { + fCallback.setUpdatePending(false); + if (insertedStartAddress) { + fCallback.updateInvalidSource(); + fCallback.unlockScroller(); + fCallback.doPending(); + fCallback.updateVisibleArea(); + } else { + fCallback.unlockScroller(); + } + } + return insertedStartAddress; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#insertSource(org.eclipse.jface.text.Position, java.math.BigInteger, java.lang.String, int) + */ + public Object insertSource(Position pos, BigInteger address, final String file, int lineNumber) { + Object sourceElement = null; + final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class); + final DsfExecutor executor= getSession().getExecutor(); + Query query= new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + final DataRequestMonitor request= new DataRequestMonitor(executor, rm) { + @Override + protected void handleSuccess() { + rm.setData(getData()); + rm.done(); + } + }; + final ISourceLookup lookup= getService(ISourceLookup.class); + lookup.getSource(ctx, file, request); + } + }; + try { + getSession().getExecutor().execute(query); + sourceElement= query.get(); + } catch (InterruptedException exc) { + DisassemblyUtils.internalError(exc); + } catch (ExecutionException exc) { + DisassemblyUtils.internalError(exc); + } + return sourceElement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#gotoSymbol(java.lang.String) + */ + public void gotoSymbol(final String symbol) { + final DsfExecutor executor= getSession().getExecutor(); + executor.execute(new DsfRunnable() { + public void run() { + final IExpressions expressions= getService(IExpressions.class); + if (expressions == null) { + return; + } + IExpressionDMContext exprDmc= expressions.createExpression(fTargetContext, '&'+symbol); + final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.HEX_FORMAT); + expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor(executor, null) { + @Override + protected void handleSuccess() { + FormattedValueDMData data= getData(); + final String value= data.getFormattedValue(); + final BigInteger address= DisassemblyUtils.decodeAddress(value); + if (address != null) { + fCallback.asyncExec(new Runnable() { + public void run() { + fCallback.gotoAddress(address); + }}); + } + } + @Override + protected void handleError() { + fCallback.asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ + }}); + } + }); + }}); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveDisassembly(java.lang.String, int, java.math.BigInteger, boolean, boolean, boolean) + */ + public void retrieveDisassembly(final String file, final int lines, final BigInteger endAddress, boolean mixed, final boolean showSymbols, final boolean showDisassembly) { + String debuggerPath= file; + // try reverse lookup + final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class); + final DsfExecutor executor= getSession().getExecutor(); + Query query= new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + final DataRequestMonitor request= new DataRequestMonitor(executor, rm) { + @Override + protected void handleSuccess() { + rm.setData(getData()); + rm.done(); + } + }; + final ISourceLookup lookup= getService(ISourceLookup.class); + lookup.getDebuggerPath(ctx, file, request); + } + }; + try { + getSession().getExecutor().execute(query); + debuggerPath= query.get(); + } catch (InterruptedException exc) { + internalError(exc); + } catch (ExecutionException exc) { + internalError(exc); + } + + final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class); + + final String finalFile= debuggerPath; + 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(null, endAddress, data, showSymbols, showDisassembly)) { + // retry in non-mixed mode + retrieveDisassembly(file, lines, endAddress, false, showSymbols, showDisassembly); + } + }}); + } else { + final IStatus status= getStatus(); + if (status != null && !status.isOK()) { + fCallback.asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ + } + }); + } + fCallback.setUpdatePending(false); + } + } + }; + assert !fCallback.getUpdatePending(); + fCallback.setUpdatePending(true); + 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, finalFile, 1, lines, disassemblyRequest); + }}); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#evaluateExpression(java.lang.String) + */ + public String evaluateExpression(final String expression) { + if (fTargetFrameContext == null) { + return null; + } + final DsfExecutor executor= DsfSession.getSession(fDsfSessionId).getExecutor(); + Query query= new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + IExecutionDMContext exeCtx = DMContexts.getAncestorOfType(fTargetFrameContext, IExecutionDMContext.class); + final IRunControl rc= getService(IRunControl.class); + if (rc == null || !rc.isSuspended(exeCtx)) { + rm.done(); + return; + } + final IExpressions expressions= getService(IExpressions.class); + if (expressions == null) { + rm.done(); + return; + } + IExpressionDMContext exprDmc= expressions.createExpression(fTargetFrameContext, expression); + final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT); + expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor(executor, rm) { + @Override + protected void handleSuccess() { + FormattedValueDMData data= getData(); + rm.setData(data); + rm.done(); + } + }); + }}; + + executor.execute(query); + FormattedValueDMData data= null; + try { + data= query.get(); + } catch (InterruptedException exc) { + } catch (ExecutionException exc) { + } + if (data != null) { + return data.getFormattedValue(); + } + return null; + + } +} \ No newline at end of file diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsfFactory.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsfFactory.java new file mode 100644 index 00000000000..41b172ca4dd --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsfFactory.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2010 Freescale Semiconductor, Inc. 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: + * Freescale Semiconductor - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; + +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IAdapterFactory; + +/** + */ +public class DisassemblyBackendDsfFactory implements IAdapterFactory { + + private static final Class[] ADAPTERS = { IDisassemblyBackend.class }; + + @SuppressWarnings("rawtypes") + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (IDisassemblyBackend.class.equals(adapterType)) { + if (adaptableObject instanceof IAdaptable && DisassemblyBackendDsf.supportsDebugContext_((IAdaptable)adaptableObject)) { + return new DisassemblyBackendDsf(); + } + } + return null; + } + + @SuppressWarnings("rawtypes") + public Class[] getAdapterList() { + return ADAPTERS; + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java index 178cbd9e5e9..a716032d6a4 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java @@ -19,16 +19,14 @@ import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.RejectedExecutionException; -import org.eclipse.cdt.core.IAddress; -import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; -import org.eclipse.cdt.dsf.concurrent.DsfExecutor; -import org.eclipse.cdt.dsf.concurrent.DsfRunnable; -import org.eclipse.cdt.dsf.concurrent.Query; -import org.eclipse.cdt.dsf.datamodel.DMContexts; -import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.ErrorPosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyDocument; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.LabelPosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyAction; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.ActionGotoAddress; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.ActionGotoProgramCounter; @@ -37,43 +35,14 @@ import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.ActionOpenPrefe import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AddressBarContributionItem; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.JumpToAddressAction; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.TextOperationAction; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.BreakpointsAnnotationModel; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.ErrorPosition; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.LabelPosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferenceConstants; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.presentation.DisassemblyIPAnnotation; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.util.HSL; -import org.eclipse.cdt.dsf.debug.service.IDisassembly; -import org.eclipse.cdt.dsf.debug.service.IExpressions; -import org.eclipse.cdt.dsf.debug.service.IFormattedValues; -import org.eclipse.cdt.dsf.debug.service.IInstruction; -import org.eclipse.cdt.dsf.debug.service.IMixedInstruction; -import org.eclipse.cdt.dsf.debug.service.IRunControl; -import org.eclipse.cdt.dsf.debug.service.ISourceLookup; -import org.eclipse.cdt.dsf.debug.service.IStack; -import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext; -import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; -import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; -import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; -import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; -import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent; -import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; -import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext; -import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; -import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; -import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; -import org.eclipse.cdt.dsf.service.DsfServicesTracker; -import org.eclipse.cdt.dsf.service.DsfSession; -import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener; -import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.cdt.internal.ui.dnd.TextViewerDragAdapter; import org.eclipse.core.commands.NotEnabledException; @@ -104,7 +73,6 @@ import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.commands.ActionHandler; -import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; @@ -189,14 +157,15 @@ import org.eclipse.ui.texteditor.IUpdate; import org.eclipse.ui.texteditor.MarkerAnnotationPreferences; import org.eclipse.ui.texteditor.SimpleMarkerAnnotation; import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; - +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.internalError; +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.getAddressText; /** * DisassemblyPart */ @SuppressWarnings("restriction") -public abstract class DisassemblyPart extends WorkbenchPart implements IDisassemblyPart, IViewportListener, ITextPresentationListener, SessionEndedListener { +public abstract class DisassemblyPart extends WorkbenchPart implements IDisassemblyPart, IViewportListener, ITextPresentationListener, IDisassemblyPartCallback { - private final static boolean DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug/disassembly")); //$NON-NLS-1$//$NON-NLS-2$ + final static boolean DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug/disassembly")); //$NON-NLS-1$//$NON-NLS-2$ /** * Annotation model attachment key for breakpoint annotations. @@ -278,7 +247,6 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem private BigInteger fGotoAddressPending= PC_UNKNOWN; private BigInteger fFocusAddress= PC_UNKNOWN; private int fBufferZone; - private volatile IExecutionDMContext fTargetContext; private String fDebugSessionId; private int fTargetFrame; private DisassemblyIPAnnotation fPCAnnotation; @@ -344,14 +312,12 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem private ArrayList fHandlerActivations; private IContextActivation fContextActivation; - - private DsfServicesTracker fServicesTracker; - private IFrameDMContext fTargetFrameContext; - protected IFrameDMData fTargetFrameData; + + private IDisassemblyBackend fBackend; private AddressBarContributionItem fAddressBar = null; private Action fJumpToAddressAction = new JumpToAddressAction(this); - + private final class ActionRefreshView extends AbstractDisassemblyAction { public ActionRefreshView() { super(DisassemblyPart.this); @@ -722,7 +688,6 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } else { updateDebugContext(); } - DsfSession.addSessionEndedListener(this); } /* @@ -756,9 +721,12 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem deactivateDisassemblyContext(); fViewer = null; - setDebugContext(null); - DsfSession.removeSessionEndedListener(this); - + if (fBackend != null) { + fBackend.clearDebugContext(); + fBackend.dispose(); + fBackend = null; + } + fAnnotationAccess = null; fAnnotationPreferences = null; fAnnotationRulerColumn = null; @@ -1369,18 +1337,6 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem fHandlerActivations.add(handlerService.activateHandler(action.getActionDefinitionId(), new ActionHandler(action))); } - private void gotoFrame(IFrameDMContext frame) { - if (fActive) { - gotoFrame(frame.getLevel(), PC_UNKNOWN); - } - } - - private void gotoFrame(int frame) { - if (fActive) { - gotoFrame(frame, PC_UNKNOWN); - } - } - /* * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoProgramCounter() */ @@ -1434,40 +1390,10 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoSymbol(java.lang.String) */ public final void gotoSymbol(final String symbol) { - if (!fActive || fTargetFrameContext == null) { + if (!fActive || fBackend == null || !fBackend.hasFrameContext()) { return; } - final DsfExecutor executor= getSession().getExecutor(); - executor.execute(new DsfRunnable() { - public void run() { - final IExpressions expressions= getService(IExpressions.class); - if (expressions == null) { - return; - } - IExpressionDMContext exprDmc= expressions.createExpression(fTargetContext, '&'+symbol); - final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.HEX_FORMAT); - expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor(executor, null) { - @Override - protected void handleSuccess() { - FormattedValueDMData data= getData(); - final String value= data.getFormattedValue(); - final BigInteger address= decodeAddress(value); - if (address != null) { - asyncExec(new Runnable() { - public void run() { - gotoAddress(address); - }}); - } - } - @Override - protected void handleError() { - asyncExec(new Runnable() { - public void run() { - ErrorDialog.openError(getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ - }}); - } - }); - }}); + fBackend.gotoSymbol(symbol); } private void gotoPosition(Position pos, boolean select) { @@ -1527,12 +1453,15 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem /** * Update lines of currently visible area + one page buffer zone below. + * + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#updateVisibleArea() */ - private void updateVisibleArea() { + public void updateVisibleArea() { + assert isGuiThread(); if (!fActive || fUpdatePending || fViewer == null || fDebugSessionId == null) { return; } - if (fTargetContext == null || !isSuspended(fTargetContext) || fFrameAddress == PC_UNKNOWN) { + if (fBackend == null || !fBackend.hasDebugContext() || !fBackend.isSuspended() || fFrameAddress == PC_UNKNOWN) { return; } StyledText styledText = fViewer.getTextWidget(); @@ -1568,9 +1497,8 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem AddressRangePosition bestPosition = null; int bestLine = -1; BigInteger bestDistance = null; - Iterator it = fDocument.getInvalidAddressRanges().iterator(); - while (it.hasNext()) { - AddressRangePosition p = it.next(); + if (DEBUG) System.out.println("DisassemblyPart.updateVisibleArea() called. There are " + fDocument.getInvalidAddressRanges().length + " invalid ranges to consider updating"); //$NON-NLS-1$ //$NON-NLS-2$ + for (AddressRangePosition p : fDocument.getInvalidAddressRanges()) { try { int line = fDocument.getLineOfOffset(p.offset); if (line >= topIndex && line <= bottomIndex) { @@ -1596,6 +1524,7 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } if (bestPosition != null) { + if (DEBUG) System.out.println("...and the best candidate is: " + bestPosition); //$NON-NLS-1$ int lines = fBufferZone+3; BigInteger startAddress = bestPosition.fAddressOffset; BigInteger endAddress = bestPosition.fAddressOffset.add(bestPosition.fAddressLength); @@ -1625,10 +1554,22 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } retrieveDisassembly(startAddress, endAddress, lines); } + else { + if (DEBUG) { + System.out.println("...but alas we didn't deem any of them worth updating. They are:"); //$NON-NLS-1$ + int i = 0; + for (AddressRangePosition p : fDocument.getInvalidAddressRanges()) { + System.out.println("[" + i++ + "] " + p); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } scheduleDoPending(); } - private void asyncExec(Runnable runnable) { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#asyncExec(java.lang.Runnable) + */ + public void asyncExec(Runnable runnable) { if (fViewer != null) { fViewer.getControl().getDisplay().asyncExec(runnable); } @@ -1643,9 +1584,12 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } /** - * Insert sourcelines if available. + * Insert source lines if available. + * + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#updateInvalidSource() */ - /*default*/ void updateInvalidSource() { + public void updateInvalidSource() { + assert isGuiThread(); if (fViewer == null) { return; } @@ -1661,14 +1605,12 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem fUpdatePending = true; lockScroller(); } - ArrayList copy = new ArrayList(fDocument.getInvalidSource()); - Iterator it = copy.iterator(); - while (it.hasNext()) { - SourcePosition p = it.next(); + SourcePosition[] invalidSources = fDocument.getInvalidSourcePositions(); + for (SourcePosition p : invalidSources) { if (!p.fValid) { insertSource(p); - } else if (DEBUG && fDocument.getInvalidSource().remove(p)) { - System.err.println("!!! valid source position in invalid source list at "+getAddressText(p.fAddressOffset)); //$NON-NLS-1$ + } else if (DEBUG && fDocument.removeInvalidSourcePosition(p)) { + System.err.println("!!! valid source position in invalid source list at "+ getAddressText(p.fAddressOffset)); //$NON-NLS-1$ } } } finally { @@ -1681,7 +1623,9 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } /** - * Show disassembly for given (source) file. + * Show disassembly for given (source) file. Retrieves disassembly starting + * at the beginning of the file, for as many lines as are specified. If + * [lines] == -1, the entire file is disassembled. * * @param file * @param lines @@ -1698,74 +1642,7 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem return; } if (DEBUG) System.out.println("retrieveDisassembly "+file); //$NON-NLS-1$ - String debuggerPath= file; - - // try reverse lookup - final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class); - final DsfExecutor executor= getSession().getExecutor(); - Query query= new Query() { - @Override - protected void execute(final DataRequestMonitor rm) { - final DataRequestMonitor request= new DataRequestMonitor(executor, rm) { - @Override - protected void handleSuccess() { - rm.setData(getData()); - rm.done(); - } - }; - final ISourceLookup lookup= getService(ISourceLookup.class); - lookup.getDebuggerPath(ctx, file, request); - } - }; - try { - getSession().getExecutor().execute(query); - debuggerPath= query.get(); - } catch (InterruptedException exc) { - internalError(exc); - } catch (ExecutionException exc) { - internalError(exc); - } - - final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class); - - final String finalFile= debuggerPath; - final DataRequestMonitor disassemblyRequest= new DataRequestMonitor(executor, null) { - @Override - public void handleCompleted() { - final IMixedInstruction[] data= getData(); - if (!isCanceled() && data != null) { - asyncExec(new Runnable() { - public void run() { - if (!insertDisassembly(null, fEndAddress, data)) { - // retry in non-mixed mode - retrieveDisassembly(file, lines, false); - } - }}); - } else { - final IStatus status= getStatus(); - if (status != null && !status.isOK()) { - asyncExec(new Runnable() { - public void run() { - ErrorDialog.openError(getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ - } - }); - } - fUpdatePending= false; - } - } - }; - assert !fUpdatePending; - fUpdatePending = true; - 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, finalFile, 1, lines, disassemblyRequest); - }}); + fBackend.retrieveDisassembly(file, lines, fEndAddress, mixed, fShowSymbols, fShowDisassembly); } private void retrieveDisassembly(BigInteger startAddress, BigInteger endAddress, int lines) { @@ -1776,7 +1653,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem retrieveDisassembly(startAddress, endAddress, lines, fShowSource, false); } - private void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final int linesHint, boolean mixed, boolean ignoreFile) { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#retrieveDisassembly(java.math.BigInteger, java.math.BigInteger, int, boolean, boolean) + */ + public void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final int linesHint, boolean mixed, boolean ignoreFile) { + assert isGuiThread(); assert !fUpdatePending; fUpdatePending = true; final int lines= linesHint + 2; @@ -1787,132 +1668,24 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem boolean insideActiveFrame= startAddress.equals(fFrameAddress); String file= null; int lineNumber= -1; - if (!ignoreFile && insideActiveFrame && fTargetFrameData != null) { - file= fTargetFrameData.getFile(); + if (!ignoreFile && insideActiveFrame && fBackend != null) { + file= fBackend.getFrameFile(); if (file != null && file.trim().length() == 0) { - file= null; + file = null; } - lineNumber= fTargetFrameData.getLine(); - } - final String finalFile= file; - final int finalLineNumber= lineNumber; - final BigInteger finalEndAddress= endAddress; - - final DsfExecutor executor= getSession().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) { - asyncExec(new Runnable() { - public void run() { - if (!insertDisassembly(startAddress, finalEndAddress, data)) { - // retry in non-mixed mode - retrieveDisassembly(startAddress, finalEndAddress, linesHint, false, false); - } - }}); - } else { - final IStatus status= getStatus(); - if (status != null && !status.isOK()) { - if( finalFile != null ) { - asyncExec(new Runnable() { - public void run() { - retrieveDisassembly(startAddress, finalEndAddress, linesHint, true, true); - }}); - } - else { - asyncExec(new Runnable() { - public void run() { - doScrollLocked(new Runnable() { - public void run() { - insertError(startAddress, status.getMessage()); - } - }); - }}); - } - } - fUpdatePending= 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, finalFile, finalLineNumber, 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) { - asyncExec(new Runnable() { - public void run() { - insertDisassembly(startAddress, finalEndAddress, getData()); - }}); - } else { - final IStatus status= getStatus(); - if (status != null && !status.isOK()) { - asyncExec(new Runnable() { - public void run() { - doScrollLocked(new Runnable() { - public void run() { - insertError(startAddress, status.getMessage()); - } - }); - }}); - } - fUpdatePending= 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.getInstructions(context, finalFile, finalLineNumber, lines, 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.getInstructions(context, startAddress, finalEndAddress, disassemblyRequest); - }}); + lineNumber= fBackend.getFrameLine(); } } + if (DEBUG) System.out.println("Asking backend to retrieve disassembly: sa=" + startAddress + ",ea=" + endAddress + ",file=" + file + ",lineNumber=" + lineNumber + ",lines=" + lines); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + fBackend.retrieveDisassembly(startAddress, endAddress, file, lineNumber, lines, mixed, fShowSymbols, fShowDisassembly, linesHint); } - private void insertError(BigInteger address, String message) { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#insertError(java.math.BigInteger, java.lang.String) + */ + public void insertError(BigInteger address, String message) { + assert isGuiThread(); AddressRangePosition p = null; p = getPositionOfAddress(address); if (p.fValid) { @@ -1925,278 +1698,27 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } - private void insertDisassembly(BigInteger startAddress, BigInteger endAddress, IInstruction[] instructions) { - if (fViewer == null || fDebugSessionId == null) { - return; - } - if (DEBUG) System.out.println("insertDisassembly "+getAddressText(startAddress)); //$NON-NLS-1$ - assert fUpdatePending; - if (!fUpdatePending) { - // safe-guard in case something weird is going on - return; - } - try { - lockScroller(); - - AddressRangePosition p= null; - for (int j = 0; j < instructions.length; j++) { - IInstruction instruction = instructions[j]; - BigInteger address= instruction.getAdress(); - if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) { - fGotoAddressPending = startAddress = address; - } - if (p == null || !p.containsAddress(address)) { - p = getPositionOfAddress(address); - } - if (p instanceof ErrorPosition && p.fValid) { - p.fValid = false; - fDocument.getInvalidAddressRanges().add(p); - } else if (p == null || p.fValid || address.compareTo(endAddress) > 0) { - if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$ - return; - } - boolean hasSource= false; - String compilationPath= null; - // insert symbol label - final String functionName= instruction.getFuntionName(); - if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) { - p = fDocument.insertLabel(p, address, functionName, fShowSymbols && (!hasSource || fShowDisassembly)); - } - // determine instruction byte length - BigInteger instrLength= null; - if (j < instructions.length - 1) { - instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); - } else if (instructions.length == 1) { - if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) { - instrLength= p.fAddressLength; - } - } - if (instrLength == null) { - // cannot determine length of last instruction - break; - } - final String opCode; - // insert function name+offset instead of opcode bytes - if (functionName != null && functionName.length() > 0) { - opCode= functionName + '+' + instruction.getOffset(); - } else { - opCode= ""; //$NON-NLS-1$ - } - p = fDocument.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), compilationPath, -1); - if (p == null) { - break; - } - } - - } catch (BadLocationException e) { - // should not happen - internalError(e); - } finally { - fUpdatePending = false; - updateInvalidSource(); - unlockScroller(); - doPending(); - updateVisibleArea(); - } + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#getAddressSize() + */ + public int getAddressSize() { + assert isGuiThread(); + return fAddressSize; } - - private boolean insertDisassembly(BigInteger startAddress, BigInteger endAddress, IMixedInstruction[] mixedInstructions) { - if (fViewer == null || fDebugSessionId == null) { - return true; - } - if (DEBUG) System.out.println("insertDisassembly "+getAddressText(startAddress)); //$NON-NLS-1$ - assert fUpdatePending; - if (!fUpdatePending) { - // safe-guard in case something weird is going on - return true; - } - // indicates whether disassembly for the start address was inserted - boolean success= false; - try { - lockScroller(); - - AddressRangePosition p= null; - for (int i = 0; i < mixedInstructions.length; ++i) { - IMixedInstruction mixedInstruction= mixedInstructions[i]; - final String file= mixedInstruction.getFileName(); - int lineNumber= mixedInstruction.getLineNumber() - 1; - IInstruction[] instructions= mixedInstruction.getInstructions(); - for (int j = 0; j < instructions.length; ++j) { - IInstruction instruction = instructions[j]; - BigInteger address= instruction.getAdress(); - if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) { - fGotoAddressPending = startAddress = address; - } - if (p == null || !p.containsAddress(address)) { - p = getPositionOfAddress(address); - } - if (p instanceof ErrorPosition && p.fValid) { - p.fValid = false; - fDocument.getInvalidAddressRanges().add(p); - } else if (p == null || address.compareTo(endAddress) > 0) { - if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$ - return success; - } else if (p.fValid) { - if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$ - if (file != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) { - // override probably unaligned disassembly - p.fValid = false; - fDocument.getInvalidAddressRanges().add(p); - } else { - return success; - } - } - boolean hasSource= false; - if (file != null && lineNumber >= 0) { - p = insertSource(p, address, file, lineNumber); - hasSource = fFile2Storage.get(file) != null; - } - // insert symbol label - final String functionName= instruction.getFuntionName(); - if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) { - p = fDocument.insertLabel(p, address, functionName, fShowSymbols && (!hasSource || fShowDisassembly)); - } - // determine instruction byte length - BigInteger instrLength= null; - if (j < instructions.length - 1) { - instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); - } else if (i < mixedInstructions.length - 1) { - int nextSrcLineIdx= i+1; - while (nextSrcLineIdx < mixedInstructions.length) { - IInstruction[] nextInstrs= mixedInstructions[nextSrcLineIdx].getInstructions(); - if (nextInstrs.length > 0) { - instrLength= nextInstrs[0].getAdress().subtract(instruction.getAdress()).abs(); - break; - } - ++nextSrcLineIdx; - } - if (nextSrcLineIdx >= mixedInstructions.length) { - break; - } - } else if (instructions.length == 1) { - if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) { - instrLength= p.fAddressLength; - } - } - if (instrLength == null) { - // cannot determine length of last instruction - break; - } - final String opCode; - // insert function name+offset instead of opcode bytes - if (functionName != null && functionName.length() > 0) { - opCode= functionName + '+' + instruction.getOffset(); - } else { - opCode= ""; //$NON-NLS-1$ - } - success= success || address.compareTo(startAddress) == 0; - p = fDocument.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), file, lineNumber); - if (p == null && success) { - break; - } - } - } - - } catch (BadLocationException e) { - // should not happen - internalError(e); - } finally { - fUpdatePending = false; - if (success) { - updateInvalidSource(); - unlockScroller(); - doPending(); - updateVisibleArea(); - } else { - unlockScroller(); - } - } - return success; - } - - private void retrieveFrameAddress(final IExecutionDMContext targetContext, final int frame) { - if (targetContext != null && isSuspended(targetContext)) { - if (fUpdatePending) { - gotoFrame(frame); - return; - } - if (DEBUG) System.out.println("retrieveFrameAddress "+frame); //$NON-NLS-1$ - fUpdatePending = true; - final DsfExecutor executor= getSession().getExecutor(); - executor.execute(new DsfRunnable() { - public void run() { - retrieveFrameAddressInSessionThread(targetContext, frame); - }}); - } - } - - private void retrieveFrameAddressInSessionThread(final IExecutionDMContext targetContext, final int frame) { - final IStack stack= fServicesTracker.getService(IStack.class); - final DsfExecutor executor= getSession().getExecutor(); - if (fTargetFrameContext == null) { - if (frame == 0) { - stack.getTopFrame(targetContext, new DataRequestMonitor(executor, null) { - @Override - protected void handleCompleted() { - fUpdatePending= false; - fTargetFrameContext= getData(); - if (fTargetFrameContext != null) { - retrieveFrameAddressInSessionThread(targetContext, frame); - } - } - }); - } else { - // TODO retrieve other stack frame - } - return; - } - stack.getFrameData(fTargetFrameContext, new DataRequestMonitor(executor, null) { - @Override - protected void handleCompleted() { - fUpdatePending= false; - IFrameDMData frameData= getData(); - fTargetFrameData= frameData; - if (!isCanceled() && frameData != null) { - final IAddress address= frameData.getAddress(); - final BigInteger addressValue= address.getValue(); - if (DEBUG) System.out.println("retrieveFrameAddress done "+getAddressText(addressValue)); //$NON-NLS-1$ - asyncExec(new Runnable() { - public void run() { - if (address.getSize() * 4 > fAddressSize) { - addressSizeChanged(address.getSize() * 4); - } - if (frame == 0) { - updatePC(addressValue); - } else { - gotoFrame(frame, addressValue); - } - } - - }); - } else { - final IStatus status= getStatus(); - if (status != null && !status.isOK()) { - asyncExec(new Runnable() { - public void run() { - ErrorDialog.openError(getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$ - } - }); - } - } - } - }); - } - - private void addressSizeChanged(int addressSize) { + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#addressSizeChanged(int) + */ + public void addressSizeChanged(int addressSize) { + assert isGuiThread(); BigInteger oldEndAddress= fEndAddress; fEndAddress= BigInteger.ONE.shiftLeft(addressSize); int oldAddressSize= fAddressSize; fAddressSize= addressSize; if (addressSize < oldAddressSize) { fDocument.deleteDisassemblyRange(fEndAddress, oldEndAddress, true, true); - List positions= fDocument.getInvalidAddressRanges(); List toRemove= new ArrayList(); - for (AddressRangePosition position : positions) { + for (AddressRangePosition position : fDocument.getInvalidAddressRanges()) { if (position.fAddressOffset.compareTo(fEndAddress) >= 0) { try { fDocument.replace(position, position.length, ""); //$NON-NLS-1$ @@ -2209,7 +1731,7 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem position.fAddressLength= fEndAddress.subtract(position.fAddressOffset); } } - positions.removeAll(toRemove); + fDocument.removeInvalidAddressRanges(toRemove); } else if (addressSize > oldAddressSize) { fDocument.insertInvalidAddressRange(fDocument.getLength(), 0, oldEndAddress, fEndAddress); } else { @@ -2223,7 +1745,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } - private AddressRangePosition getPositionOfAddress(BigInteger address) { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#getPositionOfAddress(java.math.BigInteger) + */ + public AddressRangePosition getPositionOfAddress(BigInteger address) { + assert isGuiThread(); if (address == null || address.compareTo(BigInteger.ZERO) < 0) { return null; } @@ -2254,13 +1780,13 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem refreshView(0); } else { doPendingPCUpdates(); - if (fTargetContext != null) { + if (fBackend != null && fBackend.hasDebugContext()) { int frame = getActiveStackFrame(); - if (frame < 0 && isSuspended(fTargetContext)) { + if (frame < 0 && isSuspended()) { frame= 0; } if (frame != fTargetFrame) { - gotoFrame(frame); + gotoFrameIfActive(frame); } } } @@ -2271,101 +1797,38 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } private int getActiveStackFrame() { - if (fTargetFrameContext != null) { - return fTargetFrameContext.getLevel(); + if (fBackend != null) { + return fBackend.getFrameLevel(); } return -1; } - /** - * - */ protected void updateDebugContext() { - IAdaptable debugContext= DebugUITools.getDebugContext(); - if (debugContext instanceof IDMVMContext) { - setDebugContext((IDMVMContext)debugContext); - } - } - - protected void setDebugContext(IDMVMContext vmContext) { - if (vmContext != null) { - IDMContext dmContext= vmContext.getDMContext(); - String sessionId= dmContext.getSessionId(); - if (!sessionId.equals(fDebugSessionId)) { - // switch to different session or initiate session - if (DEBUG) System.out.println("DisassemblyPart.setDebugContext() " + sessionId); //$NON-NLS-1$ - fTargetContext= null; - if (dmContext instanceof IFrameDMContext) { - IFrameDMContext frame= (IFrameDMContext) dmContext; - IExecutionDMContext executionContext= DMContexts.getAncestorOfType(frame, IExecutionDMContext.class); - if (executionContext != null) { - fTargetContext= executionContext; - fTargetFrameContext= frame; - fTargetFrame= frame.getLevel(); - } + IAdaptable context = DebugUITools.getDebugContext(); + final IDisassemblyBackend prevBackend = fBackend; + fDebugSessionId = null; + if (context != null) { + if (fBackend == null || !fBackend.supportsDebugContext(context)) { + if (fBackend != null) { + fBackend.dispose(); } - if (fTargetContext != null) { - if (fDebugSessionId != null) { - if (getSession() != null) { - try { - // Don't call getSession() from executor; may - // return different session by the time it runs - final DsfSession session = getSession(); - session.getExecutor().execute(new DsfRunnable() { - public void run() { - session.removeServiceEventListener(DisassemblyPart.this); - } - }); - } catch (RejectedExecutionException e) { - // Session is shut down. - } - } - } - fDebugSessionId= sessionId; - if (fServicesTracker != null) { - fServicesTracker.dispose(); - } - fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), sessionId); - if (fViewer != null) { + fBackend = (IDisassemblyBackend)context.getAdapter(IDisassemblyBackend.class); + if (fBackend != null) { + fBackend.init(this); + } + } + + if (fBackend != null) { + IDisassemblyBackend.SetDebugContextResult result = fBackend.setDebugContext(context); + if (result != null) { + fDebugSessionId = result.sessionId; + if (result.contextChanged && fViewer != null) { debugContextChanged(); - } - } - } else if (dmContext instanceof IFrameDMContext) { - // switch to different frame - IFrameDMContext frame= (IFrameDMContext) dmContext; - final IDMContext[] parents= frame.getParents(); - for (IDMContext context : parents) { - if (context instanceof IExecutionDMContext) { - fTargetContext= (IExecutionDMContext) context; - fTargetFrameContext= frame; - gotoFrame(frame); - break; - } - } - } - } else if (fDebugSessionId != null) { - if (getSession() != null) { - try { - // Don't call getSession() from executor; may return - // different session by the time it runs - final DsfSession session = getSession(); - session.getExecutor().execute(new DsfRunnable() { - public void run() { - session.removeServiceEventListener(DisassemblyPart.this); + if (prevBackend != null && fBackend != prevBackend) { + prevBackend.clearDebugContext(); } - }); - } catch (RejectedExecutionException e) { - // Session is shut down. - } - } - fDebugSessionId= null; - fTargetContext= null; - if (fServicesTracker != null) { - fServicesTracker.dispose(); - fServicesTracker= null; - } - if (fViewer != null) { - debugContextChanged(); + } + } } } } @@ -2378,16 +1841,6 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem if (fDebugSessionId != null) { fJumpToAddressAction.setEnabled(true); fAddressBar.enableAddressBox(true); - try { - final DsfSession session= getSession(); - session.getExecutor().execute(new DsfRunnable() { - public void run() { - session.addServiceEventListener(DisassemblyPart.this, null); - } - }); - } catch (RejectedExecutionException e) { - // Session is shut down. - } updatePC(PC_UNKNOWN); @@ -2414,66 +1867,7 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem firePropertyChange(PROP_SUSPENDED); } - /* - * @see org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener#sessionEnded(org.eclipse.cdt.dsf.service.DsfSession) - */ - public void sessionEnded(DsfSession endedSsession) { - if (endedSsession.getId().equals(fDebugSessionId)) { - asyncExec(new Runnable() { - public void run() { - setDebugContext(null); - }}); - } - } - @DsfServiceEventHandler - public void handleEvent(IExitedDMEvent event) { - if (fTargetContext == null) { - return; - } - final IExecutionDMContext context= event.getDMContext(); - if (context.equals(fTargetContext) - || DMContexts.isAncestorOf(fTargetContext, context)) { - asyncExec(new Runnable() { - public void run() { - setDebugContext(null); - }}); - } - } - - @DsfServiceEventHandler - public void handleEvent(ISuspendedDMEvent event) { - if (fTargetContext == null) { - return; - } - final IExecutionDMContext context= event.getDMContext(); - if (context.equals(fTargetContext) - || DMContexts.isAncestorOf(fTargetContext, context)) { - asyncExec(new Runnable() { - public void run() { - updatePC(PC_UNKNOWN); - firePropertyChange(PROP_SUSPENDED); - } - }); - } - } - - @DsfServiceEventHandler - public void handleEvent(IResumedDMEvent event) { - if (fTargetContext == null) { - return; - } - final IExecutionDMContext context= event.getDMContext(); - if (context.equals(fTargetContext) - || DMContexts.isAncestorOf(fTargetContext, context)) { - asyncExec(new Runnable() { - public void run() { - updatePC(PC_RUNNING); - firePropertyChange(PROP_SUSPENDED); - } - }); - } - } private void attachBreakpointsAnnotationModel() { IAnnotationModel annotationModel = fViewer.getAnnotationModel(); @@ -2502,7 +1896,7 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem if (fScrollPos != null) { fScrollPos.isDeleted = true; } - gotoFrame(targetFrame); + gotoFrameIfActive(targetFrame); } else { refreshView((int)(refreshViewScheduled - now)); } @@ -2588,6 +1982,9 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem * @return a position which denotes the documents position */ private AddressRangePosition updateAddressAnnotation(Annotation annotation, BigInteger address) { + if (fViewer == null) { + return null; // can happen during session shutdown + } IAnnotationModel annotationModel = fViewer.getAnnotationModel(); annotationModel.removeAnnotation(annotation); AddressRangePosition pos = getPCPosition(address); @@ -2631,13 +2028,35 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem return null; } - private void gotoFrame(int frame, BigInteger address) { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#gotoFrame(int) + */ + public void gotoFrame(int frame) { + assert isGuiThread(); + gotoFrame(frame, PC_UNKNOWN); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#gotoFrameIfActive(int) + */ + public void gotoFrameIfActive(int frame) { + assert isGuiThread(); + if (fActive) { + gotoFrame(frame); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#gotoFrame(int, java.math.BigInteger) + */ + public void gotoFrame(int frame, BigInteger address) { + assert isGuiThread(); if (DEBUG) System.out.println("gotoFrame " + frame + " " + getAddressText(address)); //$NON-NLS-1$ //$NON-NLS-2$ fTargetFrame = frame; fFrameAddress = address; if (fTargetFrame == -1) { fTargetFrame = getActiveStackFrame(); - if (fTargetFrame < 0 && isSuspended(fTargetContext)) { + if (fTargetFrame < 0 && fBackend != null && fBackend.isSuspended()) { fTargetFrame= 0; } if (fTargetFrame == -1) { @@ -2652,7 +2071,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem if (fFrameAddress.compareTo(PC_UNKNOWN) == 0) { if (!fUpdatePending) { fGotoFramePending = false; - retrieveFrameAddress(fTargetContext, fTargetFrame); + if (fBackend != null && fBackend.hasDebugContext() && fBackend.isSuspended()) { + if (DEBUG) System.out.println("retrieveFrameAddress "+frame); //$NON-NLS-1$ + fUpdatePending = true; + fBackend.retrieveFrameAddress(fTargetFrame); + } } return; } @@ -2694,14 +2117,18 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isConnected() */ public final boolean isConnected() { - return fDebugSessionId != null && fTargetContext != null; + if (fDebugSessionId == null) { + return false; + } + + return (fBackend != null) ? fBackend.hasDebugContext() : false; } /* * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isSuspended() */ public final boolean isSuspended() { - return isConnected() && isSuspended(fTargetContext); + return isConnected() && fBackend.isSuspended(); } /* @@ -2710,6 +2137,10 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem public final ISourceViewer getTextViewer() { return fViewer; } + + public final boolean hasViewer() { + return fViewer != null; + } /* * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#addRulerContextMenuListener(org.eclipse.jface.action.IMenuListener) @@ -2725,62 +2156,6 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem fRulerContextMenuListeners.remove(listener); } - private boolean isSuspended(final IExecutionDMContext targetContext) { - DsfSession session = getSession(); - if (session == null || !session.isActive()) { - return false; - } - if (session.getExecutor().isInExecutorThread()) { - IRunControl runControl = getRunControl(); - if (runControl == null) { - return false; - } else { - return runControl.isSuspended(targetContext); - } - } - Query query = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - try { - IRunControl runControl = getRunControl(); - if (runControl == null) { - rm.setData(false); - } else { - rm.setData(runControl.isSuspended(targetContext)); - } - } finally { - rm.done(); - } - } - }; - session.getExecutor().execute(query); - try { - return query.get(); - } catch (InterruptedException exc) { - } catch (ExecutionException exc) { - } - return false; - } - - private IRunControl getRunControl() { - return getService(IRunControl.class); - } - - /*default*/ DsfSession getSession() { - return DsfSession.getSession(fDebugSessionId); - } - - /*default*/ V getService(Class serviceClass) { - if (fServicesTracker != null) { - return fServicesTracker.getService(serviceClass); - } - return null; - } - - /*default*/ IFrameDMContext getTargetFrameContext() { - return fTargetFrameContext; - } - /** * Schedule the retrieval of a module time stamp for the given address. * Should return a Long object in case the value was computed, @@ -2812,6 +2187,12 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } + /** + * Act on the first PC in the pending list that is not a special value + * (UNKNOWN, RUNNING), discarding all special value entries leading up to + * it. If the list only has special values, act on the last one and clear + * the list. + */ private void doPendingPCUpdates() { if (fPendingPCUpdates.isEmpty()) { return; @@ -2870,8 +2251,10 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem * * @param pc Current pc address. -1 means retrieve pc from top frame, -2 * means target resumed + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#updatePC(java.math.BigInteger) */ - private void updatePC(BigInteger pc) { + public void updatePC(BigInteger pc) { + assert isGuiThread(); if (!fPendingPCUpdates.isEmpty()) { BigInteger last = fPendingPCUpdates.get(fPendingPCUpdates.size()-1); if (last.compareTo(BigInteger.ZERO) < 0) { @@ -2933,14 +2316,18 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } - private void doPending() { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#doPending() + */ + public void doPending() { + assert isGuiThread(); if (fViewer == null || fDocument == null) { return; } if (fUpdateSourcePending) { updateInvalidSource(); } - boolean sourceValid= fDocument.getInvalidSource().isEmpty(); + boolean sourceValid= !fDocument.hasInvalidSourcePositions(); if (sourceValid || fShowDisassembly) { if (fGotoFramePending) { gotoFrame(fTargetFrame, fFrameAddress); @@ -2965,8 +2352,10 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem * Safely run given runnable in a state when no update is pending. * Delays execution by 10 ms if update is currently pending. * @param doit + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#doScrollLocked(java.lang.Runnable) */ - private void doScrollLocked(final Runnable doit) { + public void doScrollLocked(final Runnable doit) { + assert isGuiThread(); if (fViewer == null || fDebugSessionId == null) { // disposed return; @@ -3011,7 +2400,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } - private void lockScroller() { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#lockScroller() + */ + public void lockScroller() { + assert isGuiThread(); assert fScrollPos == null; if (isOpcodeRulerVisible()) { fRedrawControl = fViewer.getControl(); @@ -3051,7 +2444,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } - private void unlockScroller() { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#unlockScroller() + */ + public void unlockScroller() { + assert isGuiThread(); try { if (fScrollPos == null) { return; @@ -3099,7 +2496,19 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } - private void insertSource(SourcePosition pos) { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#insertSource(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition) + */ + public void insertSource(AddressRangePosition _pos) { + assert isGuiThread(); + // IDisassemblyPartCallback does not have visibility to the + // SourcePosition type, which is DSF-specific, so it uses the base type + if (!(_pos instanceof SourcePosition)) { + assert false : "Caller should have passed in a SourcePosition"; //$NON-NLS-1$ + return; + } + SourcePosition pos = (SourcePosition)_pos; + if (!fShowSource) { fDocument.insertSource(pos, "", pos.fLine, true); //$NON-NLS-1$ return; @@ -3213,8 +2622,8 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem try { // make sure we start with first overlapping position AddressRangePosition pos = fDocument.getModelPosition(startOffset); - assert pos != null; if (pos == null) { + assert false; return; } it = fDocument.getPositionIterator(DisassemblyDocument.CATEGORY_MODEL, pos.offset); @@ -3296,56 +2705,37 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } - - private AddressRangePosition insertSource(AddressRangePosition pos, BigInteger address, final String file, int lineNr) { + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#insertSource(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition, java.math.BigInteger, java.lang.String, int) + */ + public AddressRangePosition insertSource(AddressRangePosition pos, BigInteger address, final String file, int lineNumber) { + assert isGuiThread(); Object sourceElement = null; if (fFile2Storage.containsKey(file)) { sourceElement = fFile2Storage.get(file); } else { - final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class); - final DsfExecutor executor= getSession().getExecutor(); - Query query= new Query() { - @Override - protected void execute(final DataRequestMonitor rm) { - final DataRequestMonitor request= new DataRequestMonitor(executor, rm) { - @Override - protected void handleSuccess() { - rm.setData(getData()); - rm.done(); - } - }; - final ISourceLookup lookup= getService(ISourceLookup.class); - lookup.getSource(ctx, file, request); - } - }; - try { - getSession().getExecutor().execute(query); - sourceElement= query.get(); - } catch (InterruptedException exc) { - internalError(exc); - } catch (ExecutionException exc) { - internalError(exc); - } - if (sourceElement instanceof File) { - sourceElement = new LocalFileStorage((File)sourceElement); - } - if (sourceElement instanceof IStorage) { - if (!(sourceElement instanceof IFile)) { - // try to resolve as resource - final IPath location= ((IStorage) sourceElement).getFullPath(); - if (location != null) { - IFile iFile = ResourceLookup.selectFileForLocation(location, null); - if (iFile != null) { - sourceElement = iFile; - } + sourceElement = fBackend.insertSource(pos, address, file, lineNumber); + } + if (sourceElement instanceof File) { + sourceElement = new LocalFileStorage((File)sourceElement); + } + if (sourceElement instanceof IStorage) { + if (!(sourceElement instanceof IFile)) { + // try to resolve as resource + final IPath location= ((IStorage) sourceElement).getFullPath(); + if (location != null) { + IFile iFile = ResourceLookup.selectFileForLocation(location, null); + if (iFile != null) { + sourceElement = iFile; } } - fFile2Storage.put(file, sourceElement); - } else { - fFile2Storage.put(file, null); - logWarning(DisassemblyMessages.Disassembly_log_error_locateFile+file, null); } + fFile2Storage.put(file, sourceElement); + } else { + fFile2Storage.put(file, null); + logWarning(DisassemblyMessages.Disassembly_log_error_locateFile+file, null); } + if (sourceElement instanceof IStorage) { SourceFileInfo fi = fDocument.getSourceInfo((IStorage)sourceElement); if (fi == null) { @@ -3360,8 +2750,9 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } fi.fReadingJob.schedule(); } - pos = fDocument.insertInvalidSource(pos, address, fi, lineNr); + pos = fDocument.insertInvalidSource(pos, address, fi, lineNumber); } + return pos; } @@ -3412,31 +2803,6 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem } } } - - public static BigInteger decodeAddress(String string) { - if (string.startsWith("0x")) { //$NON-NLS-1$ - return new BigInteger(string.substring(2), 16); - } - return new BigInteger(string); - } - - private static String getAddressText(BigInteger address) { - if (address == null) { - return ""; //$NON-NLS-1$ - } - if (address.compareTo(BigInteger.ZERO) < 0) { - return address.toString(); - } - String hex = address.toString(16); - return "0x" + "0000000000000000".substring(hex.length() + (address.bitLength() <= 32 ? 8 : 0)) + hex; //$NON-NLS-1$ //$NON-NLS-2$ - } - - static void internalError(Throwable e) { - if (DEBUG) { - System.err.println("Disassembly: Internal error"); //$NON-NLS-1$ - e.printStackTrace(); - } - } public AddressBarContributionItem getAddressBar() { return fAddressBar; @@ -3459,4 +2825,105 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem ctxService.deactivateContext(fContextActivation); } } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#handleTargetSuspended() + */ + public void handleTargetSuspended() { + asyncExec(new Runnable() { + public void run() { + updatePC(PC_UNKNOWN); + firePropertyChange(PROP_SUSPENDED); + } + }); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#handleTargetResumed() + */ + public void handleTargetResumed() { + asyncExec(new Runnable() { + public void run() { + updatePC(PC_RUNNING); + firePropertyChange(PROP_SUSPENDED); + } + }); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#handleTargetEnded() + */ + public void handleTargetEnded() { + asyncExec(new Runnable() { + public void run() { + fDebugSessionId = null; + debugContextChanged(); + } + }); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#setUpdatePending(boolean) + */ + public void setUpdatePending(boolean pending) { + fUpdatePending = pending; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#getUpdatePending() + */ + public boolean getUpdatePending() { + assert isGuiThread(); + return fUpdatePending; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#setGotoAddressPending(java.math.BigInteger) + */ + public void setGotoAddressPending(BigInteger address) { + assert isGuiThread(); + fGotoAddressPending = address; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#getGotoAddressPending() + */ + public BigInteger getGotoAddressPending() { + assert isGuiThread(); + return fGotoAddressPending; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#getDocument() + */ + public IDisassemblyDocument getDocument() { + assert isGuiThread(); + return fDocument; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback#getStorageForFile(java.lang.String) + */ + public Object getStorageForFile(String file) { + assert isGuiThread(); + return fFile2Storage.get(file); + } + + /** + * A passthru from the text hover code to the backend. + */ + public String evaluateExpression(String expr) { + if (fBackend != null) { + return fBackend.evaluateExpression(expr); + } + return ""; //$NON-NLS-1$ + } + + /** + * Most methods in IDisassemblyPartCallback require execution on the GUI thread. + */ + private static boolean isGuiThread() { + return Display.getCurrent() != null; + } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java index 585e023af60..463d947eb9b 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyTextHover.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -10,25 +10,10 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; -import java.util.concurrent.ExecutionException; - -import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; -import org.eclipse.cdt.dsf.concurrent.DsfExecutor; -import org.eclipse.cdt.dsf.concurrent.Query; -import org.eclipse.cdt.dsf.datamodel.DMContexts; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.LabelPosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.LabelPosition; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition; -import org.eclipse.cdt.dsf.debug.service.IExpressions; -import org.eclipse.cdt.dsf.debug.service.IFormattedValues; -import org.eclipse.cdt.dsf.debug.service.IRunControl; -import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; -import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; -import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; -import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; -import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.internal.ui.text.CWordFinder; import org.eclipse.core.runtime.IStatus; @@ -112,48 +97,7 @@ public class DisassemblyTextHover implements ITextHover { * @return expression value or null */ private String evaluateExpression(final String expr) { - final IFrameDMContext frameDmc= fDisassemblyPart.getTargetFrameContext(); - if (frameDmc == null) { - return null; - } - final DsfExecutor executor= fDisassemblyPart.getSession().getExecutor(); - Query query= new Query() { - @Override - protected void execute(final DataRequestMonitor rm) { - IExecutionDMContext exeCtx = DMContexts.getAncestorOfType(frameDmc, IExecutionDMContext.class); - final IRunControl rc= fDisassemblyPart.getService(IRunControl.class); - if (rc == null || !rc.isSuspended(exeCtx)) { - rm.done(); - return; - } - final IExpressions expressions= fDisassemblyPart.getService(IExpressions.class); - if (expressions == null) { - rm.done(); - return; - } - IExpressionDMContext exprDmc= expressions.createExpression(frameDmc, expr); - final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT); - expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor(executor, rm) { - @Override - protected void handleSuccess() { - FormattedValueDMData data= getData(); - rm.setData(data); - rm.done(); - } - }); - }}; - - executor.execute(query); - FormattedValueDMData data= null; - try { - data= query.get(); - } catch (InterruptedException exc) { - } catch (ExecutionException exc) { - } - if (data != null) { - return data.getFormattedValue(); - } - return null; + return fDisassemblyPart.evaluateExpression(expr); } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/EditionFinderJob.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/EditionFinderJob.java index 40b32498824..effc04e4720 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/EditionFinderJob.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/EditionFinderJob.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2010 Wind River Systems, Inc. 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 @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.Job; +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.internalError; /** * A job to find a suitable edition from the local history @@ -69,7 +70,7 @@ class EditionFinderJob extends Job { token.wait(1000); } } catch (InterruptedException e) { - DisassemblyPart.internalError(e); + internalError(e); } token = fDisassemblyPart.retrieveModuleTimestamp(fAddress); } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java index 216154959b2..119cfb845c3 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -10,9 +10,9 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition; import org.eclipse.jface.text.BadLocationException; /** diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/SourcePosition.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/SourcePosition.java similarity index 71% rename from dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/SourcePosition.java rename to dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/SourcePosition.java index f5138df554b..77e723f8cde 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/SourcePosition.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/SourcePosition.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -8,10 +8,13 @@ * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ -package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; +package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; import java.math.BigInteger; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; + /** * SourcePosition */ @@ -46,5 +49,13 @@ public class SourcePosition extends AddressRangePosition { fFileInfo = fileInfo; fLine = line; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString() + */ + @Override + public String toString() { + return super.toString() + "->["+fFileInfo.fFileKey + ':' + fLine + ']'; //$NON-NLS-1$ + } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java index 9002f0fc7e1..31359df0113 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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 @@ -10,10 +10,11 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.decodeAddress; + import java.math.BigInteger; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.jface.dialogs.IDialogConstants; @@ -34,7 +35,7 @@ public final class ActionGotoAddress extends AbstractDisassemblyAction { if (input == null || input.length() == 0) return " "; //$NON-NLS-1$ try { - BigInteger address= DisassemblyPart.decodeAddress(input); + BigInteger address= decodeAddress(input); if (address.compareTo(BigInteger.ZERO) < 0) { return DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address; } @@ -57,7 +58,7 @@ public final class ActionGotoAddress extends AbstractDisassemblyAction { InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, validator); if (dlg.open() == IDialogConstants.OK_ID) { String value = dlg.getValue(); - BigInteger address= DisassemblyPart.decodeAddress(value); + BigInteger address= decodeAddress(value); DsfUIPlugin.getDefault().getDialogSettings().put("gotoAddress", value); //$NON-NLS-1$ getDisassemblyPart().gotoAddress(address); } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java index 372977be8cc..a60ec2c69d4 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/JumpToAddressAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Texas Instruments, Inc. and others. + * Copyright (c) 2009, 2010 Texas Instruments, Inc. 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 @@ -16,6 +16,7 @@ import java.math.BigInteger; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart; import org.eclipse.jface.action.Action; +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.decodeAddress; public class JumpToAddressAction extends Action { @@ -37,7 +38,7 @@ public class JumpToAddressAction extends Action { location = location.trim(); BigInteger address = null; try { - address = DisassemblyPart.decodeAddress(location); + address = decodeAddress(location); if (address.compareTo(BigInteger.ZERO) < 0) { address = null; addressBar.setWarningIconVisible(true); diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java index bf9edc43bdb..cce489456e5 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java @@ -18,6 +18,8 @@ import java.util.Iterator; import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.LabelPosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IBreakpointLocationProvider; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java index 79c5248bc41..f3af3f1b2c8 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java @@ -10,14 +10,23 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; +import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.DEBUG; + import java.io.File; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.ErrorPosition; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyDocument; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.LabelPosition; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.SourcePosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDTextStore; import org.eclipse.core.resources.IStorage; @@ -32,21 +41,32 @@ import org.eclipse.jface.text.DocumentRewriteSessionType; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Position; +import org.eclipse.swt.widgets.Display; /** * DisassemblyDocument */ -public class DisassemblyDocument extends REDDocument { +public class DisassemblyDocument extends REDDocument implements IDisassemblyDocument { public final static String CATEGORY_MODEL = "category_model"; //$NON-NLS-1$ public final static String CATEGORY_DISASSEMBLY = "category_disassembly"; //$NON-NLS-1$ public final static String CATEGORY_SOURCE = "category_source"; //$NON-NLS-1$ public final static String CATEGORY_LABELS = "category_labels"; //$NON-NLS-1$ - private final static boolean DEBUG = false; + /** + * For ease of troubleshooting, don't add or remove from this list directly. + * Use the add/remove methods. Note that we're not the only ones that + * manipulate the list. This list should be accessed only from the GUI thread + */ + private final List fInvalidAddressRanges = new ArrayList(); - private final ArrayList fInvalidAddressRanges = new ArrayList(); - private final ArrayList fInvalidSource = new ArrayList(); + /** + * For ease of troubleshooting, don't add or remove from this list directly. + * Use the add/remove methods. Note that we're not the only ones that + * manipulate the list. This list should be accessed only from the GUI thread + */ + private final List fInvalidSource = new ArrayList(); + private final Map fFileInfoMap = new HashMap(); private int fMaxFunctionLength = 0; @@ -88,14 +108,19 @@ public class DisassemblyDocument extends REDDocument { */ @Override public void dispose() { + assert isGuiThread(); + super.dispose(); + // cleanup source info for (Iterator iter = fFileInfoMap.values().iterator(); iter.hasNext();) { SourceFileInfo fi = iter.next(); fi.dispose(); } fFileInfoMap.clear(); + fInvalidAddressRanges.clear(); + fInvalidSource.clear(); } @@ -109,12 +134,9 @@ public class DisassemblyDocument extends REDDocument { completeInitialization(); } - public List getInvalidAddressRanges() { - return fInvalidAddressRanges; - } - - public List getInvalidSource() { - return fInvalidSource; + public AddressRangePosition[] getInvalidAddressRanges() { + assert isGuiThread(); + return fInvalidAddressRanges.toArray(new AddressRangePosition[fInvalidAddressRanges.size()]); } public void setMaxOpcodeLength(int opcodeLength) { @@ -690,9 +712,8 @@ public class DisassemblyDocument extends REDDocument { if (list == null) { throw new BadPositionCategoryException(); } - int idx; - idx = computeIndexInPositionListLast(list, pos.fAddressOffset); - list.add(idx, pos); + if (DEBUG) System.out.println("Adding position to category <" + category + "> : " + pos); //$NON-NLS-1$ //$NON-NLS-2$ + list.add(computeIndexInPositionListLast(list, pos.fAddressOffset), pos); } /** @@ -771,7 +792,10 @@ public class DisassemblyDocument extends REDDocument { @Override public void removePosition(String category, Position position) throws BadPositionCategoryException { super.removePosition(category, position); - if (category != CATEGORY_MODEL && position instanceof AddressRangePosition) { + + if (DEBUG && isOneOfOurs(category)) System.out.println("Removing position from category(" + category + ") :" + position); //$NON-NLS-1$ //$NON-NLS-2$ + + if (!category.equals(CATEGORY_MODEL) && position instanceof AddressRangePosition) { super.removePosition(CATEGORY_MODEL, position); } } @@ -781,6 +805,15 @@ public class DisassemblyDocument extends REDDocument { if (toRemove.isEmpty()) { return; } + + if (DEBUG && isOneOfOurs(category)) { + System.out.println("Removing positions from category(" + category + ')'); //$NON-NLS-1$ + int i = 0; + for (AddressRangePosition pos : toRemove) { + System.out.println("[" + i++ +"] " + pos); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + List positions = (List) getDocumentManagedPositions().get(category); if (positions != null) { positions.removeAll(toRemove); @@ -857,6 +890,16 @@ public class DisassemblyDocument extends REDDocument { pos.offset += delta; } } + + if (DEBUG) { + String escapedText = null; + if (text != null) { + escapedText = text.replace(new StringBuffer("\n"), new StringBuffer("\\n")); //$NON-NLS-1$ //$NON-NLS-2$ + escapedText = escapedText.replace(new StringBuffer("\r"), new StringBuffer("\\r")); //$NON-NLS-1$ //$NON-NLS-2$ + escapedText = escapedText.replace(new StringBuffer("\t"), new StringBuffer("\\t")); //$NON-NLS-1$ //$NON-NLS-2$ + } + System.out.println("Calling AbstractDocument.replace("+insertPos.offset+','+replaceLength+",\""+escapedText+"\")"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + } super.replace(insertPos.offset, replaceLength, text); } @@ -869,6 +912,7 @@ public class DisassemblyDocument extends REDDocument { */ public AddressRangePosition insertAddressRange(AddressRangePosition pos, AddressRangePosition insertPos, String line, boolean addToModel) throws BadLocationException { + assert isGuiThread(); final BigInteger address = insertPos.fAddressOffset; BigInteger length = insertPos.fAddressLength; if (pos == null) { @@ -896,7 +940,7 @@ public class DisassemblyDocument extends REDDocument { it.remove(); removeModelPosition(overlap); if (!overlap.fValid) { - fInvalidAddressRanges.remove(overlap); + removeInvalidAddressRange(overlap); } } while(!pos.containsAddress(address.add(length.subtract(BigInteger.ONE)))); } @@ -914,7 +958,7 @@ public class DisassemblyDocument extends REDDocument { newEndAddress = newStartAddress; } else { replaceLength += pos.length; - fInvalidAddressRanges.remove(pos); + removeInvalidAddressRange(pos); removeDisassemblyPosition(pos); pos = null; } @@ -940,16 +984,12 @@ public class DisassemblyDocument extends REDDocument { return pos; } - /** - * @param pos - * @param address - * @param length - * @param instruction - * @throws BadPositionCategoryException - * @throws BadLocationException + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyDocument#insertDisassemblyLine(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition, java.math.BigInteger, int, java.lang.String, java.lang.String, java.lang.String, int) */ public AddressRangePosition insertDisassemblyLine(AddressRangePosition pos, BigInteger address, int length, String opcode, String instruction, String file, int lineNr) throws BadLocationException { + assert isGuiThread(); String disassLine = null; if (instruction == null || instruction.length() == 0) { disassLine = ""; //$NON-NLS-1$ @@ -1037,6 +1077,7 @@ public class DisassemblyDocument extends REDDocument { public AddressRangePosition insertErrorLine(AddressRangePosition pos, BigInteger address, BigInteger length, String line) throws BadLocationException { + assert isGuiThread(); int hashCode = line.hashCode(); final long alignment = fErrorAlignment; if (alignment > 1 && !(pos instanceof ErrorPosition)) { @@ -1053,7 +1094,7 @@ public class DisassemblyDocument extends REDDocument { if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) { replace(pos, pos.length, null); removeModelPosition(pos); - fInvalidAddressRanges.remove(pos); + removeInvalidAddressRange(pos); pos = null; } else { pos.fAddressOffset = pos.fAddressOffset.add(mergeLen); @@ -1081,7 +1122,7 @@ public class DisassemblyDocument extends REDDocument { if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) { replace(pos, pos.length, null); removeModelPosition(pos); - fInvalidAddressRanges.remove(pos); + removeInvalidAddressRange(pos); pos = null; } if (DEBUG) checkConsistency(); @@ -1101,7 +1142,7 @@ public class DisassemblyDocument extends REDDocument { pos = insertAddressRange(pos, errorPos, errorLine, true); addDisassemblyPosition(errorPos); if (!errorPos.fValid) { - fInvalidAddressRanges.add(errorPos); + addInvalidAddressRange(errorPos); } length = length.subtract(posLen); address = address.add(posLen); @@ -1110,15 +1151,12 @@ public class DisassemblyDocument extends REDDocument { return pos; } - /** - * @param pos - * @param address - * @param label - * @throws BadLocationException - * @throws BadPositionCategoryException + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyDocument#insertLabel(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition, java.math.BigInteger, java.lang.String, boolean) */ public AddressRangePosition insertLabel(AddressRangePosition pos, BigInteger address, String label, boolean showLabels) throws BadLocationException { + assert isGuiThread(); String labelLine = showLabels ? label + ":\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$ LabelPosition labelPos = getLabelPosition(address); if (labelPos != null) { @@ -1158,7 +1196,7 @@ public class DisassemblyDocument extends REDDocument { pos.length = sourceLines.length(); pos.fLine = line; pos.fValid = true; - fInvalidSource.remove(pos); + removeInvalidSourcePosition(pos); replace(pos, oldLength, sourceLines); if (!endOfSource) { if (pos.length > 0) { @@ -1167,7 +1205,7 @@ public class DisassemblyDocument extends REDDocument { pos = new SourcePosition(pos.offset+pos.length, 0, pos.fAddressOffset, pos.fFileInfo, line, false); addSourcePosition(pos); addModelPosition(pos); - fInvalidSource.add(pos); + addInvalidSourcePositions(pos); } else { //TLETODO need more checks for correct source pos pos = oldPos; @@ -1188,6 +1226,7 @@ public class DisassemblyDocument extends REDDocument { * @return */ public AddressRangePosition insertInvalidSource(AddressRangePosition pos, BigInteger address, SourceFileInfo fi, int lineNr) { + assert isGuiThread(); SourcePosition sourcePos = getSourcePosition(address); if (sourcePos != null) { return pos; @@ -1198,7 +1237,7 @@ public class DisassemblyDocument extends REDDocument { pos = insertAddressRange(pos, sourcePos, sourceLine, true); addSourcePosition(sourcePos); assert !fInvalidSource.contains(sourcePos); - fInvalidSource.add(sourcePos); + addInvalidSourcePositions(sourcePos); } catch (BadLocationException e) { internalError(e); } @@ -1213,6 +1252,7 @@ public class DisassemblyDocument extends REDDocument { * @return */ public AddressRangePosition insertInvalidAddressRange(int offset, int replaceLength, BigInteger startAddress, BigInteger endAddress) { + assert isGuiThread(); String periods = "...\n"; //$NON-NLS-1$ AddressRangePosition newPos = new AddressRangePosition(offset, periods.length(), startAddress, endAddress .subtract(startAddress), false); @@ -1220,7 +1260,7 @@ public class DisassemblyDocument extends REDDocument { addModelPositionFirst(newPos); replace(newPos, replaceLength, periods); addDisassemblyPosition(newPos); - fInvalidAddressRanges.add(newPos); + addInvalidAddressRange(newPos); } catch (BadLocationException e) { internalError(e); } @@ -1232,6 +1272,7 @@ public class DisassemblyDocument extends REDDocument { } public void deleteDisassemblyRange(BigInteger startAddress, BigInteger endAddress, boolean invalidate, boolean collapse) { + assert isGuiThread(); DocumentRewriteSession session = startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL); try { String replacement = invalidate ? "...\n" : null; //$NON-NLS-1$ @@ -1267,7 +1308,7 @@ public class DisassemblyDocument extends REDDocument { lastPos.fAddressLength = lastPos.fAddressLength.add(pos.fAddressLength); toRemove.add(pos); if (!pos.fValid) { - fInvalidAddressRanges.remove(pos); + removeInvalidAddressRange(pos); } pos = null; if (posEndAddress.compareTo(endAddress) < 0) { @@ -1293,7 +1334,7 @@ public class DisassemblyDocument extends REDDocument { if (pos != null) { if (pos.fValid && invalidate) { pos.fValid = false; - fInvalidAddressRanges.add(pos); + addInvalidAddressRange(pos); } lastPos = pos; } @@ -1306,6 +1347,7 @@ public class DisassemblyDocument extends REDDocument { } public void invalidateSource() { + assert isGuiThread(); Iterator it; try { it = getPositionIterator(CATEGORY_SOURCE, 0); @@ -1317,11 +1359,33 @@ public class DisassemblyDocument extends REDDocument { SourcePosition srcPos = (SourcePosition)it.next(); if (srcPos != null && srcPos.fValid) { srcPos.fValid = false; - assert !getInvalidSource().contains(srcPos); - getInvalidSource().add(srcPos); + assert !fInvalidSource.contains(srcPos); + addInvalidSourcePositions(srcPos); } } } + + public SourcePosition[] getInvalidSourcePositions() { + assert isGuiThread(); + return fInvalidSource.toArray(new SourcePosition[fInvalidSource.size()]); + } + + public boolean addInvalidSourcePositions(SourcePosition srcPos) { + assert isGuiThread(); + if (DEBUG) System.out.println("Adding invalid source position to list: " + srcPos); //$NON-NLS-1$ + return fInvalidSource.add(srcPos); + } + + public boolean removeInvalidSourcePosition(SourcePosition srcPos) { + assert isGuiThread(); + if (DEBUG) System.out.println("Removing invalid source position from list: " + srcPos); //$NON-NLS-1$ + return fInvalidSource.remove(srcPos); + } + + public boolean hasInvalidSourcePositions() { + assert isGuiThread(); + return fInvalidSource.size() > 0; + } public void invalidateDisassemblyWithSource(boolean removeDisassembly) { for (Iterator it = fFileInfoMap.values().iterator(); it.hasNext();) { @@ -1338,6 +1402,7 @@ public class DisassemblyDocument extends REDDocument { * @throws BadLocationException */ public void deleteLineRange(int start, int end) throws BadLocationException { + assert isGuiThread(); if (start >= end) { return; } @@ -1365,9 +1430,9 @@ public class DisassemblyDocument extends REDDocument { toRemove.add(p); if (!p.fValid) { if (p instanceof SourcePosition) { - getInvalidSource().remove(p); + removeInvalidSourcePosition((SourcePosition)p); } else { - getInvalidAddressRanges().remove(p); + removeInvalidAddressRange(p); } } if (addressLength.compareTo(BigInteger.ZERO) > 0 && p.fAddressOffset.compareTo(endPos.fAddressOffset) >= 0) { @@ -1446,4 +1511,35 @@ public class DisassemblyDocument extends REDDocument { } } + public void addInvalidAddressRange(AddressRangePosition pos) { + assert isGuiThread(); + if (DEBUG) System.out.println("Adding to invalid range list: " + pos); //$NON-NLS-1$ + fInvalidAddressRanges.add(pos); + } + + public void removeInvalidAddressRanges(Collection positions) { + assert isGuiThread(); + if (DEBUG) { + for (AddressRangePosition pos : positions) + System.out.println("Removing from invalid range list: " + pos); //$NON-NLS-1$ + } + fInvalidAddressRanges.removeAll(positions); + } + + public void removeInvalidAddressRange(AddressRangePosition pos) { + assert isGuiThread(); + if (DEBUG) System.out.println("Removing from invalid range list: " + pos); //$NON-NLS-1$ + fInvalidAddressRanges.remove(pos); + } + + private static boolean isGuiThread() { + return Display.getCurrent() != null; + } + + private static boolean isOneOfOurs(String category) { + return category.equals(CATEGORY_MODEL) || + category.equals(CATEGORY_DISASSEMBLY) || + category.equals(CATEGORY_LABELS) || + category.equals(CATEGORY_SOURCE); + } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java index 3b466857f28..837a29df19a 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems and others. + * Copyright (c) 2007, 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 @@ -12,6 +12,8 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; import java.math.BigInteger; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition; + /** * DisassemblyWithSourcePosition */ @@ -42,5 +44,13 @@ public class DisassemblyWithSourcePosition extends DisassemblyPosition { public int getLine() { return fLine; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition#toString() + */ + @Override + public String toString() { + return super.toString() + "->["+fFile + ':' + fLine + ']'; //$NON-NLS-1$ + } } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/DisassemblySelection.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/DisassemblySelection.java index 49453b13ecb..1e74767b06d 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/DisassemblySelection.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/DisassemblySelection.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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 @@ -13,9 +13,9 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional; import java.math.BigInteger; import java.net.URI; +import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.SourcePosition; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition; -import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/internal/ui/DsfUIPlugin.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/internal/ui/DsfUIPlugin.java index 17714f11099..ed997000325 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/internal/ui/DsfUIPlugin.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/internal/ui/DsfUIPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. + * 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 @@ -11,7 +11,9 @@ package org.eclipse.cdt.dsf.internal.ui; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyBackendDsfFactory; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceDocumentProvider; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; @@ -55,6 +57,10 @@ public class DsfUIPlugin extends AbstractUIPlugin { DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$ fSourceDocumentProvider = new SourceDocumentProvider(); + + // Register the DSF backend for our disassembly view (the CDT debug UI + // plugin registers the CDI one) + Platform.getAdapterManager().registerAdapters(new DisassemblyBackendDsfFactory(), IDMVMContext.class); } /*