1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Implementation of mixed disassembly mode.

This commit is contained in:
Mikhail Khodjaiants 2004-05-06 22:03:25 +00:00
parent 8ca7329e88
commit a19d23361a
13 changed files with 553 additions and 260 deletions

View file

@ -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 2004-04-30 Mikhail Khodjaiants
New copyright. New copyright.
* IJumpToAddress.java * IJumpToAddress.java

View file

@ -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();
}

View file

@ -16,26 +16,13 @@ import org.eclipse.debug.core.DebugException;
* Represents the disassembly of a debug target. * Represents the disassembly of a debug target.
*/ */
public interface IDisassembly extends ICDebugElement { 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. * Returns the disassembly block for given stack frame.
* The size of the requested list is specified by <code>length</code>.
* *
* @param address the start address * @param frame the stack frame for which the disassembly is required
* @param length the size of the requested list * @return the disassembly block for given stack frame
* @return the specified list of disassembly instructions
* @throws DebugException if this method fails. * @throws DebugException if this method fails.
*/ */
public IAsmInstruction[] getInstructions( long address, int length ) throws DebugException; IDisassemblyBlock getDisassemblyBlock( ICStackFrame frame ) throws DebugException;
} }

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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.ICDISession;
import org.eclipse.cdt.debug.core.cdi.ICDISourceManager; import org.eclipse.cdt.debug.core.cdi.ICDISourceManager;
import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction; 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.ICStackFrame;
import org.eclipse.cdt.debug.core.model.IDisassembly; 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.model.IExecFileInfo;
import org.eclipse.debug.core.DebugException; 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; final static private int DISASSEMBLY_BLOCK_SIZE = 100;
private IAsmInstruction[] fInstructions = new IAsmInstruction[0]; private DisassemblyBlock[] fBlocks = new DisassemblyBlock[1];
/** /**
* Constructor for Disassembly. * Constructor for Disassembly.
@ -43,85 +44,63 @@ public class Disassembly extends CDebugElement implements IDisassembly {
} }
/* (non-Javadoc) /* (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 { public IDisassemblyBlock getDisassemblyBlock( ICStackFrame frame ) throws DebugException {
long address = frame.getAddress(); if ( fBlocks[0] == null || !fBlocks[0].contains( frame ) ) {
if ( !containsAddress( address ) ) { fBlocks[0] = createBlock( frame );
loadInstructions( frame );
} }
return fInstructions; return fBlocks[0];
} }
/* (non-Javadoc) private DisassemblyBlock createBlock( ICStackFrame frame ) throws DebugException {
* @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 ); ICDISession session = (ICDISession)getDebugTarget().getAdapter( ICDISession.class );
if ( session != null ) { if ( session != null ) {
ICDISourceManager sm = session.getSourceManager(); ICDISourceManager sm = session.getSourceManager();
if ( sm != null ) { if ( sm != null ) {
String fileName = frame.getFile(); String fileName = frame.getFile();
int lineNumber = frame.getLineNumber(); int lineNumber = frame.getLineNumber();
ICDIInstruction[] instructions = new ICDIInstruction[0]; ICDIMixedInstruction[] mixedInstrs = new ICDIMixedInstruction[0];
long address = frame.getAddress(); long address = frame.getAddress();
if ( fileName != null && fileName.length() > 0 ) { if ( fileName != null && fileName.length() > 0 ) {
try { try {
instructions = sm.getInstructions( fileName, mixedInstrs = sm.getMixedInstructions( fileName,
lineNumber, lineNumber,
CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS ) ); CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_MAX_NUMBER_OF_INSTRUCTIONS ) );
} }
catch( CDIException e ) { catch( CDIException e ) {
targetRequestFailed( CoreModelMessages.getString( "Disassembly.Unable_to_get_disassembly_instructions_1" ), e ); //$NON-NLS-1$ 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. // Double check if debugger returns correct address range.
!containsAddress( instructions, address ) ) { !containsAddress( mixedInstrs, address ) ) {
if ( address >= 0 ) { if ( address >= 0 ) {
try { 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 ) { catch( CDIException e ) {
targetRequestFailed( CoreModelMessages.getString( "Disassembly.Unable_to_get_disassembly_instructions_2" ), e ); //$NON-NLS-1$ targetRequestFailed( CoreModelMessages.getString( "Disassembly.Unable_to_get_disassembly_instructions_2" ), e ); //$NON-NLS-1$
} }
} }
} }
fInstructions = new IAsmInstruction[instructions.length]; else {
for ( int i = 0; i < fInstructions.length; ++i ) { return DisassemblyBlock.create( this, mixedInstrs );
fInstructions[i] = new AsmInstruction( instructions[i] );
} }
} }
} }
return null;
} }
private void loadInstructions( long address, int length ) throws DebugException { private boolean containsAddress( ICDIMixedInstruction[] mi, long address ) {
fInstructions = new IAsmInstruction[0]; 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 ) { private ICDIInstruction[] getFunctionInstructions( ICDIInstruction[] rawInstructions ) {
@ -139,7 +118,11 @@ public class Disassembly extends CDebugElement implements IDisassembly {
} }
public void dispose() { 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) /* (non-Javadoc)

View file

@ -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 <code>IDisassemblyBlock</code>.
*/
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;
}
}

View file

@ -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 2004-05-02 Mikhail Khodjaiants
Check if the new stack frame is of the same debug target as the old one. Check if the new stack frame is of the same debug target as the old one.
* DisassemblyEditorInput.java * DisassemblyEditorInput.java

View file

@ -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.internal.ui.views.disassembly.DisassemblyView;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin; import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.cdt.debug.ui.ICDebugUIConstants; import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.ResourcesPlugin;
@ -109,20 +108,25 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget {
IResource resource = ResourcesPlugin.getWorkspace().getRoot(); IResource resource = ResourcesPlugin.getWorkspace().getRoot();
String sourceHandle = getSourceHandle( input ); String sourceHandle = getSourceHandle( input );
long address = ((DisassemblyEditorInput)input).getAddress( lineNumber ); long address = ((DisassemblyEditorInput)input).getAddress( lineNumber );
ICAddressBreakpoint breakpoint = CDIDebugModel.addressBreakpointExists( sourceHandle, resource, address ); if ( address != 0 ) {
if ( breakpoint != null ) { ICAddressBreakpoint breakpoint = CDIDebugModel.addressBreakpointExists( sourceHandle, resource, address );
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint( breakpoint, true ); if ( breakpoint != null ) {
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint( breakpoint, true );
}
else {
CDIDebugModel.createAddressBreakpoint( sourceHandle,
resource,
address,
true,
0,
"", //$NON-NLS-1$
true );
}
return;
} }
else { else {
CDIDebugModel.createAddressBreakpoint( sourceHandle, errorMessage = ActionMessages.getString( "ToggleBreakpointAdapter.Invalid_line_1" ); //$NON-NLS-1$
resource,
address,
true,
0,
"", //$NON-NLS-1$
true );
} }
return;
} }
} }
} }
@ -141,7 +145,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget {
if ( !(input instanceof DisassemblyEditorInput) || if ( !(input instanceof DisassemblyEditorInput) ||
((DisassemblyEditorInput)input).equals( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ) ) { ((DisassemblyEditorInput)input).equals( DisassemblyEditorInput.EMPTY_EDITOR_INPUT ) ) {
return false; return false;
} }
} }
return ( selection instanceof ITextSelection ); return ( selection instanceof ITextSelection );
} }
@ -258,8 +262,7 @@ public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget {
return ((IStorageEditorInput)input).getStorage().getName(); return ((IStorageEditorInput)input).getStorage().getName();
} }
if ( input instanceof DisassemblyEditorInput ) { if ( input instanceof DisassemblyEditorInput ) {
IFile file = ((DisassemblyEditorInput)input).getModuleFile(); return ((DisassemblyEditorInput)input).getModuleFile();
return ( file != null ) ? file.getLocation().toOSString() : ""; //$NON-NLS-1$
} }
return ""; //$NON-NLS-1$ return ""; //$NON-NLS-1$
} }

View file

@ -137,10 +137,9 @@ public class DisassemblyAnnotationModel extends AnnotationModel {
Position position = null; Position position = null;
DisassemblyEditorInput input = getInput(); DisassemblyEditorInput input = getInput();
if ( input != null ) { if ( input != null ) {
long address = input.getBreakpointAddress( breakpoint );
int start = -1; int start = -1;
if ( address > 0 && document != null ) { if ( document != null ) {
int instrNumber = input.getInstructionNumber( address ); int instrNumber = input.getInstructionLine( breakpoint );
if ( instrNumber > 0 ) { if ( instrNumber > 0 ) {
try { try {
start = fDocument.getLineOffset( instrNumber - 1 ); start = fDocument.getLineOffset( instrNumber - 1 );

View file

@ -13,13 +13,14 @@ package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import java.util.Arrays; import java.util.Arrays;
import org.eclipse.cdt.debug.core.model.IAsmInstruction; 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.IBreakpointTarget;
import org.eclipse.cdt.debug.core.model.ICDebugTarget;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.core.model.ICStackFrame; import org.eclipse.cdt.debug.core.model.ICStackFrame;
import org.eclipse.cdt.debug.core.model.IDisassembly; 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.cdt.debug.internal.ui.CDebugUIUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugException;
import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorInput;
@ -30,148 +31,6 @@ import org.eclipse.ui.IPersistableElement;
*/ */
public class DisassemblyEditorInput implements IEditorInput { 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 EMPTY_EDITOR_INPUT = new DisassemblyEditorInput();
public static final IEditorInput PENDING_EDITOR_INPUT = 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. * Constructor for DisassemblyEditorInput.
@ -198,8 +59,9 @@ public class DisassemblyEditorInput implements IEditorInput {
* @param disassembly * @param disassembly
* @param instructions * @param instructions
*/ */
public DisassemblyEditorInput( IDisassembly disassembly, IAsmInstruction[] instructions ) { private DisassemblyEditorInput( IDisassemblyBlock block ) {
fStorage = new DisassemblyStorage( disassembly, instructions ); fBlock = block;
createContents();
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -245,29 +107,158 @@ public class DisassemblyEditorInput implements IEditorInput {
} }
public boolean contains( ICStackFrame frame ) { public boolean contains( ICStackFrame frame ) {
if ( fStorage != null ) { if ( fBlock != null ) {
return fStorage.containsFrame( frame ); return fBlock.contains( frame );
} }
return false; return false;
} }
public String getContents() { public String getContents() {
return ( fStorage != null ) ? fStorage.getContents() : ""; //$NON-NLS-1$ return fContents;
} }
public int getInstructionNumber( long address ) { public int getInstructionLine( long address ) {
return ( fStorage != null ) ? fStorage.getLineNumber( address ) : 0; 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 { public int getInstructionLine( ICLineBreakpoint breakpoint ) {
return ( fStorage != null ) ? fStorage.getAddress( lineNumber ) : 0; 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() { public long getAddress( int lineNumber ) {
return ( fStorage != null ) ? fStorage.getModuleFile() : null; 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 ) { public String getModuleFile() {
return ( fStorage != null ) ? fStorage.getBreakpointAddress( breakpoint ) : 0; 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;
} }
} }

View file

@ -4,3 +4,4 @@ DisassemblyInstructionPointerAnnotation.Secondary_Pointer_1=Secondary Disassembl
DisassemblyAnnotationHover.Multiple_markers_at_this_line_1=Multiple markers at this line DisassemblyAnnotationHover.Multiple_markers_at_this_line_1=Multiple markers at this line
HTMLTextPresenter.ellipsis= HTMLTextPresenter.ellipsis=
HTML2TextReader.dash=- HTML2TextReader.dash=-
DisassemblyEditorInput.source_line_is_not_available_1=<source line is not available>

View file

@ -10,14 +10,11 @@
***********************************************************************/ ***********************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.disassembly; package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; 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.ICStackFrame;
import org.eclipse.cdt.debug.core.model.IDisassembly;
import org.eclipse.cdt.debug.internal.ui.ICDebugHelpContextIds; import org.eclipse.cdt.debug.internal.ui.ICDebugHelpContextIds;
import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants;
import org.eclipse.cdt.debug.internal.ui.actions.CBreakpointPropertiesRulerAction; import org.eclipse.cdt.debug.internal.ui.actions.CBreakpointPropertiesRulerAction;
@ -529,13 +526,8 @@ public class DisassemblyView extends AbstractDebugEventHandlerView
input = (IEditorInput)current; input = (IEditorInput)current;
} }
else { else {
IAsmInstruction[] instructions = new IAsmInstruction[0];
try { try {
IDisassembly disassembly = ((ICDebugTarget)frame.getDebugTarget()).getDisassembly(); input = DisassemblyEditorInput.create( frame );
if ( disassembly != null ) {
instructions = disassembly.getInstructions( frame );
input = new DisassemblyEditorInput( disassembly, instructions );
}
} }
catch( DebugException e ) { catch( DebugException e ) {
status = new Status( IStatus.ERROR, status = new Status( IStatus.ERROR,
@ -553,8 +545,7 @@ public class DisassemblyView extends AbstractDebugEventHandlerView
} }
protected void selectAndReveal( ICStackFrame frame, IEditorInput input ) { protected void selectAndReveal( ICStackFrame frame, IEditorInput input ) {
long address = frame.getAddress(); IRegion region = getLineInformation( frame, input );
IRegion region = getLineInformation( address, input );
if ( region != null ) { if ( region != null ) {
int start = region.getOffset(); int start = region.getOffset();
int length = region.getLength(); 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 * 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 ) { if ( input instanceof DisassemblyEditorInput ) {
int line = ((DisassemblyEditorInput)input).getInstructionNumber( address ); int line = ((DisassemblyEditorInput)input).getInstructionLine( frame.getAddress() );
if ( line > 0 ) { if ( line > 0 ) {
try { try {
return getSourceViewer().getDocument().getLineInformation( --line ); return getSourceViewer().getDocument().getLineInformation( --line );
@ -703,8 +694,8 @@ public class DisassemblyView extends AbstractDebugEventHandlerView
Assert.isNotNull( model ); Assert.isNotNull( model );
DisassemblyInstructionPointerAnnotation instrPointer = getCurrentInstructionPointer(); DisassemblyInstructionPointerAnnotation instrPointer = getCurrentInstructionPointer();
if ( instrPointer != null ) { if ( instrPointer != null ) {
model.removeAnnotation( instrPointer ); model.removeAnnotation( instrPointer );
setCurrentInstructionPointer( null ); setCurrentInstructionPointer( null );
} }
} }