diff --git a/debug/org.eclipse.cdt.debug.core/ChangeLog b/debug/org.eclipse.cdt.debug.core/ChangeLog index ccbe9bab2b4..9c0856e0f8b 100644 --- a/debug/org.eclipse.cdt.debug.core/ChangeLog +++ b/debug/org.eclipse.cdt.debug.core/ChangeLog @@ -1,3 +1,12 @@ +2004-05-06 Mikhail Khodjaiants + Implementation of mixed disassembly mode. + * IAsmSourceLine.java: new + * IDisassembly.java + * IDisassemblyBlock.java: new + * AsmSourceLine.java: new + * Disassembly.java + * DisassemblyBlock.java: new + 2004-04-30 Mikhail Khodjaiants New copyright. * IJumpToAddress.java diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IAsmSourceLine.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IAsmSourceLine.java new file mode 100644 index 00000000000..cf54e305735 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IAsmSourceLine.java @@ -0,0 +1,24 @@ +/********************************************************************** + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.debug.core.model; + +/** + * A source line in disassembly. + */ +public interface IAsmSourceLine { + + /** + * Returns the array of the disassembly instructions associated with this source line. + * + * @return the array of the disassembly instructions associated with this source line + */ + IAsmInstruction[] getInstructions(); +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IDisassembly.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IDisassembly.java index 11e6cd6ea08..b7153cd86ab 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IDisassembly.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IDisassembly.java @@ -16,26 +16,13 @@ import org.eclipse.debug.core.DebugException; * Represents the disassembly of a debug target. */ public interface IDisassembly extends ICDebugElement { - - /** - * Returns the list of disassembly instructions associated - * with the given stack frame. - * - * @param frame the stack frame for which the instructions re required. - * @return the list of disassembly instructions associated with - * the given stack frame - * @throws DebugException if this method fails. - */ - public IAsmInstruction[] getInstructions( ICStackFrame frame ) throws DebugException; /** - * Returns the list of disassembly instructions that begins at the given address. - * The size of the requested list is specified by length. + * Returns the disassembly block for given stack frame. * - * @param address the start address - * @param length the size of the requested list - * @return the specified list of disassembly instructions + * @param frame the stack frame for which the disassembly is required + * @return the disassembly block for given stack frame * @throws DebugException if this method fails. */ - public IAsmInstruction[] getInstructions( long address, int length ) throws DebugException; + IDisassemblyBlock getDisassemblyBlock( ICStackFrame frame ) throws DebugException; } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IDisassemblyBlock.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IDisassemblyBlock.java new file mode 100644 index 00000000000..28cdb55c42b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IDisassemblyBlock.java @@ -0,0 +1,54 @@ +/********************************************************************** + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.debug.core.model; + +/** + * Represents a contiguous segment of disassembly in an execution context. + */ +public interface IDisassemblyBlock { + + /** + * Returns the parent disassembly object. + * + * @return the parent disassembly object + */ + IDisassembly getDisassembly(); + + /** + * Returns the platform-dependent path of the executable associated + * with this segment. + * + * @return the platform-dependent path of the executable + */ + String getModuleFile(); + + /** + * Returns whether this block contains given stack frame. + * + * @param frame the stack frame + * @return whether this block contains given stack frame + */ + boolean contains( ICStackFrame frame ); + + /** + * Return the array of source lines associated with this block. + * + * @return the array of source lines associated with this block + */ + IAsmSourceLine[] getSourceLines(); + + /** + * Returns whether this block contains mixed source/disassembly information. + * + * @return whether this block contains mixed source/disassembly information + */ + boolean isMixedMode(); +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/AsmSourceLine.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/AsmSourceLine.java new file mode 100644 index 00000000000..59df3e81c6f --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/AsmSourceLine.java @@ -0,0 +1,47 @@ +/********************************************************************** + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.debug.internal.core.model; + +import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction; +import org.eclipse.cdt.debug.core.model.IAsmInstruction; +import org.eclipse.cdt.debug.core.model.IAsmSourceLine; + +/** + * Adapter for ICDIMixedInstruction. + */ +public class AsmSourceLine implements IAsmSourceLine { + + private String fText; + + private IAsmInstruction[] fInstructions = null; + + /** + * Constructor for AsmSourceLine. + */ + public AsmSourceLine( String text, ICDIInstruction[] cdiInstructions ) { + fText = text; + fInstructions = new IAsmInstruction[cdiInstructions.length]; + for ( int i = 0; i < fInstructions.length; ++i ) { + fInstructions[i] = new AsmInstruction( cdiInstructions[i] ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IAsmSourceLine#getInstructions() + */ + public IAsmInstruction[] getInstructions() { + return fInstructions; + } + + public String toString() { + return fText; + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/Disassembly.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/Disassembly.java index 13a1c5295d9..f9b848cefbb 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/Disassembly.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/Disassembly.java @@ -18,9 +18,10 @@ import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.ICDISession; import org.eclipse.cdt.debug.core.cdi.ICDISourceManager; import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction; -import org.eclipse.cdt.debug.core.model.IAsmInstruction; +import org.eclipse.cdt.debug.core.cdi.model.ICDIMixedInstruction; import org.eclipse.cdt.debug.core.model.ICStackFrame; import org.eclipse.cdt.debug.core.model.IDisassembly; +import org.eclipse.cdt.debug.core.model.IDisassemblyBlock; import org.eclipse.cdt.debug.core.model.IExecFileInfo; import org.eclipse.debug.core.DebugException; @@ -31,7 +32,7 @@ public class Disassembly extends CDebugElement implements IDisassembly { final static private int DISASSEMBLY_BLOCK_SIZE = 100; - private IAsmInstruction[] fInstructions = new IAsmInstruction[0]; + private DisassemblyBlock[] fBlocks = new DisassemblyBlock[1]; /** * Constructor for Disassembly. @@ -43,85 +44,63 @@ public class Disassembly extends CDebugElement implements IDisassembly { } /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.IDisassembly#getInstructions(org.eclipse.cdt.debug.core.model.ICStackFrame) + * @see org.eclipse.cdt.debug.core.model.IDisassembly#getDisassemblyBlock(org.eclipse.cdt.debug.core.model.ICStackFrame) */ - public IAsmInstruction[] getInstructions( ICStackFrame frame ) throws DebugException { - long address = frame.getAddress(); - if ( !containsAddress( address ) ) { - loadInstructions( frame ); + public IDisassemblyBlock getDisassemblyBlock( ICStackFrame frame ) throws DebugException { + if ( fBlocks[0] == null || !fBlocks[0].contains( frame ) ) { + fBlocks[0] = createBlock( frame ); } - return fInstructions; + return fBlocks[0]; } - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.IDisassembly#getInstructions(long, int) - */ - public IAsmInstruction[] getInstructions( long address, int length ) throws DebugException { - if ( !containsAddress( address ) ) { - loadInstructions( address, length ); - } - return fInstructions; - } - - private boolean containsAddress( long address ) { - for ( int i = 0; i < fInstructions.length; ++i ) { - if ( fInstructions[i].getAdress() == address ) - return true; - } - return false; - } - - private boolean containsAddress( ICDIInstruction[] instructions, long address ) { - for( int i = 0; i < instructions.length; ++i ) { - if ( instructions[i].getAdress() == address ) - return true; - } - return false; - } - - private void loadInstructions( ICStackFrame frame ) throws DebugException { - fInstructions = new IAsmInstruction[0]; + private DisassemblyBlock createBlock( ICStackFrame frame ) throws DebugException { ICDISession session = (ICDISession)getDebugTarget().getAdapter( ICDISession.class ); if ( session != null ) { ICDISourceManager sm = session.getSourceManager(); if ( sm != null ) { String fileName = frame.getFile(); int lineNumber = frame.getLineNumber(); - ICDIInstruction[] instructions = new ICDIInstruction[0]; + ICDIMixedInstruction[] mixedInstrs = new ICDIMixedInstruction[0]; long address = frame.getAddress(); if ( fileName != null && fileName.length() > 0 ) { try { - instructions = sm.getInstructions( fileName, - lineNumber, - CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS ) ); + mixedInstrs = sm.getMixedInstructions( fileName, + lineNumber, + CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS ) ); } catch( CDIException e ) { targetRequestFailed( CoreModelMessages.getString( "Disassembly.Unable_to_get_disassembly_instructions_1" ), e ); //$NON-NLS-1$ } } - if ( instructions.length == 0 || + if ( mixedInstrs.length == 0 || // Double check if debugger returns correct address range. - !containsAddress( instructions, address ) ) { + !containsAddress( mixedInstrs, address ) ) { if ( address >= 0 ) { try { - instructions = getFunctionInstructions( sm.getInstructions( address, address + DISASSEMBLY_BLOCK_SIZE ) ); + ICDIInstruction[] instructions = getFunctionInstructions( sm.getInstructions( address, address + DISASSEMBLY_BLOCK_SIZE ) ); + return DisassemblyBlock.create( this, instructions ); } catch( CDIException e ) { targetRequestFailed( CoreModelMessages.getString( "Disassembly.Unable_to_get_disassembly_instructions_2" ), e ); //$NON-NLS-1$ } } } - fInstructions = new IAsmInstruction[instructions.length]; - for ( int i = 0; i < fInstructions.length; ++i ) { - fInstructions[i] = new AsmInstruction( instructions[i] ); + else { + return DisassemblyBlock.create( this, mixedInstrs ); } } } + return null; } - private void loadInstructions( long address, int length ) throws DebugException { - fInstructions = new IAsmInstruction[0]; - + private boolean containsAddress( ICDIMixedInstruction[] mi, long address ) { + for( int i = 0; i < mi.length; ++i ) { + ICDIInstruction[] instructions = mi[i].getInstructions(); + for ( int j = 0; j < instructions.length; ++j ) + if ( instructions[j].getAdress() == address ) + return true; + } + return false; } private ICDIInstruction[] getFunctionInstructions( ICDIInstruction[] rawInstructions ) { @@ -139,7 +118,11 @@ public class Disassembly extends CDebugElement implements IDisassembly { } public void dispose() { - fInstructions = null; + for ( int i = 0; i < fBlocks.length; ++i ) + if ( fBlocks[i] != null ) { + fBlocks[i].dispose(); + fBlocks[i] = null; + } } /* (non-Javadoc) diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/DisassemblyBlock.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/DisassemblyBlock.java new file mode 100644 index 00000000000..4b497790833 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/DisassemblyBlock.java @@ -0,0 +1,196 @@ +/********************************************************************** + * Copyright (c) 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.debug.internal.core.model; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; + +import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction; +import org.eclipse.cdt.debug.core.cdi.model.ICDIMixedInstruction; +import org.eclipse.cdt.debug.core.model.IAsmInstruction; +import org.eclipse.cdt.debug.core.model.IAsmSourceLine; +import org.eclipse.cdt.debug.core.model.ICStackFrame; +import org.eclipse.cdt.debug.core.model.IDisassembly; +import org.eclipse.cdt.debug.core.model.IDisassemblyBlock; +import org.eclipse.cdt.debug.core.model.IExecFileInfo; +import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.debug.core.model.ISourceLocator; + +/** + * CDI-based implementation of IDisassemblyBlock. + */ +public class DisassemblyBlock implements IDisassemblyBlock, IAdaptable { + + private IDisassembly fDisassembly; + + private IAsmSourceLine[] fSourceLines; + + private long fStartAddress = 0; + + private long fEndAddress = 0; + + private boolean fMixedMode = false; + + /** + * Constructor for DisassemblyBlock. + */ + private DisassemblyBlock( IDisassembly disassembly ) { + fDisassembly = disassembly; + } + + public static DisassemblyBlock create( IDisassembly disassembly, ICDIMixedInstruction[] instructions ) { + DisassemblyBlock block = new DisassemblyBlock( disassembly ); + block.setMixedMode( true ); + ISourceLocator adapter = disassembly.getDebugTarget().getLaunch().getSourceLocator(); + ICSourceLocator locator = null; + if ( adapter instanceof IAdaptable ) { + locator = (ICSourceLocator)((IAdaptable)adapter).getAdapter( ICSourceLocator.class ); + } + block.setSourceLines( createSourceLines( locator, instructions ) ); + block.initializeAddresses(); + return block; + } + + public static DisassemblyBlock create( IDisassembly disassembly, ICDIInstruction[] instructions ) { + DisassemblyBlock block = new DisassemblyBlock( disassembly ); + block.setMixedMode( false ); + block.setSourceLines( createSourceLines( instructions ) ); + block.initializeAddresses(); + return block; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IDisassemblyBlock#getDisassembly() + */ + public IDisassembly getDisassembly() { + return fDisassembly; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IDisassemblyBlock#getModuleFile() + */ + public String getModuleFile() { + IDisassembly d = getDisassembly(); + if ( d != null ) { + IExecFileInfo info = (IExecFileInfo)d.getAdapter( IExecFileInfo.class ); + if ( info != null && info.getExecFile() != null ) { + return info.getExecFile().getLocation().toOSString(); + } + } + return ""; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IDisassemblyBlock#contains(org.eclipse.cdt.debug.core.model.ICStackFrame) + */ + public boolean contains( ICStackFrame frame ) { + if ( !getDisassembly().getDebugTarget().equals( frame.getDebugTarget() ) ) + return false; + long address = frame.getAddress(); + return (address >= fStartAddress && address <= fEndAddress); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IDisassemblyBlock#getSourceLines() + */ + public IAsmSourceLine[] getSourceLines() { + return fSourceLines; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter( Class adapter ) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IDisassemblyBlock#isMixedMode() + */ + public boolean isMixedMode() { + return fMixedMode; + } + + public void dispose() { + } + + private static IAsmSourceLine[] createSourceLines( ICSourceLocator locator, ICDIMixedInstruction[] mi ) { + IAsmSourceLine[] result = new IAsmSourceLine[mi.length]; + LineNumberReader reader = null; + if ( result.length > 0 && locator != null ) { + String fileName = mi[0].getFileName(); + Object element = locator.findSourceElement( fileName ); + File file= null; + if ( element instanceof IFile ) { + file = ((IFile)element).getLocation().toFile(); + } + else if ( element instanceof IStorage ) { + file = ((IStorage)element).getFullPath().toFile(); + } + if ( file != null ) { + try { + reader = new LineNumberReader( new FileReader( file ) ); + } + catch( FileNotFoundException e ) { + } + } + } + for ( int i = 0; i < result.length; ++i ) { + String text = null; + if ( reader != null ) { + int lineNumber = mi[i].getLineNumber(); + while( reader.getLineNumber() + 1 < lineNumber ) { + try { + reader.readLine(); + } + catch( IOException e ) { + } + } + if ( reader.getLineNumber() + 1 == lineNumber ) { + try { + text = reader.readLine() + '\n'; + } + catch( IOException e ) { + } + } + } + result[i] = new AsmSourceLine( text, mi[i].getInstructions() ); + } + return result; + } + + private static IAsmSourceLine[] createSourceLines( ICDIInstruction[] instructions ) { + return new IAsmSourceLine[] { new AsmSourceLine( "", instructions ) }; //$NON-NLS-1$ + } + + private void initializeAddresses() { + if ( fSourceLines.length > 0 ) { + IAsmInstruction[] instr = fSourceLines[0].getInstructions(); + fStartAddress = instr[0].getAdress(); + instr = fSourceLines[fSourceLines.length - 1].getInstructions(); + fEndAddress = instr[instr.length - 1].getAdress(); + } + } + + private void setMixedMode( boolean mixedMode ) { + this.fMixedMode = mixedMode; + } + + private void setSourceLines( IAsmSourceLine[] sourceLines ) { + this.fSourceLines = sourceLines; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/ChangeLog b/debug/org.eclipse.cdt.debug.ui/ChangeLog index ee2f77d4b42..ca876dfbfd3 100644 --- a/debug/org.eclipse.cdt.debug.ui/ChangeLog +++ b/debug/org.eclipse.cdt.debug.ui/ChangeLog @@ -1,3 +1,11 @@ +2004-05-06 Mikhail Khodjaiants + Implementation of mixed disassembly mode. + * ToggleBreakpointAdapter.java + * DisassemblyMessages.properties + * DisassemblyAnnotationModel.java + * DisassemblyEditorInput.java + * DisassemblyView.java + 2004-05-02 Mikhail Khodjaiants Check if the new stack frame is of the same debug target as the old one. * DisassemblyEditorInput.java diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java index 4bb8e7561fd..b5b2f126ab7 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/ToggleBreakpointAdapter.java @@ -18,7 +18,6 @@ import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyEditorInpu import org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyView; import org.eclipse.cdt.debug.ui.CDebugUIPlugin; import org.eclipse.cdt.debug.ui.ICDebugUIConstants; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; @@ -109,20 +108,25 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget { IResource resource = ResourcesPlugin.getWorkspace().getRoot(); String sourceHandle = getSourceHandle( input ); long address = ((DisassemblyEditorInput)input).getAddress( lineNumber ); - ICAddressBreakpoint breakpoint = CDIDebugModel.addressBreakpointExists( sourceHandle, resource, address ); - if ( breakpoint != null ) { - DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint( breakpoint, true ); + if ( address != 0 ) { + ICAddressBreakpoint breakpoint = CDIDebugModel.addressBreakpointExists( sourceHandle, resource, address ); + if ( breakpoint != null ) { + DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint( breakpoint, true ); + } + else { + CDIDebugModel.createAddressBreakpoint( sourceHandle, + resource, + address, + true, + 0, + "", //$NON-NLS-1$ + true ); + } + return; } else { - CDIDebugModel.createAddressBreakpoint( sourceHandle, - resource, - address, - true, - 0, - "", //$NON-NLS-1$ - true ); + errorMessage = ActionMessages.getString( "ToggleBreakpointAdapter.Invalid_line_1" ); //$NON-NLS-1$ } - return; } } } @@ -141,7 +145,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget { if ( !(input instanceof DisassemblyEditorInput) || ((DisassemblyEditorInput)input).equals( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ) ) { return false; - } + } } return ( selection instanceof ITextSelection ); } @@ -258,8 +262,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget { return ((IStorageEditorInput)input).getStorage().getName(); } if ( input instanceof DisassemblyEditorInput ) { - IFile file = ((DisassemblyEditorInput)input).getModuleFile(); - return ( file != null ) ? file.getLocation().toOSString() : ""; //$NON-NLS-1$ + return ((DisassemblyEditorInput)input).getModuleFile(); } return ""; //$NON-NLS-1$ } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyAnnotationModel.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyAnnotationModel.java index 7f044c000ce..85e64a1f9e2 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyAnnotationModel.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyAnnotationModel.java @@ -137,10 +137,9 @@ public class DisassemblyAnnotationModel extends AnnotationModel { Position position = null; DisassemblyEditorInput input = getInput(); if ( input != null ) { - long address = input.getBreakpointAddress( breakpoint ); int start = -1; - if ( address > 0 && document != null ) { - int instrNumber = input.getInstructionNumber( address ); + if ( document != null ) { + int instrNumber = input.getInstructionLine( breakpoint ); if ( instrNumber > 0 ) { try { start = fDocument.getLineOffset( instrNumber - 1 ); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyEditorInput.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyEditorInput.java index 7c0af3cbb06..5c268b9d074 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyEditorInput.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyEditorInput.java @@ -13,13 +13,14 @@ package org.eclipse.cdt.debug.internal.ui.views.disassembly; import java.util.Arrays; import org.eclipse.cdt.debug.core.model.IAsmInstruction; +import org.eclipse.cdt.debug.core.model.IAsmSourceLine; import org.eclipse.cdt.debug.core.model.IBreakpointTarget; +import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICStackFrame; import org.eclipse.cdt.debug.core.model.IDisassembly; -import org.eclipse.cdt.debug.core.model.IExecFileInfo; +import org.eclipse.cdt.debug.core.model.IDisassemblyBlock; import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; -import org.eclipse.core.resources.IFile; import org.eclipse.debug.core.DebugException; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.IEditorInput; @@ -30,148 +31,6 @@ import org.eclipse.ui.IPersistableElement; */ public class DisassemblyEditorInput implements IEditorInput { - /** - * A storage object used by Disassembly view. - */ - private static class DisassemblyStorage { - - private IDisassembly fDisassembly; - private IAsmInstruction[] fInstructions; - protected String fContents; - protected long fStartAddress = 0; - protected long fEndAddress = 0; - - /** - * Constructor for DisassemblyStorage. - */ - public DisassemblyStorage( IDisassembly disassembly, IAsmInstruction[] instructions ) { - fDisassembly = disassembly; - fInstructions = ( instructions != null ) ? instructions : new IAsmInstruction[0]; - initializeAddresses(); - createContent(); - } - - public String getContents() { - return fContents; - } - - public IDisassembly getDisassembly() { - return this.fDisassembly; - } - - public boolean containsFrame( ICStackFrame frame ) { - if ( !getDisassembly().getDebugTarget().equals( frame.getDebugTarget() ) ) - return false; - long address = frame.getAddress(); - return (address >= fStartAddress && address <= fEndAddress); - } - - public IFile getModuleFile() { - IDisassembly d = getDisassembly(); - IFile result = null; - if ( d != null ) { - IExecFileInfo info = (IExecFileInfo)d.getAdapter( IExecFileInfo.class ); - if ( info != null ) { - result = info.getExecFile(); - } - } - return result; - } - - public long getBreakpointAddress( ICLineBreakpoint breakpoint ) { - IDisassembly dis = getDisassembly(); - if ( dis != null ) { - IBreakpointTarget bt = (IBreakpointTarget)dis.getDebugTarget().getAdapter( IBreakpointTarget.class ); - if ( bt != null ) { - try { - return bt.getBreakpointAddress( breakpoint ); - } - catch( DebugException e ) { - } - } - } - return 0; - } - - private void createContent() { - StringBuffer lines = new StringBuffer(); - int maxFunctionName = 0; - int maxOpcodeLength = 0; - long maxOffset = 0; - for( int i = 0; i < fInstructions.length; ++i ) { - String functionName = fInstructions[i].getFunctionName(); - if ( functionName.length() > maxFunctionName ) { - maxFunctionName = functionName.length(); - } - String opcode = fInstructions[i].getOpcode(); - if ( opcode.length() > maxOpcodeLength ) - maxOpcodeLength = opcode.length(); - if ( fInstructions[i].getOffset() > maxOffset ) { - maxOffset = fInstructions[i].getOffset(); - } - } - int instrPos = calculateInstructionPosition( maxFunctionName, maxOffset ); - int argPosition = instrPos + maxOpcodeLength + 1; - for( int i = 0; i < fInstructions.length; ++i ) { - lines.append( getInstructionString( fInstructions[i], instrPos, argPosition ) ); - } - fContents = lines.toString(); - } - - private String getInstructionString( IAsmInstruction instruction, int instrPosition, int argPosition ) { - int worstCaseSpace = Math.max( instrPosition, argPosition ); - char[] spaces = new char[worstCaseSpace]; - Arrays.fill( spaces, ' ' ); - StringBuffer sb = new StringBuffer(); - if ( instruction != null ) { - sb.append( CDebugUIUtils.toHexAddressString( instruction.getAdress() ) ); - sb.append( ' ' ); - String functionName = instruction.getFunctionName(); - if ( functionName != null && functionName.length() > 0 ) { - sb.append( '<' ); - sb.append( functionName ); - if ( instruction.getOffset() != 0 ) { - sb.append( '+' ); - sb.append( instruction.getOffset() ); - } - sb.append( ">:" ); //$NON-NLS-1$ - sb.append( spaces, 0, instrPosition - sb.length() ); - } - sb.append( instruction.getOpcode() ); - sb.append( spaces, 0, argPosition - sb.length() ); - sb.append( instruction.getArguments() ); - sb.append( '\n' ); - } - return sb.toString(); - } - - private int calculateInstructionPosition( int maxFunctionName, long maxOffset ) { - return (16 + maxFunctionName + Long.toString( maxOffset ).length()); - } - - private void initializeAddresses() { - if ( fInstructions.length > 0 ) { - fStartAddress = fInstructions[0].getAdress(); - fEndAddress = fInstructions[fInstructions.length - 1].getAdress(); - } - } - - public int getLineNumber( long address ) { - for( int i = 0; i < fInstructions.length; ++i ) { - if ( fInstructions[i].getAdress() == address ) { - return i + 1; - } - } - return 0; - } - - public long getAddress( int lineNumber ) throws IllegalArgumentException { - if ( lineNumber > 0 && lineNumber <= fInstructions.length ) - return fInstructions[--lineNumber].getAdress(); - throw new IllegalArgumentException(); - } - } - public static final IEditorInput EMPTY_EDITOR_INPUT = new DisassemblyEditorInput(); public static final IEditorInput PENDING_EDITOR_INPUT = @@ -182,9 +41,11 @@ public class DisassemblyEditorInput implements IEditorInput { }; /** - * Storage associated with this editor input + * Disassembly block associated with this editor input */ - private DisassemblyStorage fStorage; + private IDisassemblyBlock fBlock; + + private String fContents = ""; //$NON-NLS-1$ /** * Constructor for DisassemblyEditorInput. @@ -198,8 +59,9 @@ public class DisassemblyEditorInput implements IEditorInput { * @param disassembly * @param instructions */ - public DisassemblyEditorInput( IDisassembly disassembly, IAsmInstruction[] instructions ) { - fStorage = new DisassemblyStorage( disassembly, instructions ); + private DisassemblyEditorInput( IDisassemblyBlock block ) { + fBlock = block; + createContents(); } /* (non-Javadoc) @@ -245,29 +107,158 @@ public class DisassemblyEditorInput implements IEditorInput { } public boolean contains( ICStackFrame frame ) { - if ( fStorage != null ) { - return fStorage.containsFrame( frame ); + if ( fBlock != null ) { + return fBlock.contains( frame ); } return false; } public String getContents() { - return ( fStorage != null ) ? fStorage.getContents() : ""; //$NON-NLS-1$ + return fContents; } - public int getInstructionNumber( long address ) { - return ( fStorage != null ) ? fStorage.getLineNumber( address ) : 0; + public int getInstructionLine( long address ) { + if ( fBlock != null ) { + IAsmSourceLine[] lines = fBlock.getSourceLines(); + int result = 0; + for ( int i = 0; i < lines.length; ++i ) { + IAsmInstruction[] instructions = lines[i].getInstructions(); + ++result; + for ( int j = 0; j < instructions.length; ++j ) { + ++result; + if ( instructions[j].getAdress() == address ) { + return result; + } + } + } + } + return 0; } - public long getAddress( int lineNumber ) throws IllegalArgumentException { - return ( fStorage != null ) ? fStorage.getAddress( lineNumber ) : 0; + public int getInstructionLine( ICLineBreakpoint breakpoint ) { + if ( fBlock != null ) { + IDisassembly dis = fBlock.getDisassembly(); + if ( dis != null ) { + IBreakpointTarget bt = (IBreakpointTarget)dis.getDebugTarget().getAdapter( IBreakpointTarget.class ); + if ( bt != null ) { + try { + long address = bt.getBreakpointAddress( breakpoint ); + if ( address != 0 ) + return getInstructionLine( address ); + } + catch( DebugException e ) { + } + } + } + } + return 0; } - public IFile getModuleFile() { - return ( fStorage != null ) ? fStorage.getModuleFile() : null; + public long getAddress( int lineNumber ) { + if ( fBlock != null ) { + IAsmSourceLine[] lines = fBlock.getSourceLines(); + int current = 0; + for ( int i = 0; i < lines.length; ++i ) { + IAsmInstruction[] instructions = lines[i].getInstructions(); + ++current; + if ( lineNumber == current ) + return instructions[0].getAdress(); + if ( lineNumber > current && lineNumber <= current + instructions.length ) + return instructions[lineNumber - current - 1].getAdress(); + current += instructions.length; + } + } + return 0; } - public long getBreakpointAddress( ICLineBreakpoint breakpoint ) { - return ( fStorage != null ) ? fStorage.getBreakpointAddress( breakpoint ) : 0; + public String getModuleFile() { + return ( fBlock != null ) ? fBlock.getModuleFile() : null; + } + + public static DisassemblyEditorInput create( ICStackFrame frame ) throws DebugException { + DisassemblyEditorInput input = null; + IDisassembly disassembly = ((ICDebugTarget)frame.getDebugTarget()).getDisassembly(); + if ( disassembly != null ) { + IDisassemblyBlock block = disassembly.getDisassemblyBlock( frame ); + input = new DisassemblyEditorInput( block ); + } + return input; + } + + private void createContents() { + StringBuffer lines = new StringBuffer(); + int maxFunctionName = 0; + int maxOpcodeLength = 0; + long maxOffset = 0; + if ( fBlock != null ) { + IAsmSourceLine[] mi = fBlock.getSourceLines(); + for ( int j = 0; j < mi.length; ++j ) { + IAsmInstruction[] instructions = mi[j].getInstructions(); + for( int i = 0; i < instructions.length; ++i ) { + String functionName = instructions[i].getFunctionName(); + if ( functionName.length() > maxFunctionName ) { + maxFunctionName = functionName.length(); + } + String opcode = instructions[i].getOpcode(); + if ( opcode.length() > maxOpcodeLength ) + maxOpcodeLength = opcode.length(); + if ( instructions[i].getOffset() > maxOffset ) { + maxOffset = instructions[i].getOffset(); + } + } + } + int instrPos = calculateInstructionPosition( maxFunctionName, maxOffset ); + int argPosition = instrPos + maxOpcodeLength + 1; + for ( int j = 0; j < mi.length; ++j ) { + if ( fBlock.isMixedMode() ) + lines.append( getSourceLineString( mi[j] ) ); + IAsmInstruction[] instructions = mi[j].getInstructions(); + for( int i = 0; i < instructions.length; ++i ) { +// if ( fBlock.isMixedMode() ) +// lines.append( "\t" ); //$NON-NLS-1$ + lines.append( getInstructionString( instructions[i], instrPos, argPosition ) ); + } + } + } + fContents = lines.toString(); + } + + private String getInstructionString( IAsmInstruction instruction, int instrPosition, int argPosition ) { + int worstCaseSpace = Math.max( instrPosition, argPosition ); + char[] spaces = new char[worstCaseSpace]; + Arrays.fill( spaces, ' ' ); + StringBuffer sb = new StringBuffer(); + if ( instruction != null ) { + sb.append( CDebugUIUtils.toHexAddressString( instruction.getAdress() ) ); + sb.append( ' ' ); + String functionName = instruction.getFunctionName(); + if ( functionName != null && functionName.length() > 0 ) { + sb.append( '<' ); + sb.append( functionName ); + if ( instruction.getOffset() != 0 ) { + sb.append( '+' ); + sb.append( instruction.getOffset() ); + } + sb.append( ">:" ); //$NON-NLS-1$ + sb.append( spaces, 0, instrPosition - sb.length() ); + } + sb.append( instruction.getOpcode() ); + sb.append( spaces, 0, argPosition - sb.length() ); + sb.append( instruction.getArguments() ); + sb.append( '\n' ); + } + return sb.toString(); + } + + private int calculateInstructionPosition( int maxFunctionName, long maxOffset ) { + return (16 + maxFunctionName + Long.toString( maxOffset ).length()); + } + + private String getSourceLineString( IAsmSourceLine line ) { + String text = line.toString(); + if ( text == null ) { + text = DisassemblyMessages.getString( "DisassemblyEditorInput.source_line_is_not_available_1" ) + '\n'; //$NON-NLS-1$ + } + return text; } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.properties index 4e86da8ee13..89bca8d99d3 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.properties @@ -4,3 +4,4 @@ DisassemblyInstructionPointerAnnotation.Secondary_Pointer_1=Secondary Disassembl DisassemblyAnnotationHover.Multiple_markers_at_this_line_1=Multiple markers at this line HTMLTextPresenter.ellipsis= HTML2TextReader.dash=- +DisassemblyEditorInput.source_line_is_not_available_1= diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyView.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyView.java index 2ef8f094e77..ec4f8267f66 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyView.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyView.java @@ -10,14 +10,11 @@ ***********************************************************************/ package org.eclipse.cdt.debug.internal.ui.views.disassembly; +import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.HashMap; -import org.eclipse.cdt.debug.core.model.IAsmInstruction; -import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.core.model.ICStackFrame; -import org.eclipse.cdt.debug.core.model.IDisassembly; import org.eclipse.cdt.debug.internal.ui.ICDebugHelpContextIds; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.cdt.debug.internal.ui.actions.CBreakpointPropertiesRulerAction; @@ -529,13 +526,8 @@ public class DisassemblyView extends AbstractDebugEventHandlerView input = (IEditorInput)current; } else { - IAsmInstruction[] instructions = new IAsmInstruction[0]; try { - IDisassembly disassembly = ((ICDebugTarget)frame.getDebugTarget()).getDisassembly(); - if ( disassembly != null ) { - instructions = disassembly.getInstructions( frame ); - input = new DisassemblyEditorInput( disassembly, instructions ); - } + input = DisassemblyEditorInput.create( frame ); } catch( DebugException e ) { status = new Status( IStatus.ERROR, @@ -553,8 +545,7 @@ public class DisassemblyView extends AbstractDebugEventHandlerView } protected void selectAndReveal( ICStackFrame frame, IEditorInput input ) { - long address = frame.getAddress(); - IRegion region = getLineInformation( address, input ); + IRegion region = getLineInformation( frame, input ); if ( region != null ) { int start = region.getOffset(); int length = region.getLength(); @@ -572,9 +563,9 @@ public class DisassemblyView extends AbstractDebugEventHandlerView /** * Returns the line information for the given line in the given editor */ - private IRegion getLineInformation( long address, IEditorInput input ) { + private IRegion getLineInformation( ICStackFrame frame, IEditorInput input ) { if ( input instanceof DisassemblyEditorInput ) { - int line = ((DisassemblyEditorInput)input).getInstructionNumber( address ); + int line = ((DisassemblyEditorInput)input).getInstructionLine( frame.getAddress() ); if ( line > 0 ) { try { return getSourceViewer().getDocument().getLineInformation( --line ); @@ -703,8 +694,8 @@ public class DisassemblyView extends AbstractDebugEventHandlerView Assert.isNotNull( model ); DisassemblyInstructionPointerAnnotation instrPointer = getCurrentInstructionPointer(); if ( instrPointer != null ) { - model.removeAnnotation( instrPointer ); - setCurrentInstructionPointer( null ); + model.removeAnnotation( instrPointer ); + setCurrentInstructionPointer( null ); } }