+++ /dev/null
-package org.xwt.mips;
-import java.io.*;
-
-public class ELF {
-
- private DataInput fd;
- private Object image;
- private void seek(long l) throws IOException {
- if (image instanceof RandomAccessFile) {
- ((RandomAccessFile)image).seek(l);
- } else if (image instanceof byte[]) {
- ByteArrayInputStream bais = new ByteArrayInputStream((byte[])image);
- bais.skip(l);
- fd = new DataInputStream(bais);
- }
- }
-
- public ELFHeader header;
- public PHeader[] pheaders;
- public SHeader[] sheaders;
-
- private byte[] stringTable;
-
- private boolean sectionReaderActive;
-
- public class ELFHeader {
- byte klass;
- byte data;
- byte osabi;
- byte abiversion;
-
- public static final short ET_EXEC = 2;
- public short type;
- public static final short EM_MIPS = 8;
- public short machine;
- public int version;
- public int entry;
- public int phoff;
- public int shoff;
- public int flags;
- public short ehsize;
- public short phentsize;
- public short phnum;
- public short shentsize;
- public short shnum;
- public short shstrndx;
-
- private static final int ELF_MAGIC = 0x7f454c46; // '\177', 'E', 'L', 'F'
- ELFHeader() throws IOException {
- if(fd.readInt() != ELF_MAGIC) throw new ELFException("Bad Magic (is: " );
- klass = fd.readByte();
- data = fd.readByte();
- fd.skipBytes(1); // version
- osabi = fd.readByte();
- abiversion = fd.readByte();
- fd.skipBytes(7);
- type = fd.readShort();
- machine = fd.readShort();
- version = fd.readInt();
- entry = fd.readInt();
- phoff = fd.readInt();
- shoff = fd.readInt();
- flags = fd.readInt();
- ehsize = fd.readShort();
- phentsize = fd.readShort();
- phnum = fd.readShort();
- shentsize = fd.readShort();
- shnum = fd.readShort();
- shstrndx = fd.readShort();
- }
- }
-
- public class PHeader {
- public int type;
- public int offset;
- public int vaddr;
- public int paddr;
- public int filesz;
- public int memsz;
- public int flags;
- public int align;
-
- public static final int PF_X = 0x1;
- public static final int PF_W = 0x2;
- public static final int PF_R = 0x4;
-
- public static final int PT_LOAD = 1;
-
- PHeader() throws IOException {
- type = fd.readInt();
- offset = fd.readInt();
- vaddr = fd.readInt();
- paddr = fd.readInt();
- filesz = fd.readInt();
- memsz = fd.readInt();
- flags = fd.readInt();
- align = fd.readInt();
- if(filesz > memsz) throw new ELFException("ELF inconsistency: filesz > memsz");
- }
-
- public boolean writable() { return (flags & PF_W) != 0; }
-
- public InputStream getInputStream() throws IOException {
- return new BufferedInputStream(new SectionInputStream(
- offset,offset+filesz));
- }
- }
-
- public class SHeader {
- int nameidx;
- public String name;
- public int type;
- public int flags;
- public int addr;
- public int offset;
- public int size;
- public int link;
- public int info;
- public int addralign;
- public int entsize;
-
- public static final int SHT_SYMTAB = 2;
- public static final int SHT_STRTAB = 3;
- public static final int SHT_NOBITS = 8;
-
- SHeader() throws IOException {
- nameidx = fd.readInt();
- type = fd.readInt();
- flags = fd.readInt();
- addr = fd.readInt();
- offset = fd.readInt();
- size = fd.readInt();
- link = fd.readInt();
- info = fd.readInt();
- addralign = fd.readInt();
- entsize = fd.readInt();
- }
-
- public InputStream getInputStream() throws IOException {
- return new BufferedInputStream(new SectionInputStream(
- offset, type == SHT_NOBITS ? 0 : offset+size));
- }
- }
-
- public ELF(Object img) throws IOException, ELFException {
- if (img instanceof String) {
- image = fd = new MyRandomAccessFile((String)img, "r");
- } else {
- image = img;
- }
- seek(0);
- header = new ELFHeader();
- pheaders = new PHeader[header.phnum];
- for(int i=0;i<header.phnum;i++) {
- seek(header.phoff+i*header.phentsize);
- pheaders[i] = new PHeader();
- }
- sheaders = new SHeader[header.shnum];
- for(int i=0;i<header.shnum;i++) {
- seek(header.shoff+i*header.shentsize);
- sheaders[i] = new SHeader();
- }
- if(header.shstrndx < 0 || header.shstrndx >= header.shnum) throw new ELFException("Bad shstrndx");
- seek(sheaders[header.shstrndx].offset);
- stringTable = new byte[sheaders[header.shstrndx].size];
- fd.readFully(stringTable);
-
- for(int i=0;i<header.shnum;i++) {
- SHeader s = sheaders[i];
- s.name = getString(s.nameidx);
- }
- }
-
- private String getString(int off) { return getString(off,stringTable); }
- private String getString(int off,byte[] strtab) {
- StringBuffer sb = new StringBuffer();
- while(off < strtab.length && strtab[off] != 0) sb.append((char)strtab[off++]);
- return sb.toString();
- }
-
- public SHeader sectionWithName(String name) {
- for(int i=0;i<sheaders.length;i++)
- if(sheaders[i].name.equals(name))
- return sheaders[i];
- return null;
- }
-
- public class ELFException extends IOException { ELFException(String s) { super(s); } }
-
- private class MyRandomAccessFile extends RandomAccessFile {
- MyRandomAccessFile(String f,String m) throws IOException { super(f,m); }
- }
-
- private class SectionInputStream extends InputStream {
- private int pos;
- private int maxpos;
- SectionInputStream(int start, int end) throws IOException {
- if(sectionReaderActive)
- throw new IOException("Section reader already active");
- sectionReaderActive = true;
- pos = start;
- seek(pos);
- maxpos = end;
- }
-
- private int bytesLeft() { return maxpos - pos; }
- public int read() throws IOException { if(bytesLeft()==0) return -1; int b = fd.readByte(); if(b >= 0) pos++; return b; }
- public int read(byte[] b, int off, int len) throws IOException {
- fd.readFully(b,off,Math.min(len,bytesLeft())); return len;
- }
- public void close() { sectionReaderActive = false; }
- }
-
- private Symtab _symtab;
- public Symtab getSymtab() throws IOException {
- if(_symtab != null) return _symtab;
-
- SHeader sh = sectionWithName(".symtab");
- if(sh == null || sh.type != SHeader.SHT_SYMTAB) return null;
-
- SHeader sth = sectionWithName(".strtab");
- if(sth == null || sth.type != SHeader.SHT_STRTAB) return null;
-
- byte[] strtab = new byte[sth.size];
- DataInputStream dis = new DataInputStream(sth.getInputStream());
- dis.readFully(strtab);
- dis.close();
-
- return _symtab = new Symtab(sh.getInputStream(),sh.size,strtab);
- }
-
- public class Symtab {
- public Symbol[] symbols;
-
- Symtab(InputStream is, int size, byte[] strtab) throws IOException {
- DataInputStream dis = new DataInputStream(is);
- int count = size/16;
- symbols = new Symbol[count];
- for(int i=0;i<count;i++) symbols[i] = new Symbol(dis,strtab);
- dis.close();
- }
- }
-
- public class Symbol {
- public String name;
- public int addr;
- public int size;
- public byte info;
- public byte type;
- public byte other;
- public SHeader sheader;
-
- public final static int STT_FUNC = 2;
-
- Symbol(DataInputStream dis, byte[] strtab) throws IOException {
- name = getString(dis.readInt(),strtab);
- addr = dis.readInt();
- size = dis.readInt();
- info = dis.readByte();
- type = (byte)(info&0xf);
- other = dis.readByte();
- // FIXME: Find sheader entry
- dis.readShort();
- }
- }
-
- private static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
-
- public static void main(String[] args) throws IOException {
- ELF elf = new ELF(args[0]);
- System.out.println("Type: " + toHex(elf.header.type));
- System.out.println("Machine: " + toHex(elf.header.machine));
- System.out.println("Entry: " + toHex(elf.header.entry));
- for(int i=0;i<elf.pheaders.length;i++) {
- ELF.PHeader ph = elf.pheaders[i];
- System.out.println("PHeader " + toHex(i));
- System.out.println("\tOffset: " + ph.offset);
- System.out.println("\tVaddr: " + toHex(ph.vaddr));
- System.out.println("\tFile Size: " + ph.filesz);
- System.out.println("\tMem Size: " + ph.memsz);
- }
- for(int i=0;i<elf.sheaders.length;i++) {
- ELF.SHeader sh = elf.sheaders[i];
- System.out.println("SHeader " + toHex(i));
- System.out.println("\tName: " + sh.name);
- System.out.println("\tOffset: " + sh.offset);
- System.out.println("\tAddr: " + toHex(sh.addr));
- System.out.println("\tSize: " + sh.size);
- System.out.println("\tType: " + toHex(sh.type));
- }
- Symtab symtab = elf.getSymtab();
- }
-}