/* * Copyright (c) 2007, 2011, 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. */ /** * Copyright (c) 2006, Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the University of California, Los Angeles nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Created Sep 30, 2006 */ package com.oracle.max.elf; import static com.oracle.max.elf.StringUtil.*; import java.io.RandomAccessFile; /** * The {@code ELFDumper} is a class that can load and display information * about ELF files. */ public final class ELFDumper { private ELFDumper() { } public static void main(String[] args) throws Exception { if (args.length < 1) { System.out.println("usage: elf-dumper <filename>"); return; } final String fname = args[0]; final RandomAccessFile fis = new RandomAccessFile(fname, "r"); try { // read the ELF header final ELFHeader header = ELFLoader.readELFHeader(fis); printHeader(header); // read the program header table (if it exists) final ELFProgramHeaderTable pht = ELFLoader.readPHT(fis, header); printPHT(pht); // read the section header table final ELFSectionHeaderTable sht = ELFLoader.readSHT(fis, header); printSHT(sht); // read the symbol tables for (ELFSymbolTable stab : ELFLoader.readSymbolTables(fis, header, sht)) { printSymbolTable(stab, sht); } } catch (ELFHeader.FormatError e) { throw new Error("Invalid ELF file", e); } } public static void printHeader(ELFHeader header) { nextln(); printSeparator(); println("Ver Machine Arch Size Endian"); printThinSeparator(); print(rightJustify(header.e_version, 3)); print(rightJustify(header.e_machine, 8)); print(rightJustify(header.getArchitecture(), 9)); print(rightJustify(header.is64Bit() ? "64 bits" : "32 bits", 9)); print(header.isLittleEndian() ? " little" : " big"); nextln(); } public static void printSHT(ELFSectionHeaderTable sht) { println("Section Header Table"); printSeparator(); print("Ent Name Type Address Offset Size Flags"); nextln(); printThinSeparator(); for (int cntr = 0; cntr < sht.entries.length; cntr++) { final ELFSectionHeaderTable.Entry e = sht.entries[cntr]; print(rightJustify(cntr, 3)); print(" " + leftJustify(e.getName(), 24)); print(rightJustify(e.getType(), 11)); if (e.is32Bit()) { final ELFSectionHeaderTable.Entry32 e32 = (ELFSectionHeaderTable.Entry32) e; print(" " + toHex(e32.sh_addr)); print(rightJustify(e32.sh_offset, 8)); print(rightJustify(e32.sh_size, 8)); } else { final ELFSectionHeaderTable.Entry64 e64 = (ELFSectionHeaderTable.Entry64) e; print(" " + toHex(e64.sh_addr)); print(rightJustify(e64.sh_offset, 8)); print(rightJustify(e64.sh_size, 8)); } print(" " + e.getFlagString()); nextln(); } nextln(); } public static String getName(ELFStringTable st, int ind) { if (st == null) { return ""; } return st.getString(ind); } public static void printPHT(ELFProgramHeaderTable pht) { println("Program Header Table"); printSeparator(); print("Ent Type Virtual Physical Offset Filesize Memsize Flags"); nextln(); printThinSeparator(); for (int cntr = 0; cntr < pht.entries.length; cntr++) { final ELFProgramHeaderTable.Entry e = pht.entries[cntr]; print(rightJustify(cntr, 3)); print(rightJustify(ELFProgramHeaderTable.getType(e), 9)); if (e.is32Bit()) { final ELFProgramHeaderTable.Entry32 e32 = (ELFProgramHeaderTable.Entry32) e; print(" " + toHex(e32.p_vaddr)); print(" " + toHex(e32.p_paddr)); print(rightJustify(e32.p_offset, 8)); print(rightJustify(e32.p_filesz, 10)); print(rightJustify(e32.p_memsz, 9)); } else { final ELFProgramHeaderTable.Entry64 e64 = (ELFProgramHeaderTable.Entry64) e; print(" " + toHex(e64.p_vaddr)); print(" " + toHex(e64.p_paddr)); print(rightJustify(e64.p_offset, 8)); print(rightJustify(e64.p_filesz, 10)); print(rightJustify(e64.p_memsz, 9)); } print(" " + e.getFlagString()); nextln(); } } public static void printSymbolTable(ELFSymbolTable stab, ELFSectionHeaderTable sht) { println("Symbol Table"); printSeparator(); print("Ent Type Section Bind Name Address Size"); nextln(); printThinSeparator(); final ELFStringTable str = stab.getStringTable(); for (int cntr = 0; cntr < stab.entries.length; cntr++) { final ELFSymbolTable.Entry e = stab.entries[cntr]; print(rightJustify(cntr, 3)); print(" " + leftJustify(e.getType(), 7)); print(" " + leftJustify(sht.getSectionName(e.getSectionHeaderIndex()), 14)); print(leftJustify(e.getBinding(), 8)); print(leftJustify(getName(str, e.getNameIndex()), 32)); if (e.is32Bit()) { final ELFSymbolTable.Entry32 e32 = (ELFSymbolTable.Entry32) e; print(" " + toHex(e32.st_value)); print(" " + rightJustify(e32.st_size, 8)); } else { final ELFSymbolTable.Entry64 e64 = (ELFSymbolTable.Entry64) e; print(" " + toHex(e64.st_value)); print(" " + rightJustify(e64.st_size, 12)); } nextln(); } } static void print(String str) { System.out.print(str); } static void print(char c) { System.out.print(c); } static void println(String str) { System.out.println(str); } static void nextln() { System.out.println(""); } static void printSeparator() { System.out.println("=============================================================================="); } static void printThinSeparator() { System.out.println("------------------------------------------------------------------------------"); } static String toHex(int v) { return StringUtil.toHex(v, 8); } static String toHex(long v) { return StringUtil.toHex(v, 16); } }