X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntime.java;h=2a91e3613ebda8733909fef05888a0aa83b9ce50;hp=f6a00df4c6c73cb177550f091a8a0a0525e6b880;hb=b11e7c6c29f2b5f7b0828bf93eb741c4a30ec411;hpb=49cb14fa5b1e479ed41c38fd60372d9cd3086cd3
diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java
index f6a00df..2a91e36 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 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
@@ -94,7 +98,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
/** Subclasses should return the address of the symbol symbol or -1 it it doesn't exits in this method
This method is only required if the call() function is used */
- protected int lookupSymbol(String symbol) { return -1; }
+ public int lookupSymbol(String symbol) { return -1; }
/** Subclasses should populate a CPUState object representing the cpu state */
protected abstract void getCPUState(CPUState state);
@@ -552,7 +556,6 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
public final void start(String[] args, String[] environ) {
int top, sp, argsAddr, envAddr;
if(state != STOPPED) throw new IllegalStateException("start() called in inappropriate state");
-
if(args == null) args = new String[]{getClass().getName()};
sp = top = writePages.length*(1<fdn and removes it from the file descriptor table */
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;
+ _preCloseFD(fds[fdn]);
fds[fdn].close();
+ _postCloseFD(fds[fdn]);
fds[fdn] = null;
return true;
}
@@ -727,7 +741,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;
@@ -736,7 +749,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);
}
@@ -754,10 +767,10 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
return null;
} catch(IOException e) { throw new ErrnoException(EIO); }
- return new SeekableFD(sf,flags) { protected FStat _fstat() { return hostFStat(f,data); } };
+ return new SeekableFD(sf,flags) { protected FStat _fstat() { return hostFStat(f,sf,data); } };
}
- FStat hostFStat(File f, Object data) { return new HostFStat(f); }
+ FStat hostFStat(File f, Seekable.File sf, Object data) { return new HostFStat(f,sf); }
FD hostFSDirFD(File f, Object data) { return null; }
@@ -806,6 +819,17 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
copyout(buf,addr,n);
return n;
}
+
+ /** The ftruncate syscall */
+ private int sys_ftruncate(int fdn, long length) {
+ if (fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if (fds[fdn] == null) return -EBADFD;
+
+ Seekable seekable = fds[fdn].seekable();
+ if (length < 0 || seekable == null) return -EINVAL;
+ try { seekable.resize(length); } catch (IOException e) { return -EIO; }
+ return 0;
+ }
/** The close syscall */
private int sys_close(int fdn) {
@@ -993,7 +1017,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
return 0;
}
- private int sys_fcntl(int fdn, int cmd, int arg) {
+ final int sys_fcntl(int fdn, int cmd, int arg) throws FaultException {
int i;
if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
@@ -1014,12 +1038,32 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
return 0;
case F_GETFD:
return closeOnExec[fdn] ? 1 : 0;
+ case F_GETLK:
+ case F_SETLK:
+ if(STDERR_DIAG) System.err.println("WARNING: file locking requires UnixRuntime");
+ return -ENOSYS;
default:
if(STDERR_DIAG) System.err.println("WARNING: Unknown fcntl command: " + cmd);
return -ENOSYS;
}
}
-
+
+ final int fsync(int fdn) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ FD fd = fds[fdn];
+
+ Seekable s = fd.seekable();
+ if (s == null) return -EINVAL;
+
+ try {
+ s.sync();
+ return 0;
+ } catch (IOException e) {
+ return -EIO;
+ }
+ }
+
/** The syscall dispatcher.
The should be called by subclasses when the syscall instruction is invoked.
syscall should be the contents of V0 and a, b, c, and d should be
@@ -1028,9 +1072,11 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
protected final int syscall(int syscall, int a, int b, int c, int d, int e, int f) {
try {
int n = _syscall(syscall,a,b,c,d,e,f);
- //if(n < 0) System.err.println("syscall: " + syscall + " returned " + n);
+ //if(n<0) throw new ErrnoException(-n);
return n;
} catch(ErrnoException ex) {
+ //System.err.println("While executing syscall: " + syscall + ":");
+ //if(syscall == SYS_open) try { System.err.println("Failed to open " + cstring(a) + " errno " + ex.errno); } catch(Exception e2) { }
//ex.printStackTrace();
return -ex.errno;
} catch(FaultException ex) {
@@ -1053,6 +1099,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
case SYS_close: return sys_close(a);
case SYS_read: return sys_read(a,b,c);
case SYS_lseek: return sys_lseek(a,b,c);
+ case SYS_ftruncate: return sys_ftruncate(a,b);
case SYS_getpid: return sys_getpid();
case SYS_calljava: return sys_calljava(a,b,c,d);
case SYS_gettimeofday: return sys_gettimeofday(a,b);
@@ -1061,7 +1108,12 @@ 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_fsync: return fsync(a);
case SYS_memcpy: memcpy(a,b,c); return a;
case SYS_memset: memset(a,b,c); return a;
@@ -1082,6 +1134,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; } }
@@ -1105,9 +1162,38 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
}
return addr;
}
-
+
+ // TODO: less memory copying (custom utf-8 reader)
+ // or at least roll strlen() into copyin()
+ public final String utfstring(int addr) throws ReadFaultException {
+ if (addr == 0) return null;
+
+ // determine length
+ int i=addr;
+ for(int word = 1; word != 0; i++) {
+ word = memRead(i&~3);
+ switch(i&3) {
+ case 0: word = (word>>>24)&0xff; break;
+ case 1: word = (word>>>16)&0xff; break;
+ case 2: word = (word>>> 8)&0xff; break;
+ case 3: word = (word>>> 0)&0xff; break;
+ }
+ }
+ if (i > addr) i--; // do not count null
+
+ byte[] bytes = new byte[i-addr];
+ copyin(addr, bytes, bytes.length);
+
+ try {
+ return new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e); // should never happen with UTF-8
+ }
+ }
+
/** Helper function to read a cstring from main memory */
public final String cstring(int addr) throws ReadFaultException {
+ if (addr == 0) return null;
StringBuffer sb = new StringBuffer();
for(;;) {
int word = memRead(addr&~3);
@@ -1123,6 +1209,14 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
/** File Descriptor class */
public static abstract class FD {
private int refCount = 1;
+ private String normalizedPath = null;
+ private boolean deleteOnClose = false;
+
+ public void setNormalizedPath(String path) { normalizedPath = path; }
+ public String getNormalizedPath() { return normalizedPath; }
+
+ public void markDeleteOnClose() { deleteOnClose = true; }
+ public boolean isMarkedForDeleteOnClose() { return deleteOnClose; }
/** Read some bytes. Should return the number of bytes read, 0 on EOF, or throw an IOException on error */
public int read(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); }
@@ -1279,7 +1373,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
pos++; len--; pb = true;
}
int n = parent.read(buf,pos,len);
- if(n == -1) return -1;
+ if(n == -1) return pb ? 1 : -1;
for(int i=0;i