alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ELFFileParser.java)

This example Java source code file (ELFFileParser.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

data_lsb, data_msb, elf32_half, elf32_word, elfexception, elffile, elffileparser, elfhashtable, elfsectionheader, elfstringtable, elfsymbol, invalid, ioexception, memoizedobject, util

The ELFFileParser.java Java example source code

/*
 * 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();
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ELFFileParser.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.