package org.eclipse.cdt.utils.elf;

/*
 * (c) Copyright QNX Software Systems Ltd. 2002.
 * All Rights Reserved.
 */

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

import java.util.Comparator;
import org.eclipse.cdt.utils.Addr2line;
import org.eclipse.cdt.utils.CPPFilt;

// test checkin
public class Elf {
	protected ERandomAccessFile efile;		

	protected ELFhdr ehdr;
	protected Section[] sections;
	protected Addr2line addr2line;
    protected boolean cppFiltEnabled = true;
	protected CPPFilt cppFilt;
	protected String file;
	protected byte[] section_strtab;	

	private int syms = 0;
	private Symbol[] symbols;
    private Symbol[] symtab_symbols;
	private Section  symtab_sym;
    private Symbol[] dynsym_symbols;
	private Section  dynsym_sym;

	protected String EMPTY_STRING = "";


	public class ELFhdr {
		/* e_ident offsets */
		public final static int EI_MAG0 = 0;
		public final static int EI_MAG1 = 1;
		public final static int EI_MAG2 = 2;
		public final static int EI_MAG3 = 3;
		public final static int EI_CLASS = 4;
	    public final static int EI_DATA = 5;
 		public final static int EI_VERSION = 6;
		public final static int EI_PAD = 7;
		public final static int EI_NDENT = 16;

		/* e_ident[EI_CLASS] */
		public final static int ELFCLASSNONE = 0;
		public final static int ELCLASS32 = 1;
		public final static int ELFCLASS64 = 2;

		/* e_ident[EI_DATA] */
		public final static int ELFDATANONE = 0;
		public final static int ELFDATA2LSB = 1;
		public final static int ELFDATA2MSB = 2;
			
		/* values of e_type */	
		public final static int ET_NONE = 0;
		public final static int ET_REL = 1;
		public final static int ET_EXEC = 2;
		public final static int ET_DYN = 3;
		public final static int ET_CORE = 4;
		public final static int ET_LOPROC = 0xff00;
		public final static int ET_HIPROC = 0xffff;
		
		/* values of e_machine */
		public final static int EM_NONE = 0;
		public final static int EM_M32 = 1;
		public final static int EM_SPARC = 2;
		public final static int EM_386 = 3;
		public final static int EM_68K = 4;
		public final static int EM_88K = 5;
		public final static int EM_486 = 6;
		public final static int EM_860 = 7;
		public final static int EM_MIPS = 8;
		public final static int EM_MIPS_RS3_LE = 10;
		public final static int EM_RS6000 = 11;
		public final static int EM_PA_RSIC = 15;
		public final static int EM_nCUBE = 16;
		public final static int EM_VPP500 = 17;
		public final static int EM_SPARC32PLUS = 18;
		public final static int EM_PPC = 20;
		public final static int EM_ARM = 40;
		public final static int EM_SH = 42;

		public byte 	e_ident[] = new byte[EI_NDENT];
		public short 	e_type; 				/* file type (Elf32_Half) */
		public short 	e_machine;				/* machine type (Elf32_Half) */
		public long		e_version;				/* version number (Elf32_Word) */
		public long		e_entry;        		/* entry point (Elf32_Addr)*/
	    public long		e_phoff;				/* Program hdr offset (Elf32_Off)*/
		public long		e_shoff;				/* Section hdr offset (Elf32_Off)*/
	    public long		e_flags;				/* Processor flags (Elf32_Word)*/
	    public short	e_ehsize;       		/* sizeof ehdr (Elf32_Half)*/
	    public short	e_phentsize;			/* Program header entry size (Elf32_Half)*/
	    public short	e_phnum;				/* Number of program headers (Elf32_Half)*/
	    public short	e_shentsize;			/* Section header entry size (Elf32_Half)*/
	    public short 	e_shnum;				/* Number of section headers (Elf32_Half)*/
	    public short	e_shstrndx;				/* String table index (Elf32_Half)*/

		protected ELFhdr() throws IOException {
			efile.seek(0);
			efile.readFully(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("Not ELF format");
			efile.setEndian(e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB);
			e_type = efile.readShortE();
			e_machine = efile.readShortE();
			e_version = efile.readIntE();
			e_entry = efile.readIntE();
			e_phoff = efile.readIntE();
			e_shoff = efile.readIntE();
			e_flags = efile.readIntE();
			e_ehsize = efile.readShortE();
			e_phentsize = efile.readShortE();
			e_phnum = efile.readShortE();
			e_shentsize = efile.readShortE();
			e_shnum = efile.readShortE();
			e_shstrndx = efile.readShortE();
		}
	}

	public class Section  {
		/* sh_type */
		public final static int SHT_NULL = 0;
		public final static int SHT_PROGBITS = 1;
		public final static int SHT_SYMTAB = 2;		
		public final static int SHT_STRTAB = 3;
		public final static int SHT_RELA = 4;
		public final static int SHT_HASH = 5;
		public final static int SHT_DYNAMIC = 6;
		public final static int SHT_NOTE = 7;
		public final static int SHT_NOBITS = 8;
		public final static int SHT_REL = 9;
		public final static int SHT_SHLIB = 10;
		public final static int SHT_DYNSYM = 11;
		
		public final static int SHT_LOPROC = 0x70000000;
		
		/* sh_flags */
		public final static int SHF_WRITE = 1;
		public final static int SHF_ALLOC = 2;
		public final static int SHF_EXECINTR = 4;
		
		public long sh_name;
		public long sh_type;
		public long sh_flags;
		public long sh_addr;
		public long sh_offset;
		public long sh_size;
		public long sh_link;
		public long sh_info;
		public long sh_addralign;
		public long sh_entsize;

        public byte[] loadSectionData() throws IOException {
            byte[] data = new byte[(int)sh_size];
            efile.seek( sh_offset );
            efile.read( data );
            return data;
        }

		public String toString() {
			try {
				if ( section_strtab == null ) {
					if ( ehdr.e_shstrndx > sections.length || ehdr.e_shstrndx < 0)
						return EMPTY_STRING;
					int size = (int)sections[ehdr.e_shstrndx].sh_size;
					if ( size <= 0 || size > efile.length() )
						return EMPTY_STRING;
					section_strtab = new byte[size];
					efile.seek(sections[ehdr.e_shstrndx].sh_offset);
					efile.read(section_strtab);
				}
				int str_size = 0;
				if ( sh_name > section_strtab.length) {
					return EMPTY_STRING;
				}
				while( section_strtab[(int)sh_name + str_size] != 0)
					str_size++;
				return new String(section_strtab, (int)sh_name, str_size);
			} catch (IOException e) {
				return EMPTY_STRING;
			}
		}
	}

	protected String string_from_elf_section(Elf.Section section, int index) throws IOException {
		StringBuffer str = new StringBuffer();
		byte tmp;
		if ( index > section.sh_size ) {
				return EMPTY_STRING;
			}
		efile.seek(section.sh_offset + index);
		while( true ) {
			tmp = efile.readByte();
			if ( tmp == 0 )
				break;
			str.append((char)tmp);
		}
		return str.toString();
	}
	
	public class Symbol implements Comparable {
		/* Symbol bindings */
		public final static int STB_LOCAL = 0;
		public final static int STB_GLOBAL = 1;
		public final static int STB_WEAK = 2;
		/* Symbol type */
		public final static int STT_NOTYPE = 0;
		public final static int STT_OBJECT = 1;
		public final static int STT_FUNC = 2;
		public final static int STT_SECTION = 3;
		public final static int STT_FILE = 4;
        /* Special Indexes */
        public final static int SHN_UNDEF = 0;
        public final static int SHN_LORESERVE = 0xffffff00;
        public final static int SHN_LOPROC = 0xffffff00;
        public final static int SHN_HIPROC = 0xffffff1f;
        public final static int SHN_LOOS = 0xffffff20; 
        public final static int SHN_HIOS = 0xffffff3f; 
        public final static int SHN_ABS = 0xfffffff1; 
        public final static int SHN_COMMON = 0xfffffff2; 
        public final static int SHN_XINDEX = 0xffffffff; 
        public final static int SHN_HIRESERVE = 0xffffffff; 


		public long st_name;
		public long st_value;
		public long st_size;
		public short st_info;
		public short st_other;
		public short st_shndx;		

		private String name = null;
		private String line = null;
		private String func = null;

        private Section sym_section;

		private String cppFilt(String in) {
            if (cppFiltEnabled) {
				try {
					if (in.indexOf("__") != -1 || in.indexOf("_._") != -1) {
						if (cppFilt == null) {
							cppFilt = new CPPFilt();
						}
						return cppFilt.getFunction(in);
					}
				} catch (IOException e) {
					return in;
				}
            }
			return in;
		}

        public Symbol( Section section ) {
            sym_section = section;
        }

		public int st_type() {
			return st_info & 0xf;
		}

		public int st_bind() {
			return (st_info >> 4) & 0xf;
		}
						
		public int compareTo(Object obj) {
			long thisVal = 0;
			long anotherVal = 0;
			if ( obj instanceof Symbol ) {
				Symbol sym = (Symbol)obj;
				thisVal = this.st_value;
				anotherVal = sym.st_value;
			} else if ( obj instanceof Long ) {
				Long val = (Long)obj;
				anotherVal = val.longValue();
				thisVal = (long)this.st_value;
			}
			return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
		}

		public String toString() {	
			if ( name == null ) {
				try { 
					Section sections[] = getSections();
					Section symstr = sections[(int)sym_section.sh_link];
					name = cppFilt(string_from_elf_section(symstr, (int)st_name ));
				} catch (IOException e ) {
					return EMPTY_STRING;
				}
			}
			return name;
		}

		/**
		 * Returns line information in the form of filename:line
		 * and if the information is not available may return null
		 * _or_ may return ??:??
		 */
		public String lineInfo() throws IOException {
			if ( line == null ) {
				if ( addr2line == null )
					addr2line = new Addr2line(file);
				long value = st_value;
				// We try to get the nearest match
				// since the symbol may not exactly align with debug info.
				// In C line number 0 is invalid, line starts at 1 for file, we use
				// this for validation.
				for (int i = 0; i <= 20; i += 4, value += i) {
					line = addr2line.getLine(value);
					if (line != null) {
						int colon = line.lastIndexOf(':');
						String number = line.substring(colon + 1);
						if (!number.startsWith("0")) {
							break; // bail out
						}
					}
				}
				func = addr2line.getFunction(value);
			}
			return line;
		}
		
		public String lineInfo(long vma) throws IOException {
			if ( addr2line == null )
				addr2line = new Addr2line(file);
			return addr2line.getLine(vma);
		}
		
		/**
		 * If the function is available from the symbol information,
		 * this will return the function name. May return null if 
		 * the function can't be determined.
		 */
		public String getFunction() throws IOException {
			if ( func == null ) {
				lineInfo();
			}
			return func;
		}
			
		/**
		 * If the filename is available from the symbol information,
		 * this will return the base filename information. May
		 * return null if the filename can't be determined.
		 */
		public String getFilename() throws IOException {
			if ( line == null ) {
				lineInfo();
			}
			int index1, index2;
			if(line == null || (index1 = line.lastIndexOf(':')) == -1) {
				return null;
			}
			// we do this because addr2line on win produces 
			// <cygdrive/pathtoexc/C:/pathtofile:##>
			
			index2 = line.indexOf(':');
			if ( index1 == index2 ) {
				index2 = 0;
			} else {
				index2--;
			}
			return line.substring(index2, index1);
		}

		/**
		 * Returns the line number of the function which is closest
		 * associated with the address if it is available.
		 * from the symbol information.  If it is not available,
		 * then -1 is returned.
		 */
		public int getFuncLineNumber() throws IOException {
			if ( line == null ) {
				lineInfo();
			}
			int index;
			if(line == null || (index = line.lastIndexOf(':')) == -1) {
				return -1;
			}
			try {
				int lineno = Integer.parseInt(line.substring(index + 1));
				return (lineno == 0) ? -1 : lineno;
			} catch(Exception e) {
				return -1;
			}
		}
		
		/**
		 * Returns the line number of the file if it is available
		 * from the symbol information.  If it is not available,
		 * then -1 is returned.  
		 */
		public int getLineNumber(long vma) throws IOException {
			int index;
			String ligne = lineInfo(vma);
			if(ligne == null || (index = ligne.lastIndexOf(':')) == -1) {
				return -1;
			}
			try {
				int lineno = Integer.parseInt(ligne.substring(index + 1));
				return (lineno == 0) ? -1 : lineno;
			} catch(Exception e) {
				return -1;
			}
		}
	}

	/**
	 * We have to implement a separate compararator since when we do the
	 * binary search down below we are using a Long and a Symbol object
	 * and the Long doesn't know how to compare against a Symbol so if
	 * we compare Symbol vs Long it is ok, but not if we do Long vs Symbol.
	 */
	class SymbolComparator implements Comparator {
		long val1, val2;
		public int compare(Object o1, Object o2) {

			if(o1 instanceof Long) {
				val1 = ((Long)o1).longValue();
			} else if(o1 instanceof Symbol) {
				val1 = ((Symbol)o1).st_value;
			} else {
				return -1;
			}
			
			if(o2 instanceof Long) {
				val2 = ((Long)o2).longValue();
			} else if(o2 instanceof Symbol) {
				val2 = ((Symbol)o2).st_value;
			} else {
				return -1;
			}
			return (val1 == val2) ? 0 
								  : ((val1 < val2) ? -1 : 1);
		}
	}

	
	public class PHdr {
		public final static int PT_NULL 	= 0;
		public final static int PT_LOAD 	= 1;
		public final static int PT_DYNAMIC 	= 2;
		public final static int PT_INTERP	= 3;
		public final static int PT_NOTE		= 4;
		public final static int PT_SHLIB	= 5;
		public final static int PT_PHDR		= 6;

		public final static int PF_X = 1;
		public final static int PF_W = 2;
		public final static int PF_R = 4;
		
		public long p_type;
		public long p_offset;
		public long p_vaddr;
		public long p_paddr;
		public long p_filesz;
		public long p_memsz;
		public long p_flags;
		public long p_align;
	}

	public PHdr[] getPHdrs() throws IOException {
		if ( ehdr.e_phnum == 0 ) {
			return new PHdr[0];
		}
		efile.seek(ehdr.e_phoff);
		PHdr phdrs[] = new PHdr[ehdr.e_phnum];
		for( int i = 0; i < ehdr.e_phnum; i++ ) {
			phdrs[i] = new PHdr();
			phdrs[i].p_type = efile.readIntE();
			phdrs[i].p_offset = efile.readIntE();
			phdrs[i].p_vaddr = efile.readIntE();
			phdrs[i].p_paddr = efile.readIntE();
			phdrs[i].p_filesz = efile.readIntE();
			phdrs[i].p_memsz = efile.readIntE();
			phdrs[i].p_flags = efile.readIntE();
			phdrs[i].p_align = efile.readIntE();
		}
		return phdrs;
	}
		
	public class Dynamic {
		public final static int DYN_ENT_SIZE = 8;

		public final static int DT_NULL 		= 0;
		public final static int DT_NEEDED 		= 1;
		public final static int DT_PLTRELSZ 	= 2;
		public final static int DT_PLTGOT 		= 3;
		public final static int DT_HASH 		= 4;
		public final static int DT_STRTAB 		= 5;
		public final static int DT_SYMTAB 		= 6;
		public final static int DT_RELA			= 7;
		public final static int DT_RELASZ 		= 8;
		public final static int DT_RELAENT 		= 9;
		public final static int DT_STRSZ		= 10;
		public final static int DT_SYMENT		= 11;
		public final static int DT_INIT			= 12;
		public final static int DT_FINI			= 13;
		public final static int DT_SONAME		= 14;
		public final static int DT_RPATH		= 15;
		public long d_tag;
		public long d_val;
		private Section section;
		private String name;
						
		protected Dynamic(Section section, long tag, long val) {
			this.section = section;
			d_tag = tag;
			d_val = val;
		}						
		
		public String toString() {
			if ( name == null ) {
				switch ( (int)d_tag ) {
					case DT_NEEDED:
					case DT_SONAME:
					case DT_RPATH:
						try {
							Section symstr = sections[(int)section.sh_link];
							name = string_from_elf_section(symstr, (int)d_val);
						} catch (IOException e) {
							name = EMPTY_STRING;
						}
						break;
					default:
						name = EMPTY_STRING;
				} 
			}
			return name;
		}
	}					

	public Dynamic[] getDynamicSections(Section section) throws IOException {
		if ( section.sh_type != Section.SHT_DYNAMIC ) {
			return new Dynamic[0];
		}
		ArrayList dynList = new ArrayList();
		efile.seek(section.sh_offset);
		int off = 0;
		// We must assume the section is a table ignoring the sh_entsize as it is not
		// set for MIPS.
		while( off < section.sh_size ) {
			Dynamic dynEnt = new Dynamic(section, efile.readIntE(), efile.readIntE());
			if ( dynEnt.d_tag == Dynamic.DT_NULL ) 
				break;
			dynList.add(dynEnt);
			off+= Dynamic.DYN_ENT_SIZE;
		}
		return (Dynamic[])dynList.toArray(new Dynamic[0]);
	}

    private void commonSetup( String file, long offset, boolean filton ) 
       throws IOException 
    {
        this.cppFiltEnabled = filton;

		try {
	        efile = new ERandomAccessFile(file, "r");
    	    efile.setFileOffset( offset );
			ehdr = new ELFhdr();
			this.file = file;
		} finally {
			if ( ehdr == null ) {
				dispose();
			}
		}
    }

	public Elf (String file, long offset) throws IOException {
        commonSetup( file, offset, true );
    }

    public Elf (String file) throws IOException {
        commonSetup( file, 0, true );
    }
     
    public Elf (String file, long offset, boolean filton) throws IOException {
        commonSetup( file, offset, filton );
    }

    public Elf (String file, boolean filton) throws IOException {
        commonSetup( file, 0, filton );
    }

    public boolean cppFilterEnabled() {
        return cppFiltEnabled;
    }

    public void setCppFilter( boolean enabled ) {
        cppFiltEnabled = enabled;
    }
  
	public ELFhdr getELFhdr() throws IOException {	
		return ehdr;		
	}

	public class Attribute {
		public static final int ELF_TYPE_EXE   = 1;
		public static final int ELF_TYPE_SHLIB = 2;
		public static final int ELF_TYPE_OBJ   = 3;
		public static final int ELF_TYPE_CORE  = 4;

		public static final int DEBUG_TYPE_NONE = 0;
		public static final int DEBUG_TYPE_STABS = 1;
		public static final int DEBUG_TYPE_DWARF = 2;

		String cpu;
		int type;
		int debugType;
		boolean bDebug;
		boolean isle;

		public String getCPU() {
			return cpu;
		}
		
		public int getType() {
			return type;
		}
		
		public boolean hasDebug() {
			return debugType != DEBUG_TYPE_NONE;
		}

		public int getDebugType() {
			return debugType;
		}
	
		public boolean isLittleEndian() {
			return isle;
		}
	}


    public Attribute getAttributes() throws IOException {
        Attribute attrib = new Attribute();

        switch( ehdr.e_type ) {
        	case Elf.ELFhdr.ET_CORE:
				attrib.type = Attribute.ELF_TYPE_CORE;
				break;
            case Elf.ELFhdr.ET_EXEC:
                attrib.type = Attribute.ELF_TYPE_EXE;
                break;
            case Elf.ELFhdr.ET_REL:
                attrib.type = Attribute.ELF_TYPE_OBJ;
                break;
            case Elf.ELFhdr.ET_DYN:
                attrib.type = Attribute.ELF_TYPE_SHLIB;
                break;
        }

		switch (ehdr.e_machine) {
			case Elf.ELFhdr.EM_386 :
			case Elf.ELFhdr.EM_486 :
				attrib.cpu = new String("x86");
				break;
			case Elf.ELFhdr.EM_PPC :
				attrib.cpu = new String("ppc");
				break;
			case Elf.ELFhdr.EM_SH :
				attrib.cpu = new String("sh");
				break;
			case Elf.ELFhdr.EM_ARM :
				attrib.cpu = new String("arm");
				break;
			case Elf.ELFhdr.EM_MIPS_RS3_LE :
			case Elf.ELFhdr.EM_MIPS :
			case Elf.ELFhdr.EM_RS6000 :
				attrib.cpu = "mips";
				break;
			case Elf.ELFhdr.EM_SPARC32PLUS:
			case Elf.ELFhdr.EM_SPARC:
				attrib.cpu = "sparc";
				break;
			case Elf.ELFhdr.EM_68K:
				attrib.cpu = "m68k";
				break;
			case Elf.ELFhdr.EM_NONE:
			default:
				attrib.cpu = "none";
		}
		switch (ehdr.e_ident[Elf.ELFhdr.EI_DATA]) {
			case Elf.ELFhdr.ELFDATA2LSB :
				attrib.isle = true;
				break;
			case Elf.ELFhdr.ELFDATA2MSB :
				attrib.isle = false;
				break;
		}
		// getSections
		// find .debug using toString
		Section [] sec = getSections();
		for (int i = 0; i < sec.length; i++) {
			String s = sec[i].toString();
			if (s.equals(".debug_info")) {
				attrib.debugType = Attribute.DEBUG_TYPE_DWARF; 
				break;
			} else if (s.equals(".stab")) {
				attrib.debugType = Attribute.DEBUG_TYPE_STABS;
				break;
			}
		}
        return attrib;
    }


	public static Attribute getAttributes(String file) throws IOException {
		Elf elf = new Elf(file);
		Attribute attrib = elf.getAttributes();
		elf.dispose();	
		return attrib;	
	}
	
	public static boolean isElfHeader(byte[] e_ident) {
		if (e_ident.length < 4 || e_ident[ELFhdr.EI_MAG0] != 0x7f || e_ident[ELFhdr.EI_MAG1] != 'E' || 
			e_ident[ELFhdr.EI_MAG2] != 'L' || e_ident[ELFhdr.EI_MAG3] != 'F')
			return false;
		return true;
	}

	public void dispose() {
		if (addr2line != null) {
			addr2line.dispose();
		}
		if (cppFilt != null) {
			cppFilt.dispose();
		}
		try {
			if (efile != null) {
				efile.close();
				efile = null;
			}
		} catch (IOException e) {
		}
	}

	/**
	 * Make sure we do not leak the fds.
	 */
	protected void finalize() throws Throwable {
		try {
			dispose();
		} finally {
			super.finalize();
		}
	}

	public Section getSectionByName(String name) throws IOException {
		if ( sections == null )
			getSections();
		for( int i = 0; i < sections.length; i++) {
			if ( sections[i].toString().equals(name)) {
				return sections[i];
			}
		}
		return null;
	}
	
	public Section[] getSections(int type) throws IOException {		
		if ( sections == null )
			getSections();
		ArrayList slist = new ArrayList();
		for( int i = 0; i < sections.length; i++ ) {
			if ( sections[i].sh_type == type)
				slist.add(sections[i]);
		}
		return (Section[])slist.toArray(new Section[0]);
	}
		
	public Section[] getSections() throws IOException {
		if ( sections == null ) {
			if ( ehdr.e_shoff == 0 ) {
				sections = new Section[0];			
				return sections;
			}
			efile.seek(ehdr.e_shoff);
			sections = new Section[ehdr.e_shnum];
			for ( int i = 0; i < ehdr.e_shnum; i++ ) {
				sections[i] = new Section();
				sections[i].sh_name = efile.readIntE();
				sections[i].sh_type = efile.readIntE();
				sections[i].sh_flags = efile.readIntE();
				sections[i].sh_addr = efile.readIntE();
				sections[i].sh_offset = efile.readIntE();
				sections[i].sh_size = efile.readIntE();
				sections[i].sh_link = efile.readIntE();
				sections[i].sh_info = efile.readIntE();
				sections[i].sh_addralign = efile.readIntE();
				sections[i].sh_entsize = efile.readIntE();
				if ( sections[i].sh_type == Section.SHT_SYMTAB )
					syms = i;
				if ( syms == 0 && sections[i].sh_type == Section.SHT_DYNSYM )
					syms = i;					
			}
		}
		return sections;
	}


    private Symbol[] loadSymbolsBySection( Section section ) throws IOException {
		int numSyms = 1;
		if (section.sh_entsize != 0) {
			numSyms = (int)section.sh_size / (int)section.sh_entsize;
		}
        ArrayList symList = new ArrayList(numSyms);
        for( int c = 0; c < numSyms; c++) {
	        efile.seek(section.sh_offset + (section.sh_entsize * c));
            Symbol symbol = new Symbol( section );
            symbol.st_name = efile.readIntE();
            symbol.st_value = efile.readIntE();
            symbol.st_size = efile.readIntE();
            symbol.st_info = efile.readByte();
            symbol.st_other = efile.readByte();
            symbol.st_shndx = efile.readShortE();
            if ( symbol.st_info == 0 )
                continue;
            symList.add(symbol);
        }
        Symbol[] results = (Symbol[])symList.toArray(new Symbol[0]);
        Arrays.sort(results);	
        return results;
    }


	public void loadSymbols() throws IOException {
		if ( symbols == null ) {
			Section section[] = getSections(Section.SHT_SYMTAB);
            if( section.length > 0 ) {
                symtab_sym = section[0];
                symtab_symbols = loadSymbolsBySection( section[0] );
            } else {
                symtab_sym = null;
                symtab_symbols = new Symbol[0];
            }

            section = getSections(Section.SHT_DYNSYM);
            if( section.length > 0 ) {
                dynsym_sym = section[0];
                dynsym_symbols = loadSymbolsBySection( section[0] );
            } else {
                dynsym_sym = null;
                dynsym_symbols = new Symbol[0];
            }

            if( symtab_sym != null ) {
                // sym = symtab_sym;
                symbols = symtab_symbols;
            } else if( dynsym_sym != null ) {
                // sym = dynsym_sym;
                symbols = dynsym_symbols;
            }
		}
	}

    public Symbol[] getSymbols() {
        return symbols;
    }

    public Symbol[] getDynamicSymbols() {
        return dynsym_symbols;
    }

    public Symbol[] getSymtabSymbols() {
        return symtab_symbols;
    }


	
	/* return the address of the function that address is in */
	public Symbol getSymbol( long vma ) {
		if ( symbols == null ) {
			return null;
		}

		//@@@ If this works, move it to a single instance in this class.
		SymbolComparator symbol_comparator = new SymbolComparator();
		
		int ndx = Arrays.binarySearch(symbols, new Long(vma), symbol_comparator);
		if ( ndx > 0 )
			return symbols[ndx];
		if ( ndx == -1 ) {
			return null;
		}
		ndx = -ndx - 1;
		return symbols[ndx-1];
	}
		
	public long swapInt( long val ) {
		if ( ehdr.e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB ) {
			short tmp[] = new short[4];
			tmp[0] = (short)(val & 0x00ff);
			tmp[1] = (short)((val >> 8) & 0x00ff);
			tmp[2] = (short)((val >> 16) & 0x00ff); 
			tmp[3] = (short)((val >> 24) & 0x00ff);
			return (long)((tmp[0] << 24) + (tmp[1] << 16) + (tmp[2] << 8) + tmp[3]);
		}
		return val;
	}

	public int swapShort( short val ) {
		if ( ehdr.e_ident[ELFhdr.EI_DATA] == ELFhdr.ELFDATA2LSB ) {
			short tmp[] = new short[2];
			tmp[0] = (short)(val & 0x00ff);
			tmp[1] = (short)((val >> 8) & 0x00ff);
			return (short)((tmp[0] << 8) + tmp[1]);
		}
		return val;
	}

    public String getFilename() {
        return file;
    }
}
