X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FUnixRuntime.java;h=c88cf241746e90e71fdae72ff6132b647ff21ba4;hp=0b50ee30b65315cd3500d455d6b3bf71d33bf1e3;hb=79be771d6242d4ed6831d737c701587e87528572;hpb=18f9d34628d03afdf74b95ccd96e6e2e8441fb54 diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 0b50ee3..c88cf24 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -1,3 +1,7 @@ +// Copyright 2000-2005 the Contributors, as shown in the revision logs. +// Licensed under the Apache Public Source License 2.0 ("the License"). +// You may not use this file except in compliance with the License. + package org.ibex.nestedvm; import org.ibex.nestedvm.util.*; @@ -6,6 +10,7 @@ import org.ibex.classgen.util.Sort; import java.io.*; import java.util.*; import java.net.*; +import java.lang.reflect.*; // For lazily linked RuntimeCompiler // FEATURE: vfork @@ -19,6 +24,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private GlobalState gs; public void setGlobalState(GlobalState gs) { if(state != STOPPED) throw new IllegalStateException("can't change GlobalState when running"); + if(gs == null) throw new NullPointerException("gs is null"); this.gs = gs; } @@ -161,7 +167,14 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { case SYS_sendto: return sys_sendto(a,b,c,d,e,f); case SYS_recvfrom: return sys_recvfrom(a,b,c,d,e,f); case SYS_select: return sys_select(a,b,c,d,e); - + case SYS_access: return sys_access(a,b); + case SYS_realpath: return sys_realpath(a,b); + case SYS_chown: return sys_chown(a,b,c); + case SYS_lchown: return sys_chown(a,b,c); + case SYS_fchown: return sys_fchown(a,b,c); + case SYS_chmod: return sys_chmod(a,b,c); + case SYS_fchmod: return sys_fchmod(a,b,c); + default: return super._syscall(syscall,a,b,c,d,e,f); } } @@ -173,6 +186,36 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private int sys_getppid() { return parent == null ? 1 : parent.pid; } + + private int sys_chown(int fileAddr, int uid, int gid) { + return 0; + } + private int sys_lchown(int fileAddr, int uid, int gid) { + return 0; + } + private int sys_fchown(int fd, int uid, int gid) { + return 0; + } + private int sys_chmod(int fileAddr, int uid, int gid) { + return 0; + } + private int sys_fchmod(int fd, int uid, int gid) { + return 0; + } + + + private int sys_access(int cstring, int mode) throws ErrnoException, ReadFaultException { + // FEATURE: sys_access + return gs.stat(this,cstring(cstring)) == null ? -ENOENT : 0; + } + + private int sys_realpath(int inAddr, int outAddr) throws FaultException { + String s = normalizePath(cstring(inAddr)); + byte[] b = getNullTerminatedBytes(s); + if(b.length > PATH_MAX) return -ERANGE; + copyout(b,outAddr,b.length); + return 0; + } // FEATURE: Signal handling // check flag only on backwards jumps to basic blocks without compulsatory checks @@ -360,43 +403,150 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private int sys_exec(int cpath, int cargv, int cenvp) throws ErrnoException, FaultException { return exec(normalizePath(cstring(cpath)),readStringArray(cargv),readStringArray(cenvp)); } + + private final static Method runtimeCompilerCompile; + static { + Method m; + try { + m = Class.forName("org.ibex.nestedvm.RuntimeCompiler").getMethod("compile",new Class[]{Seekable.class,String.class,String.class}); + } catch(NoSuchMethodException e) { + m = null; + } catch(ClassNotFoundException e) { + m = null; + } + runtimeCompilerCompile = m; + } + + public Class runtimeCompile(Seekable s, String sourceName) throws IOException { + if(runtimeCompilerCompile == null) { + if(STDERR_DIAG) System.err.println("WARNING: Exec attempted but RuntimeCompiler not found!"); + return null; + } + + try { + return (Class) runtimeCompilerCompile.invoke(null,new Object[]{s,"unixruntime,maxinsnpermethod=256,lessconstants",sourceName}); + } catch(IllegalAccessException e) { + e.printStackTrace(); + return null; + } catch(InvocationTargetException e) { + Throwable t = e.getTargetException(); + if(t instanceof IOException) throw (IOException) t; + if(t instanceof RuntimeException) throw (RuntimeException) t; + if(t instanceof Error) throw (Error) t; + if(STDERR_DIAG) t.printStackTrace(); + return null; + } + } - private int exec(String normalizedPath, String[] argv, String[] envp) throws ErrnoException { + private int exec(String path, String[] argv, String[] envp) throws ErrnoException { if(argv.length == 0) argv = new String[]{""}; - + // HACK: Hideous hack to make a standalone busybox possible + if(path.equals("bin/busybox") && getClass().getName().endsWith("BusyBox")) + return execClass(getClass(),argv,envp); + // NOTE: For this little hack to work nestedvm.root MUST be "." /*try { System.err.println("Execing normalized path: " + normalizedPath); if(true) return exec(new Interpreter(normalizedPath),argv,envp); } catch(IOException e) { throw new Error(e); }*/ - Object o = gs.exec(this,normalizedPath); - if(o == null) return -ENOENT; - - if(o instanceof Class) { - Class c = (Class) o; - try { - UnixRuntime r = (UnixRuntime) c.getDeclaredConstructor(new Class[]{Boolean.TYPE}).newInstance(new Object[]{Boolean.TRUE}); - return exec(r,argv,envp); - } catch(Exception e) { - e.printStackTrace(); - return -ENOEXEC; + FStat fstat = gs.stat(this,path); + if(fstat == null) return -ENOENT; + GlobalState.CacheEnt ent = (GlobalState.CacheEnt) gs.execCache.get(path); + long mtime = fstat.mtime(); + long size = fstat.size(); + if(ent != null) { + //System.err.println("Found cached entry for " + path); + if(ent.time ==mtime && ent.size == size) { + if(ent.o instanceof Class) + return execClass((Class) ent.o,argv,envp); + if(ent.o instanceof String[]) + return execScript(path,(String[]) ent.o,argv,envp); + throw new Error("should never happen"); } - } else { - String[] command = (String[]) o; - String[] newArgv = new String[argv.length + command[1] != null ? 2 : 1]; - int p = command[0].lastIndexOf('/'); - newArgv[0] = p == -1 ? command[0] : command[0].substring(p+1); - p = 1; - if(command[1] != null) newArgv[p++] = command[1]; - newArgv[p++] = "/" + normalizedPath; - for(int i=1;i