X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntime.java;h=f6a00df4c6c73cb177550f091a8a0a0525e6b880;hp=64ebd3366087def8c099e971650ea9dcfbee0f47;hb=49cb14fa5b1e479ed41c38fd60372d9cd3086cd3;hpb=4cc48f20c2927ad6d88f4d54e10b5fe46fcef2df
diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java
index 64ebd33..f6a00df 100644
--- a/src/org/ibex/nestedvm/Runtime.java
+++ b/src/org/ibex/nestedvm/Runtime.java
@@ -6,7 +6,6 @@ package org.ibex.nestedvm;
import org.ibex.nestedvm.util.*;
import java.io.*;
-import java.util.Arrays;
public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
public static final String VERSION = "1.0";
@@ -47,10 +46,10 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
/** When the process started */
private long startTime;
- /** Text/Data loaded in memory */
- public final static int STOPPED = 0;
/** Program is executing instructions */
- public final static int RUNNING = 1;
+ public final static int RUNNING = 0; // Horrible things will happen if this isn't 0
+ /** Text/Data loaded in memory */
+ public final static int STOPPED = 1;
/** Prgram has been started but is paused */
public final static int PAUSED = 2;
/** Program is executing a callJava() method */
@@ -71,8 +70,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;
@@ -103,6 +102,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;
@@ -120,7 +129,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");
@@ -158,11 +168,16 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
readPages[i] = writePages[i] = new int[pageSize>>2];
}
}
-
- InputStream stdin = Boolean.valueOf(getSystemProperty("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.
@@ -482,17 +497,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;
}
}
@@ -732,10 +746,9 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
return hostFSDirFD(f,data);
}
- // FIXME: Truncate
final Seekable.File sf;
try {
- sf = new Seekable.File(f,write);
+ sf = new Seekable.File(f,write,(flags & O_TRUNC) != 0);
} catch(FileNotFoundException e) {
if(e.getMessage() != null && e.getMessage().indexOf("Permission denied") >= 0) throw new ErrnoException(EACCES);
return null;
@@ -810,12 +823,11 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
/** The stat/fstat syscall helper */
- // FIXME: Populate uid/gid/nlink
int stat(FStat fs, int addr) throws FaultException {
memWrite(addr+0,(fs.dev()<<16)|(fs.inode()&0xffff)); // st_dev (top 16), // st_ino (bottom 16)
memWrite(addr+4,((fs.type()&0xf000))|(fs.mode()&0xfff)); // st_mode
- memWrite(addr+8,1<<16); // st_nlink (top 16) // st_uid (bottom 16)
- memWrite(addr+12,0); // st_gid (top 16) // st_rdev (bottom 16)
+ memWrite(addr+8,fs.nlink()<<16|fs.uid()&0xffff); // st_nlink (top 16) // st_uid (bottom 16)
+ memWrite(addr+12,fs.gid()<<16|0); // st_gid (top 16) // st_rdev (bottom 16)
memWrite(addr+16,fs.size()); // st_size
memWrite(addr+20,fs.atime()); // st_atime
// memWrite(addr+24,0) // st_spare1
@@ -942,7 +954,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
ret = callJavaCB.call(a,b,c,d);
} catch(RuntimeException e) {
System.err.println("Error while executing callJavaCB");
- e.printStackTrace();
+ e.printStackTrace();
ret = 0;
}
state = RUNNING;
@@ -963,11 +975,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;i