X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntime.java;h=2a91e3613ebda8733909fef05888a0aa83b9ce50;hp=4618dc38de00aff6f4efbcb2c79159b9602abb47;hb=b11e7c6c29f2b5f7b0828bf93eb741c4a30ec411;hpb=3e206c53f6ee3d09c3bb781526c0fe01bf8f6c75
diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java
index 4618dc3..2a91e36 100644
--- a/src/org/ibex/nestedvm/Runtime.java
+++ b/src/org/ibex/nestedvm/Runtime.java
@@ -1,5 +1,5 @@
// Copyright 2000-2005 the Contributors, as shown in the revision logs.
-// Licensed under the Apache Public Source License 2.0 ("the License").
+// 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
@@ -76,10 +76,6 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
/** Table containing all open file descriptors. (Entries are null if the fd is not in use */
FD[] fds; // package-private for UnixRuntime
boolean closeOnExec[];
-
- /** Table of all current file locks held by this process. */
- Seekable.Lock[] locks;
- public static final int LOCK_MAX = 8;
/** Pointer to a SecurityManager for this process */
SecurityManager sm;
@@ -102,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);
@@ -126,7 +122,6 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
r.startTime = 0;
r.fds = new FD[OPEN_MAX];
for(int i=0;ifdn 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;
}
@@ -762,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; }
@@ -1012,7 +1017,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
return 0;
}
- private int sys_fcntl(int fdn, int cmd, int arg) throws FaultException {
+ final int sys_fcntl(int fdn, int cmd, int arg) throws FaultException {
int i;
if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
@@ -1035,123 +1040,30 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
return closeOnExec[fdn] ? 1 : 0;
case F_GETLK:
case F_SETLK:
- try {
- return sys_fcntl_lock(fd, cmd, arg);
- } catch (IOException e) { throw new RuntimeException(e);}
+ 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;
}
}
- /** Implements the F_GETLK and F_SETLK cases of fcntl syscall.
- * If l_start = 0 and l_len = 0 the lock refers to the entire file.
- struct flock {
- short l_type; // lock type: F_UNLCK, F_RDLCK, F_WRLCK
- short l_whence; // type of l_start: SEEK_SET, SEEK_CUR, SEEK_END
- long l_start; // starting offset, bytes
- long l_len; // len = 0 means until EOF
- short l_pid; // lock owner
- short l_xxx; // padding
- };
- */
- private int sys_fcntl_lock(FD fd, int cmd, int arg)
- throws FaultException, IOException {
- if (arg == 0) { System.out.println("BAD ARG"); return -EINVAL; }
- int word = memRead(arg);
- int l_start = memRead(arg+4);
- int l_len = memRead(arg+8);
- int l_type = word>>16;
- int l_whence = word&0x00ff;
+ 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;
- switch (l_whence) {
- case SEEK_SET: break;
- case SEEK_CUR: l_start += s.pos(); break;
- case SEEK_END: l_start += s.length(); break;
- default: return -1;
- }
-
- if (cmd != F_GETLK && cmd != F_SETLK) return -EINVAL;
-
- if (cmd == F_GETLK) {
- // Check if an l_type lock can be aquired. The only way to
- // do this within the Java API is to try and create a lock.
- Seekable.Lock lock = s.lock(l_start, l_len, l_type == F_RDLCK);
-
- if (lock != null) {
- // no lock exists
- memWrite(arg, SEEK_SET|(F_UNLCK<<16));
- lock.release();
- }
-
- return 0;
- }
-
- // now processing F_SETLK
- if (cmd != F_SETLK) return -EINVAL;
-
- if (l_type == F_UNLCK) {
- // release all locks that fall within the boundaries given
- for (int i=0; i < LOCK_MAX; i++) {
- if (locks[i] == null || !s.equals(locks[i].seekable()))
- continue;
-
- int pos = (int)locks[i].position();
- if (pos < l_start) continue;
- if (l_start != 0 && l_len != 0) // start/len 0 means unlock all
- if (pos + locks[i].size() > l_start + l_len)
- continue;
-
- locks[i].release();
- locks[i] = null;
- }
- return 0;
-
- } else if (l_type == F_RDLCK || l_type == F_WRLCK) {
- // first see if a lock already exists
- for (int i=0; i < LOCK_MAX; i++) {
- if (locks[i] == null || !s.equals(locks[i].seekable()))
- continue;
- int pos = (int)locks[i].position();
- int size = (int)locks[i].size();
- if (l_start < pos && pos + size < l_start + l_len) {
- // found a lock contained in the new requested lock
- locks[i].release();
- locks[i] = null;
-
- } else if (l_start >= pos && pos + size >= l_start + l_len) {
- // found a lock that contains the requested lock
- if (locks[i].isShared() == (l_type == F_RDLCK)) {
- memWrite(arg+4, pos);
- memWrite(arg+8, size);
- return 0;
- } else {
- locks[i].release();
- locks[i] = null;
- }
- }
- }
-
- // create the lock
- Seekable.Lock lock = s.lock(l_start, l_len, l_type == F_RDLCK);
- if (lock == null) return -EAGAIN;
-
- int i;
- for (i=0; i < LOCK_MAX; i++)
- if (locks[i] == null) break;
- if (i == LOCK_MAX) return -ENOLCK;
- locks[i] = lock;
+ try {
+ s.sync();
return 0;
-
- } else {
- return -EINVAL;
+ } 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
@@ -1201,6 +1113,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
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;
@@ -1249,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);
@@ -1267,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); }
@@ -1471,10 +1421,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
static class HostFStat extends FStat {
private final File f;
+ private final Seekable.File sf;
private final boolean executable;
- public HostFStat(File f) { this(f,false); }
- public HostFStat(File f, boolean executable) {
+ public HostFStat(File f, Seekable.File sf) { this(f,sf,false); }
+ public HostFStat(File f, boolean executable) {this(f,null,executable);}
+ public HostFStat(File f, Seekable.File sf, boolean executable) {
this.f = f;
+ this.sf = sf;
this.executable = executable;
}
public int dev() { return 1; }
@@ -1489,7 +1442,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
if(f.canWrite()) mode |= 0222;
return mode;
}
- public int size() { return (int) f.length(); }
+ public int size() {
+ try {
+ return sf != null ? (int)sf.length() : (int)f.length();
+ } catch (Exception x) {
+ return (int)f.length();
+ }
+ }
public int mtime() { return (int)(f.lastModified()/1000); }
}
@@ -1588,7 +1547,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable {
static byte[] getBytes(String s) {
try {
- return s.getBytes("ISO-8859-1");
+ return s.getBytes("UTF-8");
} catch(UnsupportedEncodingException e) {
return null; // should never happen
}