X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntime.java;h=bfe1aaba8c3393f582dcd97da78ce458781d1a6c;hb=f4a70cc5b4dc1a175ba741a4eac3a52985b1b322;hp=b7903741ceed0e707314af31e5d257f22bbbea9b;hpb=897fa3c89674460aa4fad275f263cea2b341420d;p=nestedvm.git
diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java
index b790374..bfe1aab 100644
--- a/src/org/ibex/nestedvm/Runtime.java
+++ b/src/org/ibex/nestedvm/Runtime.java
@@ -2,13 +2,17 @@
// Based on org.xwt.imp.MIPS by Adam Megacz
// Portions Copyright 2003 Adam Megacz
+// FEATURE: Add a patch to gcc that enabled -Wall -Werror by default
+// FIXME: Get a hotel for IVME :)
+
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";
+
/** True to write useful diagnostic information to stderr when things go wrong */
final static boolean STDERR_DIAG = true;
@@ -45,10 +49,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 */
@@ -135,7 +139,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
stackSize = max(stackSize,pageSize);
stackSize = (stackSize + pageSize - 1) & ~(pageSize-1);
stackPages = stackSize >>> pageShift;
- heapStart = (heapStart + pageSize) & ~(pageSize-1);
+ heapStart = (heapStart + pageSize - 1) & ~(pageSize-1);
if(stackPages + STACK_GUARD_PAGES + (heapStart >>> pageShift) >= totalPages)
throw new IllegalArgumentException("total pages too small");
} else {
@@ -157,9 +161,10 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
}
- addFD(new StdinFD(System.in));
- addFD(new StdoutFD(System.out));
- addFD(new StdoutFD(System.err));
+ 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));
}
/** Copy everything from src to addr initializing uninitialized pages if required.
@@ -356,7 +361,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
if(page == null) throw new WriteFaultException(a<<2);
int index = a&pageWordMask;
int n = min(c,pageWords-index);
- Arrays.fill(page,index,index+n,fourBytes);
+ /* Arrays.fill(page,index,index+n,fourBytes);*/
+ for(int i=index;i ARG_MAX) throw new IllegalArgumentException("args/environ too big");
+ // HACK: heapStart() isn't always available when the constructor
+ // is run and this sometimes doesn't get initialized
+ if(heapEnd == 0) {
+ heapEnd = heapStart();
+ if(heapEnd == 0) throw new Error("heapEnd == 0");
+ int pageSize = writePages.length == 1 ? 4096 : (1<= 0) throw new ErrnoException(EACCES);
return null;
@@ -737,7 +755,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
/** The open syscall */
private int sys_open(int addr, int flags, int mode) throws ErrnoException, FaultException {
- FD fd = _open(cstring(addr),flags,mode);
+ String name = cstring(addr);
+
+ // HACK: TeX, or GPC, or something really sucks
+ if(name.length() == 1024 && getClass().getName().equals("tests.TeX")) name = name.trim();
+
+ flags &= ~O_NOCTTY; // this is meaningless under nestedvm
+ FD fd = _open(name,flags,mode);
if(fd == null) return -ENOENT;
int fdn = addFD(fd);
if(fdn == -1) { fd.close(); return -ENFILE; }
@@ -790,8 +814,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
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
@@ -869,6 +893,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
private int sys_sysconf(int n) {
switch(n) {
case _SC_CLK_TCK: return 1000;
+ case _SC_PAGESIZE: return writePages.length == 1 ? 4096 : (1<syscall should be the contents of V0 and a, b, c, and d should be
the contenst of A0, A1, A2, and A3. The call MAY change the state
@see Runtime#state state */
- protected final int syscall(int syscall, int a, int b, int c, int d) {
+ protected final int syscall(int syscall, int a, int b, int c, int d, int e, int f) {
try {
- return _syscall(syscall,a,b,c,d);
- } catch(ErrnoException e) {
- return -e.errno;
- } catch(FaultException e) {
+ int n = _syscall(syscall,a,b,c,d,e,f);
+ //if(n < 0) System.err.println("syscall: " + syscall + " returned " + n);
+ return n;
+ } catch(ErrnoException ex) {
+ //ex.printStackTrace();
+ return -ex.errno;
+ } catch(FaultException ex) {
return -EFAULT;
- } catch(RuntimeException e) {
- e.printStackTrace();
+ } catch(RuntimeException ex) {
+ ex.printStackTrace();
throw new Error("Internal Error in _syscall()");
}
}
- int _syscall(int syscall, int a, int b, int c, int d) throws ErrnoException, FaultException {
+ int _syscall(int syscall, int a, int b, int c, int d, int e, int f) throws ErrnoException, FaultException {
switch(syscall) {
case SYS_null: return 0;
case SYS_exit: return sys_exit(a);
@@ -1155,48 +1184,95 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
protected void _close() { try { data.close(); } catch(IOException e) { /*ignore*/ } }
}
- public static class OutputStreamFD extends FD {
- private OutputStream os;
- public int flags() { return O_WRONLY; }
- public OutputStreamFD(OutputStream os) { this.os = os; }
- public int write(byte[] a, int off, int length) throws ErrnoException {
- try {
- os.write(a,off,length);
- return length;
- } catch(IOException e) {
- throw new ErrnoException(EIO);
- }
+ public static class InputOutputStreamFD extends FD {
+ private final InputStream is;
+ private final OutputStream os;
+
+ public InputOutputStreamFD(InputStream is) { this(is,null); }
+ public InputOutputStreamFD(OutputStream os) { this(null,os); }
+ public InputOutputStreamFD(InputStream is, OutputStream os) {
+ this.is = is;
+ this.os = os;
+ if(is == null && os == null) throw new IllegalArgumentException("at least one stream must be supplied");
}
- public void _close() { try { os.close(); } catch(IOException e) { /*ignore*/ } }
- public FStat _fstat() { return new FStat(); }
- }
-
- public static class InputStreamFD extends FD {
- private InputStream is;
- public int flags() { return O_RDONLY; }
- public InputStreamFD(InputStream is) { this.is = is; }
+
+ public int flags() {
+ if(is != null && os != null) return O_RDWR;
+ if(is != null) return O_RDONLY;
+ if(os != null) return O_WRONLY;
+ throw new Error("should never happen");
+ }
+
+ public void _close() {
+ if(is != null) try { is.close(); } catch(IOException e) { /*ignore*/ }
+ if(os != null) try { os.close(); } catch(IOException e) { /*ignore*/ }
+ }
+
public int read(byte[] a, int off, int length) throws ErrnoException {
+ if(is == null) return super.read(a,off,length);
try {
int n = is.read(a,off,length);
return n < 0 ? 0 : n;
} catch(IOException e) {
throw new ErrnoException(EIO);
}
+ }
+
+ public int write(byte[] a, int off, int length) throws ErrnoException {
+ if(os == null) return super.write(a,off,length);
+ try {
+ os.write(a,off,length);
+ return length;
+ } catch(IOException e) {
+ throw new ErrnoException(EIO);
+ }
}
- public void _close() { try { is.close(); } catch(IOException e) { /*ignore*/ } }
+
public FStat _fstat() { return new FStat(); }
}
- 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; } }; }
- }
-
- static class StdoutFD extends OutputStreamFD {
- public StdoutFD(OutputStream os) { super(os); }
+ static class TerminalFD extends InputOutputStreamFD {
+ public TerminalFD(InputStream is) { this(is,null); }
+ 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 FStat _fstat() { return new FStat() { 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 {
+ private int pushedBack = -1;
+ private final InputStream parent;
+ public TextInputStream(InputStream parent) { this.parent = parent; }
+ public int read() throws IOException {
+ if(pushedBack != -1) { int c = pushedBack; pushedBack = -1; return c; }
+ int c = parent.read();
+ if(c == '\r' && (c = parent.read()) != '\n') { pushedBack = c; return '\r'; }
+ return c;
+ }
+ public int read(byte[] buf, int pos, int len) throws IOException {
+ boolean pb = false;
+ if(pushedBack != -1 && len > 0) {
+ buf[0] = (byte) pushedBack;
+ pushedBack = -1;
+ pos++; len--; pb = true;
+ }
+ int n = parent.read(buf,pos,len);
+ if(n == -1) return -1;
+ for(int i=0;i b ? a : b; }