X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntime.java;h=d77ea855d5f44ba6c95bf69b19959448808a5135;hp=f28662078395080bbd32807501a4d52d2e0ee8de;hb=HEAD;hpb=6d6d9f59a2e6fe3b9e5b3563efcf0124bea4a672 diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java index f286620..d77ea85 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 @@ -98,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); @@ -556,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; } @@ -757,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; } @@ -1007,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; @@ -1028,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 @@ -1057,7 +1087,7 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { } } - int _syscall(int syscall, int a, int b, int c, int d, int e, int f) throws ErrnoException, FaultException { + protected 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); @@ -1083,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; @@ -1131,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); @@ -1149,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); } @@ -1353,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; } @@ -1371,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); } } @@ -1470,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 }