/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os.cts;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;

/**
 * A poor man's implementation of the readelf command. This program is
 * designed to parse ELF (Executable and Linkable Format) files.
 */
public class ReadElf {
    /** The magic values for the ELF identification. */
    private static final byte[] ELF_IDENT = {
            (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F',
    };

    private static final int EI_CLASS = 4;
    private static final int EI_DATA = 5;

    private static final int EM_386 = 3;
    private static final int EM_MIPS = 8;
    private static final int EM_ARM = 40;
    // http://en.wikipedia.org/wiki/Qualcomm_Hexagon
    private static final int EM_QDSP6 = 164;

    /** Size of the e_ident[] structure in the ELF header. */
    private static final int EI_NIDENT = 16;

    /** Offset from end of ident structure in half-word sizes. */
    private static final int OFFSET_TYPE = 0;

    /** Machine type. */
    private static final int OFFSET_MACHINE = 1;

    /** ELF version. */
    private static final int OFFSET_VERSION = 2;

    /**
     * The offset to which the system transfers control. e.g., the first thing
     * executed.
     */
    private static final int OFFSET_ENTRY = 4;

    /** Program header offset in bytes. */
    private static final int OFFSET_PHOFF = 6;

    /** Segment header offset in bytes. */
    private static final int OFFSET_SHOFF = 8;

    /** Processor-specific flags for binary. */
    private static final int OFFSET_FLAGS = 10;

    /** ELF header size in bytes. */
    private static final int OFFSET_EHSIZE = 12;

    /** All program headers entry size in bytes. */
    private static final int OFFSET_PHENTSIZE = 13;

    /** Number of program headers in ELF. */
    private static final int OFFSET_PHNUM = 14;

    /** All segment headers entry size in bytes. */
    private static final int OFFSET_SHENTSIZE = 15;

    /** Number of segment headers in ELF. */
    private static final int OFFSET_SHNUM = 16;

    /** The section header index that refers to string table. */
    private static final int OFFSET_SHSTRNDX = 17;

    /** Program header offset for type of this program header. */
    private static final int PHOFF_TYPE = 0;

    /** Program header offset for absolute offset in file. */
    private static final int PHOFF_OFFSET = 2;

    /** Program header offset for virtual address. */
    private static final int PHOFF_VADDR = 4;

    /** Program header offset for physical address. */
    private static final int PHOFF_PADDR = 6;

    /** Program header offset for file size in bytes. */
    private static final int PHOFF_FILESZ = 8;

    /** Program header offset for memory size in bytes. */
    private static final int PHOFF_MEMSZ = 10;

    /** Program header offset for flags. */
    private static final int PHOFF_FLAGS = 12;

    /**
     * Program header offset for required alignment. 0 or 1 means no alignment
     * necessary.
     */
    private static final int PHOFF_ALIGN = 14;

    /** Index into string pool for segment name. */
    private static final long SHOFF_NAME = 0;

    /** Segment header offset for type (half-words) */
    private static final long SHOFF_TYPE = 2;

    /** Segment header offset for offset (meta!) (half-words) */
    private static final long SHOFF_OFFSET = 8;

    /** Segment header offset for size (half-words) */
    private static final long SHOFF_SIZE = 10;

    /** Data is presented in LSB format. */
    private static final int ELFDATA2LSB = 1;

    /** Date is presented in MSB format. */
    private static final int ELFDATA2MSB = 2;

    private static final int ELFCLASS32 = 1;

    private static final int ELFCLASS64 = 2;

    private static final long PT_LOAD = 1;

    /** Section Type: Symbol Table */
    private static final int SHT_SYMTAB = 2;

    /** Section Type: String Table */
    private static final int SHT_STRTAB = 3;

    /** Section Type: Dynamic **/
    private static final int SHT_DYNAMIC = 6;

    /** Section Type: Dynamic Symbol Table */
    private static final int SHT_DYNSYM = 11;

    /** Symbol Table Entry: Name offset */
    private static final int SYMTAB_NAME = 0;

    /** Symbol Table Entry: SymTab Info */
    private static final int SYMTAB_ST_INFO = 6;

    /** Symbol Table Entry size (half-words) */
    private static final int SYMTAB_ENTRY_HALFWORD_SIZE = 7;

    /**
     * Symbol Table Entry size (extra in bytes) to cover "st_info" and
     * "st_other"
     */
    private static final int SYMTAB_ENTRY_BYTE_EXTRA_SIZE = 2;

    public static class Symbol {
        public static final int STB_LOCAL = 0;

        public static final int STB_GLOBAL = 1;

        public static final int STB_WEAK = 2;

        public static final int STB_LOPROC = 13;

        public static final int STB_HIPROC = 15;

        public final String name;

        public final int bind;

        public final int type;

        Symbol(String name, int st_info) {
            this.name = name;
            this.bind = (st_info >> 4) & 0x0F;
            this.type = st_info & 0x0F;
        }
    };

    private final String mPath;
    private final RandomAccessFile mFile;
    private final byte[] mBuffer = new byte[512];
    private int mEndian;
    private boolean mIsDynamic;
    private boolean mIsPIE;
    private int mType;
    private int mWordSize;
    private int mHalfWordSize;

    /** Symbol Table offset */
    private long mSymTabOffset;

    /** Symbol Table size */
    private long mSymTabSize;

    /** Dynamic Symbol Table offset */
    private long mDynSymOffset;

    /** Dynamic Symbol Table size */
    private long mDynSymSize;

    /** Section Header String Table offset */
    private long mShStrTabOffset;

    /** Section Header String Table size */
    private long mShStrTabSize;

    /** String Table offset */
    private long mStrTabOffset;

    /** String Table size */
    private long mStrTabSize;

    /** Dynamic String Table offset */
    private long mDynStrOffset;

    /** Dynamic String Table size */
    private long mDynStrSize;

    /** Symbol Table symbol names */
    private Map<String, Symbol> mSymbols;

    /** Dynamic Symbol Table symbol names */
    private Map<String, Symbol> mDynamicSymbols;

    public static ReadElf read(File file) throws IOException {
        return new ReadElf(file);
    }

    public boolean isDynamic() {
        return mIsDynamic;
    }

    public int getType() {
        return mType;
    }

    public boolean isPIE() {
        return mIsPIE;
    }

    private ReadElf(File file) throws IOException {
        mPath = file.getPath();
        mFile = new RandomAccessFile(file, "r");

        if (mFile.length() < EI_NIDENT) {
            throw new IllegalArgumentException("Too small to be an ELF file: " + file);
        }

        readIdent();
        readHeader();
    }

    protected void finalize() throws Throwable {
        try {
            mFile.close();
        } catch (IOException e) {
            // nothing
        } finally {
            super.finalize();
        }
    }

    private void readHeader() throws IOException {
        mType = readHalf(getHeaderOffset(OFFSET_TYPE));
        int e_machine = readHalf(getHeaderOffset(OFFSET_MACHINE));
        if (e_machine != EM_386 && e_machine != EM_MIPS && e_machine != EM_ARM &&
                e_machine != EM_QDSP6) {
            throw new IOException("Invalid ELF e_machine: " + e_machine + ": " + mPath);
        }

        final long shOffset = readWord(getHeaderOffset(OFFSET_SHOFF));
        final int shNumber = readHalf(getHeaderOffset(OFFSET_SHNUM));
        final int shSize = readHalf(getHeaderOffset(OFFSET_SHENTSIZE));
        final int shStrIndex = readHalf(getHeaderOffset(OFFSET_SHSTRNDX));

        readSectionHeaders(shOffset, shNumber, shSize, shStrIndex);

        final long phOffset = readWord(getHeaderOffset(OFFSET_PHOFF));
        final int phNumber = readHalf(getHeaderOffset(OFFSET_PHNUM));
        final int phSize = readHalf(getHeaderOffset(OFFSET_PHENTSIZE));

        readProgramHeaders(phOffset, phNumber, phSize);
    }

    private void readSectionHeaders(long tableOffset, int shNumber, int shSize, int shStrIndex)
            throws IOException {
        // Read the Section Header String Table offset first.
        {
            final long shStrTabShOffset = tableOffset + shStrIndex * shSize;
            final long type = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_TYPE);

            if (type == SHT_STRTAB) {
                mShStrTabOffset = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_OFFSET);
                mShStrTabSize = readWord(shStrTabShOffset + mHalfWordSize * SHOFF_SIZE);
            }
        }

        for (int i = 0; i < shNumber; i++) {
            // Don't bother to re-read the Section Header StrTab.
            if (i == shStrIndex) {
                continue;
            }

            final long shOffset = tableOffset + i * shSize;

            final long type = readWord(shOffset + mHalfWordSize * SHOFF_TYPE);
            if ((type == SHT_SYMTAB) || (type == SHT_DYNSYM)) {
                final long nameOffset = readWord(shOffset + mHalfWordSize * SHOFF_NAME);
                final long offset = readWord(shOffset + mHalfWordSize * SHOFF_OFFSET);
                final long size = readWord(shOffset + mHalfWordSize * SHOFF_SIZE);

                final String symTabName = readShStrTabEntry(nameOffset);
                if (".symtab".equals(symTabName)) {
                    mSymTabOffset = offset;
                    mSymTabSize = size;
                } else if (".dynsym".equals(symTabName)) {
                    mDynSymOffset = offset;
                    mDynSymSize = size;
                }
            } else if (type == SHT_STRTAB) {
                final long nameOffset = readWord(shOffset + mHalfWordSize * SHOFF_NAME);
                final long offset = readWord(shOffset + mHalfWordSize * SHOFF_OFFSET);
                final long size = readWord(shOffset + mHalfWordSize * SHOFF_SIZE);

                final String strTabName = readShStrTabEntry(nameOffset);
                if (".strtab".equals(strTabName)) {
                    mStrTabOffset = offset;
                    mStrTabSize = size;
                } else if (".dynstr".equals(strTabName)) {
                    mDynStrOffset = offset;
                    mDynStrSize = size;
                }
            } else if (type == SHT_DYNAMIC) {
                mIsDynamic = true;
            }
        }
    }

    private void readProgramHeaders(long phOffset, int phNumber, int phSize) throws IOException {
        for (int i = 0; i < phNumber; i++) {
            final long baseOffset = phOffset + i * phSize;
            final long type = readWord(baseOffset);
            if (type == PT_LOAD) {
                final long virtAddress = readWord(baseOffset + mHalfWordSize * PHOFF_VADDR);
                if (virtAddress == 0) {
                    mIsPIE = true;
                }
            }
        }
    }

    private void readSymbolTable(Map<String, Symbol> symbolMap, long symStrOffset, long symStrSize,
            long symOffset, long symSize) throws IOException {
        final long symEnd = symOffset + symSize;
        for (long off = symOffset; off < symEnd; off += SYMTAB_ENTRY_HALFWORD_SIZE * mHalfWordSize
                + SYMTAB_ENTRY_BYTE_EXTRA_SIZE) {
            long strOffset = readWord(off + SYMTAB_NAME);
            if (strOffset == 0) {
                continue;
            }

            final String symName = readStrTabEntry(symStrOffset, symStrSize, strOffset);
            if (symName != null) {
                final int st_info = readByte(off + SYMTAB_ST_INFO);
                symbolMap.put(symName, new Symbol(symName, st_info));
            }
        }
    }

    private String readShStrTabEntry(long strOffset) throws IOException {
        if ((mShStrTabOffset == 0) || (strOffset < 0) || (strOffset >= mShStrTabSize)) {
            return null;
        }

        return readString(mShStrTabOffset + strOffset);
    }

    private String readStrTabEntry(long tableOffset, long tableSize, long strOffset)
            throws IOException {
        if ((tableOffset == 0) || (strOffset < 0) || (strOffset >= tableSize)) {
            return null;
        }

        return readString(tableOffset + strOffset);
    }

    private int getHeaderOffset(int halfWorldOffset) {
        return EI_NIDENT + halfWorldOffset * mHalfWordSize;
    }

    private int readByte(long offset) throws IOException {
        mFile.seek(offset);
        mFile.readFully(mBuffer, 0, 1);

        return mBuffer[0];
    }

    private int readHalf(long offset) throws IOException {
        mFile.seek(offset);
        mFile.readFully(mBuffer, 0, mWordSize);

        final int answer;
        if (mEndian == ELFDATA2LSB) {
            answer = mBuffer[1] << 8 | mBuffer[0];
        } else {
            answer = mBuffer[0] << 8 | mBuffer[1];
        }

        return answer;
    }

    private long readWord(long offset) throws IOException {
        mFile.seek(offset);
        mFile.readFully(mBuffer, 0, mWordSize);

        int answer = 0;
        if (mEndian == ELFDATA2LSB) {
            for (int i = mWordSize - 1; i >= 0; i--) {
                answer = (answer << 8) | (mBuffer[i] & 0xFF);
            }
        } else {
            final int N = mWordSize - 1;
            for (int i = 0; i <= N; i++) {
                answer = (answer << 8) | mBuffer[i];
            }
        }

        return answer;
    }

    private String readString(long offset) throws IOException {
        mFile.seek(offset);
        mFile.readFully(mBuffer, 0, (int) Math.min(mBuffer.length, mFile.length() - offset));

        for (int i = 0; i < mBuffer.length; i++) {
            if (mBuffer[i] == 0) {
                return new String(mBuffer, 0, i);
            }
        }

        return null;
    }

    private void readIdent() throws IOException {
        mFile.seek(0);
        mFile.readFully(mBuffer, 0, EI_NIDENT);

        if ((mBuffer[0] != ELF_IDENT[0]) || (mBuffer[1] != ELF_IDENT[1])
                || (mBuffer[2] != ELF_IDENT[2]) || (mBuffer[3] != ELF_IDENT[3])) {
            throw new IllegalArgumentException("Invalid ELF file: " + mPath);
        }

        int elfClass = mBuffer[EI_CLASS];
        if (elfClass == ELFCLASS32) {
            mWordSize = 4;
            mHalfWordSize = 2;
        } else if (elfClass == ELFCLASS64) {
            throw new IOException("Unsupported ELFCLASS64 file: " + mPath);
        } else {
            throw new IOException("Invalid ELF EI_CLASS: " + elfClass + ": " + mPath);
        }

        mEndian = mBuffer[EI_DATA];
        if (mEndian == ELFDATA2LSB) {
        } else if (mEndian == ELFDATA2MSB) {
            throw new IOException("Unsupported ELFDATA2MSB file: " + mPath);
        } else {
            throw new IOException("Invalid ELF EI_DATA: " + mEndian + ": " + mPath);
        }
    }

    public Symbol getSymbol(String name) {
        if ((mSymTabOffset == 0) && (mSymTabSize == 0)) {
            return null;
        }

        if (mSymbols == null) {
            mSymbols = new HashMap<String, Symbol>();
            try {
                readSymbolTable(mSymbols, mStrTabOffset, mStrTabSize, mSymTabOffset, mSymTabSize);
            } catch (IOException e) {
                return null;
            }
        }

        return mSymbols.get(name);
    }

    public Symbol getDynamicSymbol(String name) {
        if ((mDynSymOffset == 0) && (mDynSymSize == 0)) {
            return null;
        }

        if (mDynamicSymbols == null) {
            mDynamicSymbols = new HashMap<String, Symbol>();
            try {
                readSymbolTable(mDynamicSymbols, mDynStrOffset, mDynStrSize, mDynSymOffset,
                        mDynSymSize);
            } catch (IOException e) {
                return null;
            }
        }

        return mDynamicSymbols.get(name);
    }
}
