1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-06 07:45:50 +02:00

Bug 300053 - Inserting additional breakpoint marker into DSF Disassembly View

Patch from Patrick Chuong
This commit is contained in:
Anton Leherbauer 2010-02-05 09:14:17 +00:00
parent 42224beaf8
commit cf2231be77
3 changed files with 183 additions and 23 deletions

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation * 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; 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.math.BigInteger;
import java.util.Iterator; 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.ICAddressBreakpoint;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; 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.IFile;
import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IMarkerDelta;
@ -100,6 +103,8 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea
getAnnotationModelEvent().annotationChanged(a); getAnnotationModelEvent().annotationChanged(a);
} }
fireModelChanged(); fireModelChanged();
} else {
addBreakpointAnnotation(breakpoint, true);
} }
} }
@ -130,7 +135,7 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea
return; return;
} }
try { try {
Position position= createPositionFromBreakpoint(breakpoint); Position position = createPositionFromBreakpoint(breakpoint);
if (position != null) { if (position != null) {
addAnnotation(new MarkerAnnotation(marker), position, fireEvent); addAnnotation(new MarkerAnnotation(marker), position, fireEvent);
} }
@ -142,30 +147,71 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea
} }
private Position createPositionFromBreakpoint(IBreakpoint breakpoint) throws CoreException { private Position createPositionFromBreakpoint(IBreakpoint breakpoint) throws CoreException {
if (breakpoint instanceof ICAddressBreakpoint) { IBreakpointLocationProvider locationProvider = (IBreakpointLocationProvider) breakpoint.getAdapter(IBreakpointLocationProvider.class);
ICAddressBreakpoint addressBreakpoint= (ICAddressBreakpoint) breakpoint;
return createPositionFromAddress(decodeAddress(addressBreakpoint.getAddress())); /* if there is a location provider, than use the provider to retrieve the location */
} else if (breakpoint instanceof ILineBreakpoint) { if (locationProvider != null) {
ILineBreakpoint lineBreakpoint= (ILineBreakpoint) breakpoint;
Position position= null; /* if there is source info, than create a source line position */
final int lineNumber= lineBreakpoint.getLineNumber() - 1; String sourceFile = locationProvider.getSourceFile(breakpoint);
final IMarker marker= breakpoint.getMarker(); if (sourceFile != null) {
if (marker.getResource().getType() == IResource.FILE) { int lineNumber = locationProvider.getLineNumber(breakpoint) - 1;
position= createPositionFromSourceLine((IFile) marker.getResource(), lineNumber); return createPositionFromSourceLine(sourceFile, lineNumber);
} else if (breakpoint instanceof ICLineBreakpoint) {
ICLineBreakpoint cBreakpoint= (ICLineBreakpoint) breakpoint;
position= createPositionFromSourceLine(cBreakpoint.getFileName(), lineNumber);
if (position == null) {
position= createPositionFromAddress(decodeAddress(cBreakpoint.getAddress()));
}
} else { } else {
String fileName= marker.getAttribute(ICLineBreakpoint.SOURCE_HANDLE, null); /* if there is label info, than create a label position */
if (fileName != null) { IAddress labelAddress = locationProvider.getLabelAddress(breakpoint);
position= createPositionFromSourceLine(fileName, lineNumber); 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; return null;
} }
@ -186,6 +232,16 @@ public class BreakpointsAnnotationModel extends AnnotationModel implements IBrea
} }
return null; 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() { private DisassemblyDocument getDisassemblyDocument() {
return (DisassemblyDocument) fDocument; return (DisassemblyDocument) fDocument;

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * 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.REDDocument;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDTextStore; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDTextStore;
import org.eclipse.core.resources.IStorage; 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.debug.core.sourcelookup.containers.LocalFileStorage;
import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException; import org.eclipse.jface.text.BadPositionCategoryException;
@ -1403,6 +1405,19 @@ public class DisassemblyDocument extends REDDocument {
return info; return info;
} }
} }
return getSourceInfo(new Path(file));
}
public SourceFileInfo getSourceInfo(IPath file) {
if (fFileInfoMap == null || file == null) {
return null;
}
for (Iterator<SourceFileInfo> iter = fFileInfoMap.values().iterator(); iter.hasNext();) {
SourceFileInfo info = iter.next();
if (file.equals(new Path(info.fFileKey))) {
return info;
}
}
return null; return null;
} }

View file

@ -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;
/**
* <p>
* 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.
* </p>
*
* <p>
* 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.
* </p>
*
* <p>
* The annotation position will be determined with the following ordering:
* <ol>
* <li>If there is source info, than source marker will be use by the viewer.</li>
* <li>If there is label info, than label marker will be use by the viewer.</li>
* <li>If there is address info, than address marker will be use by the viewer.</li>
* <li>Otherwise, nothing will be created.</li>
* </ol>
* </p>
* <br>
* @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 <code>null</code> if no
* source file is associated with this breakpoint.
*
* @param breakpoint
* the breakpoint
* @return the file path, can be <code>null</code>
*/
String getSourceFile(IBreakpoint breakpoint);
/**
* Returns the label address of the breakpoint or <code>null</code> if no
* label is associated with this breakpoint.
*
* @param breakpoint
* the breakpoint
* @return the label address, can be <code>null</code>
*/
IAddress getLabelAddress(IBreakpoint breakpoint);
/**
* Returns the addresses of the breakpoint.
*
* <p>
* <i>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. </i>
* </p>
*
* @param breakpoint
* the breakpoint
* @return the addresses, can be <code>null</code>
*/
IAddress[] getAddresses(IBreakpoint breakpoint);
}