X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fmips%2FELF.java;h=2a9b611ba582b750f562af97e74e1be4f1d72a0c;hb=ff3815a13aa6a57852f28c789f8a8d22f2a1f26e;hp=50f7ab34860d6bb767c3326b4fc145108304dee0;hpb=4923e8529bbd51d0d03387d2f08ae08b38d5ef4a;p=org.ibex.core.git diff --git a/src/org/xwt/mips/ELF.java b/src/org/xwt/mips/ELF.java index 50f7ab3..2a9b611 100644 --- a/src/org/xwt/mips/ELF.java +++ b/src/org/xwt/mips/ELF.java @@ -1,13 +1,26 @@ package org.xwt.mips; import java.io.*; -class ELF { - private MyRandomAccessFile fd; +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 { @@ -37,10 +50,10 @@ class ELF { if(fd.readInt() != ELF_MAGIC) throw new ELFException("Bad Magic (is: " ); klass = fd.readByte(); data = fd.readByte(); - fd.skipFully(1); // version + fd.skipBytes(1); // version osabi = fd.readByte(); abiversion = fd.readByte(); - fd.skipFully(7); + fd.skipBytes(7); type = fd.readShort(); machine = fd.readShort(); version = fd.readInt(); @@ -88,8 +101,8 @@ class ELF { public boolean writable() { return (flags & PF_W) != 0; } public InputStream getInputStream() throws IOException { - return new BufferedInputStream(new SectionInputStream( - offset,offset+filesz)); + return new BufferedInputStream(new SectionInputStream( + offset,offset+filesz)); } } @@ -106,7 +119,9 @@ class ELF { 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(); @@ -122,36 +137,47 @@ class ELF { } 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(String file) throws IOException, ELFException { - fd = new MyRandomAccessFile(file,"r"); + 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.shnum) throw new ELFException("Bad shstrndx"); - fd.seek(sheaders[header.shstrndx].offset); - byte[] a = new byte[sheaders[header.shstrndx].size]; - fd.readFully(a); + seek(sheaders[header.shstrndx].offset); + stringTable = new byte[sheaders[header.shstrndx].size]; + fd.readFully(stringTable); + for(int i=0;i0) n-= skipBytes(n); - } + MyRandomAccessFile(String f,String m) throws FileNotFoundException { super(f,m); } } - + private class SectionInputStream extends InputStream { private int pos; private int maxpos; @@ -176,24 +199,78 @@ class ELF { throw new IOException("Section reader already active"); sectionReaderActive = true; pos = start; - fd.seek(pos); + seek(pos); maxpos = end; } private int bytesLeft() { return maxpos - pos; } - public int read() throws IOException { if(bytesLeft()==0) return -1; int b = fd.read(); if(b >= 0) pos++; return b; } + 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 { - int n = fd.read(b,off,Math.min(len,bytesLeft())); if(n > 0) pos += n; return n; + 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