From 48f0015abc207d4b8e4822283d1307a5e093d6db Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Thu, 15 Apr 2004 22:53:48 +0000 Subject: [PATCH] Implementing the Disassembly view. --- debug/org.eclipse.cdt.debug.core/ChangeLog | 7 + .../internal/core/model/AsmInstruction.java | 71 +++ .../internal/core/model/CDebugTarget.java | 23 +- .../internal/core/model/CStackFrame.java | 3 +- .../internal/core/model/Disassembly.java | 143 +++++ debug/org.eclipse.cdt.debug.ui/ChangeLog | 20 + .../icons/full/cview16/disassembly_view.gif | Bin 0 -> 238 bytes .../icons/full/obj16/inst_ptr.gif | Bin 0 -> 133 bytes .../icons/full/obj16/inst_ptr_top.gif | Bin 0 -> 130 bytes .../plugin.properties | 5 + debug/org.eclipse.cdt.debug.ui/plugin.xml | 67 +++ .../internal/ui/ICDebugHelpContextIds.java | 3 +- .../ui/IInternalCDebugUIConstants.java | 35 ++ .../DisassemblyDocumentProvider.java | 166 ++++++ .../disassembly/DisassemblyEditorInput.java | 220 +++++++ ...sassemblyInstructionPointerAnnotation.java | 97 +++ .../disassembly/DisassemblyMessages.java | 33 ++ .../DisassemblyMessages.properties | 3 + .../ui/views/disassembly/DisassemblyView.java | 561 ++++++++++++++++++ .../DisassemblyViewEventHandler.java | 76 +++ .../views/disassembly/DisassemblyViewer.java | 59 ++ .../disassembly/IDisassemblyListener.java | 32 + 22 files changed, 1619 insertions(+), 5 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/AsmInstruction.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/Disassembly.java create mode 100644 debug/org.eclipse.cdt.debug.ui/icons/full/cview16/disassembly_view.gif create mode 100644 debug/org.eclipse.cdt.debug.ui/icons/full/obj16/inst_ptr.gif create mode 100644 debug/org.eclipse.cdt.debug.ui/icons/full/obj16/inst_ptr_top.gif create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyDocumentProvider.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyEditorInput.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyInstructionPointerAnnotation.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.properties create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyView.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewEventHandler.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewer.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/IDisassemblyListener.java diff --git a/debug/org.eclipse.cdt.debug.core/ChangeLog b/debug/org.eclipse.cdt.debug.core/ChangeLog index 041b1cfd536..58487298eab 100644 --- a/debug/org.eclipse.cdt.debug.core/ChangeLog +++ b/debug/org.eclipse.cdt.debug.core/ChangeLog @@ -1,3 +1,10 @@ +2004-04-15 Mikhail Khodjaiants + Implementing core support of disassembly. + * AsmInstruction.java + * CDebugTarget.java + * CStackFrame.java + * Disassembly.java: new + 2004-04-12 Mikhail Khodjaiants Implementing retargettable breakpoint related actions. * CDebugModel.java diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/AsmInstruction.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/AsmInstruction.java new file mode 100644 index 00000000000..00b21047c10 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/AsmInstruction.java @@ -0,0 +1,71 @@ +/********************************************************************** + * 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; + +/** + * Adapter for ICDIInstruction. + */ +public class AsmInstruction implements IAsmInstruction { + + private ICDIInstruction fCDIInstruction; + + /** + * Constructor for AsmInstruction. + */ + public AsmInstruction( ICDIInstruction cdiInstruction ) { + fCDIInstruction = cdiInstruction; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IAsmInstruction#getAdress() + */ + public long getAdress() { + return fCDIInstruction.getAdress(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IAsmInstruction#getFunctionName() + */ + public String getFunctionName() { + return fCDIInstruction.getFuntionName(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IAsmInstruction#getInstructionText() + */ + public String getInstructionText() { + return fCDIInstruction.getInstruction(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IAsmInstruction#getOpcode() + */ + public String getOpcode() { + return fCDIInstruction.getOpcode(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IAsmInstruction#getArguments() + */ + public String getArguments() { + return fCDIInstruction.getArgs(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IAsmInstruction#getOffset() + */ + public long getOffset() { + return fCDIInstruction.getOffset(); + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java index bbb1e7ef4fe..9009b087353 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.debug.core.cdi.ICDIEndSteppingRange; import org.eclipse.cdt.debug.core.cdi.ICDIErrorInfo; import org.eclipse.cdt.debug.core.cdi.ICDIExpressionManager; import org.eclipse.cdt.debug.core.cdi.ICDILocation; +import org.eclipse.cdt.debug.core.cdi.ICDISession; import org.eclipse.cdt.debug.core.cdi.ICDISessionObject; import org.eclipse.cdt.debug.core.cdi.ICDISharedLibraryEvent; import org.eclipse.cdt.debug.core.cdi.ICDISignalReceived; @@ -228,6 +229,11 @@ public class CDebugTarget extends CDebugElement */ private DisassemblyManager fDisassemblyManager; + /** + * A disassembly manager for this target. + */ + private Disassembly fDisassembly; + /** * A shared library manager for this target. */ @@ -295,6 +301,7 @@ public class CDebugTarget extends CDebugElement setConfiguration( cdiTarget.getSession().getConfiguration() ); setThreadList( new ArrayList( 5 ) ); setDisassemblyManager( new DisassemblyManager( this ) ); + createDisassembly(); setSharedLibraryManager( new CSharedLibraryManager( this ) ); setSignalManager( new CSignalManager( this ) ); setRegisterManager( new CRegisterManager( this ) ); @@ -1000,6 +1007,8 @@ public class CDebugTarget extends CDebugElement return getSignalManager(); if ( adapter.equals( ICRegisterManager.class ) ) return getRegisterManager(); + if ( adapter.equals( ICDISession.class ) ) + return getCDISession(); return super.getAdapter( adapter ); } @@ -1232,6 +1241,7 @@ public class CDebugTarget extends CDebugElement disposeSignalManager(); disposeRegisterManager(); disposeDisassemblyManager(); + disposeDisassembly(); disposeSourceManager(); disposeBreakpointManager(); removeAllExpressions(); @@ -2369,8 +2379,7 @@ public class CDebugTarget extends CDebugElement * @see org.eclipse.cdt.debug.core.model.ICDebugTarget#getDisassembly() */ public IDisassembly getDisassembly() throws DebugException { - // TODO Auto-generated method stub - return null; + return fDisassembly; } /* (non-Javadoc) @@ -2426,4 +2435,14 @@ public class CDebugTarget extends CDebugElement slm.loadSymbolsForAll(); } } + + private void createDisassembly() { + this.fDisassembly = new Disassembly( this ); + } + + private void disposeDisassembly() { + if ( fDisassembly != null ) + fDisassembly.dispose(); + fDisassembly = null; + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java index 6ea35341505..3fa5c8da5b5 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.debug.core.cdi.event.ICDIEvent; import org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener; import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame; import org.eclipse.cdt.debug.core.cdi.model.ICDIVariableObject; +import org.eclipse.cdt.debug.core.model.ICStackFrame; import org.eclipse.cdt.debug.core.model.IRestart; import org.eclipse.cdt.debug.core.model.IResumeWithoutSignal; import org.eclipse.cdt.debug.core.model.IRunToLine; @@ -39,7 +40,7 @@ import org.eclipse.debug.core.model.IVariable; * @since Aug 7, 2002 */ public class CStackFrame extends CDebugElement - implements IStackFrame, + implements ICStackFrame, IStackFrameInfo, IRestart, IResumeWithoutSignal, 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 new file mode 100644 index 00000000000..0a6f4e9262a --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/Disassembly.java @@ -0,0 +1,143 @@ +/********************************************************************** + * 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.util.ArrayList; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDebugConstants; +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.model.ICStackFrame; +import org.eclipse.cdt.debug.core.model.IDisassembly; +import org.eclipse.debug.core.DebugException; + +/** + * CDI implementation of IDisassembly + */ +public class Disassembly extends CDebugElement implements IDisassembly { + + final static private int DISASSEMBLY_BLOCK_SIZE = 100; + + private IAsmInstruction[] fInstructions = new IAsmInstruction[0]; + + /** + * Constructor for Disassembly. + * + * @param target + */ + public Disassembly( CDebugTarget target ) { + super( target ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.IDisassembly#getInstructions(org.eclipse.cdt.debug.core.model.ICStackFrame) + */ + public IAsmInstruction[] getInstructions( ICStackFrame frame ) throws DebugException { + long address = frame.getAddress(); + if ( !containsAddress( address ) ) { + loadInstructions( frame ); + } + return fInstructions; + } + + /* (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]; + 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]; + 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 ) ); + } + catch( CDIException e ) { + targetRequestFailed( "Unable to get disassembly instructions.", e ); + } + } + if ( instructions.length == 0 || + // Double check if debugger returns correct address range. + !containsAddress( instructions, address ) ) { + if ( address >= 0 ) { + try { + instructions = getFunctionInstructions( sm.getInstructions( address, address + DISASSEMBLY_BLOCK_SIZE ) ); + } + catch( CDIException e ) { + targetRequestFailed( "Unable to get disassembly instructions.", e ); + } + } + } + fInstructions = new IAsmInstruction[instructions.length]; + for ( int i = 0; i < fInstructions.length; ++i ) { + fInstructions[i] = new AsmInstruction( instructions[i] ); + } + } + } + } + + private void loadInstructions( long address, int length ) throws DebugException { + fInstructions = new IAsmInstruction[0]; + + } + + private ICDIInstruction[] getFunctionInstructions( ICDIInstruction[] rawInstructions ) { + if ( rawInstructions.length > 0 && rawInstructions[0].getFuntionName() != null && rawInstructions[0].getFuntionName().length() > 0 ) { + ArrayList list = new ArrayList( rawInstructions.length ); + list.add( rawInstructions[0] ); + for( int i = 1; i < rawInstructions.length; ++i ) { + if ( rawInstructions[0].getFuntionName().equals( rawInstructions[i].getFuntionName() ) ) { + list.add( rawInstructions[i] ); + } + } + return (ICDIInstruction[])list.toArray( new ICDIInstruction[list.size()] ); + } + return rawInstructions; + } + + public void dispose() { + fInstructions = null; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/ChangeLog b/debug/org.eclipse.cdt.debug.ui/ChangeLog index df574fa1343..dbc8398e519 100644 --- a/debug/org.eclipse.cdt.debug.ui/ChangeLog +++ b/debug/org.eclipse.cdt.debug.ui/ChangeLog @@ -1,3 +1,23 @@ +2004-04-15 Mikhail Khodjaiants + Implementing the Disassembly view. + New pacckage: org.eclipse.cdt.debug.internal.ui.views.disassembly + * DisassemblyMessages.properties: new + * DisassemblyDocumentProvider.java: new + * DisassemblyEditorInput.java: new + * DisassemblyInstructionPointerAnnotation.java: new + * DisassemblyMessages.java: new + * DisassemblyView.java: new + * DisassemblyViewer.java: new + * DisassemblyViewEventHandler.java: new + * IDisassemblyListener.java: new + * ICDebugHelpContextIds.java + * IInternalCDebugUIConstants.java + * plugin.properties + * plugin.xml + * icons/full/cview16/disassembly_view.gif: new + * icons/full/obj16/inst_ptr_top.gif: new + * icons/full/obj16/inst_ptr.gif: new + 2004-04-12 Mikhail Khodjaiants Fixes in the breakpoint-related actions. * ActionMessages.properties diff --git a/debug/org.eclipse.cdt.debug.ui/icons/full/cview16/disassembly_view.gif b/debug/org.eclipse.cdt.debug.ui/icons/full/cview16/disassembly_view.gif new file mode 100644 index 0000000000000000000000000000000000000000..546c93c42d15fa850d0a11aa4d08a80556b0eabb GIT binary patch literal 238 zcmV!>eG;q zf{TPfs-s%Lxo*e6e6_A~+0>`s+qCQH)amEa=jG7u?APe#((CEf#J`zJNkU3VL;L#n z|Ns930|Nj60RR90A^8LW0018VEC2ui01yBW000GR;3tk`DFSG!ngHj%E(VlsW#83< z%wugQH^ySY`}itATg1@_^f~12pt0oZMo?K>U0HxfI8%oZjE# + + + + + + + %DetailPaneFontDefinition.description + + @@ -96,6 +114,15 @@ + + + + @@ -1175,6 +1202,14 @@ super="org.eclipse.debug.core.breakpoint" name="org.eclipse.cdt.debug.core.breakpoint"> + + + + @@ -1183,6 +1218,38 @@ icon="icons/full/obj16/brkp_obj.gif" annotationType="org.eclipse.cdt.debug.core.breakpoint"> + + + + diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/ICDebugHelpContextIds.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/ICDebugHelpContextIds.java index df0ad8a4f2f..267da2a22b4 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/ICDebugHelpContextIds.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/ICDebugHelpContextIds.java @@ -37,15 +37,14 @@ public interface ICDebugHelpContextIds public static final String AUTO_REFRESH_REGISTERS_ACTION = PREFIX + "auto_refresh_registers_action_context"; //$NON-NLS-1$ // Views - public static final String REGISTERS_VIEW = PREFIX + "registers_view_context"; //$NON-NLS-1$ public static final String MEMORY_VIEW = PREFIX + "memory_view_context"; //$NON-NLS-1$ public static final String SHARED_LIBRARIES_VIEW = PREFIX + "shared_libraries_view_context"; //$NON-NLS-1$ public static final String SIGNALS_VIEW = PREFIX + "signals_view_context"; //$NON-NLS-1$ + public static final String DISASSEMBLY_VIEW = PREFIX + "disassembly_view_context"; //$NON-NLS-1$ // Preference pages public static final String SOURCE_PREFERENCE_PAGE = PREFIX + "source_preference_page_context"; //$NON-NLS-1$ public static final String SHARED_LIBRARIES_PREFERENCE_PAGE = PREFIX + "shared_libraries_preference_page_context"; //$NON-NLS-1$ public static final String MEMORY_PREFERENCE_PAGE = PREFIX + "memory_preference_page_context"; //$NON-NLS-1$ - public static final String REGISTERS_PREFERENCE_PAGE = PREFIX + "registers_preference_page_context"; //$NON-NLS-1$ public static final String C_DEBUG_PREFERENCE_PAGE = PREFIX + "c_debug_preference_page_context"; //$NON-NLS-1$ } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java new file mode 100644 index 00000000000..9c4b00ce753 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/IInternalCDebugUIConstants.java @@ -0,0 +1,35 @@ +/********************************************************************** + * 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.ui; + +public interface IInternalCDebugUIConstants { + + /** + * The name of the font to use for disassembly view. This font is managed via + * the workbench font preference page. + */ + public static final String DISASSEMBLY_FONT = "org.eclipse.cdt.debug.ui.DisassemblyFont"; //$NON-NLS-1$ + + //Current stack frame instruction pointer + public static final String DISASM_INSTRUCTION_POINTER = "org.eclipse.cdt.debug.ui.disassemblyInstructionPointer"; //$NON-NLS-1$ + + // marker types for instruction pointer annotations - top stack frame, and secondary + public static final String DISASM_INSTRUCTION_POINTER_CURRENT = "org.eclipse.cdt.debug.ui.disassemblyInstructionPointer.current"; //$NON-NLS-1$ + public static final String DISASM_INSTRUCTION_POINTER_SECONDARY = "org.eclipse.cdt.debug.ui.disassemblyInstructionPointer.secondary"; //$NON-NLS-1$ + + // annotation types for instruction pointers + public static final String ANN_DISASM_INSTR_POINTER_CURRENT = "org.eclipse.cdt.debug.ui.currentDisassemblyIP"; //$NON-NLS-1$ + public static final String ANN_DISASM_INSTR_POINTER_SECONDARY = "org.eclipse.cdt.debug.ui.secondaryDisassemblyIP"; //$NON-NLS-1$ + + // object images + public static final String IMG_OBJS_DISASM_INSTRUCTION_POINTER_TOP = "IMG_OBJS_DISASM_INSTRUCTION_POINTER_TOP"; //$NON-NLS-1$ + public static final String IMG_OBJS_DISASM_INSTRUCTION_POINTER = "IMG_OBJS_DISASM_INSTRUCTION_POINTER"; //$NON-NLS-1$ +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyDocumentProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyDocumentProvider.java new file mode 100644 index 00000000000..714b68d85b8 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyDocumentProvider.java @@ -0,0 +1,166 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.IElementStateListener; +import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel; + + +/** + * Document provider for disassembly view. + */ +public class DisassemblyDocumentProvider implements IDocumentProvider { + + private IDocument fDocument; + + private IAnnotationModel fAnnotationModel; + + /** + * Constructor for DisassemblyDocumentProvider. + */ + public DisassemblyDocumentProvider() { + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#connect(java.lang.Object) + */ + public void connect( Object element ) throws CoreException { + if ( element instanceof IDocument ) { + IAnnotationModel model = getAnnotationModel( null ); + model.connect( (IDocument)element ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#disconnect(java.lang.Object) + */ + public void disconnect( Object element ) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getDocument(java.lang.Object) + */ + public IDocument getDocument( Object element ) { + if ( fDocument == null ) { + fDocument = new Document(); + try { + connect( fDocument ); + } + catch( CoreException e ) { + fDocument = null; + } + } + return fDocument; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#resetDocument(java.lang.Object) + */ + public void resetDocument( Object element ) throws CoreException { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#saveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.jface.text.IDocument, boolean) + */ + public void saveDocument( IProgressMonitor monitor, Object element, IDocument document, boolean overwrite ) throws CoreException { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getModificationStamp(java.lang.Object) + */ + public long getModificationStamp( Object element ) { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getSynchronizationStamp(java.lang.Object) + */ + public long getSynchronizationStamp( Object element ) { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#isDeleted(java.lang.Object) + */ + public boolean isDeleted( Object element ) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#mustSaveDocument(java.lang.Object) + */ + public boolean mustSaveDocument( Object element ) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#canSaveDocument(java.lang.Object) + */ + public boolean canSaveDocument( Object element ) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#getAnnotationModel(java.lang.Object) + */ + public IAnnotationModel getAnnotationModel( Object element ) { + if ( fAnnotationModel == null ) { + fAnnotationModel = new ResourceMarkerAnnotationModel( ResourcesPlugin.getWorkspace().getRoot() ); + } + return fAnnotationModel; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#aboutToChange(java.lang.Object) + */ + public void aboutToChange( Object element ) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#changed(java.lang.Object) + */ + public void changed( Object element ) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#addElementStateListener(org.eclipse.ui.texteditor.IElementStateListener) + */ + public void addElementStateListener( IElementStateListener listener ) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.ui.texteditor.IDocumentProvider#removeElementStateListener(org.eclipse.ui.texteditor.IElementStateListener) + */ + public void removeElementStateListener( IElementStateListener listener ) { + // TODO Auto-generated method stub + } + + protected void dispose() { + } +} 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 new file mode 100644 index 00000000000..4569cf48e6d --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyEditorInput.java @@ -0,0 +1,220 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +import java.util.Arrays; + +import org.eclipse.cdt.debug.core.model.IAsmInstruction; +import org.eclipse.cdt.debug.core.model.ICStackFrame; +import org.eclipse.cdt.debug.core.model.IDisassembly; +import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * Editor input associated with a debug element. + */ +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 containsAddress( long address ) { + return (address >= fStartAddress && address <= fEndAddress); + } + + 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 static final IEditorInput EMPTY_EDITOR_INPUT = new DisassemblyEditorInput(); + + public static final IEditorInput PENDING_EDITOR_INPUT = + new DisassemblyEditorInput() { + public String getContents() { + return DisassemblyMessages.getString( "DisassemblyDocumentProvider.Pending_1" ); //$NON-NLS-1$ + } + }; + + /** + * Storage associated with this editor input + */ + private DisassemblyStorage fStorage; + + /** + * Constructor for DisassemblyEditorInput. + */ + protected DisassemblyEditorInput() { + } + + /** + * Constructor for DisassemblyEditorInput. + * + * @param disassembly + * @param instructions + */ + public DisassemblyEditorInput( IDisassembly disassembly, IAsmInstruction[] instructions ) { + fStorage = new DisassemblyStorage( disassembly, instructions ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#exists() + */ + public boolean exists() { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + public ImageDescriptor getImageDescriptor() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getName() + */ + public String getName() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getPersistable() + */ + public IPersistableElement getPersistable() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + public String getToolTipText() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter( Class adapter ) { + return null; + } + + public boolean contains( ICStackFrame frame ) { + if ( fStorage != null ) { + return fStorage.containsAddress( frame.getAddress() ); + } + return false; + } + + public String getContents() { + return ( fStorage != null ) ? fStorage.getContents() : ""; //$NON-NLS-1$ + } + + public int getLineNumber( long address ) { + return ( fStorage != null ) ? fStorage.getLineNumber( address ) : 0; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyInstructionPointerAnnotation.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyInstructionPointerAnnotation.java new file mode 100644 index 00000000000..3e3ba8d9c40 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyInstructionPointerAnnotation.java @@ -0,0 +1,97 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +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.IInternalCDebugUIConstants; +import org.eclipse.debug.core.DebugException; +import org.eclipse.jface.text.source.Annotation; + +/** + * An annotation for the vertical ruler in the disassembly view that shows one + * of two images for the current instruction pointer when debugging (one for + * the top stack frame, one for all others). + */ +public class DisassemblyInstructionPointerAnnotation extends Annotation { + + /** + * The frame for this instruction pointer annotation. This is necessary only so that + * instances of this class can be distinguished by equals(). + */ + private ICStackFrame fStackFrame; + + /** + * Construct an instruction pointer annotation for the given stack frame. + * + * @param stackFrame frame to create an instruction pointer annotation for + * @param isTopFrame whether the given frame is the top stack frame in its thread + */ + public DisassemblyInstructionPointerAnnotation( ICStackFrame stackFrame, boolean isTopFrame ) { + super( isTopFrame ? IInternalCDebugUIConstants.ANN_DISASM_INSTR_POINTER_CURRENT : IInternalCDebugUIConstants.ANN_DISASM_INSTR_POINTER_SECONDARY, + false, + isTopFrame ? DisassemblyMessages.getString( "DisassemblyInstructionPointerAnnotation.Current_Pointer_1" ) : DisassemblyMessages.getString( "DisassemblyInstructionPointerAnnotation.Secondary_Pointer_1" ) ); //$NON-NLS-1$ //$NON-NLS-2$ + fStackFrame = stackFrame; + } + + /** + * Returns the stack frame associated with this annotation + * + * @return the stack frame associated with this annotation + */ + public ICStackFrame getStackFrame() { + return fStackFrame; + } + + private IDisassembly getDisassembly( ICStackFrame frame ) { + if ( frame != null ) { + ICDebugTarget target = (ICDebugTarget)frame.getDebugTarget(); + try { + return target.getDisassembly(); + } + catch( DebugException e ) { + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals( Object other ) { + if ( other instanceof DisassemblyInstructionPointerAnnotation ) { + ICStackFrame otherFrame = ((DisassemblyInstructionPointerAnnotation)other).getStackFrame(); + IDisassembly otherDisassembly = getDisassembly( otherFrame ); + if ( otherDisassembly != null && otherDisassembly.equals( getDisassembly( getStackFrame() ) ) ) { + return ( otherFrame.getAddress() == getStackFrame().getAddress() ); + } + } + return false; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + int hashCode = 17; + ICStackFrame frame = getStackFrame(); + IDisassembly disassembly = getDisassembly( frame ); + hashCode = 37*hashCode + (( disassembly != null ) ? disassembly.hashCode() : 0); + if ( frame != null ) { + long address = frame.getAddress(); + hashCode = 37*hashCode + (int)(address^(address>>>32)); + } + return hashCode; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.java new file mode 100644 index 00000000000..e0e1474abd4 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.java @@ -0,0 +1,33 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class DisassemblyMessages { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.internal.ui.views.disassembly.DisassemblyMessages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME ); + + private DisassemblyMessages() { + } + + public static String getString( String key ) { + try { + return RESOURCE_BUNDLE.getString( key ); + } + catch( MissingResourceException e ) { + return '!' + key + '!'; + } + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..db2d54b3365 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyMessages.properties @@ -0,0 +1,3 @@ +DisassemblyDocumentProvider.Pending_1=Pending... +DisassemblyInstructionPointerAnnotation.Current_Pointer_1=Current Disassembly Instruction Pointer +DisassemblyInstructionPointerAnnotation.Secondary_Pointer_1=Secondary Disassembly Instruction Pointer 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 new file mode 100644 index 00000000000..61166369435 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyView.java @@ -0,0 +1,561 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +import java.util.Iterator; + +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.views.AbstractDebugEventHandler; +import org.eclipse.cdt.debug.internal.ui.views.AbstractDebugEventHandlerView; +import org.eclipse.cdt.debug.internal.ui.views.IDebugExceptionHandler; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ISharedTextColors; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.source.VerticalRuler; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.INullSelectionListener; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.internal.editors.text.EditorsPlugin; +import org.eclipse.ui.texteditor.AnnotationPreference; +import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess; +import org.eclipse.ui.texteditor.DefaultRangeIndicator; +import org.eclipse.ui.texteditor.ExtendedTextEditorPreferenceConstants; +import org.eclipse.ui.texteditor.MarkerAnnotationPreferences; +import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; + +/** + * This view shows disassembly for a particular stack frame. + */ +public class DisassemblyView extends AbstractDebugEventHandlerView + implements ISelectionListener, + INullSelectionListener, + IPropertyChangeListener, + IDebugExceptionHandler, + IDisassemblyListener { + + /** + * The width of the vertical ruler. + */ + private final static int VERTICAL_RULER_WIDTH = 12; + + /** + * Preference key for highlighting current line. + */ + private final static String CURRENT_LINE = ExtendedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE; + + /** + * Preference key for highlight color of current line. + */ + private final static String CURRENT_LINE_COLOR = ExtendedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR; + + /** + * The vertical ruler. + */ + private IVerticalRuler fVerticalRuler; + + /** + * The last stack frame for which the disassembly storage has + * been requested. + */ + protected ICStackFrame fLastStackFrame = null; + + /** + * Helper for managing the decoration support of this view's viewer. + */ + private SourceViewerDecorationSupport fSourceViewerDecorationSupport; + + /** + * Helper for accessing annotation from the perspective of this view. + */ + private IAnnotationAccess fAnnotationAccess; + + /** + * The annotation preferences. + */ + private MarkerAnnotationPreferences fAnnotationPreferences; + + /** + * Disassembly document provider. + */ + private DisassemblyDocumentProvider fDocumentProvider; + + /** + * Current instruction pointer nnotation. + */ + private DisassemblyInstructionPointerAnnotation fInstrPointerAnnotation; + + /** + * Constructor for DisassemblyView. + */ + public DisassemblyView() { + super(); + fAnnotationPreferences = new MarkerAnnotationPreferences(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite) + */ + protected Viewer createViewer( Composite parent ) { + fVerticalRuler = createVerticalRuler(); + + SourceViewer viewer = createSourceViewer( parent, fVerticalRuler ); + getSourceViewerDecorationSupport( viewer ); + + EditorsPlugin.getDefault().getPreferenceStore().addPropertyChangeListener( this ); + CDebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener( this ); + + getSite().getPage().addSelectionListener( IDebugUIConstants.ID_DEBUG_VIEW, this ); + setEventHandler( createEventHandler() ); + + viewer.setDocument( getDocumentProvider().getDocument( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ), getDocumentProvider().getAnnotationModel( null ) ); + + resetViewerInput(); + + return viewer; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.AbstractDebugView#createActions() + */ + protected void createActions() { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.AbstractDebugView#getHelpContextId() + */ + protected String getHelpContextId() { + return ICDebugHelpContextIds.DISASSEMBLY_VIEW; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.AbstractDebugView#fillContextMenu(org.eclipse.jface.action.IMenuManager) + */ + protected void fillContextMenu( IMenuManager menu ) { + menu.add( new Separator( IWorkbenchActionConstants.MB_ADDITIONS ) ); + updateObjects(); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.ui.AbstractDebugView#configureToolBar(org.eclipse.jface.action.IToolBarManager) + */ + protected void configureToolBar( IToolBarManager tbm ) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged( IWorkbenchPart part, ISelection selection ) { + if ( !isAvailable() || !isVisible() ) + return; + if ( selection == null ) + resetViewerInput(); + else if ( selection instanceof IStructuredSelection ) + computeInput( (IStructuredSelection)selection ); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange( PropertyChangeEvent event ) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.views.IDebugExceptionHandler#handleException(org.eclipse.debug.core.DebugException) + */ + public void handleException( DebugException e ) { + showMessage( e.getMessage() ); + } + + /** + * Creates the vertical ruler to be used by this view. + * + * @return the vertical ruler + */ + private IVerticalRuler createVerticalRuler() { + return new VerticalRuler( VERTICAL_RULER_WIDTH, getAnnotationAccess() ); + } + + /** + * Creates the source viewer to be used by this view. + * + * @param parent the parent control + * @param ruler the vertical ruler + * @param styles style bits + * @return the source viewer + */ + private SourceViewer createSourceViewer( Composite parent, IVerticalRuler ruler ) { + DisassemblyViewer viewer = new DisassemblyViewer( parent, ruler ); + viewer.setRangeIndicator( new DefaultRangeIndicator() ); + return viewer; + } + + protected SourceViewer getSourceViewer() { + return (SourceViewer)getViewer(); + } + + /** + * Creates this view's event handler. + * + * @return an event handler + */ + protected AbstractDebugEventHandler createEventHandler() { + return new DisassemblyViewEventHandler( this ); + } + + protected void computeInput( IStructuredSelection ssel ) { + SourceViewer viewer = getSourceViewer(); + if ( viewer == null ) + return; + + fLastStackFrame = null; + if ( ssel != null && ssel.size() == 1 ) { + Object element = ssel.getFirstElement(); + if ( element instanceof ICStackFrame ) { + fLastStackFrame = (ICStackFrame)element; + IEditorInput input = getInput(); + if ( input instanceof DisassemblyEditorInput && + !((DisassemblyEditorInput)input).contains( (ICStackFrame)element ) ) + setViewerInput( DisassemblyEditorInput.PENDING_EDITOR_INPUT ); + computeInput( input, (ICStackFrame)element, this ); + return; + } + } + resetViewerInput(); + } + + protected void setViewerInput( IEditorInput input ) { + SourceViewer viewer = getSourceViewer(); + if ( viewer == null ) + return; + + if ( input == null ) + input = DisassemblyEditorInput.EMPTY_EDITOR_INPUT; + + IEditorInput current = getInput(); + if ( current != null && current.equals( input ) ) { + updateObjects(); + return; + } + + setInput( input ); + + showViewer(); + IDocument document = viewer.getDocument(); + String contents = ((DisassemblyEditorInput)input).getContents(); + document.set( contents ); + + updateObjects(); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPart#dispose() + */ + public void dispose() { + getSite().getPage().removeSelectionListener( IDebugUIConstants.ID_DEBUG_VIEW, this ); + EditorsPlugin.getDefault().getPreferenceStore().removePropertyChangeListener( this ); + CDebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener( this ); + + if ( fSourceViewerDecorationSupport != null ) { + fSourceViewerDecorationSupport.dispose(); + fSourceViewerDecorationSupport = null; + } + + if ( fDocumentProvider != null ) { + fDocumentProvider.dispose(); + } + super.dispose(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.views.disassembly.IDisassemblyListener#inputComputed(org.eclipse.cdt.debug.core.model.ICStackFrame, org.eclipse.core.runtime.IStatus, org.eclipse.ui.IEditorInput) + */ + public void inputComputed( final ICStackFrame frame, final IStatus status, final IEditorInput input ) { + Runnable runnable = new Runnable() { + public void run() { + if ( isAvailable() ) { + if ( fLastStackFrame != null && fLastStackFrame.equals( frame ) ) { + fLastStackFrame = null; + if ( !status.isOK() ) { + setInput( null ); + getViewer().setInput( null ); + showMessage( status.getMessage() ); + return; + } + } + if ( input != null ) { + setViewerInput( input ); + selectAndReveal( frame, input ); + } + else { + resetViewerInput(); + } + } + } + }; + asyncExec( runnable ); + } + + /** + * Asynchronousy computes the editor input for the given stack frame. + * + * @param current the current editor input + * @param frame the stack frame for which the input is required + * @param listener the listener to be notified when the computation is completed + */ + public void computeInput( final Object current, + final ICStackFrame frame, + final IDisassemblyListener listener ) { + Runnable runnable = new Runnable() { + public void run() { + IStatus status = Status.OK_STATUS; + IEditorInput input = null; + if ( current instanceof DisassemblyEditorInput && + ((DisassemblyEditorInput)current).contains( frame ) ) { + 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 ); + } + } + catch( DebugException e ) { + status = new Status( IStatus.ERROR, + CDebugUIPlugin.getUniqueIdentifier(), + 0, + e.getMessage(), + null ); + } + + } + listener.inputComputed( frame, status, input ); + } + }; + DebugPlugin.getDefault().asyncExec( runnable ); + } + + protected void selectAndReveal( ICStackFrame frame, IEditorInput input ) { + long address = frame.getAddress(); + IRegion region = getLineInformation( address, input ); + if ( region != null ) { + int start = region.getOffset(); + int length = region.getLength(); + StyledText widget = getSourceViewer().getTextWidget(); + widget.setRedraw( false ); + { + getSourceViewer().revealRange( start, length ); + getSourceViewer().setSelectedRange( start, 0 ); + } + widget.setRedraw( true ); + setInstructionPointer( frame, start, length ); + } + } + + /** + * Returns the line information for the given line in the given editor + */ + private IRegion getLineInformation( long address, IEditorInput input ) { + if ( input instanceof DisassemblyEditorInput ) { + int line = ((DisassemblyEditorInput)input).getLineNumber( address ); + if ( line > 0 ) { + try { + return getSourceViewer().getDocument().getLineInformation( --line ); + } + catch( BadLocationException e1 ) { + } + } + } + return null; + } + + protected IEditorInput getInput() { + if ( getSourceViewer() != null ) { + Object input = getSourceViewer().getInput(); + if ( input instanceof IEditorInput ) + return (IEditorInput)input; + } + return null; + } + + protected void setInput( IEditorInput input ) { + getSourceViewer().setInput( input ); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + public void createPartControl( Composite parent ) { + super.createPartControl( parent ); + if ( fSourceViewerDecorationSupport != null ) + fSourceViewerDecorationSupport.install( getEditorPreferenceStore() ); + } + + /** + * Returns the source viewer decoration support. + * + * @return the source viewer decoration support + */ + protected SourceViewerDecorationSupport getSourceViewerDecorationSupport( ISourceViewer viewer ) { + if ( fSourceViewerDecorationSupport == null ) { + fSourceViewerDecorationSupport = new SourceViewerDecorationSupport( viewer, null, getAnnotationAccess(), getSharedColors() ); + configureSourceViewerDecorationSupport( fSourceViewerDecorationSupport ); + } + return fSourceViewerDecorationSupport; + } + + /** + * Creates the annotation access for this view. + * + * @return the created annotation access + */ + private IAnnotationAccess createAnnotationAccess() { + return new DefaultMarkerAnnotationAccess(); + } + + /** + * Configures the decoration support for this view's the source viewer. + */ + private void configureSourceViewerDecorationSupport( SourceViewerDecorationSupport support ) { + Iterator e = fAnnotationPreferences.getAnnotationPreferences().iterator(); + while( e.hasNext() ) + support.setAnnotationPreference( (AnnotationPreference)e.next() ); + support.setCursorLinePainterPreferenceKeys( CURRENT_LINE, CURRENT_LINE_COLOR ); + } + + /** + * Returns the annotation access. + * + * @return the annotation access + */ + private IAnnotationAccess getAnnotationAccess() { + if ( fAnnotationAccess == null ) + fAnnotationAccess = createAnnotationAccess(); + return fAnnotationAccess; + } + + private ISharedTextColors getSharedColors() { + ISharedTextColors sharedColors= EditorsPlugin.getDefault().getSharedTextColors(); + return sharedColors; + } + + private IPreferenceStore getEditorPreferenceStore() { + return EditorsPlugin.getDefault().getPreferenceStore(); + } + + protected DisassemblyDocumentProvider getDocumentProvider() { + if ( this.fDocumentProvider == null ) + this.fDocumentProvider = new DisassemblyDocumentProvider(); + return this.fDocumentProvider; + } + + protected void setInstructionPointer( ICStackFrame frame, int start, int length ) { + boolean tos = isTopStackFrame( frame ); + DisassemblyInstructionPointerAnnotation instPtrAnnotation = new DisassemblyInstructionPointerAnnotation( frame, tos ); + + Position position = new Position( start, length ); + + // Add the annotation at the position to the editor's annotation model. + // If there is no annotation model, there's nothing more to do + IAnnotationModel annModel = getDocumentProvider().getAnnotationModel( null ); + if ( annModel == null ) { + return; + } + DisassemblyInstructionPointerAnnotation currentPointer = getCurrentInstructionPointer(); + if ( currentPointer != null ) + removeCurrentInstructionPointer(); + annModel.addAnnotation( instPtrAnnotation, position ); + setCurrentInstructionPointer( instPtrAnnotation ); + } + + private boolean isTopStackFrame( ICStackFrame stackFrame ) { + IThread thread = stackFrame.getThread(); + boolean tos = false; + try { + tos = stackFrame.equals( thread.getTopStackFrame() ); + } + catch( DebugException e ) { + } + return tos; + } + + private DisassemblyInstructionPointerAnnotation getCurrentInstructionPointer() { + return fInstrPointerAnnotation; + } + + private void setCurrentInstructionPointer( DisassemblyInstructionPointerAnnotation instrPointer ) { + fInstrPointerAnnotation = instrPointer; + } + + protected void removeCurrentInstructionPointer() { + DisassemblyInstructionPointerAnnotation instrPointer = getCurrentInstructionPointer(); + if ( instrPointer != null ) { + IAnnotationModel annModel = getDocumentProvider().getAnnotationModel( null ); + if ( annModel != null ) { + annModel.removeAnnotation( instrPointer ); + setCurrentInstructionPointer( null ); + } + } + } + + protected void resetViewerInput() { + SourceViewer viewer = getSourceViewer(); + if ( viewer == null ) + return; + + IEditorInput input = DisassemblyEditorInput.EMPTY_EDITOR_INPUT; + setInput( input ); + + showViewer(); + IDocument document = getSourceViewer().getDocument(); + String contents = ((DisassemblyEditorInput)input).getContents(); + document.set( contents ); + removeCurrentInstructionPointer(); + + updateObjects(); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewEventHandler.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewEventHandler.java new file mode 100644 index 00000000000..731dbf62f99 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewEventHandler.java @@ -0,0 +1,76 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +import org.eclipse.cdt.debug.internal.ui.views.AbstractDebugEventHandler; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.ui.AbstractDebugView; + + +/** + * Updates the disassembly view. + */ +public class DisassemblyViewEventHandler extends AbstractDebugEventHandler { + + /** + * Constructor for DisassemblyViewEventHandler. + * + * @param view + */ + public DisassemblyViewEventHandler( AbstractDebugView view ) { + super( view ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.views.AbstractDebugEventHandler#doHandleDebugEvents(org.eclipse.debug.core.DebugEvent[]) + */ + protected void doHandleDebugEvents( DebugEvent[] events ) { + for ( int i = 0; i < events.length; i++ ) { + DebugEvent event = events[i]; + switch( event.getKind() ) { + case DebugEvent.TERMINATE: + handleTerminateEvent( events[i] ); + break; + case DebugEvent.SUSPEND: + handleSuspendEvent( events[i] ); + break; + case DebugEvent.RESUME: + handleResumeEvent( events[i] ); + break; + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.views.AbstractDebugEventHandler#refresh() + */ + public void refresh() { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.internal.ui.views.AbstractDebugEventHandler#refresh(java.lang.Object) + */ + protected void refresh( Object element ) { + } + + private void handleTerminateEvent( DebugEvent event ) { + } + + private void handleResumeEvent( DebugEvent event ) { + } + + private void handleSuspendEvent( DebugEvent event ) { + } + + protected DisassemblyView getDisassemblyView() { + return (DisassemblyView)getView(); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewer.java new file mode 100644 index 00000000000..1ea899dee06 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/DisassemblyViewer.java @@ -0,0 +1,59 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; + +/** + * The disassembly viewer. + */ +public class DisassemblyViewer extends SourceViewer { + + /** + * The current input. + */ + private Object fInput; + + /** + * Constructor for DisassemblyViewer. + * + * @param parent + * @param ruler + * @param styles + */ + public DisassemblyViewer( Composite parent, IVerticalRuler ruler ) { + super( parent, ruler, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION ); + getTextWidget().setFont( JFaceResources.getFont( IInternalCDebugUIConstants.DISASSEMBLY_FONT ) ); + setEditable( false ); + GridData gd = new GridData( GridData.FILL_BOTH ); + getControl().setLayoutData( gd ); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IInputProvider#getInput() + */ + public Object getInput() { + return fInput; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.Viewer#setInput(java.lang.Object) + */ + public void setInput( Object input ) { + fInput = input; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/IDisassemblyListener.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/IDisassemblyListener.java new file mode 100644 index 00000000000..59989c16b30 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/disassembly/IDisassemblyListener.java @@ -0,0 +1,32 @@ +/********************************************************************** + * 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.ui.views.disassembly; + +import org.eclipse.cdt.debug.core.model.ICStackFrame; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.ui.IEditorInput; + +/** + * A disassembly listener is notified when the storage + * retrieval operation for given stack frame is completed. + */ +public interface IDisassemblyListener { + + /** + * Notifies this listener that the input is computed. + * + * @param frame the stack frame. + * @param status the result status. + * @param input the resulting editor input. + * null if status is not OK. + */ + public void inputComputed( ICStackFrame frame, IStatus status, IEditorInput input ); +}