X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fmips%2FInterpreter.java;h=81aa042cb80ae4607b623445e0a7f174f221b282;hb=4923e8529bbd51d0d03387d2f08ae08b38d5ef4a;hp=ddc4d696fc83d390d3c87872d280691d2edce7d5;hpb=14c79b82aa525bab500334fac875b4d2b2685926;p=org.ibex.core.git diff --git a/src/org/xwt/mips/Interpreter.java b/src/org/xwt/mips/Interpreter.java index ddc4d69..81aa042 100644 --- a/src/org/xwt/mips/Interpreter.java +++ b/src/org/xwt/mips/Interpreter.java @@ -1,12 +1,11 @@ // Copyright 2003 Adam Megacz // Author Brian Alliet -// Based on org.xwt.imp.MIPS by Adam Megacz - -package org.xwt.imp; +// Based on org.xwt.mips.Compiler by Adam Megacz +package org.xwt.mips; import java.io.*; -public class MIPSInterpreter extends MIPSEmu { +public class Interpreter extends VM { // Registers private int[] registers = new int[32]; @@ -661,8 +660,8 @@ public class MIPSInterpreter extends MIPSEmu { registers[RA] = 0xdeadbeef; nextPC = pc; } - public MIPSInterpreter() { } - public MIPSInterpreter(String image) throws IOException { loadImage(image); } + public Interpreter() { } + public Interpreter(String image) throws IOException { loadImage(image); } // Debug functions // NOTE: This probably requires a jdk > 1.1, however, it is only used for debugging @@ -691,7 +690,7 @@ public class MIPSInterpreter extends MIPSEmu { public static void main(String[] argv) throws Exception { String image = argv[0]; - MIPSInterpreter emu = new MIPSInterpreter(); + Interpreter emu = new Interpreter(); emu.loadImage(image); Runtime.getRuntime().addShutdownHook(new Thread(emu.new DebugShutdownHook())); // User data @@ -710,985 +709,4 @@ public class MIPSInterpreter extends MIPSEmu { } } -abstract class MIPSEmu implements Syscalls, Errno { - // Register Names - protected final static int ZERO = 0; // Immutable, hardwired to 0 - protected final static int AT = 1; // Reserved for assembler - protected final static int K0 = 26; // Reserved for kernel - protected final static int K1 = 27; // Reserved for kernel - protected final static int GP = 28; // Global pointer (the middle of .sdata/.sbss) - protected final static int SP = 29; // Stack pointer - protected final static int FP = 30; // Frame Pointer - protected final static int RA = 31; // Return Address - - // Return values (caller saved) - protected final static int V0 = 2; - protected final static int V1 = 3; - // Argument Registers (caller saved) - protected final static int A0 = 4; - protected final static int A1 = 5; - protected final static int A2 = 6; - protected final static int A3 = 7; - // Temporaries (caller saved) - protected final static int T0 = 8; - protected final static int T1 = 9; - protected final static int T2 = 10; - protected final static int T3 = 11; - protected final static int T4 = 12; - protected final static int T5 = 13; - protected final static int T6 = 14; - protected final static int T7 = 15; - protected final static int T8 = 24; - protected final static int T9 = 25; - // Saved (callee saved) - protected final static int S0 = 16; - protected final static int S1 = 17; - protected final static int S2 = 18; - protected final static int S3 = 19; - protected final static int S4 = 20; - protected final static int S5 = 21; - protected final static int S6 = 22; - protected final static int S7 = 23; - - // Page Constants - // Page Size: 4k - // Total Pages: 64k - // Maxiumum Addressable memory 256mb - // 1mb of stack space - protected final static int PAGE_SIZE = 4096; - protected final static int PAGE_WORDS = (int)(PAGE_SIZE >>> 2); - protected final static int PAGE_SHIFT = 12; - protected final static int STACK_PAGES = 256; - // NOTE: If you change TOTAL_PAGES crt0.c needs to be updated to reflect the - // new location of INITIAL_SP - protected final static int TOTAL_PAGES = 65536; - protected final static int BRK_LIMIT = 32768; - // Top page is always empty - // next page down contains command line arguments - protected final static int ARGS_ADDR = (TOTAL_PAGES-2)*PAGE_SIZE; - // next page down contains _user_info data - protected final static int USER_INFO_ADDR = (TOTAL_PAGES-3)*PAGE_SIZE; - // next page down is the start of the stack - protected final static int INITIAL_SP = (TOTAL_PAGES-3)*PAGE_SIZE; - // magic page that signified an allocated but empty (untouched) page - private final static int[] emptyPage = new int[0]; - - // Main memory - protected final int[][] readPages; - protected final int[][] writePages; - - // Brk - protected int brk; // PAGE not address - - // Entry point - what start() sets pc to - protected int entryPoint; - - // State constants - public final static int UNINITIALIZED = 0; - public final static int INITIALIZED = 1; - public final static int RUNNING = 2; - public final static int PAUSED = 3; - public final static int DONE = 4; - - // State - protected int state = UNINITIALIZED; - public final int getState() { return state; } - protected int exitStatus; - - // File descriptors - private final static int OPEN_MAX = 256; - private FileDescriptor[] fds; - - // Temporary buffer for read/write operations - private byte[] _byteBuf = null; - private final static int MAX_CHUNK = 4*1024*1024-8; - - // Abstract methods - // This should start executing at pc - public abstract void execute() throws EmulationException; - // This should initialize the cpu registers to point to the entry point - protected abstract void _start(int pc); - - public static final int PID = 1; - - public MIPSEmu() { - readPages = new int[TOTAL_PAGES][]; - writePages = new int[TOTAL_PAGES][]; - for(int i=0;i>>16)&0xff); if(length-n==0) break; - case 2: a[n++] = (byte)((word>>> 8)&0xff); if(length-n==0) break; - case 3: a[n++] = (byte)((word>>> 0)&0xff); if(length-n==0) break; - } - addr = (addr&~3)+4; - } - while(length-n > 3) { - int start = (addr&(PAGE_SIZE-1))>>2; - int end = start + (min(PAGE_SIZE-(addr&(PAGE_SIZE-1)),(length-n)&~3) >> 2); - int[] page = readPages[addr >>> PAGE_SHIFT]; - if(page == null) throw new ReadFaultException(addr); - if(page == emptyPage) { addr+=(end-start); n+=(end-start); continue; } - for(int i=start;i>>24)&0xff); a[n++] = (byte)((word>>>16)&0xff); - a[n++] = (byte)((word>>> 8)&0xff); a[n++] = (byte)((word>>> 0)&0xff); - } - } - if(length-n > 0) { - int word = memRead(addr); - if(length-n >= 1) a[n] = (byte)((word>>>24)&0xff); - if(length-n >= 2) a[n+1] = (byte)((word>>>16)&0xff); - if(length-n >= 3) a[n+2] = (byte)((word>>> 8)&0xff); - } - } - - public void copyout(byte[] a, int addr, int length) throws FaultException { - int n=0; - if((addr&3)!=0) { - int word = memRead(addr&~3); - switch(addr&3) { - case 1: word = (word&0xff00ffff)|((a[n]&0xff)<<16); n++; if(length-n==0) break; - case 2: word = (word&0xffff00ff)|((a[n]&0xff)<< 8); n++; if(length-n==0) break; - case 3: word = (word&0xffffff00)|((a[n]&0xff)<< 0); n++; if(length-n==0) break; - } - memWrite(addr&~3,word); - addr = (addr&~3)+4; - } - - while(length-n > 3) { - int start = (addr&(PAGE_SIZE-1))>>2; - int end = start + (min(PAGE_SIZE-(addr&(PAGE_SIZE-1)),(length-n)&~3) >> 2); - int[] page = writePages[addr >>> PAGE_SHIFT]; - if(page == null) throw new WriteFaultException(addr); - if(page == emptyPage) { memWrite(addr,0); page = writePages[addr >>> PAGE_SHIFT]; } - for(int i=start;i 0) { - int word = memRead(addr); - word = (word&0x00ffffff)|((a[n]&0xff)<<24); - if(length-n > 1) { word = (word&0xff00ffff)|((a[n+1]&0xff)<<16); } - if(length-n > 2) { word = (word&0xffff00ff)|((a[n+2]&0xff)<< 8); } - memWrite(addr,word); - } - } - - protected final int memRead(int addr) throws ReadFaultException { - if((addr & 3) != 0) throw new ReadFaultException(addr); - int page = addr >>> PAGE_SHIFT; - int entry = (addr >>> 2) & (PAGE_WORDS-1); - try { - return readPages[page][entry]; - } catch(ArrayIndexOutOfBoundsException e) { - if(page < 0) throw e; // should never happen - if(page > readPages.length) throw new ReadFaultException(addr); - if(readPages[page] != emptyPage) throw e; // should never happen - initPage(page); - return 0; - } catch(NullPointerException e) { - throw new ReadFaultException(addr); - } - } - - protected final void memWrite(int addr, int value) throws WriteFaultException { - if((addr & 3) != 0) throw new WriteFaultException(addr); - int page = addr >>> PAGE_SHIFT; - int entry = (addr>>>2)&(PAGE_WORDS-1); - try { - writePages[page][entry] = value; - } catch(ArrayIndexOutOfBoundsException e) { - if(page < 0) throw e;// should never happen - if(page > writePages.length) throw new WriteFaultException(addr); - if(readPages[page] != emptyPage) throw e; // should never happen - initPage(page); - writePages[page][entry] = value; - } catch(NullPointerException e) { - throw new WriteFaultException(addr); - } - } - - protected void initPage(int page) { writePages[page] = readPages[page] = new int[PAGE_WORDS]; } - - public final int exitStatus() { - if(state != DONE) throw new IllegalStateException("exitStatus() called in an inappropriate state"); - return exitStatus; - } - - public final int run(String[] args) throws EmulationException { - start(args); - for(;;) { - execute(); - if(state != PAUSED) break; - System.err.println("WARNING: Pause requested while executing run()"); - try { Thread.sleep(500); } catch(InterruptedException e) { } - } - if(state != DONE) throw new IllegalStateException("run() ended up in an inappropriate state"); - return exitStatus(); - } - - private void addArgs(String[] args) throws EmulationException { - if(state == UNINITIALIZED || state == RUNNING || state == PAUSED) throw new IllegalStateException("addArgs() called in inappropriate state"); - int count = args.length; - byte[] nullTerminator = new byte[1]; - int total = 4; /* null last table entry */ - for(int i=0;i PAGE_SIZE) throw new EmulationException("Arguments too large"); - int start = ARGS_ADDR; - int addr = start + (count+1)*4; - int[] table = new int[count+1]; - for(int i=0;i= 1024) throw new EmulationException("setUserInfo called with index >= 1024"); - memWrite(USER_INFO_ADDR+index*4,word); - } - - public int getUserInfo(int index) throws EmulationException { - if(index < 0 || index >= 1024) throw new EmulationException("getUserInfo called with index >= 1024"); - return memRead(USER_INFO_ADDR+index*4); - } - - public final void start(String[] args) throws EmulationException { - if(state == UNINITIALIZED || state == RUNNING || state == PAUSED) throw new IllegalStateException("start() called in inappropriate state"); - _start(entryPoint); - addArgs(args); - fds = new FileDescriptor[OPEN_MAX]; - fds[0] = new InputStreamFD(System.in) { public boolean isatty() { return true; } }; - fds[1] = new OutputStreamFD(System.out) { public boolean isatty() { return true; } }; - fds[2] = new OutputStreamFD(System.err) { public boolean isatty() { return true; } }; - state = PAUSED; - } - - - // Syscalls - private int write(int fdn, int addr, int count) { - int n = 0; - int r; - FileDescriptor fd; - count = Math.min(count,MAX_CHUNK); - try { - fd = fds[fdn]; - if(fd == null || !fd.writable()) return -EBADFD; - } catch(ArrayIndexOutOfBoundsException e) { - return -EBADFD; - } - try { - byte[] buf = byteBuf(count); - copyin(addr,buf,count); - return fd.write(buf,0,count); - } catch(FaultException e) { - System.err.println(e); - return -EFAULT; - } catch(IOException e) { - System.err.println(e); - return -EIO; - } - } - - private int read(int fdn, int addr, int count) { - FileDescriptor fd; - count = Math.min(count,MAX_CHUNK); - try { - fd = fds[fdn]; - if(fd == null || !fd.readable()) return -EBADFD; - } catch(ArrayIndexOutOfBoundsException e) { - return -EBADFD; - } - try { - byte[] buf = byteBuf(count); - int n = fd.read(buf,0,count); - copyout(buf,addr,n); - return n; - } catch(FaultException e) { - System.err.println(e); - return -EFAULT; - } catch(IOException e) { - System.err.println(e); - return -EIO; - } - } - - private int close(int fdn) { - FileDescriptor fd; - try { - fd = fds[fdn]; - if(fd == null) return -EBADFD; - } catch(ArrayIndexOutOfBoundsException e) { - return -EBADFD; - } - fds[fdn] = null; - fd.close(); - return 0; - } - - private int stat(FileInfo fi, int addr) { - int size = fi.size(); - try { - memWrite(addr+0,0); // st_dev (top 16), // st_ino (bottom 16) - memWrite(addr+4,(fi.type() & 0xf000)|0644); // st_mode - memWrite(addr+8,1); // st_nlink (top 16) // st_uid (bottom 16) - memWrite(addr+12,0); // st_gid (top 16) // st_rdev (bottom 16) - memWrite(addr+16,size); // st_size - memWrite(addr+20,0); // st_atime - // memWrite(addr+24,0) // st_spare1 - memWrite(addr+28,(int)(fi.modTime()/1000)); // st_mtime - // memWrite(addr+32,0) // st_spare2 - memWrite(addr+36,0); // st_atime - // memWrite(addr+40,0) // st_spare3 - memWrite(addr+44,512); // st_bklsize; - memWrite(addr+48,(size+511)&(~511)); // st_blocks - // memWrite(addr+52,0) // st_spare4[0] - // memWrite(addr+56,0) // st_spare4[1] - } catch(FaultException e) { - System.err.println(e); - return -EFAULT; - } - return 0; - } - - private int fstat(int fdn, int addr) { - FileDescriptor fd; - try { - fd = fds[fdn]; - if(fd == null) return -EBADFD; - } catch(ArrayIndexOutOfBoundsException e) { - return -EBADFD; - } - return stat(fd.fileInfo(),addr); - } - - public int sbrk(int incr) { - if(incr==0) return brk<>PAGE_SHIFT); - if(newBrk >= BRK_LIMIT) { - System.err.println("Hit BRK_LIMIT"); - return -ENOMEM; - } - for(int i=oldBrk;i= Integer.MAX_VALUE) return -EOPNOTSUPP; - } else { - if((flags & O_CREAT) == 0) return -ENOENT; - } - for(int i=0;i= 0) return -EACCES; - return -ENOENT; - } catch(IOException e) { - return -EIO; - } - } - - private int seek(int fdn, int offset, int whence) { - FileDescriptor fd; - try { - fd = fds[fdn]; - if(fd == null || !fd.readable()) return -EBADFD; - } catch(ArrayIndexOutOfBoundsException e) { - return -EBADFD; - } - try { - return fd.seek(offset,whence); - } catch(IOException e) { - System.err.println(e); - return -EPIPE; - } - } - - // This will only be called by raise() to invoke the default handler - // We don't have to worry about actually delivering the signal - private int kill(int pid, int signal) { - if(pid != PID) return -ESRCH; - if(signal < 0 || signal >= 32) return -EINVAL; - switch(signal) { - case 0: return 0; - case 17: // SIGSTOP - case 18: // SIGTSTP - case 21: // SIGTTIN - case 22: // SIGTTOU - state = PAUSED; - break; - case 19: // SIGCONT - case 20: // SIGCHLD - case 23: // SIGIO - case 28: // SIGWINCH - break; - default: { - String msg = "Terminating on signal: " + signal + "\n"; - exitStatus = 1; - state = DONE; - if(fds[2]==null) { - System.out.print(msg); - } else { - byte[] b = msg.getBytes(); - try { - fds[2].write(b,0,b.length); - } catch(IOException e) { } - } - } - } - return 0; - } - - private int getpid() { return PID; } - - protected int syscall(int syscall, int a, int b, int c, int d) { - switch(syscall) { - case SYS_null: return 0; - case SYS_exit: exitStatus = a; state = DONE; return 0; - case SYS_pause: state = PAUSED; return 0; - case SYS_write: return write(a,b,c); - case SYS_fstat: return fstat(a,b); - case SYS_sbrk: return sbrk(a); - case SYS_open: return open(a,b,c); - case SYS_close: return close(a); - case SYS_read: return read(a,b,c); - case SYS_seek: return seek(a,b,c); - case SYS_kill: return kill(a,b); - case SYS_getpid: return getpid(); - default: - System.err.println("Attempted to use unknown syscall: " + syscall); - return -ENOSYS; - } - } - - // Helper function to read a cstring from main memory - private String cstring(int addr) throws ReadFaultException { - StringBuffer sb = new StringBuffer(); - for(;;) { - int word = memRead(addr&~3); - switch(addr&3) { - case 0: if(((word>>>24)&0xff)==0) return sb.toString(); sb.append((char)((word>>>24)&0xff)); addr++; - case 1: if(((word>>>16)&0xff)==0) return sb.toString(); sb.append((char)((word>>>16)&0xff)); addr++; - case 2: if(((word>>> 8)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 8)&0xff)); addr++; - case 3: if(((word>>> 0)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 0)&0xff)); addr++; - } - } - } - - // Exceptions - public static class ReadFaultException extends FaultException { - public ReadFaultException(int addr) { super(addr); } - } - public static class WriteFaultException extends FaultException { - public WriteFaultException(int addr) { super(addr); } - } - public static abstract class FaultException extends EmulationException { - private int addr; - public FaultException(int addr) { this.addr = addr; } - public String getMessage() { return "fault at: " + toHex(addr); } - } - public static class EmulationException extends Exception { - public EmulationException() { } - public EmulationException(String s) { super(s); } - } - - // FileInfo classes - used by stat(2) - static class FileInfo { - public static final int S_IFIFO = 0010000; - public static final int S_FCHR = 0020000; - public static final int S_IFDIR = 0040000; - public static final int S_IFREG = 0100000; - - public int size() { return 0; } - public int type() { return S_IFIFO; } - public long modTime() { return 0; } - } - - public static class FileFileInfo extends FileInfo { - public File f; - public FileFileInfo(File f) { this.f = f; } - public int size() { return (int)f.length(); } - public int type() { return f.isDirectory() ? S_IFDIR : S_IFREG; } - public long modTime() { return f.lastModified(); } - } - - // File descriptor classes - public static abstract class FileDescriptor { - public boolean readable() { return false; } - public boolean writable() { return false; } - - private static final FileInfo nullFi = new FileInfo(); - private FileInfo fi; - public FileInfo fileInfo() { return fi; } - - FileDescriptor() { this(null); } - FileDescriptor(FileInfo fi) { this.fi = fi==null ? nullFi : fi; } - - public int read(byte[] a, int off, int length) throws IOException { throw new IOException("no definition"); } - public int write(byte[] a, int off, int length) throws IOException { throw new IOException("no definition"); } - - public int seek(int n, int whence) throws IOException { return -ESPIPE; } - public boolean isatty() { return false; } - - void close() { } - } - - public static class RegularFileDescriptor extends FileDescriptor { - private int mode; - private RandomAccessFile raf; - public boolean readable() { return mode != 1; } - public boolean writable() { return mode != 0; } - - RegularFileDescriptor(File f,int m) throws IOException { - super(new FileFileInfo(f)); - String mode = m == 0 ? "r" : "rw"; - this.mode = m; - raf = new RandomAccessFile(f,mode); - if(raf.length() >= Integer.MAX_VALUE) throw new IOException("File too large"); - } - - public int seek(int n, int whence) throws IOException { - final int SEEK_SET = 0; - final int SEEK_CUR = 1; - final int SEEK_END = 2; - - switch(whence) { - case SEEK_SET: break; - case SEEK_CUR: n = (int)(raf.getFilePointer()+n); break; - case SEEK_END: n = (int)(raf.length()+n); break; - default: return -EINVAL; - } - raf.seek(n); - return n; - } - - public int write(byte[] a, int off, int length) throws IOException { raf.write(a,off,length); return length; } - public int read(byte[] a, int off, int length) throws IOException { int n = raf.read(a,off,length); return n < 0 ? 0 : n; } - - void close() { try { raf.close(); } catch(Exception e) { } } - } - - public class OutputStreamFD extends FileDescriptor { - private OutputStream os; - public boolean writable() { return true; } - public OutputStreamFD(OutputStream os) { this.os = os; } - public int write(byte[] a, int off, int length) throws IOException { os.write(a,off,length); return length; } - } - - public class InputStreamFD extends FileDescriptor { - private InputStream is; - public boolean readable() { return true; } - public InputStreamFD(InputStream is) { this.is = is; } - public int read(byte[] a, int off, int length) throws IOException { int n = is.read(a,off,length); return n < 0 ? 0 : n; } - } - - // Utility functions - private byte[] byteBuf(int size) { - if(_byteBuf==null) _byteBuf = new byte[size]; - else if(_byteBuf.length < size) - _byteBuf = new byte[min(max(_byteBuf.length*2,size),MAX_CHUNK+8)]; - return _byteBuf; - } - protected final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); } - protected final static int min(int a, int b) { return a < b ? a : b; } - protected final static int max(int a, int b) { return a > b ? a : b; } -} - -class ELF { - private MyRandomAccessFile fd; - - public ELFHeader header; - public PHeader[] pheaders; - public SHeader[] sheaders; - - 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.skipFully(1); // version - osabi = fd.readByte(); - abiversion = fd.readByte(); - fd.skipFully(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 T_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 == T_NOBITS ? 0 : offset+size)); - } - } - - public ELF(String file) throws IOException, ELFException { - fd = new MyRandomAccessFile(file,"r"); - 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); - for(int i=0;i0) n-= skipBytes(n); - } - } - - 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; - fd.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(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; - } - public void close() { sectionReaderActive = false; } - } - - 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)); - for(int i=0;i