blob: 5a200c47fc76a0097744b69015f03d89e4cdbcd4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 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.IOException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.edc.internal.symbols.elf.BufferedRandomReadAccessFile;
import org.eclipse.cdt.debug.edc.internal.symbols.elf.Elf;
import org.eclipse.cdt.utils.Addr32;
import org.eclipse.cdt.utils.Addr64;
/**
* ARM Elf provides extra "mappings" in the symbol table to help distinguish
* between ARM and Thumb code. These extra symbols are mapped to the same
* address as the real symbol, but have a NULL type. The symbols of interest are
* $a and $t, for ARM and Thumb modes respectively.
*/
public class ARMElf extends Elf {
private Map<IAddress, Symbol> zeroSymbols = new HashMap<IAddress, Symbol>();
public ARMElf(String filename, boolean isLE) throws IOException {
super(new BufferedRandomReadAccessFile(filename, isLE), filename, 0);
readSymbols();
}
/**
* Record the interesting symbols once
*/
private void readSymbols() throws IOException {
Elf.Section symtab = getSectionByName(".symtab"); //$NON-NLS-1$
int numSyms = 1;
if (symtab.sh_entsize != 0) {
numSyms = (int) symtab.sh_size / (int) symtab.sh_entsize;
}
long offset = symtab.sh_offset;
for (int c = 0; c < numSyms; offset += symtab.sh_entsize, c++) {
efile.seek(offset);
Symbol symbol = new Symbol(symtab);
switch (ehdr.e_ident[ELFhdr.EI_CLASS]) {
case ELFhdr.ELFCLASS32: {
byte[] addrArray = new byte[ELF32_ADDR_SIZE];
symbol.st_name = efile.readIntE();
efile.readFullyE(addrArray);
symbol.st_value = new Addr32(addrArray);
symbol.st_size = efile.readIntE();
symbol.st_info = efile.readByte();
symbol.st_other = efile.readByte();
symbol.st_shndx = efile.readShortE();
}
break;
case ELFhdr.ELFCLASS64: {
byte[] addrArray = new byte[ELF64_ADDR_SIZE];
symbol.st_name = efile.readIntE();
symbol.st_info = efile.readByte();
symbol.st_other = efile.readByte();
symbol.st_shndx = efile.readShortE();
efile.readFullyE(addrArray);
symbol.st_value = new Addr64(addrArray);
symbol.st_size = readUnsignedLong(efile);
}
break;
case ELFhdr.ELFCLASSNONE:
default:
throw new IOException("Unknown ELF class " + ehdr.e_ident[ELFhdr.EI_CLASS]); //$NON-NLS-1$
}
if (symbol.st_size == 0) {
if (!zeroSymbols.containsKey(symbol.st_value)) {
zeroSymbols.put(symbol.st_value, symbol);
}
}
}
}
public String getMappingSymbolAtAddress(IAddress address) {
// use the start address of the symbol and try to find
// the matching mapping entry
Symbol symbol = zeroSymbols.get(address);
if (symbol == null)
return null;
return symbol.toString();
}
}