/*
 * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.debugger.posix.elf;

import java.io.*;
import java.util.*;
import sun.jvm.hotspot.utilities.memo.*;
import sun.jvm.hotspot.debugger.DataSource;
import sun.jvm.hotspot.debugger.RandomAccessFileDataSource;

public class ELFFileParser {
    private static ELFFileParser elfParser;
    private static final String US_ASCII = "US-ASCII";

    public static ELFFileParser getParser() {
        if (elfParser == null) {
            elfParser = new ELFFileParser();
        }
        return elfParser;
    }

    /**
     * Parses the data in filename and returns the ELFFile representation.
     */
    public ELFFile parse(String filename) throws ELFException {
        try {
            RandomAccessFile file = new RandomAccessFile(filename, "r");
            return parse(new RandomAccessFileDataSource(file));
        } catch (FileNotFoundException e) {
            throw new ELFException(e);
        }
    }

    /**
     * Parses the data source and returns the ELFFile representation.
     */
    public ELFFile parse(DataSource source) throws ELFException {
        return new ELFFileImpl(source);
    }

    /**
     * Implementation of the ELFFile interface.
     */
    class ELFFileImpl implements ELFFile {
        private DataSource file;
        private ELFHeader header;
        private byte ident[] = new byte[16];

        ELFFileImpl(DataSource file) throws ELFException {
            this.file = file;
            int bytesRead = readBytes(ident);
            if (bytesRead != ident.length) {
                throw new ELFException("Error reading elf header (read " +
                            bytesRead + "bytes, expected to " +
                            "read " + ident.length + "bytes).");
            }

            // Check the magic number before we continue reading the file.
            if (!Arrays.equals(getMagicNumber(), ELF_MAGIC_NUMBER)) {
                    throw new ELFException("Bad magic number for file.");
            }

            header = new ELFHeaderImpl();
        }

        public ELFHeader getHeader()     { return header; }

        public byte[] getMagicNumber() {
            byte magicNumber[] = new byte[4];
            magicNumber[0] = ident[NDX_MAGIC_0];
            magicNumber[1] = ident[NDX_MAGIC_1];
            magicNumber[2] = ident[NDX_MAGIC_2];
            magicNumber[3] = ident[NDX_MAGIC_3];
            return magicNumber;
        }

        public byte getObjectSize()         { return ident[NDX_OBJECT_SIZE]; }
        public byte getEncoding()           { return ident[NDX_ENCODING]; }
        public byte getVersion()            { return ident[NDX_VERSION]; }


        /**
         * Implementation of the ELFHeader interface.
         */
        class ELFHeaderImpl implements ELFHeader {
            /** Marks the file as an object file and provide machine-independent
             * data so the contents may be decoded and interpreted. */
            private byte ident[] = new byte[16];        // unsigned char
            /** Identifies the object file type. */
            private short file_type;                    // Elf32_Half
            /** The required architecture. */
            private short arch;                         // Elf32_Half
            /** Version */
            private int version;                        // Elf32_Word
            /** Virtual address to which the system first transfers control.
             * If there is no entry point for the file the value is 0. */
            private int entry_point;                    // Elf32_Addr
            /** Program header table offset in bytes.  If there is no program
             * header table the value is 0. */
            private int ph_offset;                      // Elf32_Off
            /** Section header table offset in bytes.  If there is no section
             * header table the value is 0. */
            private int sh_offset;                      // Elf32_Off
            /** Processor specific flags. */
            private int flags;                          // Elf32_Word
            /** ELF header size in bytes. */
            private short eh_size;                      // Elf32_Half
            /** Size of one entry in the file's program header table in bytes.
             * All entries are the same size. */
            private short ph_entry_size;                // Elf32_Half
            /** Number of entries in the program header table, 0 if no
             * entries. */
            private short num_ph;                       // Elf32_Half
            /** Section header entry size in bytes. */
            private short sh_entry_size;                // Elf32_Half
            /** Number of entries in the section header table, 0 if no
             * entries. */
            private short num_sh;                       // Elf32_Half
            /** Index into the section header table associated with the section
             * name string table.  SH_UNDEF if there is no section name string
             * table. */
            private short sh_string_ndx;                // Elf32_Half

            /** MemoizedObject array of section headers associated with this
             * ELF file. */
            private MemoizedObject[] sectionHeaders;
            /** MemoizedObject array of program headers associated with this
             * ELF file. */
            private MemoizedObject[] programHeaders;

            /** Used to cache symbol table lookup. */
            private ELFSectionHeader symbolTableSection;
            /** Used to cache dynamic symbol table lookup. */
            private ELFSectionHeader dynamicSymbolTableSection;
            /** Used to cache hash table lookup. */
            private ELFHashTable hashTable;

            /**
             * Reads the ELF header and sets up the section and program headers
             * in memoized arrays.
             */
            ELFHeaderImpl() throws ELFException {
                file_type = readShort();
                arch = readShort();
                version = readInt();
                entry_point = readInt();
                ph_offset = readInt();
                sh_offset = readInt();
                flags = readInt();
                eh_size = readShort();
                ph_entry_size = readShort();
                num_ph = readShort();
                sh_entry_size = readShort();
                num_sh = readShort();
                sh_string_ndx = readShort();

                // Set up the section headers
                sectionHeaders = new MemoizedObject[num_sh];
                for (int i = 0; i < num_sh; i++) {
                    final long sectionHeaderOffset =
                            (long)(sh_offset + (i * sh_entry_size));
                    sectionHeaders[i] = new MemoizedObject() {
                        public Object computeValue() {
                            return new ELFSectionHeaderImpl(sectionHeaderOffset);
                        }
                    };
                }

//                // Set up the program headers
//                programHeaders = new MemoizedObject[num_sh];
//                for (int i = 0; i < num_sh; i++) {
//                    final long programHeaderOffset =
//                            (long)(ph_offset + (i * ph_entry_size));
//                    programHeaders[i] = new MemoizedObject() {
//                        public Object computeValue() {
//                            return new ProgramHeaderImpl(programHeaderOffset);
//                        }
//                    };
//                }
            }

            public short getFileType()                 { return file_type; }
            public short getArch()                     { return arch; }
            public short getSectionHeaderSize()        { return sh_entry_size; }
            public short getNumberOfSectionHeaders()   { return num_sh; }

//            public short getProgramHeaderSize()      { return ph_entry_size; }
//            public short getNumberOfProgramHeaders() { return num_ph; }


            /**
             * Returns the section header at the specified index.  The section
             * header at index 0 is defined as being a undefined section. */
            public ELFSectionHeader getSectionHeader(int index) {
                return (ELFSectionHeader)sectionHeaders[index].getValue();
            }

            public ELFStringTable getSectionHeaderStringTable() {
                return getSectionHeader(sh_string_ndx).getStringTable();
            }

            public ELFStringTable getStringTable() {
                return findStringTableWithName(ELFSectionHeader.STRING_TABLE_NAME);
            }

            public ELFStringTable getDynamicStringTable() {
                return findStringTableWithName(
                        ELFSectionHeader.DYNAMIC_STRING_TABLE_NAME);
            }

            private ELFStringTable findStringTableWithName(String tableName) {
                // Loop through the section header and look for a section
                // header with the name "tableName".  We can ignore entry 0
                // since it is defined as being undefined.
                ELFSectionHeader sh = null;
                for (int i = 1; i < getNumberOfSectionHeaders(); i++) {
                    sh = getSectionHeader(i);
                    if (tableName.equals(sh.getName())) {
                        return sh.getStringTable();
                    }
                }
                return null;
            }

            /**
             * The ELFHashTable does not currently work.  This method will
             * always return null. */
            public ELFHashTable getHashTable() {
//                if (hashTable != null) {
//                    return hashTable;
//                }
//
//                ELFHashTable ht = null;
//                for (int i = 1; i < getNumberOfSectionHeaders(); i++) {
//                    if ((ht = getSectionHeader(i).getHashTable()) != null) {
//                        hashTable = ht;
//                        return hashTable;
//                    }
//                }
                return null;
            }

            public ELFSectionHeader getSymbolTableSection() {
                if (symbolTableSection != null) {
                    return symbolTableSection;
                }

                symbolTableSection =
                        getSymbolTableSection(ELFSectionHeader.TYPE_SYMTBL);
                return symbolTableSection;
            }

            public ELFSectionHeader getDynamicSymbolTableSection() {
                if (dynamicSymbolTableSection != null) {
                    return dynamicSymbolTableSection;
                }

                dynamicSymbolTableSection =
                        getSymbolTableSection(ELFSectionHeader.TYPE_DYNSYM);
                return dynamicSymbolTableSection;
            }

            private ELFSectionHeader getSymbolTableSection(int type) {
                ELFSectionHeader sh = null;
                for (int i = 1; i < getNumberOfSectionHeaders(); i++) {
                    sh = getSectionHeader(i);
                    if (sh.getType() == type) {
                        dynamicSymbolTableSection = sh;
                        return sh;
                    }
                }
                return null;
            }

            public ELFSymbol getELFSymbol(String symbolName) {
                if (symbolName == null) {
                    return null;
                }

                // Check dynamic symbol table for symbol name.
                ELFSymbol symbol = null;
                int numSymbols = 0;
                ELFSectionHeader sh = getDynamicSymbolTableSection();
                if (sh != null) {
                    numSymbols = sh.getNumberOfSymbols();
                    for (int i = 0; i < Math.ceil(numSymbols / 2); i++) {
                        if (symbolName.equals(
                                (symbol = sh.getELFSymbol(i)).getName())) {
                            return symbol;
                        } else if (symbolName.equals(
                                (symbol = sh.getELFSymbol(
                                        numSymbols - 1 - i)).getName())) {
                            return symbol;
                        }
                    }
                }

                // Check symbol table for symbol name.
                sh = getSymbolTableSection();
                if (sh != null) {
                    numSymbols = sh.getNumberOfSymbols();
                    for (int i = 0; i < Math.ceil(numSymbols / 2); i++) {
                        if (symbolName.equals(
                                (symbol = sh.getELFSymbol(i)).getName())) {
                            return symbol;
                        } else if (symbolName.equals(
                                (symbol = sh.getELFSymbol(
                                        numSymbols - 1 - i)).getName())) {
                            return symbol;
                        }
                    }
                }
                return null;
            }

            public ELFSymbol getELFSymbol(long address) {
                // Check dynamic symbol table for address.
                ELFSymbol symbol = null;
                int numSymbols = 0;
                long value = 0L;

                ELFSectionHeader sh = getDynamicSymbolTableSection();
                if (sh != null) {
                    numSymbols = sh.getNumberOfSymbols();
                    for (int i = 0; i < numSymbols; i++) {
                        symbol = sh.getELFSymbol(i);
                        value = symbol.getValue();
                        if (address >= value && address < value + symbol.getSize()) {
                           return symbol;
                        }
                    }
                }

                // Check symbol table for symbol name.
                sh = getSymbolTableSection();
                if (sh != null) {
                    numSymbols = sh.getNumberOfSymbols();
                    for (int i = 0; i < numSymbols; i++) {
                        symbol = sh.getELFSymbol(i);
                        value = symbol.getValue();
                        if (address >= value && address < value + symbol.getSize()) {
                           return symbol;
                        }
                    }
                }
                return null;
            }

//            public ProgramHeader getProgramHeader(int index) {
//                return (ProgramHeader)programHeaders[index].getValue();
//            }
        }


        /**
         * Implementation of the ELFSectionHeader interface.
         */
        class ELFSectionHeaderImpl implements ELFSectionHeader {
            /** Index into the section header string table which gives the
             * name of the section. */
            private int name_ndx;                     // Elf32_Word
            /** Section content and semantics. */
            private int type;                         // Elf32_Word
            /** Flags. */
            private int flags;                        // Elf32_Word
            /** If the section will be in the memory image of a process this
             * will be the address at which the first byte of section will be
             * loaded.  Otherwise, this value is 0. */
            private int address;                      // Elf32_Addr
            /** Offset from beginning of file to first byte of the section. */
            private int section_offset;               // Elf32_Off
            /** Size in bytes of the section.  TYPE_NOBITS is a special case. */
            private int size;                         // Elf32_Word
            /** Section header table index link. */
            private int link;                         // Elf32_Word
            /** Extra information determined by the section type. */
            private int info;                         // Elf32_Word
            /** Address alignment constraints for the section. */
            private int address_alignment;            // Elf32_Word
            /** Size of a fixed-size entry, 0 if none. */
            private int entry_size;                   // Elf32_Word

            /** Memoized symbol table.  */
            private MemoizedObject[] symbols;
            /** Memoized string table. */
            private MemoizedObject stringTable;
            /** Memoized hash table. */
            private MemoizedObject hashTable;

            /**
             * Reads the section header information located at offset.
             */
            ELFSectionHeaderImpl(long offset) throws ELFException {
                seek(offset);
                name_ndx = readInt();
                type = readInt();
                flags = readInt();
                address = readInt();
                section_offset = readInt();
                size = readInt();
                link = readInt();
                info = readInt();
                address_alignment = readInt();
                entry_size = readInt();

                switch (type) {
                    case ELFSectionHeader.TYPE_NULL:
                        break;
                    case ELFSectionHeader.TYPE_PROGBITS:
                        break;
                    case ELFSectionHeader.TYPE_SYMTBL:
                    case ELFSectionHeader.TYPE_DYNSYM:
                        // Setup the symbol table.
                        int num_entries = size / entry_size;
                        symbols = new MemoizedObject[num_entries];
                        for (int i = 0; i < num_entries; i++) {
                            final int symbolOffset = section_offset +
                                    (i * entry_size);
                            symbols[i] = new MemoizedObject() {
                                public Object computeValue() {
                                    return new ELFSymbolImpl(symbolOffset,type);
                                }
                            };
                        }
                        break;
                    case ELFSectionHeader.TYPE_STRTBL:
                        // Setup the string table.
                        final int strTableOffset = section_offset;
                        final int strTableSize = size;
                        stringTable = new MemoizedObject() {
                            public Object computeValue() {
                                return new ELFStringTableImpl(strTableOffset,
                                                           strTableSize);
                            }
                        };
                        break;
                    case ELFSectionHeader.TYPE_RELO_EXPLICIT:
                        break;
                    case ELFSectionHeader.TYPE_HASH:
                        final int hashTableOffset = section_offset;
                        final int hashTableSize = size;
                        hashTable = new MemoizedObject() {
                            public Object computeValue() {
                                return new ELFHashTableImpl(hashTableOffset,
                                                         hashTableSize);
                            }
                        };
                        break;
                    case ELFSectionHeader.TYPE_DYNAMIC:
                        break;
                    case ELFSectionHeader.TYPE_NOTE:
                        break;
                    case ELFSectionHeader.TYPE_NOBITS:
                        break;
                    case ELFSectionHeader.TYPE_RELO:
                        break;
                    case ELFSectionHeader.TYPE_SHLIB:
                        break;
                    default:
                        break;
                }
            }

            public int getType() {
                return type;
            }

            public int getNumberOfSymbols() {
                if (symbols != null) {
                    return symbols.length;
                }
                return 0;
            }

            /**
             * Returns the ELFSymbol at the specified index.  Index 0 is
             * reserved for the undefined ELF symbol. */
            public ELFSymbol getELFSymbol(int index) {
                return (ELFSymbol)symbols[index].getValue();
            }

            public ELFStringTable getStringTable() {
                if (stringTable != null) {
                    return (ELFStringTable)stringTable.getValue();
                }
                return null;
            }

            /**
             * The ELFHashTable does not currently work.  This method will
             * always return null. */
            public ELFHashTable getHashTable() {
                if (hashTable != null) {
                    return (ELFHashTable)hashTable.getValue();
                }
                return null;
            }

            public String getName() {
                if (name_ndx == 0) {
                    return null;
                }

                ELFStringTable tbl = getHeader().getSectionHeaderStringTable();
                return tbl.get(name_ndx);
            }

            public int getLink() {
                return link;
            }

            public int getOffset() {
                return section_offset;
            }
        }


//        class ProgramHeaderImpl implements ProgramHeader {
//            /** Defines the kind of segment this element describes. */
//            private int type;                           // Elf32_Word
//            /** Offset from the beginning of the file. */
//            private int offset;                         // Elf32_Off
//            /** Virtual address at which the first byte of the segment
//             * resides in memory. */
//            private int virtual_address;                // Elf32_Addr
//            /** Reserved for the physical address of the segment on systems
//             * where physical addressinf is relevant. */
//            private int physical_address;               // Elf32_addr
//            /** File image size of segment in bytes, may be 0. */
//            private int file_size;                      // Elf32_Word
//            /** Memory image size of segment in bytes, may be 0. */
//            private int mem_size;                       // Elf32_Word
//            /** Flags relevant to this segment. Values for flags are defined
//             * in ELFSectionHeader. */
//            private int flags;                          // Elf32_Word
//            private int alignment;                      // Elf32_Word
//
//            private MemoizedObject[] symbols;
//
//            ProgramHeaderImpl(long offset) throws ELFException {
//                seek(offset);
//                type = readInt();
//                this.offset = readInt();
//                virtual_address = readInt();
//                physical_address = readInt();
//                file_size = readInt();
//                mem_size = readInt();
//                flags = readInt();
//                alignment = readInt();
//
//                switch (type) {
//                    case ELFSectionHeader.TYPE_NULL:
//                        break;
//                    case ELFSectionHeader.TYPE_PROGBITS:
//                        break;
//                    case ELFSectionHeader.TYPE_SYMTBL:
//                    case ELFSectionHeader.TYPE_DYNSYM:
//                        break;
//                    case ELFSectionHeader.TYPE_STRTBL:
//                        // Setup the string table.
//                        final int strTableOffset = section_offset;
//                        final int strTableSize = size;
//                        stringTable = new MemoizedObject() {
//                            public Object computeValue() {
//                                return new ELFStringTableImpl(strTableOffset,
//                                                           strTableSize);
//                            }
//                        };
//                        new ELFStringTableImpl(offset, file_size);
//                        break;
//                    case ELFSectionHeader.TYPE_RELO_EXPLICIT:
//                        break;
//                    case ELFSectionHeader.TYPE_HASH:
//                        break;
//                    case ELFSectionHeader.TYPE_DYNAMIC:
//                        break;
//                    case ELFSectionHeader.TYPE_NOTE:
//                        break;
//                    case ELFSectionHeader.TYPE_NOBITS:
//                        break;
//                    case ELFSectionHeader.TYPE_RELO:
//                        break;
//                    case ELFSectionHeader.TYPE_SHLIB:
//                        break;
//                    default:
//                        break;
//                }
//            }
//
//            public int getType() {
//                return type;
//            }
//        }


        /**
         * Implementation of the ELFSymbol interface.
         */
        class ELFSymbolImpl implements ELFSymbol {
            /** Index into the symbol string table that holds the character
             * representation of the symbols.  0 means the symbol has no
             * character name. */
            private int name_ndx;                       // Elf32_Word
            /** Value of the associated symbol.  This may be an address or
             * an absolute value. */
            private int value;                          // Elf32_Addr
            /** Size of the symbol.  0 if the symbol has no size or the size
             * is unknown. */
            private int size;                           // Elf32_Word
            /** Specifies the symbol type and beinding attributes. */
            private byte info;                          // unsigned char
            /** Currently holds the value of 0 and has no meaning. */
            private byte other;                         // unsigned char
            /** Index to the associated section header.   This value will need
             * to be read as an unsigned short if we compare it to
             * ELFSectionHeader.NDX_LORESERVE and ELFSectionHeader.NDX_HIRESERVE. */
            private short section_header_ndx;             // Elf32_Half

            private int section_type;

            /** Offset from the beginning of the file to this symbol. */
            private long offset;

            ELFSymbolImpl(long offset, int section_type) throws ELFException {
                seek(offset);
                this.offset = offset;
                name_ndx = readInt();
                value = readInt();
                size = readInt();
                info = readByte();
                other = readByte();
                section_header_ndx = readShort();

                this.section_type = section_type;

                switch (getType()) {
                    case TYPE_NOOBJECT:
                        break;
                    case TYPE_OBJECT:
                        break;
                    case TYPE_FUNCTION:
                        break;
                    case TYPE_SECTION:
                        break;
                    case TYPE_FILE:
                        break;
                    case TYPE_LOPROC:
                        break;
                    case TYPE_HIPROC:
                        break;
                    default:
                        break;
                }
            }

            public int getBinding()             { return info >> 4; }
            public int getType()                { return info & 0x0F; }
            public long getOffset()             { return offset; }

            public String getName() {
                // Check to make sure this symbol has a name.
                if (name_ndx == 0) {
                    return null;
                }

                // Retrieve the name of the symbol from the correct string
                // table.
                String symbol_name = null;
                if (section_type == ELFSectionHeader.TYPE_SYMTBL) {
                    symbol_name = getHeader().getStringTable().get(name_ndx);
                } else if (section_type == ELFSectionHeader.TYPE_DYNSYM) {
                    symbol_name =
                            getHeader().getDynamicStringTable().get(name_ndx);
                }
                return symbol_name;
            }

            public long getValue() {
                return value;
            }

            public int getSize() {
                return size;
            }
        }

        /**
         * Implementation of the ELFStringTable interface.
         */
        class ELFStringTableImpl implements ELFStringTable {
            /** The string table data. */
            private byte data[];
            private int numStrings;

            /**
             * Reads all the strings from [offset, length].
             */
            ELFStringTableImpl(long offset, int length) throws ELFException {
                seek(offset);
                data = new byte[length];
                int bytesRead = readBytes(data);
                if (bytesRead != length) {
                    throw new ELFException("Error reading string table (read " +
                                           bytesRead + "bytes, expected to " +
                                           "read " + data.length + "bytes).");
                }

                // Count the strings.
                numStrings = 0;
                for (int ptr = 0; ptr < data.length; ptr++) {
                    if (data[ptr] == '\0') {
                        numStrings++;
                    }
                }
            }

            public String get(int index) {
                int startPtr = index;
                int endPtr = index;
                while (data[endPtr] != '\0') {
                    endPtr++;
                }
                return new String(data, startPtr, endPtr - startPtr);
            }

            public int getNumStrings() {
                return numStrings;
            }
        }


        /** Implementation of the ELFHashTable. */
        class ELFHashTableImpl implements ELFHashTable {
            private int num_buckets;
            private int num_chains;

            // These could probably be memoized.
            private int buckets[];
            private int chains[];

            ELFHashTableImpl(long offset, int length) throws ELFException {
                seek(offset);
                num_buckets = readInt();
                num_chains = readInt();

                buckets = new int[num_buckets];
                chains = new int[num_chains];
                // Read the bucket data.
                for (int i = 0; i < num_buckets; i++) {
                    buckets[i] = readInt();
                }

                // Read the chain data.
                for (int i = 0; i < num_chains; i++) {
                    chains[i] = readInt();
                }

                // Make sure that the amount of bytes we were supposed to read
                // was what we actually read.
                int actual = num_buckets * 4 + num_chains * 4 + 8;
                if (length != actual) {
                    throw new ELFException("Error reading string table (read " +
                                           actual + "bytes, expected to " +
                                           "read " + length + "bytes).");
                }
            }

            /**
             * This method doesn't work every time and is unreliable.  Use
             * ELFSection.getELFSymbol(String) to retrieve symbols by name.
             * NOTE: since this method is currently broken it will always
             * return null. */
            public ELFSymbol getSymbol(String symbolName) {
//                if (symbolName == null) {
//                    return null;
//                }
//
//                long hash = 0;
//                long g = 0;
//
//                for (int i = 0; i < symbolName.length(); i++) {
//                    hash = (hash << 4) + symbolName.charAt(i);
//                    if ((g = hash & 0xf0000000) != 0) {
//                        hash ^= g >>> 24;
//                    }
//                    hash &= ~g;
//                }
//
//                ELFSymbol symbol = null;
//                ELFSectionHeader dyn_sh =
//                    getHeader().getDynamicSymbolTableSection();
//                int index = (int)hash % num_buckets;
//                while(index != 0) {
//                    symbol = dyn_sh.getELFSymbol(index);
//                    if (symbolName.equals(symbol.getName())) {
//                        break;
//                    }
//                    symbol = null;
//                    index = chains[index];
//                }
//                return symbol;
                return null;
            }
        }


        public void close() throws ELFException {
            try {
                file.close();
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        void seek(long offset) throws ELFException {
            try {
                file.seek(offset);
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        long getFilePointer() throws ELFException {
            try {
                return file.getFilePointer();
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        byte readByte() throws ELFException {
            try {
                return file.readByte();
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        int readBytes(byte[] b) throws ELFException {
            try {
                return file.read(b);
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        short readShort() throws ELFException {
            try {
                short val;
                switch (ident[NDX_ENCODING]) {
                    case DATA_LSB:
                        val = byteSwap(file.readShort());
                        break;
                    case DATA_MSB:
                        val = file.readShort();
                        break;
                    default:
                        throw new ELFException("Invalid encoding.");
                }
                return val;
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        int readInt() throws ELFException {
            try {
                int val;
                switch (ident[NDX_ENCODING]) {
                    case DATA_LSB:
                        val = byteSwap(file.readInt());
                        break;
                    case DATA_MSB:
                        val = file.readInt();
                        break;
                    default:
                        throw new ELFException("Invalid encoding.");
                }
                return val;
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        long readLong() throws ELFException {
            try {
                long val;
                switch (ident[NDX_ENCODING]) {
                    case DATA_LSB:
                        val = byteSwap(file.readLong());
                        break;
                    case DATA_MSB:
                        val = file.readLong();
                        break;
                    default:
                        throw new ELFException("Invalid encoding.");
                }
                return val;
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        /** Signed byte utility functions used for converting from big-endian
         * (MSB) to little-endian (LSB). */
        short byteSwap(short arg) {
          return (short) ((arg << 8) | ((arg >>> 8) & 0xFF));
        }

        int byteSwap(int arg) {
            return (((int) byteSwap((short) arg)) << 16) |
                   (((int) (byteSwap((short) (arg >>> 16)))) & 0xFFFF);
        }

        long byteSwap(long arg) {
            return ((((long) byteSwap((int) arg)) << 32) |
                   (((long) byteSwap((int) (arg >>> 32))) & 0xFFFFFFFF));
        }


        /* Unsigned byte utility functions.  Since java does not have unsigned
         * data types we must convert values manually and we must return
         * unsigned values in a larger data type.  Therefore we can only have
         * unsigned values for byte, short, and int. */
        short readUnsignedByte() throws ELFException {
            try {
                return unsignedByte(file.readByte());
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        int readUnsignedShort() throws ELFException {
            try {
                int val;
                switch (ident[NDX_ENCODING]) {
                    case DATA_LSB:
                        val = unsignedByteSwap(file.readShort());
                        break;
                    case DATA_MSB:
                        val = unsignedByte(file.readShort());
                        break;
                    default:
                        throw new ELFException("Invalid encoding.");
                }
                return val;
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        long readUnsignedInt() throws ELFException {
            try {
                long val;
                switch (ident[NDX_ENCODING]) {
                    case DATA_LSB:
                        val = unsignedByteSwap(file.readInt());
                        break;
                    case DATA_MSB:
                        val = unsignedByte(file.readInt());
                        break;
                    default:
                        throw new ELFException("Invalid encoding.");
                }
                return val;
            } catch (IOException e) {
                throw new ELFException(e);
            }
        }

        /** Returns the unsigned value of the byte. */
        short unsignedByte(byte arg) {
            return (short)(arg & 0x00FF);
        }

        /** Returns a big-endian unsigned representation of the short. */
        int unsignedByte(short arg) {
            int val;
            if (arg >= 0) {
                val = arg;
            } else {
                val = (int)(((int)unsignedByte((byte)(arg >>> 8)) << 8) |
                            ((byte)arg));
            }
            return val;
        }

        /** Returns a big-endian unsigned representation of the int. */
        long unsignedByte(int arg) {
            long val;
            if (arg >= 0) {
                val = arg;
            } else {
                val = (long)(((long)unsignedByte((short)(arg >>> 16)) << 16) |
                             ((short)arg));
            }
            return val;
        }

        /** Unsigned byte utility functions used for converting from big-endian
         * (MSB) to little-endian (LSB). */
        int unsignedByteSwap(short arg) {
            return (int)(((int)unsignedByte((byte)arg)) << 8) |
                         ((int)unsignedByte((byte)(arg >>> 8)));
        }

        long unsignedByteSwap(int arg) {
            return (long)(((long)unsignedByteSwap((short)arg)) << 16) |
                          ((long)unsignedByteSwap((short)(arg >>> 16)));
        }
    }

    public static void main(String args[]) {
        if (args.length != 1) {
            System.out.println("Usage: java ELFFileParser <elf file>");
            System.exit(0);
        }

        // Parse the file.
        ELFFile elfFile = ELFFileParser.getParser().parse(args[0]);

        ELFHeader elfHeader = elfFile.getHeader();
        System.out.println("ELF File: " + args[0]);

        System.out.println("ELF object size: " +
                ((elfFile.getObjectSize() == 0) ? "Invalid Object Size" :
                (elfFile.getObjectSize() == 1) ? "32-bit" : "64-bit"));
        System.out.println("ELF data encoding: " +
                ((elfFile.getEncoding() == 0) ? "Invalid Data Encoding" :
                (elfFile.getEncoding() == 1) ? "LSB" : "MSB"));

        int h = elfHeader.getNumberOfSectionHeaders();
        System.out.println("--> Start: reading " + h + " section headers.");
        for (int i = 0; i < elfHeader.getNumberOfSectionHeaders(); i++) {
            ELFSectionHeader sh = elfHeader.getSectionHeader(i);
            String str = sh.getName();
            System.out.println("----> Start: Section (" + i + ") " + str);

            int num = 0;
            if ((num = sh.getNumberOfSymbols()) != 0) {
                System.out.println("------> Start: reading " + num + " symbols.");
                for (int j = 0; j < num ; j++) {
                    ELFSymbol sym = sh.getELFSymbol(j);
                    //String name = sym.getName();
                    //if (name != null) {
                    //    System.out.println(name);
                    //}
                }
                System.out.println("<------ End: reading " + num + " symbols.");
            }
            ELFStringTable st;
            if (sh.getType() == ELFSectionHeader.TYPE_STRTBL) {
                System.out.println("------> Start: reading string table.");
                st = sh.getStringTable();
                System.out.println("<------ End: reading string table.");
            }
            if (sh.getType() == ELFSectionHeader.TYPE_HASH) {
                System.out.println("------> Start: reading hash table.");
                sh.getHashTable();
                System.out.println("<------ End: reading hash table.");
            }
            System.out.println("<---- End: Section (" + i + ") " + str);
        }
        System.out.println("<-- End: reading " + h + " section headers.");
/*
        h = elfHeader.getNumberOfProgramHeaders();
        System.out.println("--> Start: reading " + h + " program headers.");
        for (int i = 0; i < elfHeader.getNumberOfProgramHeaders(); i++) {
            elfHeader.getProgramHeader(i);
        }
        System.out.println("<-- End: reading " + h + " program headers.");
*/
        elfFile.close();
    }
}
