X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntime.java;h=e909b81396fdaad7b24901492c83be0d072b5c1c;hb=e31fa57da728fa1c76760af23e62bd312a50e4df;hp=a54fbc20e785ee8ce45955888ed57f085499a468;hpb=095d6d46361db8b4b69790305c0310ea114d3813;p=nestedvm.git
diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java
index a54fbc2..e909b81 100644
--- a/src/org/ibex/nestedvm/Runtime.java
+++ b/src/org/ibex/nestedvm/Runtime.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.
+
// Copyright 2003 Brian Alliet
// Based on org.xwt.imp.MIPS by Adam Megacz
// Portions Copyright 2003 Adam Megacz
@@ -70,8 +74,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
public ExecutionException exitException;
/** Table containing all open file descriptors. (Entries are null if the fd is not in use */
- FD[] fds = new FD[OPEN_MAX]; // package-private for UnixRuntime
- boolean closeOnExec[] = new boolean[OPEN_MAX];
+ FD[] fds; // package-private for UnixRuntime
+ boolean closeOnExec[];
/** Pointer to a SecurityManager for this process */
SecurityManager sm;
@@ -102,6 +106,16 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
/** Subclasses should set the CPUState to the state held in state */
protected abstract void setCPUState(CPUState state);
+ /** True to enabled a few hacks to better support the win32 console */
+ final static boolean win32Hacks;
+
+ static {
+ String os = Platform.getProperty("os.name");
+ String prop = Platform.getProperty("nestedvm.win32hacks");
+ if(prop != null) { win32Hacks = Boolean.valueOf(prop).booleanValue(); }
+ else { win32Hacks = os != null && os.toLowerCase().indexOf("windows") != -1; }
+ }
+
protected Object clone() throws CloneNotSupportedException {
Runtime r = (Runtime) super.clone();
r._byteBuf = null;
@@ -119,7 +133,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
return r;
}
- protected Runtime(int pageSize, int totalPages) {
+ protected Runtime(int pageSize, int totalPages) { this(pageSize, totalPages,false); }
+ protected Runtime(int pageSize, int totalPages, boolean exec) {
if(pageSize <= 0) throw new IllegalArgumentException("pageSize <= 0");
if(totalPages <= 0) throw new IllegalArgumentException("totalPages <= 0");
if((pageSize&(pageSize-1)) != 0) throw new IllegalArgumentException("pageSize not a power of two");
@@ -157,11 +172,16 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
readPages[i] = writePages[i] = new int[pageSize>>2];
}
}
-
- InputStream stdin = Boolean.valueOf(Platform.getProperty("nestedvm.textstdin")).booleanValue() ? new TextInputStream(System.in) : System.in;
- addFD(new TerminalFD(stdin));
- addFD(new TerminalFD(System.out));
- addFD(new TerminalFD(System.err));
+
+ if(!exec) {
+ fds = new FD[OPEN_MAX];
+ closeOnExec = new boolean[OPEN_MAX];
+
+ InputStream stdin = win32Hacks ? new Win32ConsoleIS(System.in) : System.in;
+ addFD(new TerminalFD(stdin));
+ addFD(new TerminalFD(System.out));
+ addFD(new TerminalFD(System.err));
+ }
}
/** Copy everything from src to addr initializing uninitialized pages if required.
@@ -481,17 +501,16 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
/** Calls _execute() (subclass's execute()) and catches exceptions */
- // FEATURE: Have these call kill() so we get a pretty message to stdout
private void __execute() {
try {
_execute();
} catch(FaultException e) {
if(STDERR_DIAG) e.printStackTrace();
- sys_exit(128+11); // SIGSEGV
+ exit(128+11,true); // SIGSEGV
exitException = e;
} catch(ExecutionException e) {
if(STDERR_DIAG) e.printStackTrace();
- sys_exit(128+4); // SIGILL
+ exit(128+4,true); // SIGILL
exitException = e;
}
}
@@ -712,7 +731,6 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
if((flags & ~(3|O_CREAT|O_EXCL|O_APPEND|O_TRUNC)) != 0) {
if(STDERR_DIAG)
System.err.println("WARNING: Unsupported flags passed to open(\"" + f + "\"): " + toHex(flags & ~(3|O_CREAT|O_EXCL|O_APPEND|O_TRUNC)));
-
throw new ErrnoException(ENOTSUP);
}
boolean write = (flags&3) != RD_ONLY;
@@ -721,7 +739,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
if((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT)) {
try {
- if(Platform.atomicCreateFile(f)) throw new ErrnoException(EEXIST);
+ if(!Platform.atomicCreateFile(f)) throw new ErrnoException(EEXIST);
} catch(IOException e) {
throw new ErrnoException(EIO);
}
@@ -960,11 +978,21 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
/** Hook for subclasses to do something when the process exits */
void _exited() { }
- private int sys_exit(int status) {
+ void exit(int status, boolean fromSignal) {
+ if(fromSignal && fds[2] != null) {
+ try {
+ byte[] msg = getBytes("Process exited on signal " + (status - 128) + "\n");
+ fds[2].write(msg,0,msg.length);
+ } catch(ErrnoException e) { }
+ }
exitStatus = status;
for(int i=0;isyscall should be the contents of V0 and a, b, c, and d should be
@@ -1036,6 +1064,10 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
case SYS_getpagesize: return sys_getpagesize();
case SYS_fcntl: return sys_fcntl(a,b,c);
case SYS_sysconf: return sys_sysconf(a);
+ case SYS_getuid: return sys_getuid();
+ case SYS_geteuid: return sys_geteuid();
+ case SYS_getgid: return sys_getgid();
+ case SYS_getegid: return sys_getegid();
case SYS_memcpy: memcpy(a,b,c); return a;
case SYS_memset: memset(a,b,c); return a;
@@ -1057,6 +1089,11 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
}
+ private int sys_getuid() { return 0; }
+ private int sys_geteuid() { return 0; }
+ private int sys_getgid() { return 0; }
+ private int sys_getegid() { return 0; }
+
public int xmalloc(int size) { int p=malloc(size); if(p==0) throw new RuntimeException("malloc() failed"); return p; }
public int xrealloc(int addr,int newsize) { int p=realloc(addr,newsize); if(p==0) throw new RuntimeException("realloc() failed"); return p; }
public int realloc(int addr, int newsize) { try { return call("realloc",addr,newsize); } catch(CallException e) { return 0; } }
@@ -1109,8 +1146,6 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
public int getdents(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); }
- public int flags() { return O_RDONLY; }
-
/** Return a Seekable object representing this file descriptor (can be read only)
This is required for exec() */
Seekable seekable() { return null; }
@@ -1122,6 +1157,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
protected abstract FStat _fstat();
+ public abstract int flags();
/** Closes the fd */
public final void close() { if(--refCount==0) _close(); }
@@ -1225,7 +1261,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
}
- public FStat _fstat() { return new FStat(); }
+ public FStat _fstat() { return new SocketFStat(); }
}
static class TerminalFD extends InputOutputStreamFD {
@@ -1233,14 +1269,14 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
public TerminalFD(OutputStream os) { this(null,os); }
public TerminalFD(InputStream is, OutputStream os) { super(is,os); }
public void _close() { /* noop */ }
- public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } public int mode() { return 0600; } }; }
+ public FStat _fstat() { return new SocketFStat() { public int type() { return S_IFCHR; } public int mode() { return 0600; } }; }
}
// This is pretty inefficient but it is only used for reading from the console on win32
- static class TextInputStream extends InputStream {
+ static class Win32ConsoleIS extends InputStream {
private int pushedBack = -1;
private final InputStream parent;
- public TextInputStream(InputStream parent) { this.parent = parent; }
+ public Win32ConsoleIS(InputStream parent) { this.parent = parent; }
public int read() throws IOException {
if(pushedBack != -1) { int c = pushedBack; pushedBack = -1; return c; }
int c = parent.read();
@@ -1272,16 +1308,14 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
}
- public static class FStat {
- public static final int S_IFIFO = 0010000;
- public static final int S_IFCHR = 0020000;
- public static final int S_IFDIR = 0040000;
- public static final int S_IFREG = 0100000;
+ public abstract static class FStat {
+ public static final int S_IFIFO = 0010000;
+ public static final int S_IFCHR = 0020000;
+ public static final int S_IFDIR = 0040000;
+ public static final int S_IFREG = 0100000;
+ public static final int S_IFSOCK = 0140000;
- public int dev() { return 1; }
- public int inode() { return hashCode() & 0x7fff; }
public int mode() { return 0; }
- public int type() { return S_IFIFO; }
public int nlink() { return 0; }
public int uid() { return 0; }
public int gid() { return 0; }
@@ -1291,6 +1325,16 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
public int ctime() { return 0; }
public int blksize() { return 512; }
public int blocks() { return (size()+blksize()-1)/blksize(); }
+
+ public abstract int dev();
+ public abstract int type();
+ public abstract int inode();
+ }
+
+ public static class SocketFStat extends FStat {
+ public int dev() { return -1; }
+ public int type() { return S_IFSOCK; }
+ public int inode() { return hashCode() & 0x7fff; }
}
static class HostFStat extends FStat {
@@ -1302,7 +1346,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
this.executable = executable;
}
public int dev() { return 1; }
- public int inode() { return f.getName().hashCode() & 0xffff; }
+ public int inode() { return f.getAbsolutePath().hashCode() & 0x7fff; }
public int type() { return f.isDirectory() ? S_IFDIR : S_IFREG; }
public int nlink() { return 1; }
public int mode() {