/******************************************************************************* * Copyright (c) 2004, 2009 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 *******************************************************************************/ package org.eclipse.cdt.debug.internal.core.model; import java.math.BigInteger; import com.ibm.icu.text.MessageFormat; import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IAddressFactory; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.model.ICDIObject; import org.eclipse.cdt.debug.core.cdi.model.ICDISharedLibrary; import org.eclipse.cdt.debug.core.model.ICModule; import org.eclipse.cdt.internal.core.model.Binary; import org.eclipse.cdt.internal.core.model.CModelManager; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.DebugException; /** * The CDI based implementation of <code>ICModule</code>. * * This implementation is experimental and needs to be changed when * the CDI level support is available. */ public class CModule extends CDebugElement implements ICModule { private int fType = 0; private Binary fBinary; private ICDIObject fCDIObject; private IPath fImageName; private IPath fSymbolsFileName; public static CModule createExecutable( CDebugTarget target, IPath path ) { // TODO Add support for executables to CDI. return new CModule( EXECUTABLE, target, path ); } public static CModule createSharedLibrary( CDebugTarget target, ICDISharedLibrary lib ) { return new CModule( SHARED_LIBRARY, target, lib ); } /** * Constructor for CModule. Used for the program. */ private CModule( int type, CDebugTarget target, IPath path ) { super( target ); fType = type; fBinary = createBinary(path); fCDIObject = null; fImageName = path; fSymbolsFileName = path; } /** * Constructor for CModule. Used for shared libraries. */ private CModule( int type, CDebugTarget target, ICDIObject cdiObject ) { super( target ); fType = type; if ( cdiObject instanceof ICDISharedLibrary ) { ICDISharedLibrary cdiSharedLib = (ICDISharedLibrary)cdiObject; fBinary = createBinary(new Path(cdiSharedLib.getFileName())); } fCDIObject = cdiObject; fImageName = ( ( cdiObject instanceof ICDISharedLibrary ) ) ? new Path( ((ICDISharedLibrary)cdiObject).getFileName() ) : new Path( CoreModelMessages.getString( "CModule.0" ) ); //$NON-NLS-1$ fSymbolsFileName = fImageName; } /** * We used to ask the CoreModel to create the Binary (ICElement) for us but * it will do so only for binary files that are in a project output * directory (for performance reasons). So, we do all the leg work * ourselves, duplicating much of the code, unfortunately. * * THE OLD WAY... * fCElement = CoreModel.getDefault().create(path); */ private Binary createBinary(IPath path) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IFile file = root.getFileForLocation(path); if (file != null && !file.exists()) { file = null; } // In case this is an external resource see if we can find // a file for it. if (file == null) { IFile[] files = root.findFilesForLocation(path); if (files.length > 0) { file = files[0]; } } if (file != null) { ICProject cproject = CoreModel.getDefault().create(file.getProject()); IPath resourcePath = file.getParent().getFullPath(); try { ICElement cfolder = cproject.findElement(resourcePath); // Check if folder is a source root and use that instead ISourceRoot sourceRoot = cproject.findSourceRoot(resourcePath); if (sourceRoot != null) cfolder = sourceRoot; IBinaryFile bin = CModelManager.getDefault().createBinaryFile(file); if (bin != null) { return new Binary(cfolder, file, (IBinaryObject)bin); } } catch (CModelException e) { CDebugCorePlugin.log(e); } } return null; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getType() */ public int getType() { return fType; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getName() */ public String getName() { return fImageName.lastSegment().toString(); } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getImageName() */ public IPath getImageName() { return fImageName; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getSymbolsFileName() */ public IPath getSymbolsFileName() { return fSymbolsFileName; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#setSymbolsFileName(org.eclipse.core.runtime.IPath) */ public void setSymbolsFileName( IPath symbolsFile ) throws DebugException { loadSymbolsFromFile( symbolsFile ); fSymbolsFileName = symbolsFile; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getBaseAddress() */ public IAddress getBaseAddress() { return ( fCDIObject instanceof ICDISharedLibrary ) ? getAddressFactory().createAddress( ((ICDISharedLibrary)fCDIObject).getStartAddress() ) : getAddressFactory().getZero(); } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getSize() */ public long getSize() { long result = 0; if ( fCDIObject instanceof ICDISharedLibrary ) { BigInteger start = ((ICDISharedLibrary)fCDIObject).getStartAddress(); BigInteger end = ((ICDISharedLibrary)fCDIObject).getEndAddress(); if ( end.compareTo( start ) > 0 ) result = end.subtract( start ).longValue(); } return result; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#areSymbolsLoaded() */ public boolean areSymbolsLoaded() { if (fCDIObject instanceof ICDISharedLibrary) return ((ICDISharedLibrary)fCDIObject).areSymbolsLoaded(); if (fBinary != null) return fBinary.hasDebug(); return false; } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#canLoadSymbols() */ public boolean canLoadSymbols() { return ( getDebugTarget().isSuspended() && !areSymbolsLoaded() ); } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#loadSymbols() */ public void loadSymbols() throws DebugException { loadSymbolsFromFile( getSymbolsFileName() ); } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getPlatform() */ public String getPlatform() { return ( fBinary != null ) ? fBinary.getCPU() : CoreModelMessages.getString( "CModule.1" ); //$NON-NLS-1$ } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#isLittleEndian() */ public boolean isLittleEndian() { return ( fBinary != null ) ? fBinary.isLittleEndian() : ((CDebugTarget)getDebugTarget()).isLittleEndian(); } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getAddressFactory() */ public IAddressFactory getAddressFactory() { return ((CDebugTarget)getDebugTarget()).getAddressFactory(); } /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.model.ICModule#getCPU() */ public String getCPU() { return ( fBinary != null ) ? fBinary.getCPU() : null; } /* (non-Javadoc) * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) */ public Object getAdapter( Class adapter ) { if ( ICElement.class.equals( adapter ) ) { return getCElement(); } if ( IBinary.class.equals( adapter ) && getCElement() instanceof IBinary ) { return getCElement(); } return super.getAdapter( adapter ); } public void dispose() { } public boolean equals( ICDIObject cdiObject ) { return ( fCDIObject != null ) ? fCDIObject.equals( cdiObject ) : false; } protected ICElement getCElement() { return fBinary; } private void loadSymbolsFromFile(IPath path) throws DebugException { if (fCDIObject instanceof ICDISharedLibrary) { if (path == null || path.isEmpty()) { requestFailed(CoreModelMessages.getString("CModule.2"), null); //$NON-NLS-1$ } else { if (path.equals(getSymbolsFileName())) { try { ((ICDISharedLibrary) fCDIObject).loadSymbols(); } catch (CDIException e) { targetRequestFailed(e.getMessage(), null); } } else { String message = MessageFormat.format( // CoreModelMessages.getString("CModule.5"), //$NON-NLS-1$ new Object[] { path.toString() }); targetRequestFailed(message, null); } } } } }