blob: f802e561558af98dfb9434bdeefa37dc462dac82 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Nokia 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:
* Nokia - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.edc.internal.arm;
import java.io.FileInputStream;
import java.io.IOException;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.debug.edc.internal.symbols.elf.BufferedRandomReadAccessFile;
import org.eclipse.cdt.debug.edc.internal.symbols.elf.Elf;
import org.eclipse.cdt.debug.edc.internal.symbols.files.ExecutableSymbolicsReaderFactory;
import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReader;
import org.eclipse.cdt.debug.edc.symbols.IExecutableSymbolicsReaderFactory;
import org.eclipse.cdt.utils.elf.Elf.ELFhdr;
import org.eclipse.core.runtime.IPath;
/**
* Factory for creating readers of symbolics in executables.
*/
public class ARMElfExecutableSymbolicsReaderFactory implements IExecutableSymbolicsReaderFactory {
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReaderFactory#getConfidence(org.eclipse.core.runtime.IPath)
*/
public int getConfidence(IPath binaryFile) {
Elf elfFile = getARMElfFile(binaryFile);
if (elfFile == null) {
// treat the symbol file as an executable, if existing
IPath symbolFilePath = ExecutableSymbolicsReaderFactory.findSymbolicsFile(binaryFile);
if (symbolFilePath != null) {
elfFile = getARMElfFile(symbolFilePath);
}
}
return elfFile != null ? IExecutableSymbolicsReaderFactory.HIGH_CONFIDENCE :
IExecutableSymbolicsReaderFactory.NO_CONFIDENCE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.edc.internal.symbols.files.IExecutableSymbolicsReaderFactory#createExecutableSymbolicsReader(org.eclipse.core.runtime.IPath)
*/
public IExecutableSymbolicsReader createExecutableSymbolicsReader(
IPath binaryFile) {
IExecutableSymbolicsReader reader = detectExecutable(binaryFile);
if (reader == null) {
// treat the symbol file as an executable, if existing
IPath symbolFilePath = ExecutableSymbolicsReaderFactory.findSymbolicsFile(binaryFile);
if (symbolFilePath != null) {
reader = detectExecutable(symbolFilePath);
}
}
return reader;
}
private IExecutableSymbolicsReader detectExecutable(IPath binaryFile) {
try {
Elf elfFile = getARMElfFile(binaryFile);
if (elfFile != null) {
return new ARMElfExecutableSymbolicsReader(binaryFile, elfFile);
}
} catch (IOException e) {
// this class elides actual I/O errors with format errors; ignore
}
return null;
}
private Elf getARMElfFile(IPath binaryFile) {
try {
// quickly check the endianness (Elf repeats this)
FileInputStream fis = new FileInputStream(binaryFile.toOSString());
byte[] e_ident = new byte[16];
fis.read(e_ident);
if (e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' || e_ident[ELFhdr.EI_MAG2] != 'L'
|| e_ident[ELFhdr.EI_MAG3] != 'F')
throw new IOException(CCorePlugin.getResourceString("Util.exception.notELF")); //$NON-NLS-1$
boolean isle = (e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB);
// If this constructor succeeds, it's ELF
Elf elf = new Elf(new BufferedRandomReadAccessFile(binaryFile.toOSString(), isle),
binaryFile.toOSString(), 0);
if (elf.getAttributes().getCPU().compareToIgnoreCase("arm") == 0) {
return elf;
}
} catch (IOException e) {
// this class elides actual I/O errors with format errors; ignore
}
return null;
}
}