/******************************************************************************* * Copyright (c) 2004, 2008 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * QNX Software Systems - Initial API and implementation * Mike Caraman (Frescale) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=210863 *******************************************************************************/ 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.core.IAddress; import org.eclipse.cdt.core.IAddressFactory; import org.eclipse.cdt.core.model.ITranslationUnit; 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; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; /** * CDI-based implementation of <code>IDisassemblyBlock</code>. */ public class DisassemblyBlock implements IDisassemblyBlock, IAdaptable { private IDisassembly fDisassembly; private Object fSourceElement; private IAsmSourceLine[] fSourceLines; private IAddress fStartAddress = null; private IAddress fEndAddress = null; 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 ); ISourceLocator locator = disassembly.getDebugTarget().getLaunch().getSourceLocator(); IAddressFactory factory = ((CDebugTarget)disassembly.getDebugTarget()).getAddressFactory(); block.initialize( factory, locator, instructions ); return block; } public static DisassemblyBlock create( IDisassembly disassembly, ICDIInstruction[] instructions ) { DisassemblyBlock block = new DisassemblyBlock( disassembly ); IAddressFactory factory = ((CDebugTarget)disassembly.getDebugTarget()).getAddressFactory(); block.initialize( factory, instructions ); return block; } private void initialize( IAddressFactory factory, ICDIInstruction[] instructions ) { setMixedMode( false ); createSourceLines( factory, instructions ); initializeAddresses(); } private void initialize( IAddressFactory factory, ISourceLocator locator, ICDIMixedInstruction[] mi ) { setMixedMode( true ); createSourceLines( factory, locator, mi ); initializeAddresses(); } /* (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().getPath().toOSString(); } } return ""; //$NON-NLS-1$ } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.IDisassemblyBlock#getSourceElement() */ public Object getSourceElement() { return fSourceElement; } /* (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; if ( fStartAddress == null || fEndAddress == null ) return false; IAddress address = frame.getAddress(); // will return null if frame was disposed return (address != null && address.compareTo( fStartAddress ) >= 0 && address.compareTo( fEndAddress ) <= 0); } /* * (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 void createSourceLines( IAddressFactory factory, ISourceLocator 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 = null; if ( locator instanceof ISourceLookupDirector ) { element = ((ISourceLookupDirector)locator).getSourceElement( fileName ); } if ( locator instanceof ICSourceLocator ) { element = ((ICSourceLocator)locator).findSourceElement( fileName ); } fSourceElement = element; File file = null; if ( element instanceof IFile ) { file = ((IFile)element).getLocation().toFile(); } else if ( element instanceof ITranslationUnit ) { file = ((ITranslationUnit)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; boolean failed = false; int lineNumber = mi[i].getLineNumber(); if ( reader != null ) { while( reader.getLineNumber() + 1 < lineNumber ) { try { if ( reader.readLine() == null ) { // break if the end of file is reached (see bug #123745) failed = true; break; } } catch( IOException e ) { } } if ( !failed && reader.getLineNumber() + 1 == lineNumber ) { try { text = reader.readLine() + '\n'; } catch( IOException e ) { } } } result[i] = new AsmSourceLine( factory, text, lineNumber, mi[i].getInstructions() ); } fSourceLines = result; } private void createSourceLines( IAddressFactory factory, ICDIInstruction[] instructions ) { fSourceLines = new IAsmSourceLine[] { new AsmSourceLine( factory, "", instructions ) }; //$NON-NLS-1$ } private void initializeAddresses() { for ( int i = 0; i < fSourceLines.length; ++i ) { IAsmInstruction[] instr = fSourceLines[i].getInstructions(); if ( instr.length > 0 ) { if ( fStartAddress == null ) fStartAddress = instr[0].getAdress(); fEndAddress = instr[instr.length - 1].getAdress(); } } } private void setMixedMode( boolean mixedMode ) { this.fMixedMode = mixedMode; } protected boolean contains( IAddress address ) { return ( address.compareTo( fStartAddress ) >= 0 && address.compareTo( fEndAddress ) <= 0 ); } }