package org.xwt.mips;
import java.io.*;
-class ELF {
+public class ELF {
private DataInput fd;
private Object image;
public PHeader[] pheaders;
public SHeader[] sheaders;
+ private byte[] stringTable;
+
private boolean sectionReaderActive;
- private static void skipFully(DataInput fd, int n) throws IOException {
- while(n>0) n -= fd.skipBytes(n);
- }
-
public class ELFHeader {
byte klass;
byte data;
if(fd.readInt() != ELF_MAGIC) throw new ELFException("Bad Magic (is: " );
klass = fd.readByte();
data = fd.readByte();
- skipFully(fd, 1); // version
+ fd.skipBytes(1); // version
osabi = fd.readByte();
abiversion = fd.readByte();
- skipFully(fd, 7);
+ fd.skipBytes(7);
type = fd.readShort();
machine = fd.readShort();
version = fd.readInt();
}
public boolean writable() { return (flags & PF_W) != 0; }
- public boolean executable() { return (flags & PF_X) != 0; }
public InputStream getInputStream() throws IOException {
- return new BufferedInputStream(new SectionInputStream(
- offset,offset+filesz));
+ return new BufferedInputStream(new SectionInputStream(
+ offset,offset+filesz));
}
}
public int addralign;
public int entsize;
- public static final int T_NOBITS = 8;
+ 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();
}
public InputStream getInputStream() throws IOException {
- return new BufferedInputStream(new SectionInputStream(
- offset, type == T_NOBITS ? 0 : offset+size));
+ return new BufferedInputStream(new SectionInputStream(
+ offset, type == SHT_NOBITS ? 0 : offset+size));
}
}
public ELF(Object img) throws IOException, ELFException {
+ if (img instanceof String) image = new MyRandomAccessFile((String)img,"r");
image = img;
seek(0);
header = new ELFHeader();
}
if(header.shstrndx < 0 || header.shstrndx >= header.shnum) throw new ELFException("Bad shstrndx");
seek(sheaders[header.shstrndx].offset);
- byte[] a = new byte[sheaders[header.shstrndx].size];
- fd.readFully(a);
+ stringTable = new byte[sheaders[header.shstrndx].size];
+ fd.readFully(stringTable);
+
for(int i=0;i<header.shnum;i++) {
SHeader s = sheaders[i];
- StringBuffer sb = new StringBuffer();
- for(int off = s.nameidx;off < a.length && a[off] != 0; off++) sb.append((char)a[off]);
- s.name = sb.toString();
- }
+ 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))
public class ELFException extends IOException { ELFException(String s) { super(s); } }
+ private class MyRandomAccessFile extends RandomAccessFile {
+ MyRandomAccessFile(String f,String m) throws FileNotFoundException { super(f,m); }
+ }
+
private class SectionInputStream extends InputStream {
private int pos;
private int maxpos;
}
private int bytesLeft() { return maxpos - pos; }
- public int read() throws IOException {
- if(bytesLeft()==0) return -1;
- try {
- byte b = fd.readByte();
- pos++;
- return b;
- } catch (EOFException e) {
- return -1;
- }
- }
+ 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, len);
- return len;
+ 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("\tSize: " + sh.size);
System.out.println("\tType: " + toHex(sh.type));
}
+ Symtab symtab = elf.getSymtab();
}
}