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
New copyright.
* 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.
*/
public interface IDisassembly extends ICDebugElement {
/**
* Returns the list of disassembly instructions associated
* with the given stack frame.
*
* @param frame the stack frame for which the instructions re required.
* @return the list of disassembly instructions associated with
* the given stack frame
* @throws DebugException if this method fails.
*/
public IAsmInstruction[] getInstructions( ICStackFrame frame ) throws DebugException;
/**
* Returns the list of disassembly instructions that begins at the given address.
* The size of the requested list is specified by <code>length</code>.
* Returns the disassembly block for given stack frame.
*
* @param address the start address
* @param length the size of the requested list
* @return the specified list of disassembly instructions
* @param frame the stack frame for which the disassembly is required
* @return the disassembly block for given stack frame
* @throws DebugException if this method fails.
*/
public IAsmInstruction[] getInstructions( long address, int length ) throws DebugException;
IDisassemblyBlock getDisassemblyBlock( ICStackFrame frame ) throws DebugException;
}

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

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

View file

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

View file

@ -13,13 +13,14 @@ package org.eclipse.cdt.debug.internal.ui.views.disassembly;
import java.util.Arrays;
import org.eclipse.cdt.debug.core.model.IAsmInstruction;
import org.eclipse.cdt.debug.core.model.IAsmSourceLine;
import org.eclipse.cdt.debug.core.model.IBreakpointTarget;
import org.eclipse.cdt.debug.core.model.ICDebugTarget;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.core.model.ICStackFrame;
import org.eclipse.cdt.debug.core.model.IDisassembly;
import org.eclipse.cdt.debug.core.model.IExecFileInfo;
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.debug.core.DebugException;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorInput;
@ -30,148 +31,6 @@ import org.eclipse.ui.IPersistableElement;
*/
public class DisassemblyEditorInput implements IEditorInput {
/**
* A storage object used by Disassembly view.
*/
private static class DisassemblyStorage {
private IDisassembly fDisassembly;
private IAsmInstruction[] fInstructions;
protected String fContents;
protected long fStartAddress = 0;
protected long fEndAddress = 0;
/**
* Constructor for DisassemblyStorage.
*/
public DisassemblyStorage( IDisassembly disassembly, IAsmInstruction[] instructions ) {
fDisassembly = disassembly;
fInstructions = ( instructions != null ) ? instructions : new IAsmInstruction[0];
initializeAddresses();
createContent();
}
public String getContents() {
return fContents;
}
public IDisassembly getDisassembly() {
return this.fDisassembly;
}
public boolean containsFrame( ICStackFrame frame ) {
if ( !getDisassembly().getDebugTarget().equals( frame.getDebugTarget() ) )
return false;
long address = frame.getAddress();
return (address >= fStartAddress && address <= fEndAddress);
}
public IFile getModuleFile() {
IDisassembly d = getDisassembly();
IFile result = null;
if ( d != null ) {
IExecFileInfo info = (IExecFileInfo)d.getAdapter( IExecFileInfo.class );
if ( info != null ) {
result = info.getExecFile();
}
}
return result;
}
public long getBreakpointAddress( ICLineBreakpoint breakpoint ) {
IDisassembly dis = getDisassembly();
if ( dis != null ) {
IBreakpointTarget bt = (IBreakpointTarget)dis.getDebugTarget().getAdapter( IBreakpointTarget.class );
if ( bt != null ) {
try {
return bt.getBreakpointAddress( breakpoint );
}
catch( DebugException e ) {
}
}
}
return 0;
}
private void createContent() {
StringBuffer lines = new StringBuffer();
int maxFunctionName = 0;
int maxOpcodeLength = 0;
long maxOffset = 0;
for( int i = 0; i < fInstructions.length; ++i ) {
String functionName = fInstructions[i].getFunctionName();
if ( functionName.length() > maxFunctionName ) {
maxFunctionName = functionName.length();
}
String opcode = fInstructions[i].getOpcode();
if ( opcode.length() > maxOpcodeLength )
maxOpcodeLength = opcode.length();
if ( fInstructions[i].getOffset() > maxOffset ) {
maxOffset = fInstructions[i].getOffset();
}
}
int instrPos = calculateInstructionPosition( maxFunctionName, maxOffset );
int argPosition = instrPos + maxOpcodeLength + 1;
for( int i = 0; i < fInstructions.length; ++i ) {
lines.append( getInstructionString( fInstructions[i], instrPos, argPosition ) );
}
fContents = lines.toString();
}
private String getInstructionString( IAsmInstruction instruction, int instrPosition, int argPosition ) {
int worstCaseSpace = Math.max( instrPosition, argPosition );
char[] spaces = new char[worstCaseSpace];
Arrays.fill( spaces, ' ' );
StringBuffer sb = new StringBuffer();
if ( instruction != null ) {
sb.append( CDebugUIUtils.toHexAddressString( instruction.getAdress() ) );
sb.append( ' ' );
String functionName = instruction.getFunctionName();
if ( functionName != null && functionName.length() > 0 ) {
sb.append( '<' );
sb.append( functionName );
if ( instruction.getOffset() != 0 ) {
sb.append( '+' );
sb.append( instruction.getOffset() );
}
sb.append( ">:" ); //$NON-NLS-1$
sb.append( spaces, 0, instrPosition - sb.length() );
}
sb.append( instruction.getOpcode() );
sb.append( spaces, 0, argPosition - sb.length() );
sb.append( instruction.getArguments() );
sb.append( '\n' );
}
return sb.toString();
}
private int calculateInstructionPosition( int maxFunctionName, long maxOffset ) {
return (16 + maxFunctionName + Long.toString( maxOffset ).length());
}
private void initializeAddresses() {
if ( fInstructions.length > 0 ) {
fStartAddress = fInstructions[0].getAdress();
fEndAddress = fInstructions[fInstructions.length - 1].getAdress();
}
}
public int getLineNumber( long address ) {
for( int i = 0; i < fInstructions.length; ++i ) {
if ( fInstructions[i].getAdress() == address ) {
return i + 1;
}
}
return 0;
}
public long getAddress( int lineNumber ) throws IllegalArgumentException {
if ( lineNumber > 0 && lineNumber <= fInstructions.length )
return fInstructions[--lineNumber].getAdress();
throw new IllegalArgumentException();
}
}
public static final IEditorInput EMPTY_EDITOR_INPUT = new DisassemblyEditorInput();
public static final IEditorInput PENDING_EDITOR_INPUT =
@ -182,9 +41,11 @@ public class DisassemblyEditorInput implements IEditorInput {
};
/**
* Storage associated with this editor input
* Disassembly block associated with this editor input
*/
private DisassemblyStorage fStorage;
private IDisassemblyBlock fBlock;
private String fContents = ""; //$NON-NLS-1$
/**
* Constructor for DisassemblyEditorInput.
@ -198,8 +59,9 @@ public class DisassemblyEditorInput implements IEditorInput {
* @param disassembly
* @param instructions
*/
public DisassemblyEditorInput( IDisassembly disassembly, IAsmInstruction[] instructions ) {
fStorage = new DisassemblyStorage( disassembly, instructions );
private DisassemblyEditorInput( IDisassemblyBlock block ) {
fBlock = block;
createContents();
}
/* (non-Javadoc)
@ -245,29 +107,158 @@ public class DisassemblyEditorInput implements IEditorInput {
}
public boolean contains( ICStackFrame frame ) {
if ( fStorage != null ) {
return fStorage.containsFrame( frame );
if ( fBlock != null ) {
return fBlock.contains( frame );
}
return false;
}
public String getContents() {
return ( fStorage != null ) ? fStorage.getContents() : ""; //$NON-NLS-1$
return fContents;
}
public int getInstructionNumber( long address ) {
return ( fStorage != null ) ? fStorage.getLineNumber( address ) : 0;
public int getInstructionLine( long address ) {
if ( fBlock != null ) {
IAsmSourceLine[] lines = fBlock.getSourceLines();
int result = 0;
for ( int i = 0; i < lines.length; ++i ) {
IAsmInstruction[] instructions = lines[i].getInstructions();
++result;
for ( int j = 0; j < instructions.length; ++j ) {
++result;
if ( instructions[j].getAdress() == address ) {
return result;
}
}
}
}
return 0;
}
public long getAddress( int lineNumber ) throws IllegalArgumentException {
return ( fStorage != null ) ? fStorage.getAddress( lineNumber ) : 0;
public int getInstructionLine( ICLineBreakpoint breakpoint ) {
if ( fBlock != null ) {
IDisassembly dis = fBlock.getDisassembly();
if ( dis != null ) {
IBreakpointTarget bt = (IBreakpointTarget)dis.getDebugTarget().getAdapter( IBreakpointTarget.class );
if ( bt != null ) {
try {
long address = bt.getBreakpointAddress( breakpoint );
if ( address != 0 )
return getInstructionLine( address );
}
catch( DebugException e ) {
}
}
}
}
return 0;
}
public IFile getModuleFile() {
return ( fStorage != null ) ? fStorage.getModuleFile() : null;
public long getAddress( int lineNumber ) {
if ( fBlock != null ) {
IAsmSourceLine[] lines = fBlock.getSourceLines();
int current = 0;
for ( int i = 0; i < lines.length; ++i ) {
IAsmInstruction[] instructions = lines[i].getInstructions();
++current;
if ( lineNumber == current )
return instructions[0].getAdress();
if ( lineNumber > current && lineNumber <= current + instructions.length )
return instructions[lineNumber - current - 1].getAdress();
current += instructions.length;
}
}
return 0;
}
public long getBreakpointAddress( ICLineBreakpoint breakpoint ) {
return ( fStorage != null ) ? fStorage.getBreakpointAddress( breakpoint ) : 0;
public String getModuleFile() {
return ( fBlock != null ) ? fBlock.getModuleFile() : null;
}
public static DisassemblyEditorInput create( ICStackFrame frame ) throws DebugException {
DisassemblyEditorInput input = null;
IDisassembly disassembly = ((ICDebugTarget)frame.getDebugTarget()).getDisassembly();
if ( disassembly != null ) {
IDisassemblyBlock block = disassembly.getDisassemblyBlock( frame );
input = new DisassemblyEditorInput( block );
}
return input;
}
private void createContents() {
StringBuffer lines = new StringBuffer();
int maxFunctionName = 0;
int maxOpcodeLength = 0;
long maxOffset = 0;
if ( fBlock != null ) {
IAsmSourceLine[] mi = fBlock.getSourceLines();
for ( int j = 0; j < mi.length; ++j ) {
IAsmInstruction[] instructions = mi[j].getInstructions();
for( int i = 0; i < instructions.length; ++i ) {
String functionName = instructions[i].getFunctionName();
if ( functionName.length() > maxFunctionName ) {
maxFunctionName = functionName.length();
}
String opcode = instructions[i].getOpcode();
if ( opcode.length() > maxOpcodeLength )
maxOpcodeLength = opcode.length();
if ( instructions[i].getOffset() > maxOffset ) {
maxOffset = instructions[i].getOffset();
}
}
}
int instrPos = calculateInstructionPosition( maxFunctionName, maxOffset );
int argPosition = instrPos + maxOpcodeLength + 1;
for ( int j = 0; j < mi.length; ++j ) {
if ( fBlock.isMixedMode() )
lines.append( getSourceLineString( mi[j] ) );
IAsmInstruction[] instructions = mi[j].getInstructions();
for( int i = 0; i < instructions.length; ++i ) {
// if ( fBlock.isMixedMode() )
// lines.append( "\t" ); //$NON-NLS-1$
lines.append( getInstructionString( instructions[i], instrPos, argPosition ) );
}
}
}
fContents = lines.toString();
}
private String getInstructionString( IAsmInstruction instruction, int instrPosition, int argPosition ) {
int worstCaseSpace = Math.max( instrPosition, argPosition );
char[] spaces = new char[worstCaseSpace];
Arrays.fill( spaces, ' ' );
StringBuffer sb = new StringBuffer();
if ( instruction != null ) {
sb.append( CDebugUIUtils.toHexAddressString( instruction.getAdress() ) );
sb.append( ' ' );
String functionName = instruction.getFunctionName();
if ( functionName != null && functionName.length() > 0 ) {
sb.append( '<' );
sb.append( functionName );
if ( instruction.getOffset() != 0 ) {
sb.append( '+' );
sb.append( instruction.getOffset() );
}
sb.append( ">:" ); //$NON-NLS-1$
sb.append( spaces, 0, instrPosition - sb.length() );
}
sb.append( instruction.getOpcode() );
sb.append( spaces, 0, argPosition - sb.length() );
sb.append( instruction.getArguments() );
sb.append( '\n' );
}
return sb.toString();
}
private int calculateInstructionPosition( int maxFunctionName, long maxOffset ) {
return (16 + maxFunctionName + Long.toString( maxOffset ).length());
}
private String getSourceLineString( IAsmSourceLine line ) {
String text = line.toString();
if ( text == null ) {
text = DisassemblyMessages.getString( "DisassemblyEditorInput.source_line_is_not_available_1" ) + '\n'; //$NON-NLS-1$
}
return text;
}
}

View file

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

View file

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