From cf2231be779decd5d170450ba3e287410f891d81 Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Fri, 5 Feb 2010 09:14:17 +0000 Subject: [PATCH] Bug 300053 - Inserting additional breakpoint marker into DSF Disassembly View Patch from Patrick Chuong --- .../model/BreakpointsAnnotationModel.java | 100 ++++++++++++++---- .../model/DisassemblyDocument.java | 17 ++- .../IBreakpointLocationProvider.java | 89 ++++++++++++++++ 3 files changed, 183 insertions(+), 23 deletions(-) create mode 100644 dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/IBreakpointLocationProvider.java diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java index 2f231914258..bf9edc43bdb 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/BreakpointsAnnotationModel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Anton Leherbauer (Wind River Systems) - initial API and implementation + * Patrick Chuong (Texas Instruments) - bug 300053 *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; @@ -14,8 +15,10 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; import java.math.BigInteger; import java.util.Iterator; +import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IBreakpointLocationProvider; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; @@ -100,6 +103,8 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea getAnnotationModelEvent().annotationChanged(a); } fireModelChanged(); + } else { + addBreakpointAnnotation(breakpoint, true); } } @@ -130,7 +135,7 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea return; } try { - Position position= createPositionFromBreakpoint(breakpoint); + Position position = createPositionFromBreakpoint(breakpoint); if (position != null) { addAnnotation(new MarkerAnnotation(marker), position, fireEvent); } @@ -142,30 +147,71 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea } 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())); - } + IBreakpointLocationProvider locationProvider = (IBreakpointLocationProvider) breakpoint.getAdapter(IBreakpointLocationProvider.class); + + /* if there is a location provider, than use the provider to retrieve the location */ + if (locationProvider != null) { + + /* if there is source info, than create a source line position */ + String sourceFile = locationProvider.getSourceFile(breakpoint); + if (sourceFile != null) { + int lineNumber = locationProvider.getLineNumber(breakpoint) - 1; + return createPositionFromSourceLine(sourceFile, lineNumber); + } else { - String fileName= marker.getAttribute(ICLineBreakpoint.SOURCE_HANDLE, null); - if (fileName != null) { - position= createPositionFromSourceLine(fileName, lineNumber); + /* if there is label info, than create a label position */ + IAddress labelAddress = locationProvider.getLabelAddress(breakpoint); + if (labelAddress != null) { + return createPositionFromLabel(labelAddress.getValue()); + + /* Otherwise, create an address position */ + } else { + + // Discussion with Anton - comment #5 (Bug 300053) + // + // Since there can only be one annotation per marker and in order to support multiple + // annotations per breakpoint, we need a specialized annotation type. + // + // So for now, we only create an annotation for the first valid address. We can add + // support for multiple annotations per breakpoint when it's needed. + IAddress[] addresses = locationProvider.getAddresses(breakpoint); + for (int i = 0; addresses != null && i < addresses.length; ++i) { + BigInteger address = addresses[i].getValue(); + Position position = createPositionFromAddress(address); + if (position != null) + return position; + } } } - return position; + + /* otherwise, use legacy ICBreakpoint location info */ + } else { + 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; } @@ -186,6 +232,16 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea } return null; } + + private Position createPositionFromLabel(BigInteger address) { + if (address != null) { + LabelPosition p = getDisassemblyDocument().getLabelPosition(address); + if (p != null && p.fValid) { + return new Position(p.offset, p.length); + } + } + return null; + } private DisassemblyDocument getDisassemblyDocument() { return (DisassemblyDocument) fDocument; diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java index ccb4434b290..79c5248bc41 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Wind River Systems and others. + * Copyright (c) 2007, 2010 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -21,6 +21,8 @@ import java.util.Map; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDTextStore; import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadPositionCategoryException; @@ -1403,6 +1405,19 @@ public class DisassemblyDocument extends REDDocument { return info; } } + return getSourceInfo(new Path(file)); + } + + public SourceFileInfo getSourceInfo(IPath file) { + if (fFileInfoMap == null || file == null) { + return null; + } + for (Iterator iter = fFileInfoMap.values().iterator(); iter.hasNext();) { + SourceFileInfo info = iter.next(); + if (file.equals(new Path(info.fFileKey))) { + return info; + } + } return null; } diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/IBreakpointLocationProvider.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/IBreakpointLocationProvider.java new file mode 100644 index 00000000000..221b3b4fb36 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/provisional/IBreakpointLocationProvider.java @@ -0,0 +1,89 @@ +/***************************************************************** + * Copyright (c) 2010 Texas Instruments and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Patrick Chuong (Texas Instruments) - Initial API and implementation (Bug 300053) + *****************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.ILineBreakpoint; + +/** + *

+ * This interface provides location information for a breakpoint to + * determine its visual annotation position in the disassembly viewer document. + * If a breakpoint adapts to this interface, its position in the viewer is + * determined by the information provided by the location provider. + *

+ * + *

+ * Breakpoints implementing either {@link ICAddressBreakpoint} or {@link ILineBreakpoint} + * need not provide a location provider but may do so in order to override default + * location retrieval. + *

+ * + *

+ * The annotation position will be determined with the following ordering: + *

    + *
  1. If there is source info, than source marker will be use by the viewer.
  2. + *
  3. If there is label info, than label marker will be use by the viewer.
  4. + *
  5. If there is address info, than address marker will be use by the viewer.
  6. + *
  7. Otherwise, nothing will be created.
  8. + *
+ *

+ *
+ * @since 2.1 + */ +public interface IBreakpointLocationProvider { + /** + * Returns the line number of the breakpoint or -1 if no line number is + * available. + * + * @param breakpoint + * the breakpoint + * @return the line number or -1 + */ + int getLineNumber(IBreakpoint breakpoint); + + /** + * Returns the source file path of the breakpoint or null if no + * source file is associated with this breakpoint. + * + * @param breakpoint + * the breakpoint + * @return the file path, can be null + */ + String getSourceFile(IBreakpoint breakpoint); + + /** + * Returns the label address of the breakpoint or null if no + * label is associated with this breakpoint. + * + * @param breakpoint + * the breakpoint + * @return the label address, can be null + */ + IAddress getLabelAddress(IBreakpoint breakpoint); + + /** + * Returns the addresses of the breakpoint. + * + *

+ * Currently there can only be one annotation per breakpoint. Therefore + * an annotation is created only for the first valid address. Support for + * multiple annotations per breakpoint is up for future enhancements. + *

+ * + * @param breakpoint + * the breakpoint + * @return the addresses, can be null + */ + IAddress[] getAddresses(IBreakpoint breakpoint); +}