From: brian Date: Mon, 3 May 2004 19:09:08 +0000 (-0700) Subject: fix more fixmes/features X-Git-Tag: merge~26 X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=commitdiff_plain;h=ad692a248f2ed9412db5b313b85fd8365488017f fix more fixmes/features darcs-hash:20040503190908-24bed-7e9e4925bd1c9c42555070ca8beb94ad5e5a019e.gz --- diff --git a/src/org/ibex/nestedvm/ClassFileCompiler.java b/src/org/ibex/nestedvm/ClassFileCompiler.java index def556a..0f0b418 100644 --- a/src/org/ibex/nestedvm/ClassFileCompiler.java +++ b/src/org/ibex/nestedvm/ClassFileCompiler.java @@ -360,12 +360,20 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const cl.addMethod(getCPUState.getMethod()); - // FEATURE: Catch RuntimeException and turn it into a fault exception MethodGen execute = newMethod(ACC_PROTECTED,Type.VOID,Type.NO_ARGS,"_execute"); selectMethod(execute); - a(InstructionConstants.ALOAD_0); - a(fac.createInvoke(fullClassName,"trampoline",Type.VOID,Type.NO_ARGS,INVOKESPECIAL)); + InstructionHandle tryStart = a(InstructionConstants.ALOAD_0); + InstructionHandle tryEnd = a(fac.createInvoke(fullClassName,"trampoline",Type.VOID,Type.NO_ARGS,INVOKESPECIAL)); a(InstructionConstants.RETURN); + + InstructionHandle catchInsn = a(InstructionConstants.ASTORE_1); + a(fac.createNew("org.ibex.nestedvm.Runtime$FaultException")); + a(InstructionConstants.DUP); + a(InstructionConstants.ALOAD_1); + a(fac.createInvoke("org.ibex.nestedvm.Runtime$FaultException","",Type.VOID,new Type[]{new ObjectType("java.lang.RuntimeException")},INVOKESPECIAL)); + a(InstructionConstants.ATHROW); + + execute.addExceptionHandler(tryStart,tryEnd,catchInsn,new ObjectType("java.lang.RuntimeException")); execute.setMaxLocals(); execute.setMaxStack(); cl.addMethod(execute.getMethod()); @@ -1065,6 +1073,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const if(pc == -1) throw new Exn("pc modifying insn in delay slot"); int target = (pc&0xf0000000)|(jumpTarget << 2); emitInstruction(-1,nextInsn,-1); + // FIXME: Have a memcpy syscall and just override memcpy in libnestedvm if(optimizedMemcpy && (target == memcpy || target == memset)) { a(InstructionConstants.ALOAD_0); pushRegZ(R+4); @@ -1722,7 +1731,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const memWrite(); break; } - // FEATURE: This need to be atomic if we ever support threads (see SWC0/SC) + // This need to be atomic if we ever support threads (see SWC0/SC) case 48: // LWC0/LL preSetReg(R+rt); memRead(R+rs,signedImmediate); @@ -1735,7 +1744,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const setReg(); break; - /* FEATURE: This needs to fail (set rt to 0) if the memory location was modified + /* This needs to fail (set rt to 0) if the memory location was modified * between the LL and SC if we every support threads. */ case 56: // SWC0/SC diff --git a/src/org/ibex/nestedvm/Interpreter.java b/src/org/ibex/nestedvm/Interpreter.java index 276eea7..c840312 100644 --- a/src/org/ibex/nestedvm/Interpreter.java +++ b/src/org/ibex/nestedvm/Interpreter.java @@ -600,14 +600,14 @@ public class Interpreter extends UnixRuntime { memWrite(addr&~3,tmp); break; } - // FEATURE: Needs to be atomic w/ threads + // Needs to be atomic w/ threads case 48: // LWC0/LL r[rt] = memRead(r[rs] + signedImmediate); break; case 49: // LWC1 f[rt] = memRead(r[rs] + signedImmediate); break; - // FEATURE: Needs to be atomic w/ threads + // Needs to be atomic w/ threads case 56: memWrite(r[rs] + signedImmediate,r[rt]); r[rt] = 1; diff --git a/src/org/ibex/nestedvm/JavaSourceCompiler.java b/src/org/ibex/nestedvm/JavaSourceCompiler.java index b581d22..887e232 100644 --- a/src/org/ibex/nestedvm/JavaSourceCompiler.java +++ b/src/org/ibex/nestedvm/JavaSourceCompiler.java @@ -878,14 +878,14 @@ public class JavaSourceCompiler extends Compiler { memWrite("addr","tmp"); break; } - // FEATURE: Need to be atomic if threads + // Need to be atomic if threads case 48: // LWC0/LL memRead("r"+rs+"+"+signedImmediate,"r"+rt); break; case 49: // LWC1 memRead("r"+rs+"+"+signedImmediate,"f"+rt); break; - // FEATURE: Needs to be atomic if threads + // Needs to be atomic if threads case 56: // SWC1/SC memWrite("r"+rs+"+"+signedImmediate,"r"+rt); p("r" + rt + "=1;"); diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java index a745084..80fcadd 100644 --- a/src/org/ibex/nestedvm/Runtime.java +++ b/src/org/ibex/nestedvm/Runtime.java @@ -8,14 +8,11 @@ import org.ibex.nestedvm.util.*; import java.io.*; import java.util.Arrays; -// FEATURE: Look over the public API, make sure we're exposing a bare minimum -// (we might make this an interface in the future) - public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { /** Number of bits to shift to get the page number (1<<index in the _user_info table to word * The user_info table is a chunk of memory in the program's memory defined by the @@ -506,7 +503,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return state != PAUSED; } - protected static String[] concatArgv(String argv0, String[] rest) { + static String[] concatArgv(String argv0, String[] rest) { String[] argv = new String[rest.length+1]; System.arraycopy(rest,0,argv,1,rest.length); argv[0] = argv0; @@ -564,7 +561,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { } /** Hook for subclasses to do their own startup */ - protected void _started() { } + void _started() { } public final int call(String sym, Object[] args) throws CallException, FaultException { if(state != PAUSED && state != CALLJAVA) throw new IllegalStateException("call() called in inappropriate state"); @@ -651,18 +648,11 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return cpustate.r[V1]; } - - /** Determines if the process can access fileName. The default implementation simply logs - the request and allows it */ - protected boolean allowFileAccess(String fileName, boolean write) { - //System.err.println("Allowing " + (write?"write":"read-only") + " access to " + fileName); - return true; - } - + /** Allocated an entry in the FileDescriptor table for fd and returns the number. Returns -1 if the table is full. This can be used by subclasses to use custom file descriptors */ - public int addFD(FD fd) { + public final int addFD(FD fd) { if(state == EXITED || state == EXECED) throw new IllegalStateException("addFD called in inappropriate state"); int i; for(i=0;ifdn and removes it from the file descriptor table */ - public boolean closeFD(int fdn) { + public final boolean closeFD(int fdn) { if(state == EXITED || state == EXECED) throw new IllegalStateException("closeFD called in inappropriate state"); if(fdn < 0 || fdn >= OPEN_MAX) return false; if(fds[fdn] == null) return false; @@ -683,7 +673,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { } /** Duplicates the file descriptor fdn and returns the new fs */ - public int dupFD(int fdn) { + public final int dupFD(int fdn) { int i; if(fdn < 0 || fdn >= OPEN_MAX) return -1; if(fds[fdn] == null) return -1; @@ -893,7 +883,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { /** The sbrk syscall. This can also be used by subclasses to allocate memory. incr is how much to increase the break by */ - public int sbrk(int incr) { + public final int sbrk(int incr) { if(incr < 0) return -ENOMEM; if(incr==0) return heapEnd; incr = (incr+3)&~3; @@ -919,7 +909,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { /** The getpid syscall */ private int sys_getpid() { return getPid(); } - protected int getPid() { return 1; } + int getPid() { return 1; } public static interface CallJavaCB { public int call(int a, int b, int c, int d); } @@ -958,7 +948,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { /** Hook for subclasses to do something when the process exits */ - protected void _exited() { } + void _exited() { } private int sys_exit(int status) { exitStatus = status; @@ -1081,7 +1071,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { } /** Helper function to read a cstring from main memory */ - public String cstring(int addr) throws ReadFaultException { + public final String cstring(int addr) throws ReadFaultException { StringBuffer sb = new StringBuffer(); for(;;) { int word = memRead(addr&~3); @@ -1116,7 +1106,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { Seekable seekable() { return null; } /** Should return true if this is a tty */ - // FEATURE: get rid of the isatty syscall and just do with newlib's dumb isatty.c + // FIXME: get rid of the isatty syscall and just do with newlib's dumb isatty.c public boolean isatty() { return false; } private FStat cachedFStat = null; @@ -1190,13 +1180,14 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { public FStat _fstat() { return new FStat(); } } - protected static class StdinFD extends InputStreamFD { + static class StdinFD extends InputStreamFD { public StdinFD(InputStream is) { super(is); } public void _close() { /* noop */ } public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } }; } public boolean isatty() { return true; } } - protected static class StdoutFD extends OutputStreamFD { + + static class StdoutFD extends OutputStreamFD { public StdoutFD(OutputStream os) { super(os); } public void _close() { /* noop */ } public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } }; } @@ -1210,7 +1201,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { public static final int S_IFREG = 0100000; public int dev() { return -1; } - // FEATURE: inode numbers are calculated inconsistently throught the runtime + // FIXME: inode numbers are calculated inconsistently throught the runtime public int inode() { return hashCode() & 0xfffff; } public int mode() { return 0; } public int type() { return S_IFIFO; } @@ -1225,12 +1216,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { public int blocks() { return (size()+blksize()-1)/blksize(); } } - protected static class HostFStat extends FStat { + static class HostFStat extends FStat { private final File f; private final boolean executable; - public HostFStat(File f) { + public HostFStat(File f) { this(f,false); } + public HostFStat(File f, boolean executable) { this.f = f; - executable = executable(); + this.executable = executable; } public int dev() { return 1; } public int inode() { return f.getName().hashCode() & 0xffff; } @@ -1245,21 +1237,21 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return mode; } public int size() { return (int) f.length(); } - public int mtime() { return (int)(f.lastModified()/1000); } - - boolean executable() { return false; } + public int mtime() { return (int)(f.lastModified()/1000); } } // Exceptions - public class ReadFaultException extends FaultException { + public static class ReadFaultException extends FaultException { public ReadFaultException(int addr) { super(addr); } } - public class WriteFaultException extends FaultException { + public static class WriteFaultException extends FaultException { public WriteFaultException(int addr) { super(addr); } } - public abstract class FaultException extends ExecutionException { - public int addr; - public FaultException(int addr) { super("fault at: " + toHex(addr)); this.addr = addr; } + public static class FaultException extends ExecutionException { + public final int addr; + public final RuntimeException cause; + public FaultException(int addr) { super("fault at: " + toHex(addr)); this.addr = addr; cause = null; } + public FaultException(RuntimeException e) { super(e.toString()); addr = -1; cause = e; } } public static class ExecutionException extends Exception { private String message = "(null)"; @@ -1323,7 +1315,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return _byteBuf; } - protected static String getSystemProperty(String key) { + static String getSystemProperty(String key) { try { return System.getProperty(key); } catch(SecurityException e) { @@ -1348,7 +1340,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { return buf; } - protected static byte[] getBytes(String s) { + static byte[] getBytes(String s) { try { return s.getBytes("ISO-8859-1"); } catch(UnsupportedEncodingException e) { @@ -1356,7 +1348,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { } } - 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; } + final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); } + final static int min(int a, int b) { return a < b ? a : b; } + final static int max(int a, int b) { return a > b ? a : b; } } diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 051a50b..8aa5dc7 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -4,16 +4,19 @@ import org.ibex.nestedvm.util.*; import java.io.*; import java.util.*; +// FIXME: Fix readdir in support_aux.c +// FIXME: Make plain old "mips-unknown-elf-gcc -o foo foo.c" work (modify spec file or whatever) + // FEATURE: Remove System.{out,err}.printlns and throw Errors where applicable -// FEATURE: BusyBox's ASH doesn't like \r\n at the end of lines +// FIXME: BusyBox's ASH doesn't like \r\n at the end of lines // is ash just broken or are many apps like this? if so workaround in nestedvm public abstract class UnixRuntime extends Runtime implements Cloneable { /** The pid of this "process" */ private int pid; private UnixRuntime parent; - protected int getPid() { return pid; } + public final int getPid() { return pid; } private static final GlobalState defaultGD = new GlobalState(); private GlobalState gd = defaultGD; @@ -29,7 +32,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private Vector activeChildren; private Vector exitedChildren; - public UnixRuntime(int pageSize, int totalPages) { + protected UnixRuntime(int pageSize, int totalPages) { super(pageSize,totalPages); // FEATURE: Do the proper mangling for non-unix hosts @@ -59,7 +62,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return false; } - protected String[] createEnv(String[] extra) { + String[] createEnv(String[] extra) { String[] defaults = new String[5]; int n=0; if(extra == null) extra = new String[0]; @@ -78,7 +81,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private static class ProcessTableFullExn extends RuntimeException { } - protected void _started() { + void _started() { UnixRuntime[] tasks = gd.tasks; synchronized(gd) { if(pid != 0) { @@ -114,7 +117,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } } - protected FD _open(String path, int flags, int mode) throws ErrnoException { + FD _open(String path, int flags, int mode) throws ErrnoException { return gd.open(this,normalizePath(path),flags,mode); } @@ -191,7 +194,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } - protected void _exited() { + void _exited() { if(children != null) synchronized(children) { for(Enumeration e = exitedChildren.elements(); e.hasMoreElements(); ) { UnixRuntime child = (UnixRuntime) e.nextElement(); @@ -431,9 +434,8 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { protected static final int LSTAT = 3; protected static final int MKDIR = 4; - // Make this protected (need to fix _exit) - private final UnixRuntime[] tasks; - private int nextPID = 1; + final UnixRuntime[] tasks; + int nextPID = 1; private final MP[][] mps = new MP[128][]; private FS root; @@ -627,8 +629,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } public abstract static class FS { - // FEATURE: inode stuff - // FEATURE: Implement whatever is needed to get newlib's opendir and friends to work - that patch is a pain + // FIXME: inode stuff protected static FD directoryFD(String[] files, int hashCode) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); @@ -661,6 +662,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public abstract void mkdir(UnixRuntime r, String path, int mode) throws ErrnoException; } + // FEATURE: chroot support in here private String normalizePath(String path) { boolean absolute = path.startsWith("/"); int cwdl = cwd.length(); @@ -703,20 +705,21 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { //System.err.println("normalize: " + path + " -> " + new String(out,0,outp) + " (cwd: " + cwd + ")"); return new String(out,0,outp); } - - // FEATURE: override Runtime.hostFStat to add executable type checking - // hostFStat - /* try { - FileInputStream fis = new FileInputStream(f); - switch(fis.read()) { - case '\177': _executable = fis.read() == 'E' && fis.read() == 'L' && fis.read() == 'F'; break; - case '#': _executable = fis.read() == '!'; - } - fis.close(); - } catch(IOException e) { } - */ + + FStat hostFStat(final File f) { + boolean e = false; + try { + FileInputStream fis = new FileInputStream(f); + switch(fis.read()) { + case '\177': e = fis.read() == 'E' && fis.read() == 'L' && fis.read() == 'F'; break; + case '#': e = fis.read() == '!'; + } + fis.close(); + } catch(IOException e2) { } + return new HostFStat(f,e); + } - // FEATURE: inode stuff + // FIXME: inode stuff FD hostFSDirFD(File f) { return FS.directoryFD(f.list(),f.hashCode()); } public static class HostFS extends FS { diff --git a/src/tests/Test.c b/src/tests/Test.c index 88e1eb6..d133ede 100644 --- a/src/tests/Test.c +++ b/src/tests/Test.c @@ -98,6 +98,9 @@ int main(int argc, char **argv) { } else if(argc > 1 && strcmp(argv[1],"nullderef")==0) { volatile int *mem = 0; *mem = 1; + } else if(argc > 2 && strcmp(argv[1],"crashme") == 0) { + volatile int *mem = (int*) atoi(argv[2]); + *mem = 1; } else { printf("%d\n", 0xffffff); printf("%u\n", 0xffffffU);