(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;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyView.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyView.java
new file mode 100644
index 00000000000..a85b6db47e1
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyView.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
+
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+
+/**
+ * DisassemblyView
+ */
+public class DisassemblyView extends DisassemblyPart implements IViewPart {
+
+ private ISelectionListener fDebugViewListener;
+
+ /**
+ *
+ */
+ public DisassemblyView() {
+ super();
+ }
+
+ /*
+ * @see com.windriver.ide.disassembly.views.DisassemblyPart#getActionBars()
+ */
+ @Override
+ protected IActionBars getActionBars() {
+ return getViewSite().getActionBars();
+ }
+
+ /*
+ * @see org.eclipse.ui.IViewPart#getViewSite()
+ */
+ public IViewSite getViewSite() {
+ return (IViewSite)getSite();
+ }
+
+ /*
+ * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite)
+ */
+ public void init(IViewSite site) throws PartInitException {
+ setSite(site);
+ }
+
+ /*
+ * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
+ */
+ public void init(IViewSite site, IMemento memento) throws PartInitException {
+ setSite(site);
+ site.getPage().addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, fDebugViewListener= new ISelectionListener() {
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ updateDebugContext();
+ }});
+ }
+
+ /*
+ * @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
+ */
+ public void saveState(IMemento memento) {
+ }
+
+ /*
+ * @see com.windriver.ide.disassembly.views.DisassemblyPart#contributeToActionBars()
+ */
+ @Override
+ protected void contributeToActionBars(IActionBars bars) {
+ super.contributeToActionBars(bars);
+ fillLocalPullDown(bars.getMenuManager());
+ }
+
+ protected void fillLocalPullDown(IMenuManager manager) {
+ manager.add(fActionGotoPC);
+ manager.add(fActionGotoAddress);
+ manager.add(fActionToggleSource);
+ manager.add(new Separator());
+ }
+
+ /*
+ * @see com.windriver.ide.disassembly.views.DisassemblyPart#closePart()
+ */
+ @Override
+ protected void closePart() {
+ getViewSite().getPage().hideView(this);
+ }
+
+ /*
+ * @see com.windriver.ide.disassembly.views.DisassemblyPart#dispose()
+ */
+ @Override
+ public void dispose() {
+ getSite().getPage().removeSelectionListener(fDebugViewListener);
+ super.dispose();
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewer.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewer.java
new file mode 100644
index 00000000000..467ae30c0f7
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewer.java
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
+
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.IVerticalRulerColumn;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * DisassemblyViewer
+ */
+public class DisassemblyViewer extends SourceViewer {
+
+ class ResizeListener implements ControlListener {
+ /*
+ * @see ControlListener#controlResized(ControlEvent)
+ */
+ public void controlResized(ControlEvent e) {
+ updateViewportListeners(RESIZE);
+ }
+ /*
+ * @see ControlListener#controlMoved(ControlEvent)
+ */
+ public void controlMoved(ControlEvent e) {
+ }
+ }
+
+ private boolean fUserTriggeredScrolling;
+ private int fCachedLastTopPixel;
+
+ // extra resize listener to workaround bug 171018
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=171018
+ private ResizeListener fResizeListener;
+
+ /**
+ * Create a new DisassemblyViewer.
+ * @param parent
+ * @param ruler
+ * @param overviewRuler
+ * @param showsAnnotationOverview
+ * @param styles
+ */
+ public DisassemblyViewer(Composite parent, IVerticalRuler ruler, IOverviewRuler overviewRuler, boolean showsAnnotationOverview, int styles) {
+ super(parent, ruler, overviewRuler, showsAnnotationOverview, styles);
+ // always readonly
+ setEditable(false);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewer#createControl(org.eclipse.swt.widgets.Composite, int)
+ */
+ @Override
+ protected void createControl(Composite parent, int styles) {
+ super.createControl(parent, styles);
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=171018
+ getTextWidget().addControlListener(fResizeListener= new ResizeListener());
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewer#handleDispose()
+ */
+ @Override
+ protected void handleDispose() {
+ if (fResizeListener != null) {
+ getTextWidget().removeControlListener(fResizeListener);
+ }
+ super.handleDispose();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewer#doOperation(int)
+ */
+ @Override
+ public void doOperation(int operation) {
+ switch (operation) {
+ case COPY:
+ StyledText textWidget = getTextWidget();
+ if (textWidget == null || !redraws()) {
+ return;
+ }
+ if (textWidget.getSelectionCount() == 0) {
+ return;
+ }
+ String selectedText;
+ try {
+ selectedText = getSelectedText();
+ } catch (BadLocationException e) {
+ // should not happend
+ DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, e.getLocalizedMessage(), e));
+ return;
+ }
+ Clipboard clipboard = new Clipboard(textWidget.getDisplay());
+ clipboard.setContents(new Object[] { selectedText }, new Transfer[] { TextTransfer.getInstance() });
+ clipboard.dispose();
+ break;
+ default:
+ super.doOperation(operation);
+ }
+ }
+
+ /**
+ * Get the selected text together with text displayed in visible
+ * ruler columns.
+ * @return the selected text
+ * @throws BadLocationException
+ */
+ public String getSelectedText() throws BadLocationException {
+ StringBuffer text = new StringBuffer(200);
+ String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
+ DisassemblyDocument doc = (DisassemblyDocument)getDocument();
+ Point selection = getSelectedRange();
+ int startOffset = selection.x;
+ int length = selection.y;
+ int endOffset = startOffset + length;
+ int startLine = doc.getLineOfOffset(startOffset);
+ int endLine = doc.getLineOfOffset(endOffset);
+ int firstLineOffset = startOffset - doc.getLineOffset(startLine);
+ if (firstLineOffset > 0) {
+ // partial first line
+ int lineLength = doc.getLineInformation(startLine).getLength();
+ text.append(doc.get(startOffset, Math.min(lineLength - firstLineOffset, length)));
+ ++startLine;
+ if (startLine <= endLine) {
+ text.append(lineSeparator);
+ }
+ }
+ for (int line = startLine; line < endLine; ++line) {
+ String lineText = getLineText(line);
+ text.append(lineText);
+ text.append(lineSeparator);
+ }
+ if (doc.getLineOffset(endLine) < endOffset) {
+ // partial last line
+ if (startLine <= endLine) {
+ int lineStart = doc.getLineOffset(endLine);
+ text.append(getLinePrefix(endLine));
+ text.append(doc.get(lineStart, endOffset - lineStart));
+ }
+ }
+ return text.toString();
+ }
+
+ /**
+ * Return the content of the given line, excluding line separator.
+ * @param line the line number
+ * @return the line content
+ * @throws BadLocationException
+ */
+ public String getLineText(int line) throws BadLocationException {
+ IDocument doc = getDocument();
+ IRegion lineRegion = doc.getLineInformation(line);
+ return getLinePrefix(line) + doc.get(lineRegion.getOffset(), lineRegion.getLength());
+ }
+
+ /**
+ * Get the line prefix by concatenating the text displayed by
+ * the visible ruler columns.
+ * @param line the line number
+ * @return the prefix string with trailing blank or the empty string
+ */
+ public String getLinePrefix(int line) {
+ StringBuffer prefix = new StringBuffer(10);
+ IVerticalRuler ruler = getVerticalRuler();
+ if (ruler instanceof CompositeRuler) {
+ for (Iterator> iter = ((CompositeRuler)ruler).getDecoratorIterator(); iter.hasNext();) {
+ IVerticalRulerColumn column = (IVerticalRulerColumn) iter.next();
+ if (column instanceof DisassemblyRulerColumn) {
+ DisassemblyRulerColumn disassColumn = (DisassemblyRulerColumn)column;
+ String columnText = disassColumn.createDisplayString(line);
+ prefix.append(columnText);
+ int columnWidth = disassColumn.computeNumberOfCharacters();
+ columnWidth -= columnText.length();
+ while(columnWidth-- > 0)
+ prefix.append(' ');
+ prefix.append(' ');
+ }
+ }
+ }
+ return prefix.toString();
+ }
+
+ /**
+ * Scroll the given position into the visible area if it is not yet visible.
+ * @param offset
+ * @see org.eclipse.jface.text.TextViewer#revealRange(int, int)
+ */
+ public void revealOffset(int offset, boolean onTop) {
+ try {
+ IDocument doc = getVisibleDocument();
+
+ int focusLine = doc.getLineOfOffset(offset);
+
+ StyledText textWidget = getTextWidget();
+ int top = textWidget.getTopIndex();
+ if (top > -1) {
+
+ // scroll vertically
+ int lines = getEstimatedVisibleLinesInViewport();
+ int bottom = top + lines;
+
+ int bottomBuffer = Math.max(1, lines / 3);
+
+ if (!onTop && focusLine >= top && focusLine <= bottom - bottomBuffer) {
+ // do not scroll at all as it is already visible
+ } else {
+ if (focusLine > bottom - bottomBuffer && focusLine <= bottom) {
+ // focusLine is already in bottom bufferZone
+ // scroll to top of bottom bufferzone - for smooth down-scrolling
+ int scrollDelta = focusLine - (bottom - bottomBuffer);
+ textWidget.setTopIndex(top + scrollDelta);
+ } else {
+ // scroll to top of visible area minus buffer zone
+ int topBuffer = onTop ? 0 : lines / 3;
+ textWidget.setTopIndex(Math.max(0, focusLine - topBuffer));
+ }
+ updateViewportListeners(INTERNAL);
+ }
+ }
+ } catch (BadLocationException ble) {
+ throw new IllegalArgumentException(ble.getLocalizedMessage());
+ }
+ }
+
+ /**
+ * @return the number of visible lines in the viewport assuming a constant
+ * line height.
+ */
+ private int getEstimatedVisibleLinesInViewport() {
+ StyledText textWidget = getTextWidget();
+ if (textWidget != null) {
+ Rectangle clArea= textWidget.getClientArea();
+ if (!clArea.isEmpty())
+ return clArea.height / textWidget.getLineHeight();
+ }
+ return -1;
+ }
+
+ int getLastTopPixel() {
+ return fCachedLastTopPixel;
+ }
+ boolean isUserTriggeredScrolling() {
+ return fUserTriggeredScrolling;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.TextViewer#updateViewportListeners(int)
+ */
+ @Override
+ protected void updateViewportListeners(int origin) {
+ fCachedLastTopPixel = fLastTopPixel;
+ fUserTriggeredScrolling = origin != INTERNAL && origin != RESIZE;
+ super.updateViewportListeners(origin);
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewerConfiguration.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewerConfiguration.java
new file mode 100644
index 00000000000..9092894f209
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/DisassemblyViewerConfiguration.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
+
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.IUndoManager;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+
+/**
+ * DisassemblyViewerConfiguration
+ */
+public class DisassemblyViewerConfiguration extends TextSourceViewerConfiguration {
+
+ private DisassemblyPart fPart;
+
+ /**
+ * SimpleDamagerRepairer
+ */
+ public class SimpleDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
+
+ /*
+ * @see org.eclipse.jface.text.presentation.IPresentationDamager#setDocument(org.eclipse.jface.text.IDocument)
+ */
+ public void setDocument(IDocument document) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.presentation.IPresentationDamager#getDamageRegion(org.eclipse.jface.text.ITypedRegion, org.eclipse.jface.text.DocumentEvent, boolean)
+ */
+ public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) {
+ int start= e.fOffset;
+ int end= e.getOffset() + (e.getText() == null ? 0 : e.getText().length());
+ return new Region(start, end - start);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.presentation.IPresentationRepairer#createPresentation(org.eclipse.jface.text.TextPresentation, org.eclipse.jface.text.ITypedRegion)
+ */
+ public void createPresentation(TextPresentation presentation, ITypedRegion damage) {
+ // do nothing
+ }
+
+ }
+
+ /**
+ *
+ */
+ public DisassemblyViewerConfiguration(DisassemblyPart part) {
+ super(EditorsUI.getPreferenceStore());
+ fPart = part;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler = new PresentationReconciler();
+ SimpleDamagerRepairer dr = new SimpleDamagerRepairer();
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ return reconciler;
+ }
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getUndoManager(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public IUndoManager getUndoManager(ISourceViewer sourceViewer) {
+ // no undo/redo
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+ */
+ @Override
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+ return new DisassemblyTextHover(fPart);
+ }
+
+ /*
+ * @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getHyperlinkDetectors(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
+ IHyperlinkDetector[] inheritedDetectors= super.getHyperlinkDetectors(sourceViewer);
+
+ if (fPart == null)
+ return inheritedDetectors;
+
+ int inheritedDetectorsLength= inheritedDetectors != null ? inheritedDetectors.length : 0;
+ IHyperlinkDetector[] detectors= new IHyperlinkDetector[inheritedDetectorsLength + 1];
+ detectors[0]= new DisassemblyHyperlinkDetector(fPart);
+ for (int i= 0; i < inheritedDetectorsLength; i++) {
+ detectors[i+1]= inheritedDetectors[i];
+ }
+
+ return detectors;
+ }
+
+ /*
+ * @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public IReconciler getReconciler(ISourceViewer sourceViewer) {
+ // disable spell checking
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/EditionFinderJob.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/EditionFinderJob.java
new file mode 100644
index 00000000000..1d3241481eb
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/EditionFinderJob.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
+
+import java.math.BigInteger;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFileState;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+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 org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
+
+/**
+ * A job to find a suitable edition from the local history
+ * based on a file and the timestamp of the code module.
+ */
+class EditionFinderJob extends Job {
+
+ private final IFile fFile;
+ private final BigInteger fAddress;
+ private final DisassemblyPart fDisassemblyPart;
+ private final SourceFileInfo fSourceInfo;
+
+ /**
+ * Create a new edition finder for a file resource and address.
+ *
+ * @param sourceInfo the file info containing the file resource for which to find an edition
+ * @param address address inside the module
+ * @param disassemblyPart the disassembly part where this job originated from
+ */
+ public EditionFinderJob(SourceFileInfo sourceInfo, BigInteger address, DisassemblyPart disassemblyPart) {
+ super(DisassemblyMessages.EditionFinderJob_name);
+ Assert.isNotNull(sourceInfo);
+ Assert.isLegal(sourceInfo.fFile instanceof IFile);
+ fSourceInfo= sourceInfo;
+ fFile = (IFile)sourceInfo.fFile;
+ fAddress = address;
+ fDisassemblyPart= disassemblyPart;
+ setRule(fFile);
+ setSystem(true);
+ sourceInfo.fEditionJob= this;
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ monitor.beginTask(DisassemblyMessages.EditionFinderJob_name, 2);
+ monitor.subTask(DisassemblyMessages.EditionFinderJob_task_get_timestamp);
+ long moduleTime;
+ Object token = fDisassemblyPart.retrieveModuleTimestamp(fAddress);
+ if (token != null && !(token instanceof Long) && !monitor.isCanceled()) {
+ try {
+ synchronized (token) {
+ token.wait(1000);
+ }
+ } catch (InterruptedException e) {
+ DisassemblyPart.internalError(e);
+ }
+ token = fDisassemblyPart.retrieveModuleTimestamp(fAddress);
+ }
+ monitor.worked(1);
+ if (token instanceof Long && !monitor.isCanceled()) {
+ moduleTime = ((Long)token).longValue();
+ long buildTime = moduleTime * 1000;
+ if (fFile.getLocalTimeStamp() > buildTime) {
+ monitor.subTask(DisassemblyMessages.EditionFinderJob_task_search_history);
+ // get history - recent states first
+ IFileState[] states;
+ try {
+ states = fFile.getHistory(new SubProgressMonitor(monitor, 1));
+ } catch (CoreException e) {
+ states = new IFileState[0];
+ }
+ for (int i = 0; i < states.length; i++) {
+ IFileState state = states[i];
+ long saveTime = state.getModificationTime();
+ if (saveTime <= buildTime) {
+ fSourceInfo.fEdition = state;
+ break;
+ }
+ }
+ }
+ }
+ fSourceInfo.fEditionJob = null;
+ monitor.worked(1);
+ monitor.done();
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java
new file mode 100644
index 00000000000..0cc653eba03
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/FunctionOffsetRulerColumn.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
+
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition;
+import org.eclipse.jface.text.BadLocationException;
+
+/**
+ * A vertical ruler column to display the function + offset of instructions.
+ */
+public class FunctionOffsetRulerColumn extends DisassemblyRulerColumn {
+
+ /**
+ * Default constructor.
+ */
+ public FunctionOffsetRulerColumn() {
+ super();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.LineNumberRulerColumn#createDisplayString(int)
+ */
+ @Override
+ protected String createDisplayString(int line) {
+ DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
+ int offset;
+ try {
+ offset = doc.getLineOffset(line);
+ AddressRangePosition pos = doc.getDisassemblyPosition(offset);
+ if (pos instanceof DisassemblyPosition && pos.length > 0 && pos.offset == offset && pos.fValid) {
+ DisassemblyPosition disassPos = (DisassemblyPosition)pos;
+ return new String(disassPos.fFunction);
+ } else if (pos != null && !pos.fValid) {
+ return DOTS.substring(0, doc.getMaxFunctionLength());
+ }
+ } catch (BadLocationException e) {
+ // silently ignored
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /*
+ * @see com.windriver.ide.disassembly.views.DisassemblyRulerColumn#computeNumberOfCharacters()
+ */
+ @Override
+ protected int computeNumberOfCharacters() {
+ DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
+ return doc.getMaxFunctionLength();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IVerticalRulerColumn#getWidth()
+ */
+ @Override
+ public int getWidth() {
+ return super.getWidth();
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyHelpContextIds.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyHelpContextIds.java
new file mode 100644
index 00000000000..72d3754577d
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyHelpContextIds.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
+
+import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
+
+/**
+ * IDisassemblyHelpContextIds
+ */
+public interface IDisassemblyHelpContextIds {
+
+ public final static String PREFIX = DsfDebugUIPlugin.PLUGIN_ID + '.';
+ public final static String DISASSEMBLY_PREFERENCE_PAGE = PREFIX + "disassembly_preference_page"; //$NON-NLS-1$
+ public final static String DISASSEMBLY_VIEW = PREFIX + "disassembly_view"; //$NON-NLS-1$
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyPart.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyPart.java
new file mode 100644
index 00000000000..392de20c3c3
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/IDisassemblyPart.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.dd.dsf.debug.internal.ui.disassembly;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * Interface which the disassembly view and editor implement.
+ */
+public interface IDisassemblyPart extends IWorkbenchPart {
+
+ /**
+ * Property id for the active state of the part.
+ */
+ public final int PROP_ACTIVE= 0x505;
+
+ /**
+ * Property id for the connected state of the part.
+ */
+ public final int PROP_CONNECTED= 0x506;
+
+ /**
+ * Property id for the suspended state of the underlying execution context.
+ */
+ public final int PROP_SUSPENDED= 0x507;
+
+ /**
+ * Test whether this part is connected to a debug session and execution context.
+ *
+ * @return true
if the part is connected to a debug session and execution context
+ */
+ boolean isConnected();
+
+ /**
+ * Test whether this part is active. A part is active if it is visible and connected.
+ *
+ * @return true
if the part is active
+ */
+ boolean isActive();
+
+ /**
+ * Test whether the underlying execution context is currently suspended.
+ * Implies connected state.
+ *
+ * @return true
if the execution context is currently suspended
+ */
+ boolean isSuspended();
+
+ /**
+ * Get access to the text viewer.
+ *
+ * @return the text viewer
+ */
+ ISourceViewer getTextViewer();
+
+ /**
+ * Navigate to the given address.
+ *
+ * @param address
+ */
+ void gotoAddress(BigInteger address);
+
+ /**
+ * Navigate to current program counter.
+ */
+ void gotoProgramCounter();
+
+ /**
+ * Navigate to the address the given expression evaluates to.
+ *
+ * @param expression a symbolic address expression
+ */
+ void gotoSymbol(String expression);
+
+ /**
+ * Adds a ruler context menu listener to the disassembly part.
+ *
+ * @param listener the listener
+ */
+ void addRulerContextMenuListener(IMenuListener listener);
+
+ /**
+ * Removes a ruler context menu listener from the disassembly part.
+ *
+ * @param listener the listener
+ */
+ void removeRulerContextMenuListener(IMenuListener listener);
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/SourceColorerJob.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/SourceColorerJob.java
new file mode 100644
index 00000000000..6a8b339184e
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/SourceColorerJob.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.progress.UIJob;
+
+/**
+ * UI job to color source code.
+ */
+class SourceColorerJob extends UIJob implements Runnable {
+
+ private final DisassemblyPart fDisassemblyPart;
+ private final ISourceViewer fViewer;
+ private final DisassemblyDocument fDocument;
+ private final IStorage fStorage;
+
+ public SourceColorerJob(Display jobDisplay, IStorage storage, DisassemblyPart disassemblyPart) {
+ super(DisassemblyMessages.SourceColorerJob_name);
+ fDisassemblyPart= disassemblyPart;
+ fViewer= disassemblyPart.getTextViewer();
+ fDocument= (DisassemblyDocument) fViewer.getDocument();
+ fStorage = storage;
+ setDisplay(fDisassemblyPart.getSite().getShell().getDisplay());
+ setSystem(true);
+ setPriority(INTERACTIVE);
+ }
+
+ /*
+ * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ if (fViewer != null && !monitor.isCanceled()) {
+ monitor.beginTask(DisassemblyMessages.SourceColorerJob_name, IProgressMonitor.UNKNOWN);
+ SourceFileInfo fi = fDocument.getSourceInfo(fStorage);
+ if (fi != null) {
+ fi.initPresentationCreator(fViewer);
+ if (fi.fError != null) {
+ String message= DisassemblyMessages.Disassembly_log_error_readFile + fi.fFileKey;
+ fDisassemblyPart.logWarning(message, fi.fError);
+ }
+ }
+ fDisassemblyPart.updateInvalidSource();
+ monitor.done();
+ }
+ return Status.OK_STATUS;
+ }
+
+ /*
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ IWorkbenchSiteProgressService progressService = (IWorkbenchSiteProgressService)fDisassemblyPart.getSite().getAdapter(IWorkbenchSiteProgressService.class);
+ if(progressService != null) {
+ progressService.schedule(this, 0, true);
+ } else {
+ schedule();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyAction.java
new file mode 100644
index 00000000000..7ce85f57210
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyAction.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.texteditor.IUpdate;
+
+public abstract class AbstractDisassemblyAction extends Action implements IUpdate, IPropertyListener {
+
+ protected IDisassemblyPart fDisassemblyPart;
+
+ AbstractDisassemblyAction() {
+ }
+
+ /**
+ * Create a disassembly action.
+ *
+ * @param disassemblyPart
+ */
+ public AbstractDisassemblyAction(IDisassemblyPart disassemblyPart) {
+ Assert.isLegal(disassemblyPart != null);
+ fDisassemblyPart= disassemblyPart;
+ fDisassemblyPart.addPropertyListener(this);
+ }
+
+ /**
+ * @return the disassembly part
+ */
+ public final IDisassemblyPart getDisassemblyPart() {
+ return fDisassemblyPart;
+ }
+
+ /*
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public abstract void run();
+
+ public void update() {
+ boolean enabled= fDisassemblyPart == null || fDisassemblyPart.isConnected();
+ setEnabled(enabled);
+ }
+
+ /*
+ * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, int)
+ */
+ public void propertyChanged(Object source, int propId) {
+ if (source == fDisassemblyPart && (propId & 0x500) != 0) {
+ update();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyBreakpointRulerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyBreakpointRulerAction.java
new file mode 100644
index 00000000000..118abcc286e
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyBreakpointRulerAction.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
+
+/**
+ * Abstract implementation of a breakpoint ruler action.
+ */
+public abstract class AbstractDisassemblyBreakpointRulerAction extends AbstractDisassemblyRulerAction {
+
+ /**
+ * Create breakpoint ruler action.
+ *
+ * @param disassemblyPart
+ * @param rulerInfo
+ */
+ protected AbstractDisassemblyBreakpointRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
+ super(disassemblyPart, rulerInfo);
+ }
+
+ /**
+ * Returns the breakpoint at the last line of mouse activity in the ruler
+ * or null
if none.
+ *
+ * @return breakpoint associated with activity in the ruler or null
+ */
+ protected IBreakpoint getBreakpoint() {
+ IAnnotationModel annotationModel = getAnnotationModel();
+ IDocument document = getDocument();
+ if (annotationModel != null) {
+ Iterator> iterator = annotationModel.getAnnotationIterator();
+ while (iterator.hasNext()) {
+ Object object = iterator.next();
+ if (object instanceof SimpleMarkerAnnotation) {
+ SimpleMarkerAnnotation markerAnnotation = (SimpleMarkerAnnotation) object;
+ IMarker marker = markerAnnotation.getMarker();
+ try {
+ if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
+ Position position = annotationModel.getPosition(markerAnnotation);
+ int line = document.getLineOfOffset(position.getOffset());
+ if (line == getRulerInfo().getLineOfLastMouseButtonActivity()) {
+ IBreakpoint breakpoint = DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
+ if (breakpoint != null) {
+ return breakpoint;
+ }
+ }
+ }
+ } catch (CoreException e) {
+ } catch (BadLocationException e) {
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerAction.java
new file mode 100644
index 00000000000..248801fba39
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerAction.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+
+/**
+ * Abstract implementation for disassembly vertical ruler actions.
+ */
+public abstract class AbstractDisassemblyRulerAction extends AbstractDisassemblyAction {
+
+ private final IVerticalRulerInfo fRulerInfo;
+
+ protected AbstractDisassemblyRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
+ fDisassemblyPart= disassemblyPart;
+ fRulerInfo= rulerInfo;
+ }
+
+ public final IVerticalRulerInfo getRulerInfo() {
+ return fRulerInfo;
+ }
+
+ public final IDocument getDocument() {
+ return getDisassemblyPart().getTextViewer().getDocument();
+ }
+
+ public final IAnnotationModel getAnnotationModel() {
+ return getDisassemblyPart().getTextViewer().getAnnotationModel();
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerActionDelegate.java
new file mode 100644
index 00000000000..eda11b1d47d
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/AbstractDisassemblyRulerActionDelegate.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IViewActionDelegate;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.actions.ActionDelegate;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * This class serves as an adapter for actions contributed to the vertical ruler's
+ * context menu. This adapter provides the contributed actions access to their disassembly part
+ * and the disassembly part's vertical ruler. These actions gain only limited access to the vertical
+ * ruler as defined by IVerticalRulerInfo
. The adapter updates the
+ * adapter (inner) action on menu and mouse action on the vertical ruler.
+ * Extending classes must implement the factory method
+ * createAction(IDisassemblyPart, IVerticalRulerInfo)
.
+ *
+ * @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate
+ */
+public abstract class AbstractDisassemblyRulerActionDelegate extends ActionDelegate implements IEditorActionDelegate, IViewActionDelegate, MouseListener, IMenuListener {
+
+ /** The disassembly part. */
+ private IDisassemblyPart fDisassemblyPart;
+ /** The action calling the action delegate. */
+ private IAction fCallerAction;
+ /** The underlying action. */
+ private IAction fAction;
+
+ /**
+ * The factory method creating the underlying action.
+ *
+ * @param disassemblyPart the disassembly part the action to be created will work on
+ * @param rulerInfo the vertical ruler the action to be created will work on
+ * @return the created action
+ */
+ protected abstract IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo);
+
+ /*
+ * @see IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
+ */
+ public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) {
+ setTargetPart(callerAction, targetEditor);
+ }
+
+ /*
+ * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart)
+ */
+ public void init(IViewPart view) {
+ setTargetPart(fCallerAction, view);
+ }
+
+ @Override
+ public void init(IAction action) {
+ fCallerAction= action;
+ }
+
+ private void setTargetPart(IAction callerAction, IWorkbenchPart targetPart) {
+ if (fDisassemblyPart != null) {
+ IVerticalRulerInfo rulerInfo= (IVerticalRulerInfo) fDisassemblyPart.getAdapter(IVerticalRulerInfo.class);
+ if (rulerInfo != null) {
+ Control control= rulerInfo.getControl();
+ if (control != null && !control.isDisposed())
+ control.removeMouseListener(this);
+ }
+
+ fDisassemblyPart.removeRulerContextMenuListener(this);
+ }
+
+ fDisassemblyPart= (IDisassemblyPart)(targetPart == null ? null : targetPart.getAdapter(IDisassemblyPart.class));
+ fCallerAction= callerAction;
+ fAction= null;
+
+ if (fDisassemblyPart != null) {
+ fDisassemblyPart.addRulerContextMenuListener(this);
+
+ IVerticalRulerInfo rulerInfo= (IVerticalRulerInfo) fDisassemblyPart.getAdapter(IVerticalRulerInfo.class);
+ if (rulerInfo != null) {
+ fAction= createAction(fDisassemblyPart, rulerInfo);
+ update();
+
+ Control control= rulerInfo.getControl();
+ if (control != null && !control.isDisposed())
+ control.addMouseListener(this);
+ }
+ }
+ }
+
+ @Override
+ public void run(IAction callerAction) {
+ if (fAction != null)
+ fAction.run();
+ }
+
+ @Override
+ public void runWithEvent(IAction action, Event event) {
+ if (fAction != null)
+ fAction.runWithEvent(event);
+ }
+
+ @Override
+ public void selectionChanged(IAction action, ISelection selection) {
+ /*
+ * This is a ruler action - don't update on selection.
+ */
+ }
+
+ /**
+ * Updates to the current state.
+ */
+ private void update() {
+ if (fAction instanceof IUpdate) {
+ ((IUpdate) fAction).update();
+ if (fCallerAction != null) {
+ fCallerAction.setText(fAction.getText());
+ fCallerAction.setEnabled(fAction.isEnabled());
+ }
+ }
+ }
+
+ /*
+ * @see IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
+ */
+ public void menuAboutToShow(IMenuManager manager) {
+ update();
+ }
+
+ /*
+ * @see MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ /*
+ * @see MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDown(MouseEvent e) {
+ update();
+ }
+
+ /*
+ * @see MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseUp(MouseEvent e) {
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java
new file mode 100644
index 00000000000..99c9525dd7b
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoAddress.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import java.math.BigInteger;
+
+import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyPart;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.swt.widgets.Shell;
+
+public final class ActionGotoAddress extends AbstractDisassemblyAction {
+ public ActionGotoAddress(IDisassemblyPart disassemblyPart) {
+ super(disassemblyPart);
+ setText(DisassemblyMessages.Disassembly_action_GotoAddress_label);
+ }
+ @Override
+ public void run() {
+ IInputValidator validator = new IInputValidator() {
+ public String isValid(String input) {
+ if (input == null || input.length() == 0)
+ return " "; //$NON-NLS-1$
+ try {
+ BigInteger address= DisassemblyPart.decodeAddress(input);
+ if (address.compareTo(BigInteger.ZERO) < 0) {
+ return DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address;
+ }
+ } catch (NumberFormatException x) {
+ return DisassemblyMessages.Disassembly_GotoAddressDialog_error_not_a_number; //;
+ }
+ return null;
+ }
+ };
+ String defaultValue = ((ITextSelection)getDisassemblyPart().getSite().getSelectionProvider().getSelection()).getText();
+ if (validator.isValid(defaultValue) != null) {
+ defaultValue = DsfDebugUIPlugin.getDefault().getDialogSettings().get("gotoAddress"); //$NON-NLS-1$
+ if (validator.isValid(defaultValue) != null) {
+ defaultValue = ""; //$NON-NLS-1$
+ }
+ }
+ String dlgTitle = DisassemblyMessages.Disassembly_GotoAddressDialog_title;
+ String dlgLabel = DisassemblyMessages.Disassembly_GotoAddressDialog_label;
+ final Shell shell= getDisassemblyPart().getSite().getShell();
+ InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, validator);
+ if (dlg.open() == IDialogConstants.OK_ID) {
+ String value = dlg.getValue();
+ BigInteger address= DisassemblyPart.decodeAddress(value);
+ DsfDebugUIPlugin.getDefault().getDialogSettings().put("gotoAddress", value); //$NON-NLS-1$
+ getDisassemblyPart().gotoAddress(address);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoProgramCounter.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoProgramCounter.java
new file mode 100644
index 00000000000..d5729b29f76
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoProgramCounter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+
+public final class ActionGotoProgramCounter extends AbstractDisassemblyAction {
+ public ActionGotoProgramCounter(IDisassemblyPart disassemblyPart) {
+ super(disassemblyPart);
+ setText(DisassemblyMessages.Disassembly_action_GotoPC_label);
+ setToolTipText(DisassemblyMessages.Disassembly_action_GotoPC_tooltip);
+ }
+ @Override
+ public void run() {
+ getDisassemblyPart().gotoProgramCounter();
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoSymbol.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoSymbol.java
new file mode 100644
index 00000000000..4849a8bd5d3
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionGotoSymbol.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.cdt.internal.ui.text.CWordFinder;
+import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.swt.widgets.Shell;
+
+public final class ActionGotoSymbol extends AbstractDisassemblyAction {
+ public ActionGotoSymbol(IDisassemblyPart disassemblyPart) {
+ super(disassemblyPart);
+ setText(DisassemblyMessages.Disassembly_action_GotoSymbol_label);
+ }
+ @Override
+ public void run() {
+ ITextViewer viewer = getDisassemblyPart().getTextViewer();
+ IDocument document= viewer.getDocument();
+ IRegion wordRegion = CWordFinder.findWord(document, viewer.getSelectedRange().x);
+ String defaultValue = null;
+ if (wordRegion != null) {
+ try {
+ defaultValue = document.get(wordRegion.getOffset(), wordRegion.getLength());
+ } catch (BadLocationException e) {
+ // safely ignored
+ }
+ }
+ if (defaultValue == null) {
+ defaultValue = DsfDebugUIPlugin.getDefault().getDialogSettings().get("gotoSymbol"); //$NON-NLS-1$
+ if (defaultValue == null) {
+ defaultValue = ""; //$NON-NLS-1$
+ }
+ }
+ String dlgTitle = DisassemblyMessages.Disassembly_GotoSymbolDialog_title;
+ String dlgLabel = DisassemblyMessages.Disassembly_GotoSymbolDialog_label;
+ final Shell shell= getDisassemblyPart().getSite().getShell();
+ InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, null);
+ if (dlg.open() == IDialogConstants.OK_ID) {
+ String value = dlg.getValue();
+ DsfDebugUIPlugin.getDefault().getDialogSettings().put("gotoSymbol", value); //$NON-NLS-1$
+ getDisassemblyPart().gotoSymbol(value);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionOpenPreferences.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionOpenPreferences.java
new file mode 100644
index 00000000000..7be4676c79f
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/ActionOpenPreferences.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+
+public final class ActionOpenPreferences extends Action {
+ private final static String PREF_PAGE_ID = "org.eclipse.dd.dsf.debug.ui.disassembly.preferencePage"; //$NON-NLS-1$
+ private final Shell fShell;
+ public ActionOpenPreferences(Shell shell) {
+ fShell= shell;
+ setText(DisassemblyMessages.Disassembly_action_OpenPreferences_label);
+ }
+ @Override
+ public void run() {
+ PreferencesUtil.createPreferenceDialogOn(fShell, PREF_PAGE_ID, new String[] { PREF_PAGE_ID }, null).open();
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java
new file mode 100644
index 00000000000..17aa90acbb9
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.cdt.debug.core.model.ICBreakpoint;
+import org.eclipse.cdt.debug.internal.ui.CBreakpointContext;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
+
+/**
+ * Ruler action to display breakpoint properties.
+ */
+public class BreakpointPropertiesRulerAction extends AbstractDisassemblyBreakpointRulerAction {
+
+ private Object fContext;
+
+ protected BreakpointPropertiesRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
+ super(disassemblyPart, rulerInfo);
+ setText(DisassemblyMessages.Disassembly_action_BreakpointProperties_label);
+ }
+
+ /*
+ * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyAction#run()
+ */
+ @Override
+ public void run() {
+ if ( fContext != null ) {
+ PropertyDialogAction action = new PropertyDialogAction( getDisassemblyPart().getSite(), new ISelectionProvider() {
+
+ public void addSelectionChangedListener( ISelectionChangedListener listener ) {
+ }
+
+ public ISelection getSelection() {
+ return new StructuredSelection( fContext );
+ }
+
+ public void removeSelectionChangedListener( ISelectionChangedListener listener ) {
+ }
+
+ public void setSelection( ISelection selection ) {
+ }
+ } );
+ action.run();
+ action.dispose();
+ }
+ }
+
+ /*
+ * @see IUpdate#update()
+ */
+ @Override
+ public void update() {
+ IBreakpoint breakpoint= getBreakpoint();
+ if (breakpoint instanceof ICBreakpoint) {
+ fContext = new CBreakpointContext((ICBreakpoint)breakpoint, getDebugContext());
+ } else {
+ fContext = breakpoint;
+ }
+ setEnabled( fContext != null );
+ }
+
+ private ISelection getDebugContext() {
+ return DebugUITools.getDebugContextManager().getContextService(getDisassemblyPart().getSite().getWorkbenchWindow()).getActiveContext();
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerActionDelegate.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerActionDelegate.java
new file mode 100644
index 00000000000..c34f3b78ea9
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerActionDelegate.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.source.IVerticalRulerInfo;
+
+/**
+ * Ruler action delegate for the breakpoint properties action.
+ */
+public class BreakpointPropertiesRulerActionDelegate extends AbstractDisassemblyRulerActionDelegate {
+
+ /*
+ * @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyRulerActionDelegate#createAction(org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart, org.eclipse.jface.text.source.IVerticalRulerInfo)
+ */
+ @Override
+ protected IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
+ return new BreakpointPropertiesRulerAction(disassemblyPart, rulerInfo);
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/TextOperationAction.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/TextOperationAction.java
new file mode 100644
index 00000000000..765d96027d6
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/actions/TextOperationAction.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * TextOperationAction
+ */
+public class TextOperationAction extends Action implements IUpdate {
+
+ private int fOperationCode= -1;
+ private ITextOperationTarget fOperationTarget;
+
+ public TextOperationAction(ITextViewer viewer, int operationCode) {
+ fOperationCode= operationCode;
+ fOperationTarget= viewer.getTextOperationTarget();
+ update();
+ }
+
+ /**
+ * Updates the enabled state of the action.
+ * Fires a property change if the enabled state changes.
+ *
+ * @see Action#firePropertyChange(String, Object, Object)
+ */
+ public void update() {
+
+ boolean wasEnabled= isEnabled();
+ boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
+ setEnabled(isEnabled);
+
+ if (wasEnabled != isEnabled) {
+ firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE);
+ }
+ }
+
+ /**
+ * @see Action#run()
+ */
+ @Override
+ public void run() {
+ if (fOperationCode != -1 && fOperationTarget != null) {
+ fOperationTarget.doOperation(fOperationCode);
+ }
+ }
+ }
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/Addr2Line.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/Addr2Line.java
new file mode 100644
index 00000000000..0e171abb8a2
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/Addr2Line.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+
+public class Addr2Line {
+ public BigInteger addr;
+ public Addr2Line next;
+ public int first;
+ public int last;
+
+ public static int hash(BigInteger addr, int size) {
+ return (int)((addr.shiftRight(2).longValue()) % size);
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java
new file mode 100644
index 00000000000..4740a8f7335
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/AddressRangePosition.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.text.Position;
+
+/**
+ * AddressRangePosition
+ */
+public class AddressRangePosition extends Position {
+
+ public BigInteger fAddressOffset;
+ public BigInteger fAddressLength;
+ public boolean fValid;
+
+ /**
+ * @param offset
+ * @param length
+ */
+ public AddressRangePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength) {
+ super(offset, length);
+ fAddressOffset = addressOffset;
+ fAddressLength = addressLength;
+ fValid = true;
+ }
+
+ /**
+ * @param offset
+ * @param length
+ * @param valid
+ */
+ public AddressRangePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, boolean valid) {
+ super(offset, length);
+ fAddressOffset = addressOffset;
+ fAddressLength = addressLength;
+ fValid = valid;
+ }
+
+ /**
+ * @param address
+ * @return
+ */
+ public boolean containsAddress(BigInteger address) {
+ return address.compareTo(fAddressOffset) >= 0
+ && address.compareTo(fAddressOffset.add(fAddressLength)) < 0;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object other) {
+ // identity comparison
+ return this == other;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java
new file mode 100644
index 00000000000..ff9c7ba36cf
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+import java.util.Iterator;
+
+import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
+import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointListener;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
+
+/**
+ * Annotation model for breakpoints in the disassembly.
+ * Works only with {@link DisassemblyDocument}.
+ */
+public class BreakpointsAnnotationModel extends AnnotationModel implements IBreakpointListener, IDocumentListener {
+
+ private Runnable fCatchup;
+
+ @Override
+ public void connect(IDocument document) {
+ super.connect(document);
+ if (document instanceof DisassemblyDocument) {
+ final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager();
+ addBreakpoints(bpMgr.getBreakpoints());
+ bpMgr.addBreakpointListener(this);
+ document.addDocumentListener(this);
+ }
+ }
+
+ @Override
+ public void disconnect(IDocument document) {
+ if (document instanceof DisassemblyDocument) {
+ final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager();
+ bpMgr.removeBreakpointListener(this);
+ document.removeDocumentListener(this);
+ fCatchup= null;
+ }
+ super.disconnect(document);
+ }
+
+ private void catchupWithBreakpoints() {
+ removeAllAnnotations(false);
+ final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager();
+ addBreakpoints(bpMgr.getBreakpoints());
+ }
+
+ private void addBreakpoints(IBreakpoint[] breakpoints) {
+ for (IBreakpoint breakpoint : breakpoints) {
+ addBreakpointAnnotation(breakpoint, false);
+ }
+ fireModelChanged();
+ }
+
+ /*
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
+ */
+ public void breakpointAdded(IBreakpoint breakpoint) {
+ addBreakpointAnnotation(breakpoint, true);
+ }
+
+ /*
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
+ */
+ public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
+ Annotation a= findAnnotation(breakpoint.getMarker());
+ if (a != null) {
+ if (a instanceof SimpleMarkerAnnotation) {
+ ((SimpleMarkerAnnotation)a).update();
+ }
+ synchronized (getLockObject()) {
+ getAnnotationModelEvent().annotationChanged(a);
+ }
+ fireModelChanged();
+ }
+ }
+
+ /*
+ * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
+ */
+ public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
+ Annotation a= findAnnotation(breakpoint.getMarker());
+ if (a != null) {
+ removeAnnotation(a, true);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Annotation findAnnotation(IMarker marker) {
+ for (Iterator it= getAnnotationIterator(false); it.hasNext();) {
+ SimpleMarkerAnnotation a= it.next();
+ if (a.getMarker().equals(marker)) {
+ return a;
+ }
+ }
+ return null;
+ }
+
+ private void addBreakpointAnnotation(IBreakpoint breakpoint, boolean fireEvent) {
+ final IMarker marker= breakpoint.getMarker();
+ if (marker == null) {
+ return;
+ }
+ try {
+ Position position= createPositionFromBreakpoint(breakpoint);
+ if (position != null) {
+ addAnnotation(new MarkerAnnotation(marker), position, fireEvent);
+ }
+ } catch (CoreException exc) {
+ // ignore problems accessing attributes
+ } catch (BadLocationException exc) {
+ // ignore wrong positions
+ }
+ }
+
+ private Position createPositionFromBreakpoint(IBreakpoint breakpoint) throws CoreException {
+ if (breakpoint instanceof ICAddressBreakpoint) {
+ ICAddressBreakpoint addressBreakpoint= (ICAddressBreakpoint) breakpoint;
+ return createPositionFromAddress(decodeAddress(addressBreakpoint.getAddress()));
+ } else if (breakpoint instanceof ILineBreakpoint) {
+ ILineBreakpoint lineBreakpoint= (ILineBreakpoint) breakpoint;
+ Position position= null;
+ final int lineNumber= lineBreakpoint.getLineNumber() - 1;
+ final IMarker marker= breakpoint.getMarker();
+ if (marker.getResource().getType() == IResource.FILE) {
+ position= createPositionFromSourceLine((IFile) marker.getResource(), lineNumber);
+ } else if (breakpoint instanceof ICLineBreakpoint) {
+ ICLineBreakpoint cBreakpoint= (ICLineBreakpoint) breakpoint;
+ position= createPositionFromSourceLine(cBreakpoint.getFileName(), lineNumber);
+ if (position == null) {
+ position= createPositionFromAddress(decodeAddress(cBreakpoint.getAddress()));
+ }
+ } else {
+ String fileName= marker.getAttribute(ICLineBreakpoint.SOURCE_HANDLE, null);
+ if (fileName != null) {
+ position= createPositionFromSourceLine(fileName, lineNumber);
+ }
+ }
+ return position;
+ }
+ return null;
+ }
+
+ private Position createPositionFromSourceLine(String fileName, int lineNumber) {
+ return getDisassemblyDocument().getSourcePosition(fileName, lineNumber);
+ }
+
+ private Position createPositionFromSourceLine(IFile file, int lineNumber) {
+ return getDisassemblyDocument().getSourcePosition(file, lineNumber);
+ }
+
+ private Position createPositionFromAddress(BigInteger address) {
+ AddressRangePosition p= getDisassemblyDocument().getDisassemblyPosition(address);
+ if (p != null && p.fValid) {
+ return new Position(p.offset, p.length);
+ }
+ return null;
+ }
+
+ private DisassemblyDocument getDisassemblyDocument() {
+ return (DisassemblyDocument) fDocument;
+ }
+
+ /**
+ * Decode given string representation of a non-negative integer. A
+ * hexadecimal encoded integer is expected to start with 0x
.
+ *
+ * @param string
+ * decimal or hexadecimal representation of an non-negative integer
+ * @return address value as BigInteger
+ */
+ private static BigInteger decodeAddress(String string) {
+ if (string.startsWith("0x")) { //$NON-NLS-1$
+ return new BigInteger(string.substring(2), 16);
+ }
+ return new BigInteger(string);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent event) {
+ if (fCatchup == null && event.fText != null && event.fText.length() > 0) {
+ fCatchup= new Runnable() {
+ public void run() {
+ if (fCatchup == this) {
+ catchupWithBreakpoints();
+ fCatchup= null;
+ }
+ }};
+ Display.getCurrent().timerExec(50, fCatchup);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java
new file mode 100644
index 00000000000..e6bc008e426
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java
@@ -0,0 +1,1423 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.io.File;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.text.REDDocument;
+import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+
+/**
+ * DisassemblyDocument
+ */
+public class DisassemblyDocument extends REDDocument {
+
+ 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;
+
+ public ArrayList fInvalidAddressRanges = new ArrayList();
+ public ArrayList fInvalidSource = new ArrayList();
+ private Map fFileInfoMap = new HashMap();
+
+ private int fMaxFunctionLength = 0;
+
+ private boolean fShowAddresses = false;
+ private int fRadix = 16;
+ private boolean fShowRadixPrefix = false;
+ private String fRadixPrefix;
+ private int fNumberOfDigits;
+ private boolean fShowCodeBytes = false;
+
+ private int fNumberOfInstructions;
+ private double fMeanSizeOfInstructions = 4;
+
+ public DisassemblyDocument() {
+ super();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.AbstractDocument#completeInitialization()
+ */
+ @Override
+ protected void completeInitialization() {
+ super.completeInitialization();
+ addPositionCategory(CATEGORY_MODEL);
+ addPositionCategory(CATEGORY_DISASSEMBLY);
+ addPositionCategory(CATEGORY_SOURCE);
+ addPositionCategory(CATEGORY_LABELS);
+ setRadix(16);
+ setShowRadixPrefix(false);
+ }
+
+ /**
+ * Cleanup.
+ */
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (fFileInfoMap != null) {
+ // cleanup source info
+ for (Iterator iter = fFileInfoMap.values().iterator(); iter.hasNext();) {
+ SourceFileInfo fi = iter.next();
+ fi.dispose();
+ }
+ fFileInfoMap = null;
+ }
+ }
+
+ public List getInvalidAddressRanges() {
+ return fInvalidAddressRanges;
+ }
+
+ public List getInvalidSource() {
+ return fInvalidSource;
+ }
+
+ public void setMaxOpcodeLength(int opcodeLength) {
+ fMaxFunctionLength = opcodeLength;
+ }
+
+ public int getMaxFunctionLength() {
+ return fMaxFunctionLength;
+ }
+
+ public int getAddressLength() {
+ return fNumberOfDigits+2;
+ }
+
+ public int getMeanSizeOfInstructions() {
+ return (int)(fMeanSizeOfInstructions+.9);
+ }
+
+ public Iterator getModelPositionIterator(BigInteger address) {
+ try {
+ return getPositionIterator(CATEGORY_MODEL, address);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ return null;
+ }
+
+ public Iterator getPositionIterator(String category, int offset) throws BadPositionCategoryException {
+ @SuppressWarnings("unchecked")
+ List positions = (List) getDocumentManagedPositions().get(category);
+ if (positions == null) {
+ throw new BadPositionCategoryException();
+ }
+ int idx = computeIndexInPositionList(positions, offset, true);
+ return positions.listIterator(idx);
+ }
+
+ public Iterator getPositionIterator(String category, BigInteger address) throws BadPositionCategoryException {
+ @SuppressWarnings("unchecked")
+ List positions = (List) getDocumentManagedPositions().get(category);
+ if (positions == null) {
+ throw new BadPositionCategoryException();
+ }
+ int idx = computeIndexInPositionListFirst(positions, address);
+ return positions.listIterator(idx);
+ }
+
+ public int computeIndexInCategory(String category, BigInteger address) throws BadPositionCategoryException {
+ @SuppressWarnings("unchecked")
+ List c = (List) getDocumentManagedPositions().get(category);
+ if (c == null) {
+ throw new BadPositionCategoryException();
+ }
+ return computeIndexInPositionListFirst(c, address);
+ }
+
+ /**
+ * Computes the index in the list of positions at which a position with the
+ * given address would be inserted. The position is supposed to become the
+ * first in this list of all positions with the same offset.
+ *
+ * @param positions
+ * the list in which the index is computed
+ * @param address
+ * the address for which the index is computed
+ * @return the computed index
+ *
+ */
+ protected int computeIndexInPositionListFirst(List positions, BigInteger address) {
+ int size = positions.size();
+ if (size == 0) {
+ return 0;
+ }
+ int left = 0;
+ int right = size - 1;
+ int mid = 0;
+ while (left <= right) {
+ mid = (left + right) / 2;
+ AddressRangePosition range = positions.get(mid);
+ if (address.compareTo(range.fAddressOffset) < 0) {
+ right = mid - 1;
+ } else if (address.compareTo(range.fAddressOffset) == 0) {
+ break;
+ } else if (address.compareTo(range.fAddressOffset.add(range.fAddressLength)) >= 0) {
+ left = mid + 1;
+ } else {
+ break;
+ }
+ }
+ int idx = mid;
+ AddressRangePosition p = positions.get(idx);
+ if (address.compareTo(p.fAddressOffset.add(p.fAddressLength)) > 0) {
+ ++idx;
+ } else if (address.compareTo(p.fAddressOffset) == 0) {
+ do {
+ --idx;
+ if (idx < 0) {
+ break;
+ }
+ p = positions.get(idx);
+ } while (address.compareTo(p.fAddressOffset) == 0);
+ ++idx;
+ }
+ return idx;
+ }
+
+ /**
+ * Computes the index in the list of positions at which a position with the
+ * given address would be inserted. The position is supposed to become the
+ * last but one in this list of all positions with the same address.
+ *
+ * @param positions
+ * the list in which the index is computed
+ * @param address
+ * the address for which the index is computed
+ * @return the computed index
+ *
+ */
+ protected int computeIndexInPositionListLast(List positions, BigInteger address) {
+ int size = positions.size();
+ if (size == 0) {
+ return 0;
+ }
+ int left = 0;
+ int right = size - 1;
+ int mid = 0;
+ while (left <= right) {
+ mid = (left + right) / 2;
+ AddressRangePosition range = positions.get(mid);
+ if (address.compareTo(range.fAddressOffset) < 0) {
+ right = mid - 1;
+ } else if (address.compareTo(range.fAddressOffset) == 0) {
+ break;
+ } else if (address.compareTo(range.fAddressOffset.add(range.fAddressLength)) >= 0) {
+ left = mid + 1;
+ } else {
+ break;
+ }
+ }
+ int idx = mid;
+ AddressRangePosition p = positions.get(idx);
+ if (address.compareTo(p.fAddressOffset) > 0) {
+ ++idx;
+ } else if (address.compareTo(p.fAddressOffset) == 0 && p.fAddressLength.compareTo(BigInteger.ZERO) == 0) {
+ do {
+ ++idx;
+ if (idx == size) {
+ break;
+ }
+ p = positions.get(idx);
+ } while (address.compareTo(p.fAddressOffset) == 0 && p.fAddressLength.compareTo(BigInteger.ZERO) == 0);
+ // --idx;
+ }
+ return idx;
+ }
+
+ /**
+ * Computes the index in the list of positions at which a position with the
+ * given offset would be inserted. The position is supposed to become the
+ * last in this list of all positions with the same offset.
+ *
+ * @param positions
+ * the list in which the index is computed
+ * @param offset
+ * the offset for which the index is computed
+ * @return the computed index
+ *
+ * @see IDocument#computeIndexInCategory(String, int)
+ */
+ protected int computeIndexInPositionListLast(List positions, int offset) {
+
+ if (positions.size() == 0)
+ return 0;
+
+ int left = 0;
+ int right = positions.size() - 1;
+ int mid = 0;
+ Position p = null;
+
+ while (left < right) {
+
+ mid = (left + right) / 2;
+
+ p = positions.get(mid);
+ if (offset < p.getOffset()) {
+ if (left == mid)
+ right = left;
+ else
+ right = mid - 1;
+ } else if (offset > p.getOffset()) {
+ if (right == mid)
+ left = right;
+ else
+ left = mid + 1;
+ } else if (offset == p.getOffset()) {
+ left = right = mid;
+ }
+
+ }
+
+ int pos = left;
+ p = positions.get(pos);
+ while (offset >= p.getOffset()) {
+ // entry will become the last of all entries with the same offset
+ ++pos;
+ if (pos == positions.size()) {
+ break;
+ }
+ p = positions.get(pos);
+ }
+
+ assert 0 <= pos && pos <= positions.size();
+
+ return pos;
+ }
+
+ /**
+ * Get the position for the supplied category and index.
+ *
+ * @param category
+ * @param index
+ * @return a Position matching the category and index, or null
.
+ */
+ public Position getPositionOfIndex(String category, int index) throws BadPositionCategoryException {
+ if (index >= 0) {
+ @SuppressWarnings("unchecked")
+ List positions = (List) getDocumentManagedPositions().get(category);
+ if (positions == null) {
+ throw new BadPositionCategoryException();
+ }
+ if (index < positions.size()) {
+ return positions.get(index);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param address
+ * @return
+ */
+ public AddressRangePosition getPositionOfAddress(BigInteger address) {
+ AddressRangePosition pos = getPositionOfAddress(CATEGORY_DISASSEMBLY, address);
+ return pos;
+ }
+
+ /**
+ * @param category
+ * @param address
+ * @return
+ */
+ public AddressRangePosition getPositionOfAddress(String category, BigInteger address) {
+ @SuppressWarnings("unchecked")
+ List positions = (List) getDocumentManagedPositions().get(category);
+ if (positions == null) {
+ return null;
+ }
+ int index = computeIndexInPositionListFirst(positions, address);
+ if (index < positions.size()) {
+ AddressRangePosition p = positions.get(index);
+ if (address.compareTo(p.fAddressOffset) == 0 || p.containsAddress(address)) {
+ return p;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param category
+ * @param range
+ * @return
+ */
+ public AddressRangePosition getPositionInAddressRange(String category, AddressRangePosition range) {
+ @SuppressWarnings("unchecked")
+ List positions = (List) getDocumentManagedPositions().get(category);
+ if (positions == null) {
+ return null;
+ }
+ BigInteger endAddress = range.fAddressOffset.add(range.fAddressLength);
+ int index = computeIndexInPositionListFirst(positions, range.fAddressOffset);
+ if (index < positions.size()) {
+ do {
+ AddressRangePosition p = positions.get(index);
+ if (p.fAddressOffset.compareTo(endAddress) >= 0) {
+ --index;
+ } else {
+ return p;
+ }
+ } while (index >= 0);
+ }
+ return null;
+ }
+
+ /**
+ * Compute the address of the given document line number.
+ *
+ * @param line
+ * @return the address of the given document line number, -1 if no valid
+ * address can be computed
+ */
+ public BigInteger getAddressOfLine(int line) {
+ try {
+ int offset = getLineOffset(line);
+ return getAddressOfOffset(offset);
+ } catch (BadLocationException e) {
+ // intentionally ignored
+ }
+ return BigInteger.valueOf(-1);
+ }
+
+ /**
+ * Compute the address off the given document offset.
+ *
+ * @param offset
+ * @return the address of the given document offset, -1 if no valid address
+ * can be computed
+ */
+ public BigInteger getAddressOfOffset(int offset) {
+ AddressRangePosition pos;
+ try {
+ pos = getModelPosition(offset);
+ } catch (BadLocationException e) {
+ internalError(e);
+ return BigInteger.valueOf(-1);
+ }
+ if (pos == null) {
+ return BigInteger.valueOf(-1);
+ }
+ return pos.fAddressOffset;
+ }
+
+ /**
+ * @param offset
+ * @return
+ */
+ public AddressRangePosition getDisassemblyPosition(int offset) throws BadLocationException {
+ Position p = null;
+ try {
+ p = getPosition(CATEGORY_DISASSEMBLY, offset, false);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ return (AddressRangePosition) p;
+ }
+
+ /**
+ * @param address
+ * @return
+ */
+ public AddressRangePosition getDisassemblyPosition(BigInteger address) {
+ return getPositionOfAddress(CATEGORY_DISASSEMBLY, address);
+ }
+
+
+ /**
+ * @param offset
+ * @return
+ * @throws BadLocationException
+ */
+ public AddressRangePosition getModelPosition(int offset) throws BadLocationException {
+ Position p = null;
+ try {
+ p = getPosition(CATEGORY_MODEL, offset, false);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ return (AddressRangePosition) p;
+ }
+
+ /**
+ * @param offset
+ * @return
+ * @throws BadLocationException
+ */
+ public SourcePosition getSourcePosition(int offset) throws BadLocationException {
+ Position p = null;
+ try {
+ p = getPosition(CATEGORY_SOURCE, offset, true);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ return (SourcePosition) p;
+ }
+
+ /**
+ * @param address
+ * @return
+ */
+ public SourcePosition getSourcePosition(BigInteger address) {
+ return (SourcePosition) getPositionOfAddress(CATEGORY_SOURCE, address);
+ }
+
+ /**
+ * @param address
+ * @return
+ */
+ public LabelPosition getLabelPosition(BigInteger address) {
+ return (LabelPosition) getPositionOfAddress(CATEGORY_LABELS, address);
+ }
+
+ /**
+ * @param range
+ * @return
+ */
+ public SourcePosition getSourcePositionInAddressRange(AddressRangePosition range) {
+ return (SourcePosition) getPositionInAddressRange(CATEGORY_SOURCE, range);
+ }
+
+ /**
+ * Compute document position of the given source line.
+ *
+ * @param file the file as an IStorage
+ * @param lineNumber the 0-based line number
+ * @return the document position or null
+ */
+ public Position getSourcePosition(IStorage file, int lineNumber) {
+ SourceFileInfo info= getSourceInfo(file);
+ return getSourcePosition(info, lineNumber);
+ }
+
+ /**
+ * Compute document position of the given source line.
+ *
+ * @param fileName the file name, may be a raw debugger path or the path to an external file
+ * @param lineNumber the 0-based line number
+ * @return the document position or null
+ */
+ public Position getSourcePosition(String fileName, int lineNumber) {
+ SourceFileInfo info= getSourceInfo(fileName);
+ if (info == null) {
+ info= getSourceInfo(new LocalFileStorage(new File(fileName)));
+ }
+ return getSourcePosition(info, lineNumber);
+ }
+
+ /**
+ * Compute document position of the given source line.
+ *
+ * @param info
+ * @param lineNumber the 0-based line number
+ * @return the document position or null
+ */
+ protected Position getSourcePosition(SourceFileInfo info, int lineNumber) {
+ if (info == null) {
+ return null;
+ }
+ try {
+ SourcePosition srcPos= null;
+ IRegion stmtLineRegion= info.fSource.getLineInformation(lineNumber);
+ final int lineOffset = stmtLineRegion.getOffset();
+ final int lineLength = stmtLineRegion.getLength() + 1;
+ BigInteger stmtAddress = info.fLine2Addr[lineNumber];
+ if (stmtAddress != null && stmtAddress.compareTo(BigInteger.ZERO) > 0) {
+ srcPos = getSourcePosition(stmtAddress);
+ }
+ if (srcPos == null) {
+ for (Iterator iterator = getPositionIterator(CATEGORY_SOURCE, 0); iterator.hasNext(); ) {
+ SourcePosition pos= (SourcePosition) iterator.next();
+ if (pos.fFileInfo == info && pos.fValid && lineNumber >= pos.fLine) {
+ int baseOffset= info.fSource.getLineOffset(srcPos.fLine);
+ if (lineOffset + lineLength - baseOffset <= srcPos.length) {
+ srcPos= pos;
+ break;
+ }
+ }
+ }
+ if (srcPos == null) {
+ return null;
+ }
+ } else if (!srcPos.fValid) {
+ return null;
+ }
+ assert lineNumber >= srcPos.fLine;
+ int baseOffset = info.fSource.getLineOffset(srcPos.fLine);
+ int offset = srcPos.offset + lineOffset - baseOffset;
+ if (offset >= srcPos.offset && offset < srcPos.offset + srcPos.length) {
+ return new Position(offset, lineLength);
+ }
+ } catch (BadLocationException exc) {
+ // TLETODO Auto-generated catch block
+ exc.printStackTrace();
+ } catch (BadPositionCategoryException exc) {
+ // TLETODO Auto-generated catch block
+ exc.printStackTrace();
+ }
+ return null;
+ }
+
+
+ /**
+ * @param category
+ * @param offset
+ * @return
+ * @throws BadPositionCategoryException
+ * @throws BadLocationException
+ */
+ public Position getPosition(String category, int offset, boolean allowZeroLength) throws BadLocationException, BadPositionCategoryException {
+ @SuppressWarnings("unchecked")
+ List list = (List) getDocumentManagedPositions().get(category);
+ int idx;
+ idx = computeIndexInPositionList(list, offset, true);
+ if (idx > 0) {
+ --idx;
+ }
+ while (idx < list.size()) {
+ Position pos = list.get(idx);
+ if (pos.offset > offset) {
+ break;
+ }
+ if (pos.includes(offset)) {
+ return pos;
+ }
+ if (allowZeroLength && pos.offset == offset) {
+ return pos;
+ }
+ ++idx;
+ }
+ return null;
+ }
+
+ /**
+ * @param pos
+ */
+ public void addModelPosition(AddressRangePosition pos) {
+ try {
+ addPositionLast(CATEGORY_MODEL, pos);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ }
+
+ /**
+ * @param pos
+ */
+ public void addModelPositionFirst(AddressRangePosition pos) {
+ @SuppressWarnings("unchecked")
+ List list = (List) getDocumentManagedPositions().get(CATEGORY_MODEL);
+ int idx;
+ idx = computeIndexInPositionListFirst(list, pos.fAddressOffset.add(pos.fAddressLength));
+ if (idx < list.size()) {
+ AddressRangePosition nextPos = list.get(idx);
+ assert nextPos.fAddressOffset.compareTo(pos.fAddressOffset.add(pos.fAddressLength)) == 0;
+ }
+ list.add(idx, pos);
+ }
+
+ /**
+ * @param pos
+ * @throws BadLocationException
+ */
+ public void addDisassemblyPosition(AddressRangePosition pos) throws BadLocationException {
+ try {
+ addPositionLast(CATEGORY_DISASSEMBLY, pos);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ if (pos instanceof DisassemblyPosition) {
+ int functionLength = ((DisassemblyPosition)pos).fFunction.length;
+ if (functionLength > fMaxFunctionLength) {
+ fMaxFunctionLength = functionLength;
+ }
+ if (fNumberOfInstructions < 100) {
+ fMeanSizeOfInstructions = (fMeanSizeOfInstructions * fNumberOfInstructions + pos.fAddressLength.floatValue()) / (++fNumberOfInstructions);
+ }
+ }
+ }
+
+ /**
+ * @param pos
+ * @throws BadPositionCategoryException
+ */
+ public void addPositionLast(String category, AddressRangePosition pos) throws BadPositionCategoryException {
+ @SuppressWarnings("unchecked")
+ List list = (List) getDocumentManagedPositions().get(category);
+ if (list == null) {
+ throw new BadPositionCategoryException();
+ }
+ int idx;
+ idx = computeIndexInPositionListLast(list, pos.fAddressOffset);
+ list.add(idx, pos);
+ }
+
+ /**
+ * @param pos
+ * @throws BadLocationException
+ */
+ public void addLabelPosition(AddressRangePosition pos) throws BadLocationException {
+ try {
+ addPositionLast(CATEGORY_LABELS, pos);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ }
+
+ /**
+ * @param pos
+ */
+ public void addSourcePosition(AddressRangePosition pos) throws BadLocationException {
+ try {
+ addPositionLast(CATEGORY_SOURCE, pos);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ }
+
+ /**
+ * @param pos
+ */
+ public void removeDisassemblyPosition(AddressRangePosition pos) {
+ try {
+ removePosition(CATEGORY_DISASSEMBLY, pos);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ }
+
+ /**
+ * @param pos
+ */
+ public void removeSourcePosition(AddressRangePosition pos) {
+ try {
+ removePosition(CATEGORY_SOURCE, pos);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ }
+
+ /**
+ * @param pos
+ */
+ public void removeModelPosition(AddressRangePosition pos) {
+ try {
+ removePosition(getCategory(pos), pos);
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ }
+
+ /**
+ * @param pos
+ * @return
+ */
+ private static String getCategory(AddressRangePosition pos) {
+ if (pos instanceof LabelPosition) {
+ return CATEGORY_LABELS;
+ } else if (pos instanceof SourcePosition) {
+ return CATEGORY_SOURCE;
+ }
+ return CATEGORY_DISASSEMBLY;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocument#removePosition(java.lang.String,
+ * org.eclipse.jface.text.Position)
+ */
+ @Override
+ public void removePosition(String category, Position position) throws BadPositionCategoryException {
+ super.removePosition(category, position);
+ if (category != CATEGORY_MODEL && position instanceof AddressRangePosition) {
+ super.removePosition(CATEGORY_MODEL, position);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void removePositions(String category, List toRemove) {
+ if (toRemove.isEmpty()) {
+ return;
+ }
+ List positions = (List) getDocumentManagedPositions().get(category);
+ if (positions != null) {
+ positions.removeAll(toRemove);
+ }
+ if (category != CATEGORY_MODEL) {
+ positions = (List) getDocumentManagedPositions().get(CATEGORY_MODEL);
+ if (positions != null) {
+ positions.removeAll(toRemove);
+ }
+ }
+ }
+
+ public void addPositionLast(String category, Position position) throws BadLocationException,
+ BadPositionCategoryException {
+
+ if ((0 > position.offset) || (0 > position.length) || (position.offset + position.length > getLength()))
+ throw new BadLocationException();
+
+ if (category == null)
+ throw new BadPositionCategoryException();
+
+ @SuppressWarnings("unchecked")
+ List list = (List) getDocumentManagedPositions().get(category);
+ if (list == null)
+ throw new BadPositionCategoryException();
+
+ list.add(computeIndexInPositionListLast(list, position.offset), position);
+ }
+
+ public void checkConsistency() {
+ AddressRangePosition last = null;
+ try {
+ for (Iterator it = getPositionIterator(CATEGORY_MODEL, 0); it.hasNext();) {
+ AddressRangePosition pos = (AddressRangePosition) it.next();
+ if (last != null) {
+ assert last.fAddressOffset.compareTo(pos.fAddressOffset) <= 0;
+ assert last.fAddressOffset.add(last.fAddressLength).compareTo(pos.fAddressOffset) == 0;
+ assert last.offset <= pos.offset;
+ assert last.offset + last.length == pos.offset;
+ }
+ last = pos;
+ }
+ } catch (BadPositionCategoryException e) {
+ assert false;
+ }
+ }
+
+ /**
+ * @param insertPos
+ * @param replaceLength
+ * @param text
+ * @throws BadLocationException
+ */
+ public void replace(AddressRangePosition insertPos, int replaceLength, String text) throws BadLocationException {
+ int delta = (text != null ? text.length() : 0) - replaceLength;
+ if (delta != 0) {
+ BigInteger address = insertPos.fAddressOffset;
+ Iterator it = getModelPositionIterator(address);
+ while (it.hasNext()) {
+ AddressRangePosition pos = it.next();
+ assert pos.fAddressOffset.compareTo(address) >= 0;
+ if (pos.fAddressOffset.compareTo(address) > 0) {
+ break;
+ }
+ if (pos.offset > insertPos.offset) {
+ break;
+ }
+ if (pos == insertPos) {
+ break;
+ }
+ }
+ while (it.hasNext()) {
+ AddressRangePosition pos = it.next();
+ pos.offset += delta;
+ }
+ }
+ super.replace(insertPos.offset, replaceLength, text);
+ }
+
+ /**
+ * @param pos
+ * @param insertPos
+ * @param line
+ * @throws BadPositionCategoryException
+ * @throws BadLocationException
+ */
+ public AddressRangePosition insertAddressRange(AddressRangePosition pos, AddressRangePosition insertPos, String line, boolean addToModel)
+ throws BadLocationException {
+ final BigInteger address = insertPos.fAddressOffset;
+ BigInteger length = insertPos.fAddressLength;
+ if (pos == null) {
+ pos = getPositionOfAddress(address);
+ }
+ assert !pos.isDeleted && !pos.fValid && (length.compareTo(BigInteger.ZERO) == 0 || pos.containsAddress(address));
+ int insertOffset;
+ int replaceLength = 0;
+ if (length.compareTo(BigInteger.ONE) > 0 && !pos.containsAddress(address.add(length.subtract(BigInteger.ONE)))) {
+ // merge with successor positions
+ Iterator it = getModelPositionIterator(pos.fAddressOffset.add(pos.fAddressLength));
+ assert it.hasNext();
+ do {
+ AddressRangePosition overlap = it.next();
+ BigInteger posEndAddress= pos.fAddressOffset.add(pos.fAddressLength);
+ assert pos.offset <= overlap.offset && overlap.fAddressOffset.compareTo(posEndAddress) == 0;
+ if (overlap instanceof LabelPosition || overlap instanceof SourcePosition) {
+ // don't override label or source positions, instead fix
+ // length of disassembly line to insert
+ length = insertPos.fAddressLength = posEndAddress.subtract(address.max(pos.fAddressOffset));
+ break;
+ }
+ pos.fAddressLength = pos.fAddressLength.add(overlap.fAddressLength);
+ replaceLength = overlap.offset + overlap.length - pos.offset - pos.length;
+ it.remove();
+ removeModelPosition(overlap);
+ if (!overlap.fValid) {
+ fInvalidAddressRanges.remove(overlap);
+ }
+ } while(!pos.containsAddress(address.add(length.subtract(BigInteger.ONE))));
+ }
+ BigInteger newEndAddress = pos.fAddressOffset.add(pos.fAddressLength);
+ BigInteger newStartAddress = address.add(length);
+ assert newEndAddress.compareTo(newStartAddress) >= 0;
+ if (address.compareTo(pos.fAddressOffset) == 0) {
+ // insert at start of range
+ insertOffset = pos.offset;
+ if (replaceLength == 0 && newEndAddress.compareTo(newStartAddress) > 0) {
+ // optimization: shrink position in place
+ pos.fAddressOffset = newStartAddress;
+ pos.fAddressLength = pos.fAddressLength.subtract(length);
+ // don't insert new pos
+ newEndAddress = newStartAddress;
+ } else {
+ replaceLength += pos.length;
+ fInvalidAddressRanges.remove(pos);
+ removeDisassemblyPosition(pos);
+ pos = null;
+ }
+ } else {
+ // insert in mid/end of range
+ insertOffset = pos.offset + pos.length;
+ pos.fAddressLength = address.subtract(pos.fAddressOffset);
+ assert pos.fAddressLength.compareTo(BigInteger.ZERO) > 0;
+ pos = null;
+ }
+ if (newEndAddress.compareTo(newStartAddress) > 0) {
+ pos = insertInvalidAddressRange(insertOffset+replaceLength, 0, newStartAddress, newEndAddress);
+ }
+ assert pos == null || pos.fAddressLength.compareTo(BigInteger.ZERO) > 0 && pos.containsAddress(address.add(length));
+ assert insertOffset + replaceLength <= getLength();
+
+ insertPos.offset = insertOffset;
+ if (addToModel) {
+ addModelPosition(insertPos);
+ }
+ replace(insertPos, replaceLength, line);
+ if (DEBUG) checkConsistency();
+ return pos;
+ }
+
+ /**
+ * @param pos
+ * @param address
+ * @param length
+ * @param instruction
+ * @throws BadPositionCategoryException
+ * @throws BadLocationException
+ */
+ public AddressRangePosition insertDisassemblyLine(AddressRangePosition pos, BigInteger address, int length, String opcode, String instruction, String file, int lineNr)
+ throws BadLocationException {
+ String disassLine = null;
+ if (instruction == null || instruction.length() == 0) {
+ disassLine = ""; //$NON-NLS-1$
+ } else {
+ disassLine = buildDisassemblyLine(address, opcode, instruction);
+ }
+ AddressRangePosition disassPos;
+ if (lineNr < 0) {
+ disassPos = new DisassemblyPosition(0, disassLine.length(), address, BigInteger.valueOf(length), opcode);
+ } else {
+ disassPos = new DisassemblyWithSourcePosition(0, disassLine.length(), address, BigInteger.valueOf(length),
+ opcode, file, lineNr);
+ }
+ pos = insertAddressRange(pos, disassPos, disassLine, true);
+ addDisassemblyPosition(disassPos);
+ return pos;
+ }
+ /**
+ * @param address
+ * @param opcode
+ * @param instruction
+ */
+ private String buildDisassemblyLine(BigInteger address, String opcode, String instruction) {
+ StringBuffer buf = new StringBuffer(40);
+ if (fShowAddresses) {
+ if (fRadixPrefix != null) {
+ buf.append(fRadixPrefix);
+ }
+ String str = address.toString(fRadix);
+ for (int i=str.length(); i 0) {
+ buf.append(opcode);
+ int tab = 16;
+ if (opcode.length() >= 16) {
+ tab = (opcode.length() + 8) & ~7;
+ }
+ int diff = tab - opcode.length();
+ while (diff-- > 0) {
+ buf.append(' ');
+ }
+ } else if (!fShowAddresses) {
+ buf.append(' ');
+ buf.append(' ');
+ }
+ int n = instruction.length();
+ int prefixLen = buf.length();
+ for (int j = 0; j < n; j++) {
+ char ch = instruction.charAt(j);
+ if (ch == '\t') {
+ int tab = (buf.length()-prefixLen + 8) & ~0x7;
+ do
+ buf.append(' ');
+ while (buf.length()-prefixLen < tab);
+ } else {
+ buf.append(ch);
+ }
+ }
+ buf.append('\n');
+ return buf.toString();
+ }
+
+ public void setRadix(int radix) {
+ fRadix = radix;
+ fNumberOfDigits = (int)(Math.log(1L<<32)/Math.log(radix)+0.9);
+ setShowRadixPrefix(fShowRadixPrefix);
+ }
+
+ public void setShowRadixPrefix(boolean showRadixPrefix) {
+ fShowRadixPrefix = showRadixPrefix;
+ if (!fShowRadixPrefix) {
+ fRadixPrefix = null;
+ } else if (fRadix == 16) {
+ fRadixPrefix = "0x"; //$NON-NLS-1$
+ } else if (fRadix == 8) {
+ fRadixPrefix = "0"; //$NON-NLS-1$
+ } else {
+ fRadixPrefix = null;
+ }
+ }
+
+ public AddressRangePosition insertErrorLine(AddressRangePosition pos, BigInteger address, BigInteger length, String line)
+ throws BadLocationException {
+ int hashCode = line.hashCode();
+ final long alignment = 0x1L;
+ if (alignment > 1 && !(pos instanceof ErrorPosition)) {
+ AddressRangePosition before = getPositionOfAddress(address.subtract(BigInteger.ONE));
+ if (before instanceof ErrorPosition && before.hashCode() == hashCode && before.offset + before.length == pos.offset) {
+ assert before.fAddressOffset.add(before.fAddressLength).compareTo(address) == 0;
+ assert pos.fAddressOffset.compareTo(address) == 0;
+ // merge with previous error position
+ BigInteger pageOffset = before.fAddressOffset.and(BigInteger.valueOf(~(alignment-1)));
+ BigInteger mergeLen = pageOffset.add(BigInteger.valueOf(alignment))
+ .subtract((before.fAddressOffset.add(before.fAddressLength))).min(length);
+ if (mergeLen.compareTo(BigInteger.ZERO) > 0) {
+ pos.fAddressLength = pos.fAddressLength.subtract(mergeLen);
+ if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) {
+ replace(pos, pos.length, null);
+ removeModelPosition(pos);
+ fInvalidAddressRanges.remove(pos);
+ pos = null;
+ } else {
+ pos.fAddressOffset = pos.fAddressOffset.add(mergeLen);
+ }
+ before.fAddressLength = before.fAddressLength.add(mergeLen);
+ address = address.add(mergeLen);
+ length = length.subtract(mergeLen);
+ if (DEBUG) checkConsistency();
+ if (length.compareTo(BigInteger.ZERO) == 0) {
+ return pos;
+ }
+ }
+ }
+ AddressRangePosition after = getPositionOfAddress(address.add(length));
+ if (after instanceof ErrorPosition && after.hashCode() == hashCode && pos.offset + pos.length == after.offset) {
+ assert after.fAddressOffset == address.add(length);
+ assert pos.fAddressOffset.add(pos.fAddressLength).compareTo(after.fAddressOffset) == 0;
+ // merge with next error position
+ BigInteger pageOffset = after.fAddressOffset.add(BigInteger.valueOf(~(alignment-1)));
+ BigInteger mergeLen = after.fAddressOffset.subtract(pageOffset).min(length);
+ if (mergeLen.compareTo(BigInteger.ZERO) > 0) {
+ after.fAddressOffset = after.fAddressOffset.subtract(mergeLen);
+ after.fAddressLength = after.fAddressLength.add(mergeLen);
+ pos.fAddressLength = pos.fAddressLength.subtract(mergeLen);
+ if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) {
+ replace(pos, pos.length, null);
+ removeModelPosition(pos);
+ fInvalidAddressRanges.remove(pos);
+ pos = null;
+ }
+ if (DEBUG) checkConsistency();
+ length = length.subtract(mergeLen);
+ if (length.compareTo(BigInteger.ZERO) == 0) {
+ return pos;
+ }
+ }
+ }
+ }
+ BigInteger pageOffset = address.and(BigInteger.valueOf(~(alignment-1)));
+ BigInteger posLen = pageOffset.add(BigInteger.valueOf(alignment)).subtract(address).min(length);
+ while (length.compareTo(BigInteger.ZERO) > 0) {
+ AddressRangePosition errorPos = new ErrorPosition(0, 0, address, posLen, hashCode);
+ String errorLine = buildDisassemblyLine(address, null, line);
+ // TLEHACK: check for error messages, which occur only temporarily:
+ // "Target is busy. Try again later"
+ // "Cannot Perform requested Operation"
+ if (line.startsWith("Target is busy") || line.startsWith("Cannot perform")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // try again only once...
+ if (!(pos instanceof ErrorPosition)) {
+ errorLine = "...\n"; //$NON-NLS-1$
+ errorPos.fValid = false;
+ }
+ }
+ errorPos.length = errorLine.length();
+ pos = insertAddressRange(pos, errorPos, errorLine, true);
+ addDisassemblyPosition(errorPos);
+ if (!errorPos.fValid) {
+ fInvalidAddressRanges.add(errorPos);
+ }
+ length = length.subtract(posLen);
+ address = address.add(posLen);
+ posLen = BigInteger.valueOf(alignment).min(length);
+ }
+ return pos;
+ }
+
+ /**
+ * @param pos
+ * @param address
+ * @param label
+ * @throws BadLocationException
+ * @throws BadPositionCategoryException
+ */
+ public AddressRangePosition insertLabel(AddressRangePosition pos, BigInteger address, String label, boolean showLabels)
+ throws BadLocationException {
+ String labelLine = showLabels ? label + ":\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$
+ LabelPosition labelPos = getLabelPosition(address);
+ if (labelPos != null) {
+ assert labelPos.fAddressOffset.compareTo(address) == 0;
+ if (labelPos.length != labelLine.length()) {
+ int oldLength = labelPos.length;
+ labelPos.length = labelLine.length();
+ replace(labelPos, oldLength, labelLine);
+ }
+ return pos;
+ }
+ labelPos = new LabelPosition(0, labelLine.length(), address, null);
+ pos = insertAddressRange(pos, labelPos, labelLine, true);
+ addLabelPosition(labelPos);
+ return pos;
+ }
+
+ /**
+ * @param pos
+ * @param address
+ * @param source
+ * @param line
+ * @param endOfSource
+ * @throws BadLocationException
+ * @throws BadPositionCategoryException
+ */
+ public SourcePosition insertSource(SourcePosition pos, String source, int line, boolean endOfSource) {
+// System.out.println("insertSource at "+getAddressText(pos.fAddressOffset));
+// System.out.println(source);
+ String sourceLines = source;
+ if (source.length() > 0 && sourceLines.charAt(source.length() - 1) != '\n') {
+ sourceLines += "\n"; //$NON-NLS-1$
+ }
+ try {
+ assert !pos.fValid;
+ int oldLength = pos.length;
+ pos.length = sourceLines.length();
+ pos.fLine = line;
+ pos.fValid = true;
+ fInvalidSource.remove(pos);
+ replace(pos, oldLength, sourceLines);
+ if (!endOfSource) {
+ if (pos.length > 0) {
+ SourcePosition oldPos = getSourcePosition(pos.offset+pos.length);
+ if (oldPos == null || oldPos.fAddressOffset.compareTo(pos.fAddressOffset) != 0) {
+ pos = new SourcePosition(pos.offset+pos.length, 0, pos.fAddressOffset, pos.fFileInfo, line, false);
+ addSourcePosition(pos);
+ addModelPosition(pos);
+ fInvalidSource.add(pos);
+ } else {
+ //TLETODO need more checks for correct source pos
+ pos = oldPos;
+ }
+ }
+ }
+ } catch (BadLocationException e) {
+ internalError(e);
+ }
+ return pos;
+ }
+
+ /**
+ * @param pos
+ * @param address
+ * @param fi
+ * @param lineNr
+ * @return
+ */
+ public AddressRangePosition insertInvalidSource(AddressRangePosition pos, BigInteger address, SourceFileInfo fi, int lineNr) {
+ SourcePosition sourcePos = getSourcePosition(address);
+ if (sourcePos != null) {
+ return pos;
+ }
+ String sourceLine = ""; //$NON-NLS-1$
+ sourcePos = new SourcePosition(0, sourceLine.length(), address, fi, lineNr, false);
+ try {
+ pos = insertAddressRange(pos, sourcePos, sourceLine, true);
+ addSourcePosition(sourcePos);
+ assert !fInvalidSource.contains(sourcePos);
+ fInvalidSource.add(sourcePos);
+ } catch (BadLocationException e) {
+ internalError(e);
+ }
+ return pos;
+ }
+
+ /**
+ * @param offset
+ * @param replaceLength
+ * @param startAddress
+ * @param endAddress
+ * @return
+ */
+ public AddressRangePosition insertInvalidAddressRange(int offset, int replaceLength, BigInteger startAddress, BigInteger endAddress) {
+ String periods = "...\n"; //$NON-NLS-1$
+ AddressRangePosition newPos = new AddressRangePosition(offset, periods.length(), startAddress, endAddress
+ .subtract(startAddress), false);
+ try {
+ addModelPositionFirst(newPos);
+ replace(newPos, replaceLength, periods);
+ addDisassemblyPosition(newPos);
+ fInvalidAddressRanges.add(newPos);
+ } catch (BadLocationException e) {
+ internalError(e);
+ }
+ return newPos;
+ }
+
+ public void invalidateAddressRange(BigInteger startAddress, BigInteger endAddress, boolean collapse) {
+ deleteDisassemblyRange(startAddress, endAddress, true, collapse);
+ }
+
+ public void deleteDisassemblyRange(BigInteger startAddress, BigInteger endAddress, boolean invalidate, boolean collapse) {
+ String replacement = invalidate ? "...\n" : null; //$NON-NLS-1$
+ int replaceLen = replacement != null ? replacement.length() : 0;
+ AddressRangePosition lastPos = null;
+ ArrayList toRemove = new ArrayList();
+ Iterator it = getModelPositionIterator(startAddress);
+ while (it.hasNext()) {
+ AddressRangePosition pos = it.next();
+ BigInteger posEndAddress = pos.fAddressOffset.add(pos.fAddressLength);
+ if (pos instanceof LabelPosition) {
+ if (!invalidate && pos.length > 0 && posEndAddress.compareTo(endAddress) > 0) {
+ try {
+ int oldLength = pos.length;
+ pos.length = 0;
+ replace(pos, oldLength, null);
+ } catch (BadLocationException e) {
+ internalError(e);
+ }
+ }
+ pos = null;
+ } else if (pos instanceof SourcePosition) {
+ pos = null;
+ } else if (pos instanceof ErrorPosition) {
+ pos = null;
+ } else if (pos instanceof DisassemblyPosition) {
+ // optimization: join adjacent positions
+ if (collapse && lastPos != null
+ && (invalidate || lastPos.fValid == pos.fValid)
+ && lastPos.offset+lastPos.length == pos.offset) {
+ assert lastPos.fAddressOffset.add(lastPos.fAddressLength).compareTo(pos.fAddressOffset) == 0;
+ lastPos.length += pos.length;
+ lastPos.fAddressLength = lastPos.fAddressLength.add(pos.fAddressLength);
+ toRemove.add(pos);
+ if (!pos.fValid) {
+ fInvalidAddressRanges.remove(pos);
+ }
+ pos = null;
+ if (posEndAddress.compareTo(endAddress) < 0) {
+ continue;
+ }
+ }
+ }
+ if (lastPos != null) {
+ try {
+ if (lastPos.length > 0 || replaceLen > 0) {
+ int oldLength = lastPos.length;
+ lastPos.length = replaceLen;
+ replace(lastPos, oldLength, replacement);
+ }
+ } catch (BadLocationException e) {
+ internalError(e);
+ }
+ }
+ if (pos == null && posEndAddress.compareTo(endAddress) >= 0) {
+ break;
+ }
+ lastPos = null;
+ if (pos != null) {
+ if (pos.fValid && invalidate) {
+ pos.fValid = false;
+ fInvalidAddressRanges.add(pos);
+ }
+ lastPos = pos;
+ }
+ }
+ removePositions(CATEGORY_DISASSEMBLY, toRemove);
+ if (DEBUG) checkConsistency();
+ }
+
+ public void invalidateSource() {
+ Iterator it;
+ try {
+ it = getPositionIterator(CATEGORY_SOURCE, 0);
+ } catch (BadPositionCategoryException e) {
+ internalError(e);
+ return;
+ }
+ while (it.hasNext()) {
+ SourcePosition srcPos = (SourcePosition)it.next();
+ if (srcPos != null && srcPos.fValid) {
+ srcPos.fValid = false;
+ assert !getInvalidSource().contains(srcPos);
+ getInvalidSource().add(srcPos);
+ }
+ }
+ }
+
+ public void invalidateDisassemblyWithSource(boolean removeDisassembly) {
+ for (Iterator it = fFileInfoMap.values().iterator(); it.hasNext();) {
+ SourceFileInfo info = it.next();
+ if (info.fLine2Addr != null) {
+ deleteDisassemblyRange(info.fStartAddress, info.fEndAddress.add(BigInteger.ONE), !removeDisassembly, !removeDisassembly);
+ }
+ }
+ }
+
+ /**
+ * @param start
+ * @param end
+ * @throws BadLocationException
+ */
+ public void deleteLineRange(int start, int end) throws BadLocationException {
+ if (start >= end) {
+ return;
+ }
+ int startOffset = getLineOffset(start);
+ int endOffset = getLineOffset(end);
+ int replaceLength = 0;
+ AddressRangePosition startPos = getDisassemblyPosition(startOffset);
+ if (startPos == null) {
+ return;
+ }
+ startOffset = startPos.offset;
+ AddressRangePosition endPos = getDisassemblyPosition(endOffset);
+ if (endPos == null) {
+ return;
+ }
+ BigInteger startAddress = BigInteger.ZERO;
+ BigInteger addressLength = BigInteger.ZERO;
+ ArrayList toRemove = new ArrayList();
+ try {
+ Iterator it = getPositionIterator(DisassemblyDocument.CATEGORY_MODEL, startAddress);
+ while (it.hasNext()) {
+ AddressRangePosition p = it.next();
+ addressLength = addressLength.add(p.fAddressLength);
+ replaceLength += p.length;
+ toRemove.add(p);
+ if (!p.fValid) {
+ if (p instanceof SourcePosition) {
+ getInvalidSource().remove(p);
+ } else {
+ getInvalidAddressRanges().remove(p);
+ }
+ }
+ if (addressLength.compareTo(BigInteger.ZERO) > 0 && p.fAddressOffset.compareTo(endPos.fAddressOffset) >= 0) {
+ break;
+ }
+ }
+ } catch (BadPositionCategoryException e) {
+ // cannot happen
+ }
+ for (Iterator iter = toRemove.iterator(); iter.hasNext();) {
+ AddressRangePosition pos = iter.next();
+ removeModelPosition(pos);
+ }
+ if (addressLength.compareTo(BigInteger.ZERO) > 0) {
+ insertInvalidAddressRange(startOffset, replaceLength, startAddress, startAddress.add(addressLength));
+ }
+ }
+
+ public SourceFileInfo getSourceInfo(BigInteger address) {
+ AddressRangePosition pos = getDisassemblyPosition(address);
+ if (pos instanceof DisassemblyPosition) {
+ DisassemblyPosition disassPos = (DisassemblyPosition)pos;
+ return getSourceInfo(disassPos.getFile());
+ }
+ return null;
+ }
+
+ public SourceFileInfo getSourceInfo(String file) {
+ if (fFileInfoMap == null || file == null) {
+ return null;
+ }
+ for (Iterator iter = fFileInfoMap.values().iterator(); iter.hasNext();) {
+ SourceFileInfo info = iter.next();
+ if (file.equals(info.fFileKey)) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ public SourceFileInfo getSourceInfo(IStorage sourceElement) {
+ if (fFileInfoMap == null) {
+ return null;
+ }
+ SourceFileInfo fi = fFileInfoMap.get(sourceElement);
+ return fi;
+ }
+
+ public SourceFileInfo createSourceInfo(String fileKey, IStorage sourceElement, Runnable done) {
+ SourceFileInfo fi = new SourceFileInfo(fileKey, sourceElement);
+ assert fFileInfoMap != null;
+ if (fFileInfoMap != null) {
+ fFileInfoMap.put(sourceElement, fi);
+ new SourceReadingJob(fi, done);
+ }
+ return fi;
+ }
+
+ private void internalError(Throwable e) {
+ if (DEBUG) {
+ System.err.println("Disassembly: Internal error"); //$NON-NLS-1$
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java
new file mode 100644
index 00000000000..8b2010cd515
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyPosition.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+/**
+ * DisassemblyPosition
+ */
+public class DisassemblyPosition extends AddressRangePosition {
+
+ public char[] fFunction;
+
+ /**
+ *
+ * @param offset
+ * @param length
+ * @param addressOffset
+ * @param addressLength
+ * @param opcodes
+ */
+ public DisassemblyPosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, String opcodes) {
+ super(offset, length, addressOffset, addressLength);
+ fFunction = opcodes.toCharArray();
+ }
+
+ /**
+ * @return source file
+ */
+ public String getFile() {
+ return null;
+ }
+
+ /**
+ * @return source line number
+ */
+ public int getLine() {
+ return -1;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java
new file mode 100644
index 00000000000..55e537e5935
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/DisassemblyWithSourcePosition.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+/**
+ * DisassemblyWithSourcePosition
+ */
+public class DisassemblyWithSourcePosition extends DisassemblyPosition {
+
+ private String fFile;
+ private int fLine;
+
+ /**
+ * @param offset
+ * @param length
+ * @param addressOffset
+ * @param addressLength
+ * @param opcodes
+ */
+ public DisassemblyWithSourcePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, String opcodes, String file, int lineNr) {
+ super(offset, length, addressOffset, addressLength, opcodes);
+ fFile = file;
+ fLine = lineNr;
+ }
+
+ /* (non-Javadoc)
+ * @see com.windriver.ide.disassembly.model.DisassemblyPosition#getFile()
+ */
+ @Override
+ public String getFile() {
+ return fFile;
+ }
+
+ /* (non-Javadoc)
+ * @see com.windriver.ide.disassembly.model.DisassemblyPosition#getLine()
+ */
+ @Override
+ public int getLine() {
+ return fLine;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java
new file mode 100644
index 00000000000..93be42f3f7a
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/ErrorPosition.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+/**
+ * ErrorPosition
+ */
+public class ErrorPosition extends AddressRangePosition {
+
+ public int fHashCode;
+
+ /**
+ * @param offset
+ * @param length
+ * @param addressOffset
+ * @param addressLength
+ */
+ public ErrorPosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, int hashCode) {
+ super(offset, length, addressOffset, addressLength);
+ fHashCode = hashCode;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return fHashCode;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/LabelPosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/LabelPosition.java
new file mode 100644
index 00000000000..88157414d89
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/LabelPosition.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+/**
+ * LabelPosition
+ */
+public class LabelPosition extends AddressRangePosition {
+
+ public String fLabel;
+
+ /**
+ * @param offset
+ * @param length
+ * @param addressOffset
+ */
+ public LabelPosition(int offset, int length, BigInteger addressOffset, String label) {
+ super(offset, length, addressOffset, BigInteger.ZERO);
+ fLabel = label;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceDocumentProvider.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceDocumentProvider.java
new file mode 100644
index 00000000000..c9a1dfb8233
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceDocumentProvider.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.util.Iterator;
+
+import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFileState;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.text.REDDocument;
+import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.editors.text.StorageDocumentProvider;
+
+/**
+ * SourceDocumentProvider
+ */
+public class SourceDocumentProvider extends StorageDocumentProvider {
+
+ public SourceDocumentProvider() {
+ super();
+ }
+
+ /**
+ * Dispose all connected documents.
+ */
+ public void dispose() {
+ Iterator> it = getConnectedElements();
+ while(it.hasNext()) {
+ Object element = it.next();
+ ElementInfo info = getElementInfo(element);
+ // force refcount to 1
+ info.fCount = 1;
+ disconnect(element);
+ }
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object)
+ */
+ @Override
+ protected IDocument createEmptyDocument() {
+ IDocument doc = new REDDocument();
+ return doc;
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createAnnotationModel(java.lang.Object)
+ */
+ @Override
+ protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.ui.editors.text.StorageDocumentProvider#setupDocument(java.lang.Object, org.eclipse.jface.text.IDocument)
+ */
+ @Override
+ protected void setupDocument(Object element, IDocument document) {
+ super.setupDocument(element, document);
+ if (element instanceof IStorageEditorInput) {
+ new CDocumentSetupParticipant().setup(document);
+ }
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#disposeElementInfo(java.lang.Object, org.eclipse.ui.texteditor.AbstractDocumentProvider.ElementInfo)
+ */
+ @Override
+ protected void disposeElementInfo(Object element, ElementInfo info) {
+ super.disposeElementInfo(element, info);
+ IDocument doc = info.fDocument;
+ if (doc instanceof REDDocument) {
+ ((REDDocument)doc).dispose();
+ }
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getModificationStamp(java.lang.Object)
+ */
+ @Override
+ public long getModificationStamp(Object element) {
+ try {
+ if (element instanceof IStorageEditorInput) {
+ IStorage file= ((IStorageEditorInput)element).getStorage();
+ if (file instanceof IFile) {
+ return ((IFile)file).getLocalTimeStamp();
+ } else if (file instanceof IFileState) {
+ return ((IFileState)file).getModificationTime();
+ } else if (file instanceof LocalFileStorage) {
+ return ((LocalFileStorage)file).getFile().lastModified();
+ }
+ } else if (element instanceof IURIEditorInput) {
+ return EFS.getStore(((IURIEditorInput)element).getURI()).fetchInfo().getLastModified();
+ }
+ } catch (CoreException e) {
+ // ignore
+ }
+ return 0;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceEditorInput.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceEditorInput.java
new file mode 100644
index 00000000000..df7ebc592f1
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceEditorInput.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.util.StorageEditorInput;
+
+/**
+ * SourceEditorInput
+ */
+public class SourceEditorInput extends StorageEditorInput {
+
+ /**
+ * @param storage
+ */
+ public SourceEditorInput(IStorage storage) {
+ super(storage);
+ }
+
+ /*
+ * @see org.eclipse.ui.IEditorInput#exists()
+ */
+ public boolean exists() {
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceFileInfo.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceFileInfo.java
new file mode 100644
index 00000000000..97522e9031c
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceFileInfo.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.LanguageManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation.ISourcePresentationCreator;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation.SourcePresentationCreatorFactory;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * Holds information about a source file.
+ */
+public class SourceFileInfo {
+ public final String fFileKey;
+ public final IStorage fFile;
+ public IStorage fEdition;
+ public BigInteger[] fLine2Addr;
+ public Addr2Line[] fAddr2Line;
+ public volatile IDocument fSource;
+ public volatile boolean fValid;
+ public Object fLinesNode;
+ public Throwable fError;
+ public volatile SourceReadingJob fReadingJob;
+ public volatile Job fEditionJob;
+ public ISourcePresentationCreator fPresentationCreator;
+ public BigInteger fStartAddress = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE);
+ public BigInteger fEndAddress= BigInteger.ZERO;
+
+ public SourceFileInfo(String fileKey, IStorage file) {
+ fFileKey = fileKey;
+ fFile = fEdition = file;
+ }
+
+ /**
+ * Initialize source document.
+ * @throws CoreException
+ */
+ public void initSource() throws CoreException {
+ SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider();
+ IEditorInput input = new SourceEditorInput(fEdition);
+ synchronized (provider) {
+ provider.connect(input);
+ }
+ IStatus status = provider.getStatus(input);
+ if (status != null && !status.isOK()) {
+ throw new CoreException(status);
+ }
+ }
+
+ /**
+ * Initialize presentation creator.
+ * @param viewer
+ */
+ public void initPresentationCreator(ITextViewer viewer) {
+ SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider();
+ IEditorInput input = new SourceEditorInput(fEdition);
+ IDocument doc = provider.getDocument(input);
+ if (doc != null) {
+ IContentType contentType= null;
+ if (fEdition instanceof IFile) {
+ IFile file= (IFile)fEdition;
+ contentType= CCorePlugin.getContentType(file.getProject(), file.getName());
+ } else {
+ contentType= CCorePlugin.getContentType(fEdition.getName());
+ }
+ ILanguage language= null;
+ if (contentType != null) {
+ language= LanguageManager.getInstance().getLanguage(contentType);
+ }
+ if (language != null) {
+ fPresentationCreator= SourcePresentationCreatorFactory.create(language, fEdition, viewer);
+ }
+ int lines = doc.getNumberOfLines();
+ fLine2Addr = new BigInteger[lines];
+ fAddr2Line = new Addr2Line[lines / 10 + 1];
+ // assign fSource last, triggering source update
+ fSource = doc;
+ }
+ }
+
+ /**
+ * Dispose this object.
+ */
+ public void dispose() {
+ if (fReadingJob != null) {
+ if (!fReadingJob.cancel()) {
+ fReadingJob.dispose();
+ }
+ fReadingJob = null;
+ }
+ if (fPresentationCreator != null) {
+ fPresentationCreator.dispose();
+ fPresentationCreator = null;
+ }
+ SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider();
+ synchronized (provider) {
+ provider.disconnect(new SourceEditorInput(fEdition));
+ }
+ fSource = null;
+ fValid = false;
+// fLinesNode = null;
+ }
+
+ public String getLine(int lineNr) {
+ return getLines(lineNr, lineNr);
+ }
+
+ public String getLines(int first, int last) {
+ try {
+ int startOffset = fSource.getLineOffset(first);
+ int endOffset;
+ if (last < fSource.getNumberOfLines()-1) {
+ IRegion lastRegion = fSource.getLineInformation(last+1);
+ endOffset = lastRegion.getOffset();
+ } else {
+ // last line
+ IRegion lastRegion = fSource.getLineInformation(last);
+ endOffset = lastRegion.getOffset() + lastRegion.getLength();
+ }
+ return fSource.get(startOffset, endOffset - startOffset);
+ } catch (BadLocationException e) {
+ return null;
+ }
+ }
+
+ public IRegion getRegion(int line, int length) {
+ try {
+ IRegion lineRegion = fSource.getLineInformation(line);
+ return new Region(lineRegion.getOffset(), length);
+ } catch (BadLocationException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Get or create text presentation for the given region.
+ * Must be called in display thread.
+ * @param region
+ * @return text presentation
+ */
+ public TextPresentation getPresentation(IRegion region) {
+ if (fSource != null && fPresentationCreator != null) {
+ return fPresentationCreator.getPresentation(region, fSource);
+ }
+ return null;
+ }
+
+ /**
+ * @return offset of given line
+ */
+ public int getLineOffset(int line) {
+ if (fSource != null) {
+ try {
+ return fSource.getLineOffset(line);
+ } catch (BadLocationException e) {
+ // ignored
+ }
+ }
+ return -1;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourcePosition.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourcePosition.java
new file mode 100644
index 00000000000..e03699948e2
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourcePosition.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import java.math.BigInteger;
+
+/**
+ * SourcePosition
+ */
+public class SourcePosition extends AddressRangePosition {
+
+ public SourceFileInfo fFileInfo;
+ public int fLine;
+
+ /**
+ *
+ * @param offset
+ * @param length
+ * @param addressOffset
+ * @param fileInfo
+ * @param line
+ */
+ public SourcePosition(int offset, int length, BigInteger addressOffset, SourceFileInfo fileInfo, int line) {
+ this(offset, length, addressOffset, fileInfo, line, true);
+ }
+
+ /**
+ *
+ * @param offset
+ * @param length
+ * @param addressOffset
+ * @param fileInfo
+ * @param line
+ * @param valid
+ */
+ public SourcePosition(int offset, int length, BigInteger addressOffset, SourceFileInfo fileInfo, int line, boolean valid) {
+ super(offset, length, addressOffset, BigInteger.ZERO, valid);
+ fFileInfo = fileInfo;
+ fLine = line;
+ }
+
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceReadingJob.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceReadingJob.java
new file mode 100644
index 00000000000..54e87a68596
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/model/SourceReadingJob.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
+
+
+/**
+ * Low-level job to read source files in the background.
+ */
+public class SourceReadingJob extends Job {
+
+ private final static String NAME = DisassemblyMessages.SourceReadingJob_name;
+
+ private SourceFileInfo fFileInfo;
+ private Runnable fDone;
+
+ public SourceReadingJob(SourceFileInfo fi, Runnable done) {
+ super(NAME);
+ fFileInfo = fi;
+ fFileInfo.fReadingJob = this;
+ fDone = done;
+ if (fi.fFile instanceof ISchedulingRule) {
+ setRule((ISchedulingRule)fi.fFile);
+ }
+ setSystem(true);
+ // usually short lived job
+ setPriority(SHORT);
+ if (fi.fFile.getFullPath() != null) {
+ String fileName = fi.fFile.getFullPath().lastSegment();
+ setName(NAME + " (" + fileName + ')'); //$NON-NLS-1$
+ }
+ }
+
+ public synchronized void dispose() {
+ fDone = null;
+ Thread thread = getThread();
+ if (thread != null && thread.isAlive()) {
+ thread.interrupt();
+ }
+ }
+
+ @Override
+ public IStatus run(IProgressMonitor monitor) {
+ if (fFileInfo.fEditionJob != null) {
+ try {
+ fFileInfo.fEditionJob.join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ try {
+ fFileInfo.initSource();
+ } catch (Throwable e) {
+ fFileInfo.fError = e;
+ } finally {
+ fFileInfo.fReadingJob = null;
+ synchronized (this) {
+ if (fDone != null && !getThread().isInterrupted()) {
+ fDone.run();
+ }
+ }
+ }
+ // errors are handled elsewhere
+ return Status.OK_STATUS;
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java
new file mode 100644
index 00000000000..1b6415dc400
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferenceConstants.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences;
+
+import java.math.BigInteger;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.TextEditorPreferenceConstants;
+
+/**
+ * DisassemblyPreferenceConstants
+ */
+public class DisassemblyPreferenceConstants {
+
+ public static final String START_ADDRESS = "startAddress"; //$NON-NLS-1$
+ public static final String END_ADDRESS = "endAddress"; //$NON-NLS-1$
+ public static final String PC_HISTORY_SIZE = "pcHistorySize"; //$NON-NLS-1$
+ public static final String SHOW_SOURCE = "showSource"; //$NON-NLS-1$
+ public static final String SHOW_LABELS = "showLabels"; //$NON-NLS-1$
+ public static final String SHOW_SYMBOLS = "showSymbols"; //$NON-NLS-1$
+ public static final String SIMPLIFIED = "simplified"; //$NON-NLS-1$
+ public static final String INSTRUCTION_RADIX = "instructionRadix"; //$NON-NLS-1$
+ public static final String ADDRESS_RADIX = "addressRadix"; //$NON-NLS-1$
+ public static final String SHOW_ADDRESS_RADIX = "showAddressRadix"; //$NON-NLS-1$
+ public static final String SHOW_ADDRESS_RULER = "showAddressRuler"; //$NON-NLS-1$
+ public static final String ADDRESS_COLOR = "addressColor"; //$NON-NLS-1$
+ public static final String SHOW_FUNCTION_OFFSETS = "showOpcodeRuler"; //$NON-NLS-1$
+ public static final String OPCODE_COLOR = "opcodeColor"; //$NON-NLS-1$
+ public static final String USE_SOURCE_ONLY_MODE = "useSourceOnlyMode"; //$NON-NLS-1$
+ public static final String AVOID_READ_BEFORE_PC = "avoidReadBeforePC"; //$NON-NLS-1$
+
+ /**
+ *
+ */
+ private DisassemblyPreferenceConstants() {
+ // not intended to be subclassed or instatiated
+ }
+
+ /**
+ * Initialize preference default values.
+ * @param store
+ */
+ public static void initializeDefaults(IPreferenceStore store) {
+ TextEditorPreferenceConstants.initializeDefaultValues(store);
+ store.setDefault(START_ADDRESS, 0x0L);
+ store.setDefault(END_ADDRESS, "0x" + BigInteger.ONE.shiftLeft(64).toString(16)); //$NON-NLS-1$
+ store.setDefault(PC_HISTORY_SIZE, 4);
+ store.setDefault(SHOW_SOURCE, true);
+ store.setDefault(SHOW_FUNCTION_OFFSETS, false);
+ store.setDefault(SHOW_LABELS, true);
+ store.setDefault(SHOW_SYMBOLS, true);
+ store.setDefault(SIMPLIFIED, true);
+ store.setDefault(INSTRUCTION_RADIX, 16);
+ store.setDefault(ADDRESS_RADIX, 16);
+ store.setDefault(SHOW_ADDRESS_RADIX, false);
+ store.setDefault(SHOW_ADDRESS_RULER, true);
+ store.setDefault(AVOID_READ_BEFORE_PC, false);
+ store.setDefault(USE_SOURCE_ONLY_MODE, false);
+ PreferenceConverter.setDefault(store, ADDRESS_COLOR, new RGB(0, 96, 0));
+ PreferenceConverter.setDefault(store, OPCODE_COLOR, new RGB(96, 0, 0));
+ }
+
+ public static class Initializer extends AbstractPreferenceInitializer {
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = DsfDebugUIPlugin.getDefault().getPreferenceStore();
+ initializeDefaults(store);
+ EditorsUI.useAnnotationsPreferencePage(store);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferencePage.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferencePage.java
new file mode 100644
index 00000000000..372eaab2cbb
--- /dev/null
+++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/internal/ui/disassembly/preferences/DisassemblyPreferencePage.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
+import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyHelpContextIds;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * DisassemblyPreferencePage
+ */
+public class DisassemblyPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ private List