From a544cae02c05c300d729d9172e7a5dbab1e25a10 Mon Sep 17 00:00:00 2001 From: badvision Date: Fri, 4 Nov 2016 22:40:46 -0500 Subject: [PATCH] Removed JavaFX packager dependency (it's built-in now) and also switched to using a nestedVM dependency instead of including the classes directly. --- pom.xml | 12 +- .../java/org/ibex/nestedvm/Interpreter.java | 787 ------ .../java/org/ibex/nestedvm/Registers.java | 46 - src/main/java/org/ibex/nestedvm/Runtime.java | 1566 ---------- .../java/org/ibex/nestedvm/UnixRuntime.java | 2512 ----------------- .../org/ibex/nestedvm/UsermodeConstants.java | 480 ---- src/main/java/org/ibex/nestedvm/util/ELF.java | 388 --- .../org/ibex/nestedvm/util/InodeCache.java | 207 -- .../java/org/ibex/nestedvm/util/Platform.java | 241 -- .../java/org/ibex/nestedvm/util/Seekable.java | 182 -- .../java/org/ibex/nestedvm/util/Sort.java | 47 - 11 files changed, 5 insertions(+), 6463 deletions(-) delete mode 100644 src/main/java/org/ibex/nestedvm/Interpreter.java delete mode 100644 src/main/java/org/ibex/nestedvm/Registers.java delete mode 100644 src/main/java/org/ibex/nestedvm/Runtime.java delete mode 100644 src/main/java/org/ibex/nestedvm/UnixRuntime.java delete mode 100644 src/main/java/org/ibex/nestedvm/UsermodeConstants.java delete mode 100644 src/main/java/org/ibex/nestedvm/util/ELF.java delete mode 100644 src/main/java/org/ibex/nestedvm/util/InodeCache.java delete mode 100644 src/main/java/org/ibex/nestedvm/util/Platform.java delete mode 100644 src/main/java/org/ibex/nestedvm/util/Seekable.java delete mode 100644 src/main/java/org/ibex/nestedvm/util/Sort.java diff --git a/pom.xml b/pom.xml index 35a1700..524a0e1 100644 --- a/pom.xml +++ b/pom.xml @@ -84,13 +84,6 @@ - - javafx-packager - javafx-packager - 1.7 - ${java.home}/../lib/ant-javafx.jar - system - org.reflections reflections @@ -102,5 +95,10 @@ 4.10 test + + org.xerial.thirdparty + nestedvm + 1.0 + diff --git a/src/main/java/org/ibex/nestedvm/Interpreter.java b/src/main/java/org/ibex/nestedvm/Interpreter.java deleted file mode 100644 index 719aa74..0000000 --- a/src/main/java/org/ibex/nestedvm/Interpreter.java +++ /dev/null @@ -1,787 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source 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 - -package org.ibex.nestedvm; - -import org.ibex.nestedvm.util.*; -import java.io.*; - -public class Interpreter extends UnixRuntime implements Cloneable { - // Registers - private int[] registers = new int[32]; - private int hi,lo; - - // Floating Point Registers - private int[] fpregs = new int[32]; - // 24-31 - unused - // 23 - conditional bit - // 18-22 - unused - // 12-17 - cause bits (unimplemented) - // 7-11 - enables bits (unimplemented) - // 2-6 - flags (unimplemented) - // 0-1 - rounding mode (only implemented for fixed point conversions) - private int fcsr; - - private int pc; - - // The filename if the binary we're running - public String image; - private ELF.Symtab symtab; - - // Register Operations - private final void setFC(boolean b) { fcsr = (fcsr&~0x800000) | (b ? 0x800000 : 0x000000); } - private final int roundingMode() { return fcsr & 3; /* bits 0-1 */ } - private final double getDouble(int r) { - return Double.longBitsToDouble(((fpregs[r+1]&0xffffffffL) << 32) | (fpregs[r]&0xffffffffL)); - } - private final void setDouble(int r, double d) { - long l = Double.doubleToLongBits(d); - fpregs[r+1] = (int)(l >>> 32); fpregs[r] = (int)l; - } - private final float getFloat(int r) { return Float.intBitsToFloat(fpregs[r]); } - private final void setFloat(int r, float f) { fpregs[r] = Float.floatToRawIntBits(f); } - - protected void _execute() throws ExecutionException { - try { - runSome(); - } catch(ExecutionException e) { - e.setLocation(toHex(pc) + ": " + sourceLine(pc)); - throw e; - } - } - - protected Object clone() throws CloneNotSupportedException { - Interpreter r = (Interpreter) super.clone(); - r.registers = (int[]) registers.clone(); - r.fpregs = (int[]) fpregs.clone(); - return r; - } - - // Main interpretor - // the return value is meaningless, its just to catch people typing "return" by accident - private final int runSome() throws FaultException,ExecutionException { - final int PAGE_WORDS = (1<>2; - int[] r = registers; - int[] f = fpregs; - int pc = this.pc; - int nextPC = pc + 4; - try { - OUTER: for(;;) { - int insn; - try { - insn = readPages[pc>>>pageShift][(pc>>>2)&PAGE_WORDS-1]; - } catch (RuntimeException e) { - if(pc == 0xdeadbeef) throw new Error("fell off cpu: r2: " + r[2]); - insn = memRead(pc); - } - - int op = (insn >>> 26) & 0xff; // bits 26-31 - int rs = (insn >>> 21) & 0x1f; // bits 21-25 - int rt = (insn >>> 16) & 0x1f; // bits 16-20 - int ft = (insn >>> 16) & 0x1f; - int rd = (insn >>> 11) & 0x1f; // bits 11-15 - int fs = (insn >>> 11) & 0x1f; - int shamt = (insn >>> 6) & 0x1f; // bits 6-10 - int fd = (insn >>> 6) & 0x1f; - int subcode = insn & 0x3f; // bits 0-5 - - int jumpTarget = (insn & 0x03ffffff); // bits 0-25 - int unsignedImmediate = insn & 0xffff; - int signedImmediate = (insn << 16) >> 16; - int branchTarget = signedImmediate; - - int tmp, addr; // temporaries - - r[ZERO] = 0; - - switch(op) { - case 0: { - switch(subcode) { - case 0: // SLL - if(insn == 0) break; - r[rd] = r[rt] << shamt; - break; - case 2: // SRL - r[rd] = r[rt] >>> shamt; - break; - case 3: // SRA - r[rd] = r[rt] >> shamt; - break; - case 4: // SLLV - r[rd] = r[rt] << (r[rs]&0x1f); - break; - case 6: // SRLV - r[rd] = r[rt] >>> (r[rs]&0x1f); - break; - case 7: // SRAV - r[rd] = r[rt] >> (r[rs]&0x1f); - break; - case 8: // JR - tmp = r[rs]; pc += 4; nextPC = tmp; - continue OUTER; - case 9: // JALR - tmp = r[rs]; pc += 4; r[rd] = pc+4; nextPC = tmp; - continue OUTER; - case 12: // SYSCALL - this.pc = pc; - r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3],r[T0],r[T1]); - if(state != RUNNING) { this.pc = nextPC; break OUTER; } - break; - case 13: // BREAK - throw new ExecutionException("Break"); - case 16: // MFHI - r[rd] = hi; - break; - case 17: // MTHI - hi = r[rs]; - break; - case 18: // MFLO - r[rd] = lo; - break; - case 19: // MTLO - lo = r[rs]; - break; - case 24: { // MULT - long hilo = ((long)r[rs]) * ((long)r[rt]); - hi = (int) (hilo >>> 32); - lo = (int) hilo; - break; - } - case 25: { // MULTU - long hilo = (r[rs] & 0xffffffffL) * (r[rt] & 0xffffffffL); - hi = (int) (hilo >>> 32); - lo = (int) hilo; - break; - } - case 26: // DIV - hi = r[rs]%r[rt]; - lo = r[rs]/r[rt]; - break; - case 27: // DIVU - if(rt != 0) { - hi = (int)((r[rs] & 0xffffffffL) % (r[rt] & 0xffffffffL)); - lo = (int)((r[rs] & 0xffffffffL) / (r[rt] & 0xffffffffL)); - } - break; - case 32: // ADD - throw new ExecutionException("ADD (add with oveflow trap) not suported"); - /*This must trap on overflow - r[rd] = r[rs] + r[rt]; - break;*/ - case 33: // ADDU - r[rd] = r[rs] + r[rt]; - break; - case 34: // SUB - throw new ExecutionException("SUB (sub with oveflow trap) not suported"); - /*This must trap on overflow - r[rd] = r[rs] - r[rt]; - break;*/ - case 35: // SUBU - r[rd] = r[rs] - r[rt]; - break; - case 36: // AND - r[rd] = r[rs] & r[rt]; - break; - case 37: // OR - r[rd] = r[rs] | r[rt]; - break; - case 38: // XOR - r[rd] = r[rs] ^ r[rt]; - break; - case 39: // NOR - r[rd] = ~(r[rs] | r[rt]); - break; - case 42: // SLT - r[rd] = r[rs] < r[rt] ? 1 : 0; - break; - case 43: // SLTU - r[rd] = ((r[rs] & 0xffffffffL) < (r[rt] & 0xffffffffL)) ? 1 : 0; - break; - default: - throw new ExecutionException("Illegal instruction 0/" + subcode); - } - break; - } - case 1: { - switch(rt) { - case 0: // BLTZ - if(r[rs] < 0) { - pc += 4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 1: // BGEZ - if(r[rs] >= 0) { - pc += 4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 16: // BLTZAL - if(r[rs] < 0) { - pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 17: // BGEZAL - if(r[rs] >= 0) { - pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - default: - throw new ExecutionException("Illegal Instruction"); - } - break; - } - case 2: { // J - tmp = (pc&0xf0000000) | (jumpTarget << 2); - pc+=4; nextPC = tmp; - continue OUTER; - } - case 3: { // JAL - tmp = (pc&0xf0000000) | (jumpTarget << 2); - pc+=4; r[RA] = pc+4; nextPC = tmp; - continue OUTER; - } - case 4: // BEQ - if(r[rs] == r[rt]) { - pc += 4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 5: // BNE - if(r[rs] != r[rt]) { - pc += 4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 6: //BLEZ - if(r[rs] <= 0) { - pc += 4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 7: //BGTZ - if(r[rs] > 0) { - pc += 4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 8: // ADDI - r[rt] = r[rs] + signedImmediate; - break; - case 9: // ADDIU - r[rt] = r[rs] + signedImmediate; - break; - case 10: // SLTI - r[rt] = r[rs] < signedImmediate ? 1 : 0; - break; - case 11: // SLTIU - r[rt] = (r[rs]&0xffffffffL) < (signedImmediate&0xffffffffL) ? 1 : 0; - break; - case 12: // ANDI - r[rt] = r[rs] & unsignedImmediate; - break; - case 13: // ORI - r[rt] = r[rs] | unsignedImmediate; - break; - case 14: // XORI - r[rt] = r[rs] ^ unsignedImmediate; - break; - case 15: // LUI - r[rt] = unsignedImmediate << 16; - break; - case 16: - throw new ExecutionException("TLB/Exception support not implemented"); - case 17: { // FPU - boolean debug = false; - String line = debug ? sourceLine(pc) : ""; - boolean debugon = debug && (line.indexOf("dtoa.c:51") >= 0 || line.indexOf("dtoa.c:52") >= 0 || line.indexOf("test.c") >= 0); - if(rs > 8 && debugon) - System.out.println(" FP Op: " + op + "/" + rs + "/" + subcode + " " + line); - if(roundingMode() != 0 && rs != 6 /*CTC.1*/ && !((rs==16 || rs==17) && subcode == 36 /* CVT.W.Z */)) - throw new ExecutionException("Non-cvt.w.z operation attempted with roundingMode != round to nearest"); - switch(rs) { - case 0: // MFC.1 - r[rt] = f[rd]; - break; - case 2: // CFC.1 - if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable"); - r[rt] = fcsr; - break; - case 4: // MTC.1 - f[rd] = r[rt]; - break; - case 6: // CTC.1 - if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable"); - fcsr = r[rt]; - break; - case 8: // BC1F, BC1T - if(((fcsr&0x800000)!=0) == (((insn>>>16)&1)!=0)) { - pc += 4; tmp = pc + branchTarget*4; nextPC = tmp; - continue OUTER; - } - break; - case 16: { // Single - switch(subcode) { - case 0: // ADD.S - setFloat(fd,getFloat(fs)+getFloat(ft)); - break; - case 1: // SUB.S - setFloat(fd,getFloat(fs)-getFloat(ft)); - break; - case 2: // MUL.S - setFloat(fd,getFloat(fs)*getFloat(ft)); - break; - case 3: // DIV.S - setFloat(fd,getFloat(fs)/getFloat(ft)); - break; - case 5: // ABS.S - setFloat(fd,Math.abs(getFloat(fs))); - break; - case 6: // MOV.S - f[fd] = f[fs]; - break; - case 7: // NEG.S - setFloat(fd,-getFloat(fs)); - break; - case 33: // CVT.D.S - setDouble(fd,getFloat(fs)); - break; - case 36: // CVT.W.S - switch(roundingMode()) { - case 0: f[fd] = (int)Math.floor(getFloat(fs)+0.5f); break; // Round to nearest - case 1: f[fd] = (int)getFloat(fs); break; // Round towards zero - case 2: f[fd] = (int)Math.ceil(getFloat(fs)); break; // Round towards plus infinity - case 3: f[fd] = (int)Math.floor(getFloat(fs)); break; // Round towards minus infinity - } - break; - case 50: // C.EQ.S - setFC(getFloat(fs) == getFloat(ft)); - break; - case 60: // C.LT.S - setFC(getFloat(fs) < getFloat(ft)); - break; - case 62: // C.LE.S - setFC(getFloat(fs) <= getFloat(ft)); - break; - default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc)); - } - break; - } - case 17: { // Double - switch(subcode) { - case 0: // ADD.D - setDouble(fd,getDouble(fs)+getDouble(ft)); - break; - case 1: // SUB.D - if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") - f" + ft + " (" + getDouble(ft) + ")"); - setDouble(fd,getDouble(fs)-getDouble(ft)); - break; - case 2: // MUL.D - if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") * f" + ft + " (" + getDouble(ft) + ")"); - setDouble(fd,getDouble(fs)*getDouble(ft)); - if(debugon) System.out.println("f" + fd + " = " + getDouble(fd)); - break; - case 3: // DIV.D - setDouble(fd,getDouble(fs)/getDouble(ft)); - break; - case 5: // ABS.D - setDouble(fd,Math.abs(getDouble(fs))); - break; - case 6: // MOV.D - f[fd] = f[fs]; - f[fd+1] = f[fs+1]; - break; - case 7: // NEG.D - setDouble(fd,-getDouble(fs)); - break; - case 32: // CVT.S.D - setFloat(fd,(float)getDouble(fs)); - break; - case 36: // CVT.W.D - if(debugon) System.out.println("CVT.W.D rm: " + roundingMode() + " f" + fs + ":" + getDouble(fs)); - switch(roundingMode()) { - case 0: f[fd] = (int)Math.floor(getDouble(fs)+0.5); break; // Round to nearest - case 1: f[fd] = (int)getDouble(fs); break; // Round towards zero - case 2: f[fd] = (int)Math.ceil(getDouble(fs)); break; // Round towards plus infinity - case 3: f[fd] = (int)Math.floor(getDouble(fs)); break; // Round towards minus infinity - } - if(debugon) System.out.println("CVT.W.D: f" + fd + ":" + f[fd]); - break; - case 50: // C.EQ.D - setFC(getDouble(fs) == getDouble(ft)); - break; - case 60: // C.LT.D - setFC(getDouble(fs) < getDouble(ft)); - break; - case 62: // C.LE.D - setFC(getDouble(fs) <= getDouble(ft)); - break; - default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc)); - } - break; - } - case 20: { // Integer - switch(subcode) { - case 32: // CVT.S.W - setFloat(fd,f[fs]); - break; - case 33: // CVT.D.W - setDouble(fd,f[fs]); - break; - default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc)); - } - break; - } - default: - throw new ExecutionException("Invalid Instruction 17/" + rs); - } - break; - } - case 18: case 19: - throw new ExecutionException("No coprocessor installed"); - case 32: { // LB - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr&~3); - } - switch(addr&3) { - case 0: tmp = (tmp>>>24)&0xff; break; - case 1: tmp = (tmp>>>16)&0xff; break; - case 2: tmp = (tmp>>> 8)&0xff; break; - case 3: tmp = (tmp>>> 0)&0xff; break; - } - if((tmp&0x80)!=0) tmp |= 0xffffff00; // sign extend - r[rt] = tmp; - break; - } - case 33: { // LH - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr&~3); - } - switch(addr&3) { - case 0: tmp = (tmp>>>16)&0xffff; break; - case 2: tmp = (tmp>>> 0)&0xffff; break; - default: throw new ReadFaultException(addr); - } - if((tmp&0x8000)!=0) tmp |= 0xffff0000; // sign extend - r[rt] = tmp; - break; - } - case 34: { // LWL; - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr&~3); - } - switch(addr&3) { - case 0: r[rt] = (r[rt]&0x00000000)|(tmp<< 0); break; - case 1: r[rt] = (r[rt]&0x000000ff)|(tmp<< 8); break; - case 2: r[rt] = (r[rt]&0x0000ffff)|(tmp<<16); break; - case 3: r[rt] = (r[rt]&0x00ffffff)|(tmp<<24); break; - } - break; - } - case 35: // LW - addr = r[rs] + signedImmediate; - try { - r[rt] = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - r[rt] = memRead(addr); - } - break; - case 36: { // LBU - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr); - } - switch(addr&3) { - case 0: r[rt] = (tmp>>>24)&0xff; break; - case 1: r[rt] = (tmp>>>16)&0xff; break; - case 2: r[rt] = (tmp>>> 8)&0xff; break; - case 3: r[rt] = (tmp>>> 0)&0xff; break; - } - break; - } - case 37: { // LHU - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr&~3); - } - switch(addr&3) { - case 0: r[rt] = (tmp>>>16)&0xffff; break; - case 2: r[rt] = (tmp>>> 0)&0xffff; break; - default: throw new ReadFaultException(addr); - } - break; - } - case 38: { // LWR - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr&~3); - } - switch(addr&3) { - case 0: r[rt] = (r[rt]&0xffffff00)|(tmp>>>24); break; - case 1: r[rt] = (r[rt]&0xffff0000)|(tmp>>>16); break; - case 2: r[rt] = (r[rt]&0xff000000)|(tmp>>> 8); break; - case 3: r[rt] = (r[rt]&0x00000000)|(tmp>>> 0); break; - } - break; - } - case 40: { // SB - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr&~3); - } - switch(addr&3) { - case 0: tmp = (tmp&0x00ffffff) | ((r[rt]&0xff)<<24); break; - case 1: tmp = (tmp&0xff00ffff) | ((r[rt]&0xff)<<16); break; - case 2: tmp = (tmp&0xffff00ff) | ((r[rt]&0xff)<< 8); break; - case 3: tmp = (tmp&0xffffff00) | ((r[rt]&0xff)<< 0); break; - } - try { - writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp; - } catch(RuntimeException e) { - memWrite(addr&~3,tmp); - } - break; - } - case 41: { // SH - addr = r[rs] + signedImmediate; - try { - tmp = readPages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)]; - } catch(RuntimeException e) { - tmp = memRead(addr&~3); - } - switch(addr&3) { - case 0: tmp = (tmp&0x0000ffff) | ((r[rt]&0xffff)<<16); break; - case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break; - default: throw new WriteFaultException(addr); - } - try { - writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp; - } catch(RuntimeException e) { - memWrite(addr&~3,tmp); - } - break; - } - case 42: { // SWL - addr = r[rs] + signedImmediate; - tmp = memRead(addr&~3); - switch(addr&3) { - case 0: tmp=(tmp&0x00000000)|(r[rt]>>> 0); break; - case 1: tmp=(tmp&0xff000000)|(r[rt]>>> 8); break; - case 2: tmp=(tmp&0xffff0000)|(r[rt]>>>16); break; - case 3: tmp=(tmp&0xffffff00)|(r[rt]>>>24); break; - } - try { - writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = tmp; - } catch(RuntimeException e) { - memWrite(addr&~3,tmp); - } - break; - } - case 43: // SW - addr = r[rs] + signedImmediate; - try { - writePages[addr>>>pageShift][(addr>>>2)&(PAGE_WORDS-1)] = r[rt]; - } catch(RuntimeException e) { - memWrite(addr&~3,r[rt]); - } - break; - case 46: { // SWR - addr = r[rs] + signedImmediate; - tmp = memRead(addr&~3); - switch(addr&3) { - case 0: tmp=(tmp&0x00ffffff)|(r[rt]<<24); break; - case 1: tmp=(tmp&0x0000ffff)|(r[rt]<<16); break; - case 2: tmp=(tmp&0x000000ff)|(r[rt]<< 8); break; - case 3: tmp=(tmp&0x00000000)|(r[rt]<< 0); break; - } - memWrite(addr&~3,tmp); - break; - } - // Needs to be atomic w/ threads - case 48: // LWC0/LL - r[rt] = memRead(r[rs] + signedImmediate); - break; - case 49: // LWC1 - f[rt] = memRead(r[rs] + signedImmediate); - break; - // Needs to be atomic w/ threads - case 56: - memWrite(r[rs] + signedImmediate,r[rt]); - r[rt] = 1; - break; - case 57: // SWC1 - memWrite(r[rs] + signedImmediate,f[rt]); - break; - default: - throw new ExecutionException("Invalid Instruction: " + op); - } - pc = nextPC; - nextPC = pc + 4; - } // for(;;) - } catch(ExecutionException e) { - this.pc = pc; - throw e; - } - return 0; - } - - public int lookupSymbol(String name) { - ELF.Symbol sym = symtab.getSymbol(name); - return sym == null ? -1 : sym.addr; - } - - private int gp; - protected int gp() { return gp; } - - private ELF.Symbol userInfo; - protected int userInfoBae() { return userInfo == null ? 0 : userInfo.addr; } - protected int userInfoSize() { return userInfo == null ? 0 : userInfo.size; } - - private int entryPoint; - protected int entryPoint() { return entryPoint; } - - private int heapStart; - protected int heapStart() { return heapStart; } - - // Image loading function - private void loadImage(Seekable data) throws IOException { - ELF elf = new ELF(data); - symtab = elf.getSymtab(); - - if(elf.header.type != ELF.ET_EXEC) throw new IOException("Binary is not an executable"); - if(elf.header.machine != ELF.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture"); - if(elf.ident.data != ELF.ELFDATA2MSB) throw new IOException("Binary is not big endian"); - - entryPoint = elf.header.entry; - - ELF.Symtab symtab = elf.getSymtab(); - if(symtab == null) throw new IOException("No symtab in binary (did you strip it?)"); - userInfo = symtab.getSymbol("user_info"); - ELF.Symbol gpsym = symtab.getSymbol("_gp"); - - if(gpsym == null) throw new IOException("NO _gp symbol!"); - gp = gpsym.addr; - - entryPoint = elf.header.entry; - - ELF.PHeader[] pheaders = elf.pheaders; - int brk = 0; - int pageSize = (1<> 2; - for(int i=0;i>> pageShift; - if(readPages[page] == null) - readPages[page] = new int[pageWords]; - if(ph.writable()) writePages[page] = readPages[page]; - } - if(filesize != 0) { - filesize = filesize & ~3; - DataInputStream dis = new DataInputStream(ph.getInputStream()); - do { - readPages[addr >>> pageShift][(addr >>> 2)&(pageWords-1)] = dis.readInt(); - addr+=4; - filesize-=4; - } while(filesize > 0); - dis.close(); - } - } - heapStart = (brk+pageSize-1)&~(pageSize-1); - } - - protected void setCPUState(CPUState state) { - for(int i=1;i<32;i++) registers[i] = state.r[i]; - for(int i=0;i<32;i++) fpregs[i] = state.f[i]; - hi=state.hi; lo=state.lo; fcsr=state.fcsr; - pc=state.pc; - } - - protected void getCPUState(CPUState state) { - for(int i=1;i<32;i++) state.r[i] = registers[i]; - for(int i=0;i<32;i++) state.f[i] = fpregs[i]; - state.hi=hi; state.lo=lo; state.fcsr=fcsr; - state.pc=pc; - } - - public Interpreter(Seekable data) throws IOException { - super(4096,65536); - loadImage(data); - } - public Interpreter(String filename) throws IOException { - this(new Seekable.File(filename,false)); - image = filename; - } - public Interpreter(InputStream is) throws IOException { this(new Seekable.InputStream(is)); } - - // Debug functions - // NOTE: This probably requires a jdk > 1.1, however, it is only used for debugging - private java.util.HashMap sourceLineCache; - public String sourceLine(int pc) { - final String addr2line = "mips-unknown-elf-addr2line"; - String line = (String) (sourceLineCache == null ? null : sourceLineCache.get(new Integer(pc))); - if(line != null) return line; - if(image==null) return null; - try { - Process p = java.lang.Runtime.getRuntime().exec(new String[]{addr2line,"-e",image,toHex(pc)}); - line = new BufferedReader(new InputStreamReader(p.getInputStream())).readLine(); - if(line == null) return null; - while(line.startsWith("../")) line = line.substring(3); - if(sourceLineCache == null) sourceLineCache = new java.util.HashMap(); - sourceLineCache.put(new Integer(pc),line); - return line; - } catch(IOException e) { - return null; - } - } - - public class DebugShutdownHook implements Runnable { - public void run() { - int pc = Interpreter.this.pc; - if(getState() == RUNNING) - System.err.print("\nCPU Executing " + toHex(pc) + ": " + sourceLine(pc) + "\n"); - } - } - - public static void main(String[] argv) throws Exception { - String image = argv[0]; - Interpreter emu = new Interpreter(image); - java.lang.Runtime.getRuntime().addShutdownHook(new Thread(emu.new DebugShutdownHook())); - int status = emu.run(argv); - System.err.println("Exit status: " + status); - System.exit(status); - } -} diff --git a/src/main/java/org/ibex/nestedvm/Registers.java b/src/main/java/org/ibex/nestedvm/Registers.java deleted file mode 100644 index a441af5..0000000 --- a/src/main/java/org/ibex/nestedvm/Registers.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source License 2.0 ("the License"). -// You may not use this file except in compliance with the License. - -package org.ibex.nestedvm; - -interface Registers { - // Register Names - public final static int ZERO = 0; // Immutable, hardwired to 0 - public final static int AT = 1; // Reserved for assembler - public final static int K0 = 26; // Reserved for kernel - public final static int K1 = 27; // Reserved for kernel - public final static int GP = 28; // Global pointer (the middle of .sdata/.sbss) - public final static int SP = 29; // Stack pointer - public final static int FP = 30; // Frame Pointer - public final static int RA = 31; // Return Address - - // Return values (caller saved) - public final static int V0 = 2; - public final static int V1 = 3; - // Argument Registers (caller saved) - public final static int A0 = 4; - public final static int A1 = 5; - public final static int A2 = 6; - public final static int A3 = 7; - // Temporaries (caller saved) - public final static int T0 = 8; - public final static int T1 = 9; - public final static int T2 = 10; - public final static int T3 = 11; - public final static int T4 = 12; - public final static int T5 = 13; - public final static int T6 = 14; - public final static int T7 = 15; - public final static int T8 = 24; - public final static int T9 = 25; - // Saved (callee saved) - public final static int S0 = 16; - public final static int S1 = 17; - public final static int S2 = 18; - public final static int S3 = 19; - public final static int S4 = 20; - public final static int S5 = 21; - public final static int S6 = 22; - public final static int S7 = 23; -} diff --git a/src/main/java/org/ibex/nestedvm/Runtime.java b/src/main/java/org/ibex/nestedvm/Runtime.java deleted file mode 100644 index 2c599a0..0000000 --- a/src/main/java/org/ibex/nestedvm/Runtime.java +++ /dev/null @@ -1,1566 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source 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 - -package org.ibex.nestedvm; - -import org.ibex.nestedvm.util.*; -import java.io.*; - -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; - - /** Number of bits to shift to get the page number (1<<symbol or -1 it it doesn't exits in this method - This method is only required if the call() function is used */ - public int lookupSymbol(String symbol) { return -1; } - - /** Subclasses should populate a CPUState object representing the cpu state */ - protected abstract void getCPUState(CPUState state); - - /** 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; - r.startTime = 0; - r.fds = new FD[OPEN_MAX]; - for(int i=0;i>>_pageShift != 1) _pageShift++; - pageShift = _pageShift; - - int heapStart = heapStart(); - int totalMemory = totalPages * pageSize; - int stackSize = max(totalMemory/512,ARG_MAX+65536); - int stackPages = 0; - if(totalPages > 1) { - stackSize = max(stackSize,pageSize); - stackSize = (stackSize + pageSize - 1) & ~(pageSize-1); - stackPages = stackSize >>> pageShift; - heapStart = (heapStart + pageSize - 1) & ~(pageSize-1); - if(stackPages + STACK_GUARD_PAGES + (heapStart >>> pageShift) >= totalPages) - throw new IllegalArgumentException("total pages too small"); - } else { - if(pageSize < heapStart + stackSize) throw new IllegalArgumentException("total memory too small"); - heapStart = (heapStart + 4095) & ~4096; - } - - stackBottom = totalMemory - stackSize; - heapEnd = heapStart; - - readPages = new int[totalPages][]; - writePages = new int[totalPages][]; - - if(totalPages == 1) { - readPages[0] = writePages[0] = new int[pageSize>>2]; - } else { - for(int i=(stackBottom >>> pageShift);i>2]; - } - } - - 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. - Newly initalized pages will be marked read-only if ro is set */ - protected final void initPages(int[] src, int addr, boolean ro) { - int pageWords = (1<>>2; - int pageMask = (1<>> pageShift; - int start = (addr&pageMask)>>2; - int elements = min(pageWords-start,src.length-i); - if(readPages[page]==null) { - initPage(page,ro); - } else if(!ro) { - if(writePages[page] == null) writePages[page] = readPages[page]; - } - System.arraycopy(src,i,readPages[page],start,elements); - i += elements; - addr += elements*4; - } - } - - /** Initialize words of pages starting at addr to 0 */ - protected final void clearPages(int addr, int words) { - int pageWords = (1<>>2; - int pageMask = (1<>> pageShift; - int start = (addr&pageMask)>>2; - int elements = min(pageWords-start,words-i); - if(readPages[page]==null) { - readPages[page] = writePages[page] = new int[pageWords]; - } else { - if(writePages[page] == null) writePages[page] = readPages[page]; - for(int j=start;jlength bytes from the processes memory space starting at - addr INTO a java byte array a */ - public final void copyin(int addr, byte[] buf, int count) throws ReadFaultException { - int pageWords = (1<>>2; - int pageMask = pageWords - 1; - - int x=0; - if(count == 0) return; - if((addr&3)!=0) { - int word = memRead(addr&~3); - switch(addr&3) { - case 1: buf[x++] = (byte)((word>>>16)&0xff); if(--count==0) break; - case 2: buf[x++] = (byte)((word>>> 8)&0xff); if(--count==0) break; - case 3: buf[x++] = (byte)((word>>> 0)&0xff); if(--count==0) break; - } - addr = (addr&~3)+4; - } - if((count&~3) != 0) { - int c = count>>>2; - int a = addr>>>2; - while(c != 0) { - int[] page = readPages[a >>> (pageShift-2)]; - if(page == null) throw new ReadFaultException(a<<2); - int index = a&pageMask; - int n = min(c,pageWords-index); - for(int i=0;i>>24)&0xff); buf[x+1] = (byte)((word>>>16)&0xff); - buf[x+2] = (byte)((word>>> 8)&0xff); buf[x+3] = (byte)((word>>> 0)&0xff); - } - a += n; c -=n; - } - addr = a<<2; count &=3; - } - if(count != 0) { - int word = memRead(addr); - switch(count) { - case 3: buf[x+2] = (byte)((word>>>8)&0xff); - case 2: buf[x+1] = (byte)((word>>>16)&0xff); - case 1: buf[x+0] = (byte)((word>>>24)&0xff); - } - } - } - - /** Copies length bytes OUT OF the java array a into the processes memory - space at addr */ - public final void copyout(byte[] buf, int addr, int count) throws FaultException { - int pageWords = (1<>>2; - int pageWordMask = pageWords - 1; - - int x=0; - if(count == 0) return; - if((addr&3)!=0) { - int word = memRead(addr&~3); - switch(addr&3) { - case 1: word = (word&0xff00ffff)|((buf[x++]&0xff)<<16); if(--count==0) break; - case 2: word = (word&0xffff00ff)|((buf[x++]&0xff)<< 8); if(--count==0) break; - case 3: word = (word&0xffffff00)|((buf[x++]&0xff)<< 0); if(--count==0) break; - } - memWrite(addr&~3,word); - addr += x; - } - - if((count&~3) != 0) { - int c = count>>>2; - int a = addr>>>2; - while(c != 0) { - int[] page = writePages[a >>> (pageShift-2)]; - if(page == null) throw new WriteFaultException(a<<2); - int index = a&pageWordMask; - int n = min(c,pageWords-index); - for(int i=0;i>>2; - int pageWordMask = pageWords - 1; - if((dst&3) == 0 && (src&3)==0) { - if((count&~3) != 0) { - int c = count>>2; - int s = src>>>2; - int d = dst>>>2; - while(c != 0) { - int[] srcPage = readPages[s>>>(pageShift-2)]; - if(srcPage == null) throw new ReadFaultException(s<<2); - int[] dstPage = writePages[d>>>(pageShift-2)]; - if(dstPage == null) throw new WriteFaultException(d<<2); - int srcIndex = s&pageWordMask; - int dstIndex = d&pageWordMask; - int n = min(c,pageWords-max(srcIndex,dstIndex)); - System.arraycopy(srcPage,srcIndex,dstPage,dstIndex,n); - s += n; d += n; c -= n; - } - src = s<<2; dst = d<<2; count&=3; - } - if(count != 0) { - int word1 = memRead(src); - int word2 = memRead(dst); - switch(count) { - case 1: memWrite(dst,(word1&0xff000000)|(word2&0x00ffffff)); break; - case 2: memWrite(dst,(word1&0xffff0000)|(word2&0x0000ffff)); break; - case 3: memWrite(dst,(word1&0xffffff00)|(word2&0x000000ff)); break; - } - } - } else { - while(count > 0) { - int n = min(count,MAX_CHUNK); - byte[] buf = byteBuf(n); - copyin(src,buf,n); - copyout(buf,dst,n); - count -= n; src += n; dst += n; - } - } - } - - public final void memset(int addr, int ch, int count) throws FaultException { - int pageWords = (1<>>2; - int pageWordMask = pageWords - 1; - - int fourBytes = ((ch&0xff)<<24)|((ch&0xff)<<16)|((ch&0xff)<<8)|((ch&0xff)<<0); - if((addr&3)!=0) { - int word = memRead(addr&~3); - switch(addr&3) { - case 1: word = (word&0xff00ffff)|((ch&0xff)<<16); if(--count==0) break; - case 2: word = (word&0xffff00ff)|((ch&0xff)<< 8); if(--count==0) break; - case 3: word = (word&0xffffff00)|((ch&0xff)<< 0); if(--count==0) break; - } - memWrite(addr&~3,word); - addr = (addr&~3)+4; - } - if((count&~3) != 0) { - int c = count>>2; - int a = addr>>>2; - while(c != 0) { - int[] page = readPages[a>>>(pageShift-2)]; - 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);*/ - for(int i=index;iaddr */ - public final int memRead(int addr) throws ReadFaultException { - if((addr & 3) != 0) throw new ReadFaultException(addr); - return unsafeMemRead(addr); - } - - protected final int unsafeMemRead(int addr) throws ReadFaultException { - int page = addr >>> pageShift; - int entry = (addr&(1<>2; - try { - return readPages[page][entry]; - } catch(ArrayIndexOutOfBoundsException e) { - if(page < 0 || page >= readPages.length) throw new ReadFaultException(addr); - throw e; // should never happen - } catch(NullPointerException e) { - throw new ReadFaultException(addr); - } - } - - /** Writes a word to the processes memory at addr */ - public final void memWrite(int addr, int value) throws WriteFaultException { - if((addr & 3) != 0) throw new WriteFaultException(addr); - unsafeMemWrite(addr,value); - } - - protected final void unsafeMemWrite(int addr, int value) throws WriteFaultException { - int page = addr >>> pageShift; - int entry = (addr&(1<>2; - try { - writePages[page][entry] = value; - } catch(ArrayIndexOutOfBoundsException e) { - if(page < 0 || page >= writePages.length) throw new WriteFaultException(addr); - throw e; // should never happen - } catch(NullPointerException e) { - throw new WriteFaultException(addr); - } - } - - /** Created a new non-empty writable page at page number page */ - private final int[] initPage(int page) { return initPage(page,false); } - /** Created a new non-empty page at page number page. If ro is set the page will be read-only */ - private final int[] initPage(int page, boolean ro) { - int[] buf = new int[(1<>>2]; - writePages[page] = ro ? null : buf; - readPages[page] = buf; - return buf; - } - - /** Returns the exit status of the process. (only valid if state == DONE) - @see Runtime#state */ - public final int exitStatus() { - if(state != EXITED) throw new IllegalStateException("exitStatus() called in an inappropriate state"); - return exitStatus; - } - - private int addStringArray(String[] strings, int topAddr) throws FaultException { - int count = strings.length; - int total = 0; /* null last table entry */ - for(int i=0;iindex in the _user_info table to word - * The user_info table is a chunk of memory in the program's memory defined by the - * symbol "user_info". The compiler/interpreter automatically determine the size - * and location of the user_info table from the ELF symbol table. setUserInfo and - * getUserInfo are used to modify the words in the user_info table. */ - public void setUserInfo(int index, int word) { - if(index < 0 || index >= userInfoSize()/4) throw new IndexOutOfBoundsException("setUserInfo called with index >= " + (userInfoSize()/4)); - try { - memWrite(userInfoBase()+index*4,word); - } catch(FaultException e) { throw new RuntimeException(e.toString()); } - } - - /** Returns the word in the _user_info table entry index - @see Runtime#setUserInfo(int,int) setUserInfo */ - public int getUserInfo(int index) { - if(index < 0 || index >= userInfoSize()/4) throw new IndexOutOfBoundsException("setUserInfo called with index >= " + (userInfoSize()/4)); - try { - return memRead(userInfoBase()+index*4); - } catch(FaultException e) { throw new RuntimeException(e.toString()); } - } - - /** Calls _execute() (subclass's execute()) and catches exceptions */ - private void __execute() { - try { - _execute(); - } catch(FaultException e) { - if(STDERR_DIAG) e.printStackTrace(); - exit(128+11,true); // SIGSEGV - exitException = e; - } catch(ExecutionException e) { - if(STDERR_DIAG) e.printStackTrace(); - exit(128+4,true); // SIGILL - exitException = e; - } - } - - /** Executes the process until the PAUSE syscall is invoked or the process exits. Returns true if the process exited. */ - public final boolean execute() { - if(state != PAUSED) throw new IllegalStateException("execute() called in inappropriate state"); - if(startTime == 0) startTime = System.currentTimeMillis(); - state = RUNNING; - __execute(); - if(state != PAUSED && state != EXITED && state != EXECED) - throw new IllegalStateException("execute() ended up in an inappropriate state (" + state + ")"); - return state != PAUSED; - } - - static String[] concatArgv(String argv0, String[] rest) { - String[] argv = new String[rest.length+1]; - System.arraycopy(rest,0,argv,1,rest.length); - argv[0] = argv0; - return argv; - } - - public final int run() { return run(null); } - public final int run(String argv0, String[] rest) { return run(concatArgv(argv0,rest)); } - public final int run(String[] args) { return run(args,null); } - - /** Runs the process until it exits and returns the exit status. - If the process executes the PAUSE syscall execution will be paused for 500ms and a warning will be displayed */ - public final int run(String[] args, String[] env) { - start(args,env); - for(;;) { - if(execute()) break; - if(STDERR_DIAG) System.err.println("WARNING: Pause requested while executing run()"); - } - if(state == EXECED && STDERR_DIAG) System.err.println("WARNING: Process exec()ed while being run under run()"); - return state == EXITED ? exitStatus() : 0; - } - - public final void start() { start(null); } - public final void start(String[] args) { start(args,null); } - - /** Initializes the process and prepairs it to be executed with execute() */ - 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< 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< 7) throw new IllegalArgumentException("args.length > 7"); - CPUState state = new CPUState(); - getCPUState(state); - - int sp = state.r[SP]; - int[] ia = new int[args.length]; - for(int i=0;iaddr in the process setting A0-A3 and S0-S3 to the given arguments - and returns the contents of V1 when the the pause syscall is invoked */ - //public final int call(int addr, int a0, int a1, int a2, int a3, int s0, int s1, int s2, int s3) { - public final int call(int addr, int a0, int[] rest) throws CallException { - if(rest.length > 7) throw new IllegalArgumentException("rest.length > 7"); - if(state != PAUSED && state != CALLJAVA) throw new IllegalStateException("call() called in inappropriate state"); - int oldState = state; - CPUState saved = new CPUState(); - getCPUState(saved); - CPUState cpustate = saved.dup(); - - cpustate.r[SP] = cpustate.r[SP]&~15; - cpustate.r[RA] = 0xdeadbeef; - cpustate.r[A0] = a0; - switch(rest.length) { - case 7: cpustate.r[S3] = rest[6]; - case 6: cpustate.r[S2] = rest[5]; - case 5: cpustate.r[S1] = rest[4]; - case 4: cpustate.r[S0] = rest[3]; - case 3: cpustate.r[A3] = rest[2]; - case 2: cpustate.r[A2] = rest[1]; - case 1: cpustate.r[A1] = rest[0]; - } - cpustate.pc = addr; - - state = RUNNING; - - setCPUState(cpustate); - __execute(); - getCPUState(cpustate); - setCPUState(saved); - - if(state != PAUSED) throw new CallException("Process exit()ed while servicing a call() request"); - state = oldState; - - return cpustate.r[V1]; - } - - /** Allocated an entry in the FileDescriptor table for fd and returns the number. - Returns -1 if the table is full. This can be used by subclasses to use custom file - descriptors */ - public final int addFD(FD fd) { - if(state == EXITED || state == EXECED) throw new IllegalStateException("addFD called in inappropriate state"); - int i; - for(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; - } - - /** Duplicates the file descriptor fdn and returns the new fs */ - public final int dupFD(int fdn) { - int i; - if(fdn < 0 || fdn >= OPEN_MAX) return -1; - if(fds[fdn] == null) return -1; - for(i=0;i= 0) throw new ErrnoException(EACCES); - return null; - } catch(IOException e) { throw new ErrnoException(EIO); } - - return new SeekableFD(sf,flags) { protected FStat _fstat() { return hostFStat(f,sf,data); } }; - } - - FStat hostFStat(File f, Seekable.File sf, Object data) { return new HostFStat(f,sf); } - - FD hostFSDirFD(File f, Object data) { return null; } - - FD _open(String path, int flags, int mode) throws ErrnoException { - return hostFSOpen(new File(path),flags,mode,null); - } - - /** The open syscall */ - private int sys_open(int addr, int flags, int mode) throws ErrnoException, FaultException { - 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; } - return fdn; - } - - /** The write syscall */ - - private int sys_write(int fdn, int addr, int count) throws FaultException, ErrnoException { - count = Math.min(count,MAX_CHUNK); - if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; - if(fds[fdn] == null) return -EBADFD; - byte[] buf = byteBuf(count); - copyin(addr,buf,count); - try { - return fds[fdn].write(buf,0,count); - } catch(ErrnoException e) { - if(e.errno == EPIPE) sys_exit(128+13); - throw e; - } - } - - /** The read syscall */ - private int sys_read(int fdn, int addr, int count) throws FaultException, ErrnoException { - count = Math.min(count,MAX_CHUNK); - if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; - if(fds[fdn] == null) return -EBADFD; - byte[] buf = byteBuf(count); - int n = fds[fdn].read(buf,0,count); - 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) { - return closeFD(fdn) ? 0 : -EBADFD; - } - - - /** The seek syscall */ - private int sys_lseek(int fdn, int offset, int whence) throws ErrnoException { - if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; - if(fds[fdn] == null) return -EBADFD; - if(whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) return -EINVAL; - int n = fds[fdn].seek(offset,whence); - return n < 0 ? -ESPIPE : n; - } - - /** The stat/fstat syscall helper */ - 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,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 - memWrite(addr+28,fs.mtime()); // st_mtime - // memWrite(addr+32,0) // st_spare2 - memWrite(addr+36,fs.ctime()); // st_ctime - // memWrite(addr+40,0) // st_spare3 - memWrite(addr+44,fs.blksize()); // st_bklsize; - memWrite(addr+48,fs.blocks()); // st_blocks - // memWrite(addr+52,0) // st_spare4[0] - // memWrite(addr+56,0) // st_spare4[1] - return 0; - } - - /** The fstat syscall */ - private int sys_fstat(int fdn, int addr) throws FaultException { - if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; - if(fds[fdn] == null) return -EBADFD; - return stat(fds[fdn].fstat(),addr); - } - - /* - struct timeval { - long tv_sec; - long tv_usec; - }; - */ - private int sys_gettimeofday(int timevalAddr, int timezoneAddr) throws FaultException { - long now = System.currentTimeMillis(); - int tv_sec = (int)(now / 1000); - int tv_usec = (int)((now%1000)*1000); - memWrite(timevalAddr+0,tv_sec); - memWrite(timevalAddr+4,tv_usec); - return 0; - } - - private int sys_sleep(int sec) { - if(sec < 0) sec = Integer.MAX_VALUE; - try { - Thread.sleep((long)sec*1000); - return 0; - } catch(InterruptedException e) { - return -1; - } - } - - /* - #define _CLOCKS_PER_SEC_ 1000 - #define _CLOCK_T_ unsigned long - struct tms { - clock_t tms_utime; - clock_t tms_stime; - clock_t tms_cutime; - clock_t tms_cstime; - };*/ - - private int sys_times(int tms) { - long now = System.currentTimeMillis(); - int userTime = (int)((now - startTime)/16); - int sysTime = (int)((now - startTime)/16); - - try { - if(tms!=0) { - memWrite(tms+0,userTime); - memWrite(tms+4,sysTime); - memWrite(tms+8,userTime); - memWrite(tms+12,sysTime); - } - } catch(FaultException e) { - return -EFAULT; - } - return (int)now; - } - - private int sys_sysconf(int n) { - switch(n) { - case _SC_CLK_TCK: return 1000; - case _SC_PAGESIZE: return writePages.length == 1 ? 4096 : (1<incr is how much to increase the break by */ - public final int sbrk(int incr) { - if(incr < 0) return -ENOMEM; - if(incr==0) return heapEnd; - incr = (incr+3)&~3; - int oldEnd = heapEnd; - int newEnd = oldEnd + incr; - if(newEnd >= stackBottom) return -ENOMEM; - - if(writePages.length > 1) { - int pageMask = (1<>> 2; - int start = (oldEnd + pageMask) >>> pageShift; - int end = (newEnd + pageMask) >>> pageShift; - try { - for(int i=start;i= OPEN_MAX) return -EBADFD; - if(fds[fdn] == null) return -EBADFD; - FD fd = fds[fdn]; - - switch(cmd) { - case F_DUPFD: - if(arg < 0 || arg >= OPEN_MAX) return -EINVAL; - for(i=arg;i= 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 - 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, int e, int f) { - try { - int n = _syscall(syscall,a,b,c,d,e,f); - //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) { - return -EFAULT; - } catch(RuntimeException ex) { - ex.printStackTrace(); - throw new Error("Internal Error in _syscall()"); - } - } - - 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); - case SYS_pause: return sys_pause(); - case SYS_write: return sys_write(a,b,c); - case SYS_fstat: return sys_fstat(a,b); - case SYS_sbrk: return sbrk(a); - case SYS_open: return sys_open(a,b,c); - 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); - case SYS_sleep: return sys_sleep(a); - case SYS_times: return sys_times(a); - 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; - - case SYS_kill: - case SYS_fork: - case SYS_pipe: - case SYS_dup2: - case SYS_waitpid: - case SYS_stat: - case SYS_mkdir: - case SYS_getcwd: - case SYS_chdir: - if(STDERR_DIAG) System.err.println("Attempted to use a UnixRuntime syscall in Runtime (" + syscall + ")"); - return -ENOSYS; - default: - if(STDERR_DIAG) System.err.println("Attempted to use unknown syscall: " + syscall); - return -ENOSYS; - } - } - - 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; } } - public int malloc(int size) { try { return call("malloc",size); } catch(CallException e) { return 0; } } - public void free(int p) { try { if(p!=0) call("free",p); } catch(CallException e) { /*noop*/ } } - - /** Helper function to create a cstring in main memory */ - public int strdup(String s) { - byte[] a; - if(s == null) s = "(null)"; - byte[] a2 = getBytes(s); - a = new byte[a2.length+1]; - System.arraycopy(a2,0,a,0,a2.length); - int addr = malloc(a.length); - if(addr == 0) return 0; - try { - copyout(a,addr,a.length); - } catch(FaultException e) { - free(addr); - return 0; - } - 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); - switch(addr&3) { - case 0: if(((word>>>24)&0xff)==0) return sb.toString(); sb.append((char)((word>>>24)&0xff)); addr++; - case 1: if(((word>>>16)&0xff)==0) return sb.toString(); sb.append((char)((word>>>16)&0xff)); addr++; - case 2: if(((word>>> 8)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 8)&0xff)); addr++; - case 3: if(((word>>> 0)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 0)&0xff)); addr++; - } - } - } - - /** 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); } - /** Write. Should return the number of bytes written or throw an IOException on error */ - public int write(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); } - - /** Seek in the filedescriptor. Whence is SEEK_SET, SEEK_CUR, or SEEK_END. Should return -1 on error or the new position. */ - public int seek(int n, int whence) throws ErrnoException { return -1; } - - public int getdents(byte[] a, int off, int length) throws ErrnoException { throw new ErrnoException(EBADFD); } - - /** Return a Seekable object representing this file descriptor (can be read only) - This is required for exec() */ - Seekable seekable() { return null; } - - private FStat cachedFStat = null; - public final FStat fstat() { - if(cachedFStat == null) cachedFStat = _fstat(); - return cachedFStat; - } - - protected abstract FStat _fstat(); - public abstract int flags(); - - /** Closes the fd */ - public final void close() { if(--refCount==0) _close(); } - protected void _close() { /* noop*/ } - - FD dup() { refCount++; return this; } - } - - /** FileDescriptor class for normal files */ - public abstract static class SeekableFD extends FD { - private final int flags; - private final Seekable data; - - SeekableFD(Seekable data, int flags) { this.data = data; this.flags = flags; } - - protected abstract FStat _fstat(); - public int flags() { return flags; } - - Seekable seekable() { return data; } - - public int seek(int n, int whence) throws ErrnoException { - try { - switch(whence) { - case SEEK_SET: break; - case SEEK_CUR: n += data.pos(); break; - case SEEK_END: n += data.length(); break; - default: return -1; - } - data.seek(n); - return n; - } catch(IOException e) { - throw new ErrnoException(ESPIPE); - } - } - - public int write(byte[] a, int off, int length) throws ErrnoException { - if((flags&3) == RD_ONLY) throw new ErrnoException(EBADFD); - // NOTE: There is race condition here but we can't fix it in pure java - if((flags&O_APPEND) != 0) seek(0,SEEK_END); - try { - return data.write(a,off,length); - } catch(IOException e) { - throw new ErrnoException(EIO); - } - } - - public int read(byte[] a, int off, int length) throws ErrnoException { - if((flags&3) == WR_ONLY) throw new ErrnoException(EBADFD); - try { - int n = data.read(a,off,length); - return n < 0 ? 0 : n; - } catch(IOException e) { - throw new ErrnoException(EIO); - } - } - - protected void _close() { try { data.close(); } catch(IOException e) { /*ignore*/ } } - } - - 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 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 FStat _fstat() { return new SocketFStat(); } - } - - 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 SocketFStat() { 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 Win32ConsoleIS extends InputStream { - private int pushedBack = -1; - private final InputStream parent; - public Win32ConsoleIS(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 pb ? 1 : -1; - for(int i=0;i 0) buf[n++] = prev | (int)(l>>>(56-left)); - if(n < words) buf[n++] = (int) (l >>> (24-left)); - left = (left + 8) & 0x1f; - prev = (int)(l << left); - } - return buf; - } - - static byte[] getBytes(String s) { - try { - return s.getBytes("UTF-8"); - } catch(UnsupportedEncodingException e) { - return null; // should never happen - } - } - - static byte[] getNullTerminatedBytes(String s) { - byte[] buf1 = getBytes(s); - byte[] buf2 = new byte[buf1.length+1]; - System.arraycopy(buf1,0,buf2,0,buf1.length); - return buf2; - } - - final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); } - final static int min(int a, int b) { return a < b ? a : b; } - final static int max(int a, int b) { return a > b ? a : b; } -} diff --git a/src/main/java/org/ibex/nestedvm/UnixRuntime.java b/src/main/java/org/ibex/nestedvm/UnixRuntime.java deleted file mode 100644 index eaf3466..0000000 --- a/src/main/java/org/ibex/nestedvm/UnixRuntime.java +++ /dev/null @@ -1,2512 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source License 2.0 ("the License"). -// You may not use this file except in compliance with the License. - -package org.ibex.nestedvm; - -import org.ibex.nestedvm.util.*; -import java.io.*; -import java.util.*; -import java.net.*; -import java.nio.file.*; -import java.lang.reflect.*; // For lazily linked RuntimeCompiler - -// FEATURE: vfork - -public abstract class UnixRuntime extends Runtime implements Cloneable { - /** The pid of this "process" */ - private int pid; - private UnixRuntime parent; - public final int getPid() { - return pid; - } - - private static final GlobalState defaultGS = new GlobalState(); - private GlobalState gs; - public void setGlobalState(GlobalState gs) { - if(state != STOPPED) throw new IllegalStateException("can't change GlobalState when running"); - if(gs == null) throw new NullPointerException("gs is null"); - this.gs = gs; - } - - /** proceses' current working directory - absolute path WITHOUT leading slash - "" = root, "bin" = /bin "usr/bin" = /usr/bin */ - private String cwd; - - /** The runtime that should be run next when in state == EXECED */ - private UnixRuntime execedRuntime; - - private Object children; // used only for synchronizatin - private Vector activeChildren; - private Vector exitedChildren; - - protected UnixRuntime(int pageSize, int totalPages) { - this(pageSize,totalPages,false); - } - - protected UnixRuntime(int pageSize, int totalPages, boolean exec) { - super(pageSize,totalPages,exec); - - if(!exec) { - gs = defaultGS; - String userdir = Platform.getProperty("user.dir"); - cwd = userdir == null ? null : gs.mapHostPath(userdir); - if(cwd == null) cwd = "/"; - cwd = cwd.substring(1); - } - } - - private static String posixTZ() { - StringBuffer sb = new StringBuffer(); - TimeZone zone = TimeZone.getDefault(); - int off = zone.getRawOffset() / 1000; - sb.append(Platform.timeZoneGetDisplayName(zone,false,false)); - if(off > 0) sb.append("-"); - else off = -off; - sb.append(off/3600); - off = off%3600; - if(off > 0) sb.append(":").append(off/60); - off=off%60; - if(off > 0) sb.append(":").append(off); - if(zone.useDaylightTime()) - sb.append(Platform.timeZoneGetDisplayName(zone,true,false)); - return sb.toString(); - } - - private static boolean envHas(String key,String[] environ) { - for(int i=0; i= gs.tasks.length)) return -ECHILD; - if(children == null) return blocking ? -ECHILD : 0; - - UnixRuntime done = null; - - synchronized(children) { - for(;;) { - if(pid == -1) { - if(exitedChildren.size() > 0) { - done = (UnixRuntime)exitedChildren.elementAt(exitedChildren.size() - 1); - exitedChildren.removeElementAt(exitedChildren.size() - 1); - } - } else if(pid > 0) { - if(pid >= gs.tasks.length) return -ECHILD; - UnixRuntime t = gs.tasks[pid]; - if(t.parent != this) return -ECHILD; - if(t.state == EXITED) { - if(!exitedChildren.removeElement(t)) throw new Error("should never happen"); - done = t; - } - } else { - // process group stuff, EINVAL returned above - throw new Error("should never happen"); - } - if(done == null) { - if(!blocking) return 0; - try { - children.wait(); - } - catch(InterruptedException e) {} - //System.err.println("waitpid woke up: " + exitedChildren.size()); - } else { - gs.tasks[done.pid] = null; - break; - } - } - } - if(statusAddr!=0) memWrite(statusAddr,done.exitStatus()<<8); - return done.pid; - } - - - void _exited() { - if(children != null) synchronized(children) { - for(Enumeration e = exitedChildren.elements(); e.hasMoreElements(); ) { - UnixRuntime child = (UnixRuntime) e.nextElement(); - gs.tasks[child.pid] = null; - } - exitedChildren.removeAllElements(); - for(Enumeration e = activeChildren.elements(); e.hasMoreElements(); ) { - UnixRuntime child = (UnixRuntime) e.nextElement(); - child.parent = null; - } - activeChildren.removeAllElements(); - } - - UnixRuntime _parent = parent; - if(_parent == null) { - gs.tasks[pid] = null; - } else { - synchronized(_parent.children) { - if(parent == null) { - gs.tasks[pid] = null; - } else { - if(!parent.activeChildren.removeElement(this)) throw new Error("should never happen _exited: pid: " + pid); - parent.exitedChildren.addElement(this); - parent.children.notify(); - } - } - } - } - - protected Object clone() throws CloneNotSupportedException { - UnixRuntime r = (UnixRuntime) super.clone(); - r.pid = 0; - r.parent = null; - r.children = null; - r.activeChildren = r.exitedChildren = null; - return r; - } - - private int sys_fork() { - final UnixRuntime r; - - try { - r = (UnixRuntime) clone(); - } catch(Exception e) { - e.printStackTrace(); - return -ENOMEM; - } - - r.parent = this; - - try { - r._started(); - } catch(ProcessTableFullExn e) { - return -ENOMEM; - } - - //System.err.println("fork " + pid + " -> " + r.pid + " tasks[" + r.pid + "] = " + gd.tasks[r.pid]); - if(children == null) { - children = new Object(); - activeChildren = new Vector(); - exitedChildren = new Vector(); - } - activeChildren.addElement(r); - - CPUState state = new CPUState(); - getCPUState(state); - state.r[V0] = 0; // return 0 to child - state.pc += 4; // skip over syscall instruction - r.setCPUState(state); - r.state = PAUSED; - - new ForkedProcess(r); - - return r.pid; - } - - public static final class ForkedProcess extends Thread { - private final UnixRuntime initial; - public ForkedProcess(UnixRuntime initial) { - this.initial = initial; - start(); - } - public void run() { - UnixRuntime.executeAndExec(initial); - } - } - - public static int runAndExec(UnixRuntime r, String argv0, String[] rest) { - return runAndExec(r,concatArgv(argv0,rest)); - } - public static int runAndExec(UnixRuntime r, String[] argv) { - r.start(argv); - return executeAndExec(r); - } - - public static int executeAndExec(UnixRuntime r) { - for(;;) { - for(;;) { - if(r.execute()) break; - if(STDERR_DIAG) System.err.println("WARNING: Pause requested while executing runAndExec()"); - } - if(r.state != EXECED) return r.exitStatus(); - r = r.execedRuntime; - } - } - - private String[] readStringArray(int addr) throws ReadFaultException { - int count = 0; - for(int p=addr; memRead(p) != 0; p+=4) count++; - String[] a = new String[count]; - for(int i=0,p=addr; i c,String[] argv, String[] envp) { - try { - UnixRuntime r = (UnixRuntime) c.getDeclaredConstructor(new Class[] {Boolean.TYPE}).newInstance(new Object[] {Boolean.TRUE}); - return exec(r,argv,envp); - } catch(Exception e) { - e.printStackTrace(); - return -ENOEXEC; - } - } - - private int exec(UnixRuntime r, String[] argv, String[] envp) { - //System.err.println("Execing " + r); - for(int i=0; i= OPEN_MAX) return -EBADFD; - if(newd < 0 || newd >= OPEN_MAX) return -EBADFD; - if(fds[oldd] == null) return -EBADFD; - if(fds[newd] != null) fds[newd].close(); - fds[newd] = fds[oldd].dup(); - return 0; - } - - private int sys_dup(int oldd) { - if(oldd < 0 || oldd >= OPEN_MAX) return -EBADFD; - if(fds[oldd] == null) return -EBADFD; - FD fd = fds[oldd].dup(); - int newd = addFD(fd); - if(newd < 0) { - fd.close(); - return -ENFILE; - } - return newd; - } - - private int sys_stat(int cstring, int addr) throws FaultException, ErrnoException { - FStat s = gs.stat(this,normalizePath(cstring(cstring))); - if(s == null) return -ENOENT; - return stat(s,addr); - } - - private int sys_lstat(int cstring, int addr) throws FaultException, ErrnoException { - FStat s = gs.lstat(this,normalizePath(cstring(cstring))); - if(s == null) return -ENOENT; - return stat(s,addr); - } - - private int sys_mkdir(int cstring, int mode) throws FaultException, ErrnoException { - gs.mkdir(this,normalizePath(cstring(cstring)),mode); - return 0; - } - - private int sys_unlink(int cstring) throws FaultException, ErrnoException { - gs.unlink(this,normalizePath(cstring(cstring))); - return 0; - } - - private int sys_link(int cstring1, int cstring2) throws FaultException, ErrnoException { - gs.link(this,normalizePath(cstring(cstring1)), normalizePath(cstring(cstring2))); - return 0; - } - - private int sys_rmdir(int ptrPathName) throws ErrnoException, ReadFaultException { - gs.rmdir(this, normalizePath(cstring(ptrPathName))); - return 0; - } - - private int sys_getcwd(int addr, int size) throws FaultException, ErrnoException { - byte[] b = getBytes(cwd); - if(size == 0) return -EINVAL; - if(size < b.length+2) return -ERANGE; - memset(addr,'/',1); - copyout(b,addr+1,b.length); - memset(addr+b.length+1,0,1); - return addr; - } - - private int sys_chdir(int addr) throws ErrnoException, FaultException { - String path = normalizePath(cstring(addr)); - FStat st = gs.stat(this,path); - if(st == null) return -ENOENT; - if(st.type() != FStat.S_IFDIR) return -ENOTDIR; - cwd = path; - return 0; - } - - private int sys_getdents(int fdn, int addr, int count, int seekptr) throws FaultException, ErrnoException { - count = Math.min(count,MAX_CHUNK); - if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; - if(fds[fdn] == null) return -EBADFD; - byte[] buf = byteBuf(count); - int n = fds[fdn].getdents(buf,0,count); - copyout(buf,addr,n); - return n; - } - - void _preCloseFD(FD fd) { - // release all fcntl locks on this file - Seekable s = fd.seekable(); - if (s == null) return; - - try { - for (int i=0; i < gs.locks.length; i++) { - Seekable.Lock l = gs.locks[i]; - if (l == null) continue; - if (s.equals(l.seekable()) && l.getOwner() == this) { - l.release(); - gs.locks[i] = null; - } - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - void _postCloseFD(FD fd) { - if (fd.isMarkedForDeleteOnClose()) { - try { - gs.unlink(this, fd.getNormalizedPath()); - } - catch (Throwable t) {} - } - } - - /** 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. - * Uses GlobalState to ensure locking across processes in the same JVM. - 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(int fdn, int cmd, int arg) throws FaultException { - if (cmd != F_GETLK && cmd != F_SETLK) return sys_fcntl(fdn, cmd, arg); - - if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD; - if(fds[fdn] == null) return -EBADFD; - FD fd = fds[fdn]; - - if (arg == 0) 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; - - Seekable.Lock[] locks = gs.locks; - Seekable s = fd.seekable(); - if (s == null) return -EINVAL; - - try { - - 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) { - // The simple Java file locking below will happily return - // a lock that overlaps one already held by the JVM. Thus - // we must check over all the locks held by other Runtimes - for (int i=0; i < locks.length; i++) { - if (locks[i] == null || !s.equals(locks[i].seekable())) - continue; - if (!locks[i].overlaps(l_start, l_len)) - continue; - if (locks[i].getOwner() == this) - continue; - if (locks[i].isShared() && l_type == F_RDLCK) - continue; - - // overlapping lock held by another process - return 0; - } - - // check if an area is lockable by attempting to obtain 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 < locks.length; i++) { - if (locks[i] == null || !s.equals(locks[i].seekable())) - continue; - if (locks[i].getOwner() != this) 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 < locks.length; i++) { - if (locks[i] == null || !s.equals(locks[i].seekable())) - continue; - - if (locks[i].getOwner() == this) { - // if this Runtime owns an overlapping lock work with it - if (locks[i].contained(l_start, l_len)) { - locks[i].release(); - locks[i] = null; - } else if (locks[i].contains(l_start, l_len)) { - if (locks[i].isShared() == (l_type == F_RDLCK)) { - // return this more general lock - memWrite(arg+4, (int)locks[i].position()); - memWrite(arg+8, (int)locks[i].size()); - return 0; - } else { - locks[i].release(); - locks[i] = null; - } - } - } else { - // if another Runtime has an lock and it is exclusive or - // we want an exclusive lock then fail - if (locks[i].overlaps(l_start, l_len) - && (!locks[i].isShared() || l_type == F_WRLCK)) - return -EAGAIN; - } - } - - // create the lock - Seekable.Lock lock = s.lock(l_start, l_len, l_type == F_RDLCK); - if (lock == null) return -EAGAIN; - lock.setOwner(this); - - int i; - for (i=0; i < locks.length; i++) - if (locks[i] == null) break; - if (i == locks.length) return -ENOLCK; - locks[i] = lock; - return 0; - - } else { - return -EINVAL; - } - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - static class SocketFD extends FD { - public static final int TYPE_STREAM = 0; - public static final int TYPE_DGRAM = 1; - public static final int LISTEN = 2; - public int type() { - return flags & 1; - } - public boolean listen() { - return (flags & 2) != 0; - } - - int flags; - int options; - - Socket s; - ServerSocket ss; - DatagramSocket ds; - - InetAddress bindAddr; - int bindPort = -1; - InetAddress connectAddr; - int connectPort = -1; - - DatagramPacket dp; - InputStream is; - OutputStream os; - - private static final byte[] EMPTY = new byte[0]; - public SocketFD(int type) { - flags = type; - if(type == TYPE_DGRAM) - dp = new DatagramPacket(EMPTY,0); - } - - public SocketAddress getLocalSocketAddress() { - int type = type(); - if(type == SocketFD.TYPE_STREAM) { - if(listen()) { - return ss.getLocalSocketAddress(); - } else { - return s.getLocalSocketAddress(); - } - } else { - return ds.getLocalSocketAddress(); - } - } - - public void setOptions() { - try { - if(s != null && type() == TYPE_STREAM && !listen()) { - Platform.socketSetKeepAlive(s,(options & SO_KEEPALIVE) != 0); - } - } catch(SocketException e) { - if(STDERR_DIAG) e.printStackTrace(); - } - } - - public void _close() { - try { - if(s != null) s.close(); - if(ss != null) ss.close(); - if(ds != null) ds.close(); - } catch(IOException e) { - /* ignore */ - } - } - - public int read(byte[] a, int off, int length) throws ErrnoException { - if(type() == TYPE_DGRAM) return recvfrom(a,off,length,null,null); - if(is == null) throw new ErrnoException(EPIPE); - try { - int n = is.read(a,off,length); - return n < 0 ? 0 : n; - } catch(IOException e) { - throw new ErrnoException(EIO); - } - } - - public int recvfrom(byte[] a, int off, int length, InetAddress[] sockAddr, int[] port) throws ErrnoException { - if(type() == TYPE_STREAM) return read(a,off,length); - - if(off != 0) throw new IllegalArgumentException("off must be 0"); - dp.setData(a); - dp.setLength(length); - try { - if(ds == null) ds = new DatagramSocket(); - ds.receive(dp); - } catch(IOException e) { - if(STDERR_DIAG) e.printStackTrace(); - throw new ErrnoException(EIO); - } - if(sockAddr != null) { - sockAddr[0] = dp.getAddress(); - port[0] = dp.getPort(); - } - return dp.getLength(); - } - - public int write(byte[] a, int off, int length) throws ErrnoException { - if(type() == TYPE_DGRAM) return sendto(a,off,length,null,-1); - - if(os == null) throw new ErrnoException(EPIPE); - try { - os.write(a,off,length); - return length; - } catch(IOException e) { - throw new ErrnoException(EIO); - } - } - - public int sendto(byte[] a, int off, int length, InetAddress destAddr, int destPort) throws ErrnoException { - if(off != 0) throw new IllegalArgumentException("off must be 0"); - if(type() == TYPE_STREAM) return write(a,off,length); - - if(destAddr == null) { - destAddr = connectAddr; - destPort = connectPort; - - if(destAddr == null) throw new ErrnoException(ENOTCONN); - } - - dp.setAddress(destAddr); - dp.setPort(destPort); - dp.setData(a); - dp.setLength(length); - - try { - if(ds == null) ds = new DatagramSocket(); - ds.send(dp); - } catch(IOException e) { - if(STDERR_DIAG) e.printStackTrace(); - if("Network is unreachable".equals(e.getMessage())) throw new ErrnoException(EHOSTUNREACH); - throw new ErrnoException(EIO); - } - return dp.getLength(); - } - - public int flags() { - return O_RDWR; - } - public FStat _fstat() { - return new SocketFStat(); - } - } - - private int sys_socket(int domain, int type, int proto) { - if(domain != AF_INET || (type != SOCK_STREAM && type != SOCK_DGRAM)) return -EPROTONOSUPPORT; - return addFD(new SocketFD(type == SOCK_STREAM ? SocketFD.TYPE_STREAM : SocketFD.TYPE_DGRAM)); - } - - private SocketFD getSocketFD(int fdn) throws ErrnoException { - if(fdn < 0 || fdn >= OPEN_MAX) throw new ErrnoException(EBADFD); - if(fds[fdn] == null) throw new ErrnoException(EBADFD); - if(!(fds[fdn] instanceof SocketFD)) throw new ErrnoException(ENOTSOCK); - - return (SocketFD) fds[fdn]; - } - - private int sys_connect(int fdn, int addr, int namelen) throws ErrnoException, FaultException { - SocketFD fd = getSocketFD(fdn); - - if(fd.type() == SocketFD.TYPE_STREAM && (fd.s != null || fd.ss != null)) return -EISCONN; - int word1 = memRead(addr); - if( ((word1 >>> 16)&0xff) != AF_INET) return -EAFNOSUPPORT; - int port = word1 & 0xffff; - byte[] ip = new byte[4]; - copyin(addr+4,ip,4); - - InetAddress inetAddr; - try { - inetAddr = Platform.inetAddressFromBytes(ip); - } catch(UnknownHostException e) { - return -EADDRNOTAVAIL; - } - - fd.connectAddr = inetAddr; - fd.connectPort = port; - - try { - switch(fd.type()) { - case SocketFD.TYPE_STREAM: { - Socket s = new Socket(inetAddr,port); - fd.s = s; - fd.setOptions(); - fd.is = s.getInputStream(); - fd.os = s.getOutputStream(); - break; - } - case SocketFD.TYPE_DGRAM: - break; - default: - throw new Error("should never happen"); - } - } catch(IOException e) { - return -ECONNREFUSED; - } - - return 0; - } - - private int sys_resolve_hostname(int chostname, int addr, int sizeAddr) throws FaultException { - String hostname = cstring(chostname); - int size = memRead(sizeAddr); - InetAddress[] inetAddrs; - try { - inetAddrs = InetAddress.getAllByName(hostname); - } catch(UnknownHostException e) { - return HOST_NOT_FOUND; - } - int count = min(size/4,inetAddrs.length); - for(int i=0; i>> 16)&0xff) != AF_INET) return -EAFNOSUPPORT; - int port = word1 & 0xffff; - InetAddress inetAddr = null; - if(memRead(addr+4) != 0) { - byte[] ip = new byte[4]; - copyin(addr+4,ip,4); - - try { - inetAddr = Platform.inetAddressFromBytes(ip); - } catch(UnknownHostException e) { - return -EADDRNOTAVAIL; - } - } - - switch(fd.type()) { - case SocketFD.TYPE_STREAM: { - fd.bindAddr = inetAddr; - fd.bindPort = port; - return 0; - } - case SocketFD.TYPE_DGRAM: { - if(fd.ds != null) fd.ds.close(); - try { - fd.ds = inetAddr != null ? new DatagramSocket(port,inetAddr) : new DatagramSocket(port); - } catch(IOException e) { - return -EADDRINUSE; - } - return 0; - } - default: - throw new Error("should never happen"); - } - } - - private int sys_listen(int fdn, int backlog) throws ErrnoException { - SocketFD fd = getSocketFD(fdn); - if(fd.type() != SocketFD.TYPE_STREAM) return -EOPNOTSUPP; - if(fd.ss != null || fd.s != null) return -EISCONN; - if(fd.bindPort < 0) return -EOPNOTSUPP; - - try { - fd.ss = new ServerSocket(fd.bindPort,backlog,fd.bindAddr); - fd.flags |= SocketFD.LISTEN; - return 0; - } catch(IOException e) { - return -EADDRINUSE; - } - - } - - private int sys_accept(int fdn, int addr, int lenaddr) throws ErrnoException, FaultException { - SocketFD fd = getSocketFD(fdn); - if(fd.type() != SocketFD.TYPE_STREAM) return -EOPNOTSUPP; - if(!fd.listen()) return -EOPNOTSUPP; - - int size = memRead(lenaddr); - - ServerSocket s = fd.ss; - Socket client; - try { - client = s.accept(); - } catch(IOException e) { - return -EIO; - } - - if(size >= 8) { - memWrite(addr,(6 << 24) | (AF_INET << 16) | client.getPort()); - byte[] b = client.getInetAddress().getAddress(); - copyout(b,addr+4,4); - memWrite(lenaddr,8); - } - - SocketFD clientFD = new SocketFD(SocketFD.TYPE_STREAM); - clientFD.s = client; - try { - clientFD.is = client.getInputStream(); - clientFD.os = client.getOutputStream(); - } catch(IOException e) { - return -EIO; - } - int n = addFD(clientFD); - if(n == -1) { - clientFD.close(); - return -ENFILE; - } - return n; - } - - private int sys_shutdown(int fdn, int how) throws ErrnoException { - SocketFD fd = getSocketFD(fdn); - if(fd.type() != SocketFD.TYPE_STREAM || fd.listen()) return -EOPNOTSUPP; - if(fd.s == null) return -ENOTCONN; - - Socket s = fd.s; - - try { - if(how == SHUT_RD || how == SHUT_RDWR) Platform.socketHalfClose(s,false); - if(how == SHUT_WR || how == SHUT_RDWR) Platform.socketHalfClose(s,true); - } catch(IOException e) { - return -EIO; - } - - return 0; - } - - private int sys_sendto(int fdn, int addr, int count, int flags, int destAddr, int socklen) throws ErrnoException,ReadFaultException { - SocketFD fd = getSocketFD(fdn); - if(flags != 0) throw new ErrnoException(EINVAL); - - int word1 = memRead(destAddr); - if( ((word1 >>> 16)&0xff) != AF_INET) return -EAFNOSUPPORT; - int port = word1 & 0xffff; - InetAddress inetAddr; - byte[] ip = new byte[4]; - copyin(destAddr+4,ip,4); - try { - inetAddr = Platform.inetAddressFromBytes(ip); - } catch(UnknownHostException e) { - return -EADDRNOTAVAIL; - } - - count = Math.min(count,MAX_CHUNK); - byte[] buf = byteBuf(count); - copyin(addr,buf,count); - try { - return fd.sendto(buf,0,count,inetAddr,port); - } catch(ErrnoException e) { - if(e.errno == EPIPE) exit(128+13,true); - throw e; - } - } - - private int sys_recvfrom(int fdn, int addr, int count, int flags, int sourceAddr, int socklenAddr) throws ErrnoException, FaultException { - SocketFD fd = getSocketFD(fdn); - if(flags != 0) throw new ErrnoException(EINVAL); - - InetAddress[] inetAddr = sourceAddr == 0 ? null : new InetAddress[1]; - int[] port = sourceAddr == 0 ? null : new int[1]; - - count = Math.min(count,MAX_CHUNK); - byte[] buf = byteBuf(count); - int n = fd.recvfrom(buf,0,count,inetAddr,port); - copyout(buf,addr,n); - - if(sourceAddr != 0) { - memWrite(sourceAddr,(AF_INET << 16) | port[0]); - byte[] ip = inetAddr[0].getAddress(); - copyout(ip,sourceAddr+4,4); - } - - return n; - } - - private int sys_select(int n, int readFDs, int writeFDs, int exceptFDs, int timevalAddr) throws ReadFaultException, ErrnoException { - return -ENOSYS; - } - - private static String hostName() { - try { - return InetAddress.getLocalHost().getHostName(); - } catch(UnknownHostException e) { - return "darkstar"; - } - } - - private int sys_sysctl(int nameaddr, int namelen, int oldp, int oldlenaddr, int newp, int newlen) throws FaultException { - if(newp != 0) return -EPERM; - if(namelen == 0) return -ENOENT; - if(oldp == 0) return 0; - - Object o = null; - switch(memRead(nameaddr)) { - case CTL_KERN: - if(namelen != 2) break; - switch(memRead(nameaddr+4)) { - case KERN_OSTYPE: - o = "NestedVM"; - break; - case KERN_HOSTNAME: - o = hostName(); - break; - case KERN_OSRELEASE: - o = VERSION; - break; - case KERN_VERSION: - o = "NestedVM Kernel Version " + VERSION; - break; - } - break; - case CTL_HW: - if(namelen != 2) break; - switch(memRead(nameaddr+4)) { - case HW_MACHINE: - o = "NestedVM Virtual Machine"; - break; - } - break; - } - if(o == null) return -ENOENT; - int len = memRead(oldlenaddr); - if(o instanceof String) { - byte[] b = getNullTerminatedBytes((String)o); - if(len < b.length) return -ENOMEM; - len = b.length; - copyout(b,oldp,len); - memWrite(oldlenaddr,len); - } else if(o instanceof Integer) { - if(len < 4) return -ENOMEM; - memWrite(oldp,((Integer)o).intValue()); - } else { - throw new Error("should never happen"); - } - return 0; - } - - public static final class GlobalState { - Hashtable execCache = new Hashtable(); - - final UnixRuntime[] tasks; - int nextPID = 1; - - /** Table of all current file locks held by this process. */ - Seekable.Lock[] locks = new Seekable.Lock[16]; - - private MP[] mps = new MP[0]; - private FS root; - - public GlobalState() { - this(255); - } - - public GlobalState(int maxProcs) { - this(maxProcs,true); - } - - public GlobalState(int maxProcs, boolean defaultMounts) { - tasks = new UnixRuntime[maxProcs+1]; - if(defaultMounts) { - File root = null; - if(Platform.getProperty("nestedvm.root") != null) { - root = new File(Platform.getProperty("nestedvm.root")); - if(!root.isDirectory()) throw new IllegalArgumentException("nestedvm.root is not a directory"); - } else { - String cwd = Platform.getProperty("user.dir"); - root = Platform.getRoot(new File(cwd != null ? cwd : ".")); - } - - addMount("/",new HostFS(root)); - - if(Platform.getProperty("nestedvm.root") == null) { - File[] roots = Platform.listRoots(); - for(int i=0; i=0; i--) { - FS fs = i == mps.length ? root : mps[i].fs; - String path = i == mps.length ? "" : mps[i].path; - if(!(fs instanceof HostFS)) continue; - File fsroot = ((HostFS)fs).getRoot(); - if(!fsroot.isAbsolute()) fsroot = new File(fsroot.getAbsolutePath()); - if(f.getPath().startsWith(fsroot.getPath())) { - char sep = File.separatorChar; - String child = f.getPath().substring(fsroot.getPath().length()); - if(sep != '/') { - char[] child_ = child.toCharArray(); - for(int j=0; j 0) outp--; - while(outp > 0 && out[outp] != '/') outp--; - //System.err.println("After ..: " + new String(out,0,outp)); - continue; - } - // Just read a /.[^.] or /..[^/$] - inp++; - out[outp++] = '/'; - out[outp++] = '.'; - } - if(outp > 0 && out[outp-1] == '/') outp--; - //System.err.println("normalize: " + path + " -> " + new String(out,0,outp) + " (cwd: " + cwd + ")"); - int outStart = out[0] == '/' ? 1 : 0; - return new String(out,outStart,outp - outStart); - } - - FStat hostFStat(final File f, Object data) { - boolean e = false; - try { - FileInputStream fis = new FileInputStream(f); - switch(fis.read()) { - case '\177': - e = fis.read() == 'E' && fis.read() == 'L' && fis.read() == 'F'; - break; - case '#': - e = fis.read() == '!'; - } - fis.close(); - } catch(IOException e2) { } - HostFS fs = (HostFS) data; - final int inode = fs.inodes.get(f.getAbsolutePath()); - final int devno = fs.devno; - return new HostFStat(f,e) { - public int inode() { - return inode; - } - public int dev() { - return devno; - } - }; - } - - FD hostFSDirFD(File f, Object _fs) { - HostFS fs = (HostFS) _fs; - return fs.new HostDirFD(f); - } - - public static class HostFS extends FS { - InodeCache inodes = new InodeCache(4000); - protected File root; - public File getRoot() { - return root; - } - - protected File hostFile(String path) { - char sep = File.separatorChar; - if(sep != '/') { - char buf[] = path.toCharArray(); - for(int i=0; i>>24)&0xff); - buf[off+1] = (byte)((n>>>16)&0xff); - buf[off+2] = (byte)((n>>> 8)&0xff); - buf[off+3] = (byte)((n>>> 0)&0xff); - } - - public static abstract class DirFD extends FD { - private int pos = -2; - - protected abstract int size(); - protected abstract String name(int n); - protected abstract int inode(int n); - protected abstract int myDev(); - protected abstract int parentInode(); - protected abstract int myInode(); - public int flags() { - return O_RDONLY; - } - - public int getdents(byte[] buf, int off, int len) { - int ooff = off; - int ino; - int reclen; - OUTER: for(; len > 0 && pos < size(); pos++) { - switch(pos) { - case -2: - case -1: - ino = pos == -1 ? parentInode() : myInode(); - if(ino == -1) continue; - reclen = 9 + (pos == -1 ? 2 : 1); - if(reclen > len) break OUTER; - buf[off+8] = '.'; - if(pos == -1) buf[off+9] = '.'; - break; - default: { - String f = name(pos); - byte[] fb = getBytes(f); - reclen = fb.length + 9; - if(reclen > len) break OUTER; - ino = inode(pos); - System.arraycopy(fb,0,buf,off+8,fb.length); - } - } - buf[off+reclen-1] = 0; // null terminate - reclen = (reclen + 3) & ~3; // add padding - putInt(buf,off,reclen); - putInt(buf,off+4,ino); - off += reclen; - len -= reclen; - } - return off-ooff; - } - - protected FStat _fstat() { - return new FStat() { - public int type() { - return S_IFDIR; - } - public int inode() { - return myInode(); - } - public int dev() { - return myDev(); - } - }; - } - } - - public static class DevFS extends FS { - private static final int ROOT_INODE = 1; - private static final int NULL_INODE = 2; - private static final int ZERO_INODE = 3; - private static final int FD_INODE = 4; - private static final int FD_INODES = 32; - - private abstract class DevFStat extends FStat { - public int dev() { - return devno; - } - public int mode() { - return 0666; - } - public int type() { - return S_IFCHR; - } - public int nlink() { - return 1; - } - public abstract int inode(); - } - - private abstract class DevDirFD extends DirFD { - public int myDev() { - return devno; - } - } - - private FD devZeroFD = new FD() { - public int read(byte[] a, int off, int length) { - /*Arrays.fill(a,off,off+length,(byte)0);*/ - for(int i=off; i= OPEN_MAX) return null; - if(r.fds[n] == null) return null; - return r.fds[n].dup(); - } - if(path.equals("fd")) { - int count=0; - for(int i=0; i= OPEN_MAX) return null; - if(r.fds[n] == null) return null; - return r.fds[n].fstat(); - } - if(path.equals("fd")) return new FStat() { - public int inode() { - return FD_INODE; - } - public int dev() { - return devno; - } - public int type() { - return S_IFDIR; - } - public int mode() { - return 0444; - } - }; - if(path.equals("")) return new FStat() { - public int inode() { - return ROOT_INODE; - } - public int dev() { - return devno; - } - public int type() { - return S_IFDIR; - } - public int mode() { - return 0444; - } - }; - return null; - } - - public void mkdir(UnixRuntime r, String path, int mode) throws ErrnoException { - throw new ErrnoException(EROFS); - } - public void rmdir(UnixRuntime r, String path) throws ErrnoException { - throw new ErrnoException(EROFS); - } - public void unlink(UnixRuntime r, String path) throws ErrnoException { - throw new ErrnoException(EROFS); - } - public void link(UnixRuntime r, String oldpath, String newpath) throws ErrnoException { - throw new ErrnoException(EROFS); - } - } - - - public static class ResourceFS extends FS { - final InodeCache inodes = new InodeCache(500); - - public FStat lstat(UnixRuntime r, String path) throws ErrnoException { - return stat(r,path); - } - public void mkdir(UnixRuntime r, String path, int mode) throws ErrnoException { - throw new ErrnoException(EROFS); - } - public void unlink(UnixRuntime r, String path) throws ErrnoException { - throw new ErrnoException(EROFS); - } - public void rmdir(UnixRuntime r, String path) throws ErrnoException { - throw new ErrnoException(EROFS); - } - public void link(UnixRuntime r, String oldpath, String newpath) throws ErrnoException { - throw new ErrnoException(EROFS); - } - - FStat connFStat(final URLConnection conn) { - return new FStat() { - public int type() { - return S_IFREG; - } - public int nlink() { - return 1; - } - public int mode() { - return 0444; - } - public int size() { - return conn.getContentLength(); - } - public int mtime() { - return (int)(conn.getDate() / 1000); - } - public int inode() { - return inodes.get(conn.getURL().toString()); - } - public int dev() { - return devno; - } - }; - } - - public FStat stat(UnixRuntime r, String path) throws ErrnoException { - URL url = r.getClass().getResource("/" + path); - if(url == null) return null; - try { - return connFStat(url.openConnection()); - } catch(IOException e) { - throw new ErrnoException(EIO); - } - } - - public FD open(UnixRuntime r, String path, int flags, int mode) throws ErrnoException { - if((flags & ~3) != 0) { - if(STDERR_DIAG) - System.err.println("WARNING: Unsupported flags passed to ResourceFS.open(\"" + path + "\"): " + toHex(flags & ~3)); - throw new ErrnoException(ENOTSUP); - } - if((flags&3) != RD_ONLY) throw new ErrnoException(EROFS); - URL url = r.getClass().getResource("/" + path); - if(url == null) return null; - try { - final URLConnection conn = url.openConnection(); - Seekable.InputStream si = new Seekable.InputStream(conn.getInputStream()); - return new SeekableFD(si,flags) { - protected FStat _fstat() { - return connFStat(conn); - } - }; - } catch(FileNotFoundException e) { - if(e.getMessage() != null && e.getMessage().indexOf("Permission denied") >= 0) throw new ErrnoException(EACCES); - return null; - } catch(IOException e) { - throw new ErrnoException(EIO); - } - } - } -} diff --git a/src/main/java/org/ibex/nestedvm/UsermodeConstants.java b/src/main/java/org/ibex/nestedvm/UsermodeConstants.java deleted file mode 100644 index 0385965..0000000 --- a/src/main/java/org/ibex/nestedvm/UsermodeConstants.java +++ /dev/null @@ -1,480 +0,0 @@ -// THIS FILE IS AUTOGENERATED! DO NOT EDIT! -// run "make rebuild-constants" if it needs to be updated - -package org.ibex.nestedvm; -public interface UsermodeConstants { - public static final int SYS_null = 0; - public static final int SYS_exit = 1; - public static final int SYS_pause = 2; - public static final int SYS_open = 3; - public static final int SYS_close = 4; - public static final int SYS_read = 5; - public static final int SYS_write = 6; - public static final int SYS_sbrk = 7; - public static final int SYS_fstat = 8; - public static final int SYS_lseek = 10; - public static final int SYS_kill = 11; - public static final int SYS_getpid = 12; - public static final int SYS_calljava = 13; - public static final int SYS_stat = 14; - public static final int SYS_gettimeofday = 15; - public static final int SYS_sleep = 16; - public static final int SYS_times = 17; - public static final int SYS_mkdir = 18; - public static final int SYS_getpagesize = 19; - public static final int SYS_unlink = 20; - public static final int SYS_utime = 21; - public static final int SYS_chdir = 22; - public static final int SYS_pipe = 23; - public static final int SYS_dup2 = 24; - public static final int SYS_fork = 25; - public static final int SYS_waitpid = 26; - public static final int SYS_getcwd = 27; - public static final int SYS_exec = 28; - public static final int SYS_fcntl = 29; - public static final int SYS_rmdir = 30; - public static final int SYS_sysconf = 31; - public static final int SYS_readlink = 32; - public static final int SYS_lstat = 33; - public static final int SYS_symlink = 34; - public static final int SYS_link = 35; - public static final int SYS_getdents = 36; - public static final int SYS_memcpy = 37; - public static final int SYS_memset = 38; - public static final int SYS_dup = 39; - public static final int SYS_vfork = 40; - public static final int SYS_chroot = 41; - public static final int SYS_mknod = 42; - public static final int SYS_lchown = 43; - public static final int SYS_ftruncate = 44; - public static final int SYS_usleep = 45; - public static final int SYS_getppid = 46; - public static final int SYS_mkfifo = 47; - public static final int SYS_klogctl = 51; - public static final int SYS_realpath = 52; - public static final int SYS_sysctl = 53; - public static final int SYS_setpriority = 54; - public static final int SYS_getpriority = 55; - public static final int SYS_socket = 56; - public static final int SYS_connect = 57; - public static final int SYS_resolve_hostname = 58; - public static final int SYS_accept = 59; - public static final int SYS_setsockopt = 60; - public static final int SYS_getsockopt = 61; - public static final int SYS_listen = 62; - public static final int SYS_bind = 63; - public static final int SYS_shutdown = 64; - public static final int SYS_sendto = 65; - public static final int SYS_recvfrom = 66; - public static final int SYS_select = 67; - public static final int SYS_getuid = 68; - public static final int SYS_getgid = 69; - public static final int SYS_geteuid = 70; - public static final int SYS_getegid = 71; - public static final int SYS_getgroups = 72; - public static final int SYS_umask = 73; - public static final int SYS_chmod = 74; - public static final int SYS_fchmod = 75; - public static final int SYS_chown = 76; - public static final int SYS_fchown = 77; - public static final int SYS_access = 78; - public static final int SYS_alarm = 79; - public static final int SYS_setuid = 80; - public static final int SYS_setgid = 81; - public static final int SYS_send = 82; - public static final int SYS_recv = 83; - public static final int SYS_getsockname = 84; - public static final int SYS_getpeername = 85; - public static final int SYS_seteuid = 86; - public static final int SYS_setegid = 87; - public static final int SYS_setgroups = 88; - public static final int SYS_resolve_ip = 89; - public static final int SYS_setsid = 90; - public static final int SYS_fsync = 91; - public static final int AF_UNIX = 1; - public static final int AF_INET = 2; - public static final int SOCK_STREAM = 1; - public static final int SOCK_DGRAM = 2; - public static final int HOST_NOT_FOUND = 1; - public static final int TRY_AGAIN = 2; - public static final int NO_RECOVERY = 3; - public static final int NO_DATA = 4; - public static final int SOL_SOCKET = 0xffff; - public static final int SO_REUSEADDR = 0x0004; - public static final int SO_KEEPALIVE = 0x0008; - public static final int SO_BROADCAST = 0x0020; - public static final int SO_TYPE = 0x1008; - public static final int SHUT_RD = 0; - public static final int SHUT_WR = 1; - public static final int SHUT_RDWR = 2; - public static final int INADDR_ANY = 0; - public static final int INADDR_LOOPBACK = 0x7f000001; - public static final int INADDR_BROADCAST = 0xffffffff; - public static final int EPERM = 1; /* Not super-user */ - public static final int ENOENT = 2; /* No such file or directory */ - public static final int ESRCH = 3; /* No such process */ - public static final int EINTR = 4; /* Interrupted system call */ - public static final int EIO = 5; /* I/O error */ - public static final int ENXIO = 6; /* No such device or address */ - public static final int E2BIG = 7; /* Arg list too long */ - public static final int ENOEXEC = 8; /* Exec format error */ - public static final int EBADF = 9; /* Bad file number */ - public static final int ECHILD = 10; /* No children */ - public static final int EAGAIN = 11; /* No more processes */ - public static final int ENOMEM = 12; /* Not enough core */ - public static final int EACCES = 13; /* Permission denied */ - public static final int EFAULT = 14; /* Bad address */ - public static final int ENOTBLK = 15; /* Block device required */ - public static final int EBUSY = 16; /* Mount device busy */ - public static final int EEXIST = 17; /* File exists */ - public static final int EXDEV = 18; /* Cross-device link */ - public static final int ENODEV = 19; /* No such device */ - public static final int ENOTDIR = 20; /* Not a directory */ - public static final int EISDIR = 21; /* Is a directory */ - public static final int EINVAL = 22; /* Invalid argument */ - public static final int ENFILE = 23; /* Too many open files in system */ - public static final int EMFILE = 24; /* Too many open files */ - public static final int ENOTTY = 25; /* Not a typewriter */ - public static final int ETXTBSY = 26; /* Text file busy */ - public static final int EFBIG = 27; /* File too large */ - public static final int ENOSPC = 28; /* No space left on device */ - public static final int ESPIPE = 29; /* Illegal seek */ - public static final int EROFS = 30; /* Read only file system */ - public static final int EMLINK = 31; /* Too many links */ - public static final int EPIPE = 32; /* Broken pipe */ - public static final int EDOM = 33; /* Math arg out of domain of func */ - public static final int ERANGE = 34; /* Math result not representable */ - public static final int ENOMSG = 35; /* No message of desired type */ - public static final int EIDRM = 36; /* Identifier removed */ - public static final int ECHRNG = 37; /* Channel number out of range */ - public static final int EL2NSYNC = 38; /* Level 2 not synchronized */ - public static final int EL3HLT = 39; /* Level 3 halted */ - public static final int EL3RST = 40; /* Level 3 reset */ - public static final int ELNRNG = 41; /* Link number out of range */ - public static final int EUNATCH = 42; /* Protocol driver not attached */ - public static final int ENOCSI = 43; /* No CSI structure available */ - public static final int EL2HLT = 44; /* Level 2 halted */ - public static final int EDEADLK = 45; /* Deadlock condition */ - public static final int ENOLCK = 46; /* No record locks available */ - public static final int EBADE = 50; /* Invalid exchange */ - public static final int EBADR = 51; /* Invalid request descriptor */ - public static final int EXFULL = 52; /* Exchange full */ - public static final int ENOANO = 53; /* No anode */ - public static final int EBADRQC = 54; /* Invalid request code */ - public static final int EBADSLT = 55; /* Invalid slot */ - public static final int EDEADLOCK = 56; /* File locking deadlock error */ - public static final int EBFONT = 57; /* Bad font file fmt */ - public static final int ENOSTR = 60; /* Device not a stream */ - public static final int ENODATA = 61; /* No data (for no delay io) */ - public static final int ETIME = 62; /* Timer expired */ - public static final int ENOSR = 63; /* Out of streams resources */ - public static final int ENONET = 64; /* Machine is not on the network */ - public static final int ENOPKG = 65; /* Package not installed */ - public static final int EREMOTE = 66; /* The object is remote */ - public static final int ENOLINK = 67; /* The link has been severed */ - public static final int EADV = 68; /* Advertise error */ - public static final int ESRMNT = 69; /* Srmount error */ - public static final int ECOMM = 70; /* Communication error on send */ - public static final int EPROTO = 71; /* Protocol error */ - public static final int EMULTIHOP = 74; /* Multihop attempted */ - public static final int ELBIN = 75; /* Inode is remote (not really error) */ - public static final int EDOTDOT = 76; /* Cross mount point (not really error) */ - public static final int EBADMSG = 77; /* Trying to read unreadable message */ - public static final int EFTYPE = 79; /* Inappropriate file type or format */ - public static final int ENOTUNIQ = 80; /* Given log. name not unique */ - public static final int EBADFD = 81; /* f.d. invalid for this operation */ - public static final int EREMCHG = 82; /* Remote address changed */ - public static final int ELIBACC = 83; /* Can't access a needed shared lib */ - public static final int ELIBBAD = 84; /* Accessing a corrupted shared lib */ - public static final int ELIBSCN = 85; /* .lib section in a.out corrupted */ - public static final int ELIBMAX = 86; /* Attempting to link in too many libs */ - public static final int ELIBEXEC = 87; /* Attempting to exec a shared library */ - public static final int ENOSYS = 88; /* Function not implemented */ - public static final int ENMFILE = 89; /* No more files */ - public static final int ENOTEMPTY = 90; /* Directory not empty */ - public static final int ENAMETOOLONG = 91; /* File or path name too long */ - public static final int ELOOP = 92; /* Too many symbolic links */ - public static final int EOPNOTSUPP = 95; /* Operation not supported on transport endpoint */ - public static final int EPFNOSUPPORT = 96; /* Protocol family not supported */ - public static final int ECONNRESET = 104; /* Connection reset by peer */ - public static final int ENOBUFS = 105; /* No buffer space available */ - public static final int EAFNOSUPPORT = 106; /* Address family not supported by protocol family */ - public static final int EPROTOTYPE = 107; /* Protocol wrong type for socket */ - public static final int ENOTSOCK = 108; /* Socket operation on non-socket */ - public static final int ENOPROTOOPT = 109; /* Protocol not available */ - public static final int ESHUTDOWN = 110; /* Can't send after socket shutdown */ - public static final int ECONNREFUSED = 111; /* Connection refused */ - public static final int EADDRINUSE = 112; /* Address already in use */ - public static final int ECONNABORTED = 113; /* Connection aborted */ - public static final int ENETUNREACH = 114; /* Network is unreachable */ - public static final int ENETDOWN = 115; /* Network interface is not configured */ - public static final int ETIMEDOUT = 116; /* Connection timed out */ - public static final int EHOSTDOWN = 117; /* Host is down */ - public static final int EHOSTUNREACH = 118; /* Host is unreachable */ - public static final int EINPROGRESS = 119; /* Connection already in progress */ - public static final int EALREADY = 120; /* Socket already connected */ - public static final int EDESTADDRREQ = 121; /* Destination address required */ - public static final int EMSGSIZE = 122; /* Message too long */ - public static final int EPROTONOSUPPORT = 123; /* Unknown protocol */ - public static final int ESOCKTNOSUPPORT = 124; /* Socket type not supported */ - public static final int EADDRNOTAVAIL = 125; /* Address not available */ - public static final int ENETRESET = 126; - public static final int EISCONN = 127; /* Socket is already connected */ - public static final int ENOTCONN = 128; /* Socket is not connected */ - public static final int ETOOMANYREFS = 129; - public static final int EPROCLIM = 130; - public static final int EUSERS = 131; - public static final int EDQUOT = 132; - public static final int ESTALE = 133; - public static final int ENOTSUP = 134; /* Not supported */ - public static final int ENOMEDIUM = 135; /* No medium (in tape drive) */ - public static final int ENOSHARE = 136; /* No such host or network path */ - public static final int ECASECLASH = 137; /* Filename exists with different case */ - public static final int EILSEQ = 138; - public static final int EOVERFLOW = 139; /* Value too large for defined data type */ - public static final int __ELASTERROR = 2000; /* Users can add values starting here */ - public static final int F_OK = 0; - public static final int R_OK = 4; - public static final int W_OK = 2; - public static final int X_OK = 1; - public static final int SEEK_SET = 0; - public static final int SEEK_CUR = 1; - public static final int SEEK_END = 2; - public static final int STDIN_FILENO = 0; /* standard input file descriptor */ - public static final int STDOUT_FILENO = 1; /* standard output file descriptor */ - public static final int STDERR_FILENO = 2; /* standard error file descriptor */ - public static final int _SC_ARG_MAX = 0; - public static final int _SC_CHILD_MAX = 1; - public static final int _SC_CLK_TCK = 2; - public static final int _SC_NGROUPS_MAX = 3; - public static final int _SC_OPEN_MAX = 4; - public static final int _SC_JOB_CONTROL = 5; - public static final int _SC_SAVED_IDS = 6; - public static final int _SC_VERSION = 7; - public static final int _SC_PAGESIZE = 8; - public static final int _SC_NPROCESSORS_CONF = 9; - public static final int _SC_NPROCESSORS_ONLN = 10; - public static final int _SC_PHYS_PAGES = 11; - public static final int _SC_AVPHYS_PAGES = 12; - public static final int _SC_MQ_OPEN_MAX = 13; - public static final int _SC_MQ_PRIO_MAX = 14; - public static final int _SC_RTSIG_MAX = 15; - public static final int _SC_SEM_NSEMS_MAX = 16; - public static final int _SC_SEM_VALUE_MAX = 17; - public static final int _SC_SIGQUEUE_MAX = 18; - public static final int _SC_TIMER_MAX = 19; - public static final int _SC_TZNAME_MAX = 20; - public static final int _SC_ASYNCHRONOUS_IO = 21; - public static final int _SC_FSYNC = 22; - public static final int _SC_MAPPED_FILES = 23; - public static final int _SC_MEMLOCK = 24; - public static final int _SC_MEMLOCK_RANGE = 25; - public static final int _SC_MEMORY_PROTECTION = 26; - public static final int _SC_MESSAGE_PASSING = 27; - public static final int _SC_PRIORITIZED_IO = 28; - public static final int _SC_REALTIME_SIGNALS = 29; - public static final int _SC_SEMAPHORES = 30; - public static final int _SC_SHARED_MEMORY_OBJECTS = 31; - public static final int _SC_SYNCHRONIZED_IO = 32; - public static final int _SC_TIMERS = 33; - public static final int _SC_AIO_LISTIO_MAX = 34; - public static final int _SC_AIO_MAX = 35; - public static final int _SC_AIO_PRIO_DELTA_MAX = 36; - public static final int _SC_DELAYTIMER_MAX = 37; - public static final int _SC_THREAD_KEYS_MAX = 38; - public static final int _SC_THREAD_STACK_MIN = 39; - public static final int _SC_THREAD_THREADS_MAX = 40; - public static final int _SC_TTY_NAME_MAX = 41; - public static final int _SC_THREADS = 42; - public static final int _SC_THREAD_ATTR_STACKADDR = 43; - public static final int _SC_THREAD_ATTR_STACKSIZE = 44; - public static final int _SC_THREAD_PRIORITY_SCHEDULING = 45; - public static final int _SC_THREAD_PRIO_INHERIT = 46; - public static final int _SC_THREAD_PRIO_PROTECT = 47; - public static final int _SC_THREAD_PROCESS_SHARED = 48; - public static final int _SC_THREAD_SAFE_FUNCTIONS = 49; - public static final int _SC_GETGR_R_SIZE_MAX = 50; - public static final int _SC_GETPW_R_SIZE_MAX = 51; - public static final int _SC_LOGIN_NAME_MAX = 52; - public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS = 53; - public static final int _SC_STREAM_MAX = 100; - public static final int _SC_PRIORITY_SCHEDULING = 101; - public static final int _PC_LINK_MAX = 0; - public static final int _PC_MAX_CANON = 1; - public static final int _PC_MAX_INPUT = 2; - public static final int _PC_NAME_MAX = 3; - public static final int _PC_PATH_MAX = 4; - public static final int _PC_PIPE_BUF = 5; - public static final int _PC_CHOWN_RESTRICTED = 6; - public static final int _PC_NO_TRUNC = 7; - public static final int _PC_VDISABLE = 8; - public static final int _PC_ASYNC_IO = 9; - public static final int _PC_PRIO_IO = 10; - public static final int _PC_SYNC_IO = 11; - public static final int _PC_POSIX_PERMISSIONS = 90; - public static final int _PC_POSIX_SECURITY = 91; - public static final int MAXPATHLEN = 1024; - public static final int ARG_MAX = 65536; /* max bytes for an exec function */ - public static final int CHILD_MAX = 40; /* max simultaneous processes */ - public static final int LINK_MAX = 32767; /* max file link count */ - public static final int MAX_CANON = 255; /* max bytes in term canon input line */ - public static final int MAX_INPUT = 255; /* max bytes in terminal input */ - public static final int NAME_MAX = 255; /* max bytes in a file name */ - public static final int NGROUPS_MAX = 16; /* max supplemental group id's */ - public static final int OPEN_MAX = 64; /* max open files per process */ - public static final int PATH_MAX = 1024; /* max bytes in pathname */ - public static final int PIPE_BUF = 512; /* max bytes for atomic pipe writes */ - public static final int IOV_MAX = 1024; /* max elements in i/o vector */ - public static final int BC_BASE_MAX = 99; /* max ibase/obase values in bc(1) */ - public static final int BC_DIM_MAX = 2048; /* max array elements in bc(1) */ - public static final int BC_SCALE_MAX = 99; /* max scale value in bc(1) */ - public static final int BC_STRING_MAX = 1000; /* max const string length in bc(1) */ - public static final int COLL_WEIGHTS_MAX = 0; /* max weights for order keyword */ - public static final int EXPR_NEST_MAX = 32; /* max expressions nested in expr(1) */ - public static final int LINE_MAX = 2048; /* max bytes in an input line */ - public static final int RE_DUP_MAX = 255; /* max RE's in interval notation */ - public static final int CTL_MAXNAME = 12; - public static final int CTL_UNSPEC = 0; /* unused */ - public static final int CTL_KERN = 1; /* "high kernel": proc, limits */ - public static final int CTL_VM = 2; /* virtual memory */ - public static final int CTL_VFS = 3; /* file system, mount type is next */ - public static final int CTL_NET = 4; /* network, see socket.h */ - public static final int CTL_DEBUG = 5; /* debugging parameters */ - public static final int CTL_HW = 6; /* generic cpu/io */ - public static final int CTL_MACHDEP = 7; /* machine dependent */ - public static final int CTL_USER = 8; /* user-level */ - public static final int CTL_P1003_1B = 9; /* POSIX 1003.1B */ - public static final int CTL_MAXID = 10; /* number of valid top-level ids */ - public static final int KERN_OSTYPE = 1; /* string: system version */ - public static final int KERN_OSRELEASE = 2; /* string: system release */ - public static final int KERN_OSREV = 3; /* int: system revision */ - public static final int KERN_VERSION = 4; /* string: compile time info */ - public static final int KERN_MAXVNODES = 5; /* int: max vnodes */ - public static final int KERN_MAXPROC = 6; /* int: max processes */ - public static final int KERN_MAXFILES = 7; /* int: max open files */ - public static final int KERN_ARGMAX = 8; /* int: max arguments to exec */ - public static final int KERN_SECURELVL = 9; /* int: system security level */ - public static final int KERN_HOSTNAME = 10; /* string: hostname */ - public static final int KERN_HOSTID = 11; /* int: host identifier */ - public static final int KERN_CLOCKRATE = 12; /* struct: struct clockrate */ - public static final int KERN_VNODE = 13; /* struct: vnode structures */ - public static final int KERN_PROC = 14; /* struct: process entries */ - public static final int KERN_FILE = 15; /* struct: file entries */ - public static final int KERN_PROF = 16; /* node: kernel profiling info */ - public static final int KERN_POSIX1 = 17; /* int: POSIX.1 version */ - public static final int KERN_NGROUPS = 18; /* int: # of supplemental group ids */ - public static final int KERN_JOB_CONTROL = 19; /* int: is job control available */ - public static final int KERN_SAVED_IDS = 20; /* int: saved set-user/group-ID */ - public static final int KERN_BOOTTIME = 21; /* struct: time kernel was booted */ - public static final int KERN_NISDOMAINNAME = 22; /* string: YP domain name */ - public static final int KERN_UPDATEINTERVAL = 23; /* int: update process sleep time */ - public static final int KERN_OSRELDATE = 24; /* int: OS release date */ - public static final int KERN_NTP_PLL = 25; /* node: NTP PLL control */ - public static final int KERN_BOOTFILE = 26; /* string: name of booted kernel */ - public static final int KERN_MAXFILESPERPROC = 27; /* int: max open files per proc */ - public static final int KERN_MAXPROCPERUID = 28; /* int: max processes per uid */ - public static final int KERN_DUMPDEV = 29; /* dev_t: device to dump on */ - public static final int KERN_IPC = 30; /* node: anything related to IPC */ - public static final int KERN_DUMMY = 31; /* unused */ - public static final int KERN_PS_STRINGS = 32; /* int: address of PS_STRINGS */ - public static final int KERN_USRSTACK = 33; /* int: address of USRSTACK */ - public static final int KERN_LOGSIGEXIT = 34; /* int: do we log sigexit procs? */ - public static final int KERN_MAXID = 35; /* number of valid kern ids */ - public static final int KERN_PROC_ALL = 0; /* everything */ - public static final int KERN_PROC_PID = 1; /* by process id */ - public static final int KERN_PROC_PGRP = 2; /* by process group id */ - public static final int KERN_PROC_SESSION = 3; /* by session of pid */ - public static final int KERN_PROC_TTY = 4; /* by controlling tty */ - public static final int KERN_PROC_UID = 5; /* by effective uid */ - public static final int KERN_PROC_RUID = 6; /* by real uid */ - public static final int KERN_PROC_ARGS = 7; /* get/set arguments/proctitle */ - public static final int KIPC_MAXSOCKBUF = 1; /* int: max size of a socket buffer */ - public static final int KIPC_SOCKBUF_WASTE = 2; /* int: wastage factor in sockbuf */ - public static final int KIPC_SOMAXCONN = 3; /* int: max length of connection q */ - public static final int KIPC_MAX_LINKHDR = 4; /* int: max length of link header */ - public static final int KIPC_MAX_PROTOHDR = 5; /* int: max length of network header */ - public static final int KIPC_MAX_HDR = 6; /* int: max total length of headers */ - public static final int KIPC_MAX_DATALEN = 7; /* int: max length of data? */ - public static final int KIPC_MBSTAT = 8; /* struct: mbuf usage statistics */ - public static final int KIPC_NMBCLUSTERS = 9; /* int: maximum mbuf clusters */ - public static final int HW_MACHINE = 1; /* string: machine class */ - public static final int HW_MODEL = 2; /* string: specific machine model */ - public static final int HW_NCPU = 3; /* int: number of cpus */ - public static final int HW_BYTEORDER = 4; /* int: machine byte order */ - public static final int HW_PHYSMEM = 5; /* int: total memory */ - public static final int HW_USERMEM = 6; /* int: non-kernel memory */ - public static final int HW_PAGESIZE = 7; /* int: software page size */ - public static final int HW_DISKNAMES = 8; /* strings: disk drive names */ - public static final int HW_DISKSTATS = 9; /* struct: diskstats[] */ - public static final int HW_FLOATINGPT = 10; /* int: has HW floating point? */ - public static final int HW_MACHINE_ARCH = 11; /* string: machine architecture */ - public static final int HW_MAXID = 12; /* number of valid hw ids */ - public static final int USER_CS_PATH = 1; /* string: _CS_PATH */ - public static final int USER_BC_BASE_MAX = 2; /* int: BC_BASE_MAX */ - public static final int USER_BC_DIM_MAX = 3; /* int: BC_DIM_MAX */ - public static final int USER_BC_SCALE_MAX = 4; /* int: BC_SCALE_MAX */ - public static final int USER_BC_STRING_MAX = 5; /* int: BC_STRING_MAX */ - public static final int USER_COLL_WEIGHTS_MAX = 6; /* int: COLL_WEIGHTS_MAX */ - public static final int USER_EXPR_NEST_MAX = 7; /* int: EXPR_NEST_MAX */ - public static final int USER_LINE_MAX = 8; /* int: LINE_MAX */ - public static final int USER_RE_DUP_MAX = 9; /* int: RE_DUP_MAX */ - public static final int USER_POSIX2_VERSION = 10; /* int: POSIX2_VERSION */ - public static final int USER_POSIX2_C_BIND = 11; /* int: POSIX2_C_BIND */ - public static final int USER_POSIX2_C_DEV = 12; /* int: POSIX2_C_DEV */ - public static final int USER_POSIX2_CHAR_TERM = 13; /* int: POSIX2_CHAR_TERM */ - public static final int USER_POSIX2_FORT_DEV = 14; /* int: POSIX2_FORT_DEV */ - public static final int USER_POSIX2_FORT_RUN = 15; /* int: POSIX2_FORT_RUN */ - public static final int USER_POSIX2_LOCALEDEF = 16; /* int: POSIX2_LOCALEDEF */ - public static final int USER_POSIX2_SW_DEV = 17; /* int: POSIX2_SW_DEV */ - public static final int USER_POSIX2_UPE = 18; /* int: POSIX2_UPE */ - public static final int USER_STREAM_MAX = 19; /* int: POSIX2_STREAM_MAX */ - public static final int USER_TZNAME_MAX = 20; /* int: POSIX2_TZNAME_MAX */ - public static final int USER_MAXID = 21; /* number of valid user ids */ - public static final int CTL_P1003_1B_ASYNCHRONOUS_IO = 1; /* boolean */ - public static final int CTL_P1003_1B_MAPPED_FILES = 2; /* boolean */ - public static final int CTL_P1003_1B_MEMLOCK = 3; /* boolean */ - public static final int CTL_P1003_1B_MEMLOCK_RANGE = 4; /* boolean */ - public static final int CTL_P1003_1B_MEMORY_PROTECTION = 5; /* boolean */ - public static final int CTL_P1003_1B_MESSAGE_PASSING = 6; /* boolean */ - public static final int CTL_P1003_1B_PRIORITIZED_IO = 7; /* boolean */ - public static final int CTL_P1003_1B_PRIORITY_SCHEDULING = 8; /* boolean */ - public static final int CTL_P1003_1B_REALTIME_SIGNALS = 9; /* boolean */ - public static final int CTL_P1003_1B_SEMAPHORES = 10; /* boolean */ - public static final int CTL_P1003_1B_FSYNC = 11; /* boolean */ - public static final int CTL_P1003_1B_SHARED_MEMORY_OBJECTS = 12; /* boolean */ - public static final int CTL_P1003_1B_SYNCHRONIZED_IO = 13; /* boolean */ - public static final int CTL_P1003_1B_TIMERS = 14; /* boolean */ - public static final int CTL_P1003_1B_AIO_LISTIO_MAX = 15; /* int */ - public static final int CTL_P1003_1B_AIO_MAX = 16; /* int */ - public static final int CTL_P1003_1B_AIO_PRIO_DELTA_MAX = 17; /* int */ - public static final int CTL_P1003_1B_DELAYTIMER_MAX = 18; /* int */ - public static final int CTL_P1003_1B_MQ_OPEN_MAX = 19; /* int */ - public static final int CTL_P1003_1B_PAGESIZE = 20; /* int */ - public static final int CTL_P1003_1B_RTSIG_MAX = 21; /* int */ - public static final int CTL_P1003_1B_SEM_NSEMS_MAX = 22; /* int */ - public static final int CTL_P1003_1B_SEM_VALUE_MAX = 23; /* int */ - public static final int CTL_P1003_1B_SIGQUEUE_MAX = 24; /* int */ - public static final int CTL_P1003_1B_TIMER_MAX = 25; /* int */ - public static final int CTL_P1003_1B_MAXID = 26; - public static final int F_UNLKSYS = 4; - public static final int F_CNVT = 12; - public static final int F_SETFD = 2; - public static final int F_SETFL = 4; - public static final int F_SETLK = 8; - public static final int F_SETOWN = 6; - public static final int F_RDLCK = 1; - public static final int F_WRLCK = 2; - public static final int F_SETLKW = 9; - public static final int F_GETFD = 1; - public static final int F_DUPFD = 0; - public static final int O_WRONLY = 1; - public static final int F_RSETLKW = 13; - public static final int O_RDWR = 2; - public static final int F_RGETLK = 10; - public static final int O_RDONLY = 0; - public static final int F_UNLCK = 3; - public static final int F_GETOWN = 5; - public static final int F_RSETLK = 11; - public static final int F_GETFL = 3; - public static final int F_GETLK = 7; -} diff --git a/src/main/java/org/ibex/nestedvm/util/ELF.java b/src/main/java/org/ibex/nestedvm/util/ELF.java deleted file mode 100644 index 2f97071..0000000 --- a/src/main/java/org/ibex/nestedvm/util/ELF.java +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source License 2.0 ("the License"). -// You may not use this file except in compliance with the License. - -package org.ibex.nestedvm.util; - -import java.io.*; - -public class ELF { - private static final int ELF_MAGIC = 0x7f454c46; // '\177', 'E', 'L', 'F' - - public static final int ELFCLASSNONE = 0; - public static final int ELFCLASS32 = 1; - public static final int ELFCLASS64 = 2; - - public static final int ELFDATANONE = 0; - public static final int ELFDATA2LSB = 1; - public static final int ELFDATA2MSB = 2; - - public static final int SHT_SYMTAB = 2; - public static final int SHT_STRTAB = 3; - public static final int SHT_NOBITS = 8; - - public static final int SHF_WRITE = 1; - public static final int SHF_ALLOC = 2; - public static final int SHF_EXECINSTR = 4; - - public static final int PF_X = 0x1; - public static final int PF_W = 0x2; - public static final int PF_R = 0x4; - - public static final int PT_LOAD = 1; - - public static final short ET_EXEC = 2; - public static final short EM_MIPS = 8; - - - private Seekable data; - - public ELFIdent ident; - public ELFHeader header; - public PHeader[] pheaders; - public SHeader[] sheaders; - - private byte[] stringTable; - - private boolean sectionReaderActive; - - - private void readFully(byte[] buf) throws IOException { - int len = buf.length; - int pos = 0; - while(len > 0) { - int n = data.read(buf,pos,len); - if(n == -1) throw new IOException("EOF"); - pos += n; - len -= n; - } - } - - private int readIntBE() throws IOException { - byte[] buf = new byte[4]; - readFully(buf); - return ((buf[0]&0xff)<<24)|((buf[1]&0xff)<<16)|((buf[2]&0xff)<<8)|((buf[3]&0xff)<<0); - } - private int readInt() throws IOException { - int x = readIntBE(); - if(ident!=null && ident.data == ELFDATA2LSB) - x = ((x<<24)&0xff000000) | ((x<<8)&0xff0000) | ((x>>>8)&0xff00) | ((x>>24)&0xff); - return x; - } - - private short readShortBE() throws IOException { - byte[] buf = new byte[2]; - readFully(buf); - return (short)(((buf[0]&0xff)<<8)|((buf[1]&0xff)<<0)); - } - private short readShort() throws IOException { - short x = readShortBE(); - if(ident!=null && ident.data == ELFDATA2LSB) - x = (short)((((x<<8)&0xff00) | ((x>>8)&0xff))&0xffff); - return x; - } - - private byte readByte() throws IOException { - byte[] buf = new byte[1]; - readFully(buf); - return buf[0]; - } - - public class ELFIdent { - public byte klass; - public byte data; - public byte osabi; - public byte abiversion; - - ELFIdent() throws IOException { - if(readIntBE() != ELF_MAGIC) throw new ELFException("Bad Magic"); - - klass = readByte(); - if(klass != ELFCLASS32) throw new ELFException("org.ibex.nestedvm.util.ELF does not suport 64-bit binaries"); - - data = readByte(); - if(data != ELFDATA2LSB && data != ELFDATA2MSB) throw new ELFException("Unknown byte order"); - - readByte(); // version - osabi = readByte(); - abiversion = readByte(); - for(int i=0;i<7;i++) readByte(); // padding - } - } - - public class ELFHeader { - public short type; - public short machine; - public int version; - public int entry; - public int phoff; - public int shoff; - public int flags; - public short ehsize; - public short phentsize; - public short phnum; - public short shentsize; - public short shnum; - public short shstrndx; - - ELFHeader() throws IOException { - type = readShort(); - machine = readShort(); - version = readInt(); - if(version != 1) throw new ELFException("version != 1"); - entry = readInt(); - phoff = readInt(); - shoff = readInt(); - flags = readInt(); - ehsize = readShort(); - phentsize = readShort(); - phnum = readShort(); - shentsize = readShort(); - shnum = readShort(); - shstrndx = readShort(); - } - } - - public class PHeader { - public int type; - public int offset; - public int vaddr; - public int paddr; - public int filesz; - public int memsz; - public int flags; - public int align; - - PHeader() throws IOException { - type = readInt(); - offset = readInt(); - vaddr = readInt(); - paddr = readInt(); - filesz = readInt(); - memsz = readInt(); - flags = readInt(); - align = readInt(); - if(filesz > memsz) throw new ELFException("ELF inconsistency: filesz > memsz (" + toHex(filesz) + " > " + toHex(memsz) + ")"); - } - - public boolean writable() { return (flags & PF_W) != 0; } - - public InputStream getInputStream() throws IOException { - return new BufferedInputStream(new SectionInputStream( - offset,offset+filesz)); - } - } - - public class SHeader { - int nameidx; - public String name; - public int type; - public int flags; - public int addr; - public int offset; - public int size; - public int link; - public int info; - public int addralign; - public int entsize; - - SHeader() throws IOException { - nameidx = readInt(); - type = readInt(); - flags = readInt(); - addr = readInt(); - offset = readInt(); - size = readInt(); - link = readInt(); - info = readInt(); - addralign = readInt(); - entsize = readInt(); - } - - public InputStream getInputStream() throws IOException { - return new BufferedInputStream(new SectionInputStream( - offset, type == SHT_NOBITS ? 0 : offset+size)); - } - - public boolean isText() { return name.equals(".text"); } - public boolean isData() { return name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"); } - public boolean isBSS() { return name.equals(".bss") || name.equals(".sbss"); } - } - - public ELF(String file) throws IOException, ELFException { this(new Seekable.File(file,false)); } - public ELF(Seekable data) throws IOException, ELFException { - this.data = data; - ident = new ELFIdent(); - header = new ELFHeader(); - pheaders = new PHeader[header.phnum]; - for(int i=0;i= header.shnum) throw new ELFException("Bad shstrndx"); - data.seek(sheaders[header.shstrndx].offset); - stringTable = new byte[sheaders[header.shstrndx].size]; - readFully(stringTable); - - for(int i=0;i= strtab.length) return ""; - while(off >= 0 && off < strtab.length && strtab[off] != 0) sb.append((char)strtab[off++]); - return sb.toString(); - } - - public SHeader sectionWithName(String name) { - for(int i=0;i 0) pos += n; return n; - } - public void close() { sectionReaderActive = false; } - } - - private Symtab _symtab; - public Symtab getSymtab() throws IOException { - if(_symtab != null) return _symtab; - - if(sectionReaderActive) throw new ELFException("Can't read the symtab while a section reader is active"); - - SHeader sh = sectionWithName(".symtab"); - if(sh == null || sh.type != SHT_SYMTAB) return null; - - SHeader sth = sectionWithName(".strtab"); - if(sth == null || sth.type != SHT_STRTAB) return null; - - byte[] strtab = new byte[sth.size]; - DataInputStream dis = new DataInputStream(sth.getInputStream()); - dis.readFully(strtab); - dis.close(); - - return _symtab = new Symtab(sh.offset, sh.size,strtab); - } - - public class Symtab { - public Symbol[] symbols; - - Symtab(int off, int size, byte[] strtab) throws IOException { - data.seek(off); - int count = size/16; - symbols = new Symbol[count]; - for(int i=0;i>4); - other = readByte(); - shndx = readShort(); - } - } - - private static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); } - - /*public static void main(String[] args) throws IOException { - ELF elf = new ELF(new Seekable.InputStream(new FileInputStream(args[0]))); - System.out.println("Type: " + toHex(elf.header.type)); - System.out.println("Machine: " + toHex(elf.header.machine)); - System.out.println("Entry: " + toHex(elf.header.entry)); - for(int i=0;i " + toHex(symtab.symbols[i].addr)); - } else { - System.out.println("Symbol table: None"); - } - }*/ -} diff --git a/src/main/java/org/ibex/nestedvm/util/InodeCache.java b/src/main/java/org/ibex/nestedvm/util/InodeCache.java deleted file mode 100644 index 02913de..0000000 --- a/src/main/java/org/ibex/nestedvm/util/InodeCache.java +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source License 2.0 ("the License"). -// You may not use this file except in compliance with the License. - -package org.ibex.nestedvm.util; - -// Based on the various org.xwt.util.* classes by Adam Megacz - -public class InodeCache { - private static final Object PLACEHOLDER = new Object(); - private static final short SHORT_PLACEHOLDER = -2; - private static final short SHORT_NULL = -1; - private static final int LOAD_FACTOR = 2; - - private final int maxSize; - private final int totalSlots; - private final int maxUsedSlots; - - private final Object[] keys; - private final short[] next; - private final short[] prev; - private final short[] inodes; - private final short[] reverse; - - private int size, usedSlots; - private short mru, lru; - - public InodeCache() { this(1024); } - public InodeCache(int maxSize) { - this.maxSize = maxSize; - totalSlots = maxSize*LOAD_FACTOR*2 + 3; - maxUsedSlots = totalSlots / LOAD_FACTOR; - if(totalSlots > Short.MAX_VALUE) throw new IllegalArgumentException("cache size too large"); - keys = new Object[totalSlots]; - next = new short[totalSlots]; - prev = new short[totalSlots]; - inodes = new short[totalSlots]; - reverse = new short[totalSlots]; - clear(); - } - - private static void fill(Object[] a,Object o) { for(int i=0;i " + inodes[i] + "(prev: " + prev[i] + " next: " + next[i] + ")"); - if(i == lru) break; - } - } - - private void stats() { - int freeKeys = 0; - int freeReverse = 0; - int placeholderKeys = 0; - int placeholderReverse = 0; - for(int i=0;i " + c.reverse(n)); - } else { - //System.err.println("Adding " + s); - short n = c.get(s); - System.err.println("Added " + s + " -> " + n); - //c.dump(); - } - } - good = true; - } finally { - if(!good) c.stats(); - } - }*/ -} diff --git a/src/main/java/org/ibex/nestedvm/util/Platform.java b/src/main/java/org/ibex/nestedvm/util/Platform.java deleted file mode 100644 index 775af41..0000000 --- a/src/main/java/org/ibex/nestedvm/util/Platform.java +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source License 2.0 ("the License"). -// You may not use this file except in compliance with the License. - -package org.ibex.nestedvm.util; - -import java.io.*; -import java.nio.channels.*; -import java.net.*; -import java.util.*; - -import java.text.DateFormatSymbols; - -/* - GCCLASS_HINT: org.ibex.nestedvm.util.Platform. org.ibex.nestedvm.util.Platform$Jdk11. - GCCLASS_HINT: org.ibex.nestedvm.util.Platform. org.ibex.nestedvm.util.Platform$Jdk12. - GCCLASS_HINT: org.ibex.nestedvm.util.Platform. org.ibex.nestedvm.util.Platform$Jdk13. - GCCLASS_HINT: org.ibex.nestedvm.util.Platform. org.ibex.nestedvm.util.Platform$Jdk14. -*/ - -public abstract class Platform { - Platform() { } - private static final Platform p; - - static { - float version; - try { - if(getProperty("java.vm.name").equals("SableVM")) - version = 1.2f; - else - version = Float.valueOf(getProperty("java.specification.version")).floatValue(); - } catch(Exception e) { - System.err.println("WARNING: " + e + " while trying to find jvm version - assuming 1.1"); - version = 1.1f; - } - String platformClass; - if(version >= 1.4f) platformClass = "Jdk14"; - else if(version >= 1.3f) platformClass = "Jdk13"; - else if(version >= 1.2f) platformClass = "Jdk12"; - else if(version >= 1.1f) platformClass = "Jdk11"; - else throw new Error("JVM Specification version: " + version + " is too old. (see org.ibex.util.Platform to add support)"); - - try { - p = (Platform) Class.forName(Platform.class.getName() + "$" + platformClass).newInstance(); - } catch(Exception e) { - e.printStackTrace(); - throw new Error("Error instansiating platform class"); - } - } - - public static String getProperty(String key) { - try { - return System.getProperty(key); - } catch(SecurityException e) { - return null; - } - } - - - abstract boolean _atomicCreateFile(File f) throws IOException; - public static boolean atomicCreateFile(File f) throws IOException { return p._atomicCreateFile(f); } - - abstract Seekable.Lock _lockFile(Seekable s, RandomAccessFile raf, long pos, long size, boolean shared) throws IOException; - public static Seekable.Lock lockFile(Seekable s, RandomAccessFile raf, long pos, long size, boolean shared) throws IOException { - return p._lockFile(s, raf, pos, size, shared); } - - abstract void _socketHalfClose(Socket s, boolean output) throws IOException; - public static void socketHalfClose(Socket s, boolean output) throws IOException { p._socketHalfClose(s,output); } - - abstract void _socketSetKeepAlive(Socket s, boolean on) throws SocketException; - public static void socketSetKeepAlive(Socket s, boolean on) throws SocketException { p._socketSetKeepAlive(s,on); } - - abstract InetAddress _inetAddressFromBytes(byte[] a) throws UnknownHostException; - public static InetAddress inetAddressFromBytes(byte[] a) throws UnknownHostException { return p._inetAddressFromBytes(a); } - - abstract String _timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l); - public static String timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l) { return p._timeZoneGetDisplayName(tz,dst,showlong,l); } - public static String timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong) { return timeZoneGetDisplayName(tz,dst,showlong,Locale.getDefault()); } - - abstract void _setFileLength(RandomAccessFile f, int length) - throws IOException; - public static void setFileLength(RandomAccessFile f, int length) - throws IOException { p._setFileLength(f, length); } - - abstract File[] _listRoots(); - public static File[] listRoots() { return p._listRoots(); } - - abstract File _getRoot(File f); - public static File getRoot(File f) { return p._getRoot(f); } - - static class Jdk11 extends Platform { - boolean _atomicCreateFile(File f) throws IOException { - // This is not atomic, but its the best we can do on jdk 1.1 - if(f.exists()) return false; - new FileOutputStream(f).close(); - return true; - } - Seekable.Lock _lockFile(Seekable s, RandomAccessFile raf, long p, long size, boolean shared) throws IOException { - throw new IOException("file locking requires jdk 1.4+"); - } - void _socketHalfClose(Socket s, boolean output) throws IOException { - throw new IOException("half closing sockets not supported"); - } - InetAddress _inetAddressFromBytes(byte[] a) throws UnknownHostException { - if(a.length != 4) throw new UnknownHostException("only ipv4 addrs supported"); - return InetAddress.getByName(""+(a[0]&0xff)+"."+(a[1]&0xff)+"."+(a[2]&0xff)+"."+(a[3]&0xff)); - } - void _socketSetKeepAlive(Socket s, boolean on) throws SocketException { - if(on) throw new SocketException("keepalive not supported"); - } - String _timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l) { - String[][] zs = new DateFormatSymbols(l).getZoneStrings(); - String id = tz.getID(); - for(int i=0;i 0) sb.append(":").append(off/60); off=off%60; - if(off > 0) sb.append(":").append(off); - return sb.toString(); - } - - void _setFileLength(RandomAccessFile f, int length) throws IOException{ - InputStream in = new FileInputStream(f.getFD()); - OutputStream out = new FileOutputStream(f.getFD()); - - byte[] buf = new byte[1024]; - for (int len; length > 0; length -= len) { - len = in.read(buf, 0, Math.min(length, buf.length)); - if (len == -1) break; - out.write(buf, 0, len); - } - if (length == 0) return; - - // fill the rest of the space with zeros - for (int i=0; i < buf.length; i++) buf[i] = 0; - while (length > 0) { - out.write(buf, 0, Math.min(length, buf.length)); - length -= buf.length; - } - } - - RandomAccessFile _truncatedRandomAccessFile(File f, String mode) throws IOException { - new FileOutputStream(f).close(); - return new RandomAccessFile(f,mode); - } - - File[] _listRoots() { - String[] rootProps = new String[]{"java.home","java.class.path","java.library.path","java.io.tmpdir","java.ext.dirs","user.home","user.dir" }; - Hashtable known = new Hashtable(); - for(int i=0;i " + root); - known.put(root,Boolean.TRUE); - if(p == -1) break; - } - } - File[] ret = new File[known.size()]; - int i=0; - for(Enumeration e = known.keys();e.hasMoreElements();) - ret[i++] = (File) e.nextElement(); - return ret; - } - - File _getRoot(File f) { - if(!f.isAbsolute()) f = new File(f.getAbsolutePath()); - String p; - while((p = f.getParent()) != null) f = new File(p); - if(f.getPath().length() == 0) f = new File("/"); // work around a classpath bug - return f; - } - } - - static class Jdk12 extends Jdk11 { - boolean _atomicCreateFile(File f) throws IOException { - return f.createNewFile(); - } - - String _timeZoneGetDisplayName(TimeZone tz, boolean dst, boolean showlong, Locale l) { - return tz.getDisplayName(dst,showlong ? TimeZone.LONG : TimeZone.SHORT, l); - } - - void _setFileLength(RandomAccessFile f, int length) throws IOException { - f.setLength(length); - } - - File[] _listRoots() { return File.listRoots(); } - } - - static class Jdk13 extends Jdk12 { - void _socketHalfClose(Socket s, boolean output) throws IOException { - if(output) s.shutdownOutput(); - else s.shutdownInput(); - } - - void _socketSetKeepAlive(Socket s, boolean on) throws SocketException { - s.setKeepAlive(on); - } - } - - static class Jdk14 extends Jdk13 { - InetAddress _inetAddressFromBytes(byte[] a) throws UnknownHostException { return InetAddress.getByAddress(a); } - - Seekable.Lock _lockFile(Seekable s, RandomAccessFile r, long pos, long size, boolean shared) throws IOException { - FileLock flock; - try { - flock = pos == 0 && size == 0 ? r.getChannel().lock() : - r.getChannel().tryLock(pos, size, shared); - } catch (OverlappingFileLockException e) { flock = null; } - if (flock == null) return null; // region already locked - return new Jdk14FileLock(s, flock); - } - } - - private static final class Jdk14FileLock extends Seekable.Lock { - private final Seekable s; - private final FileLock l; - - Jdk14FileLock(Seekable sk, FileLock flock) { s = sk; l = flock; } - public Seekable seekable() { return s; } - public boolean isShared() { return l.isShared(); } - public boolean isValid() { return l.isValid(); } - public void release() throws IOException { l.release(); } - public long position() { return l.position(); } - public long size() { return l.size(); } - public String toString() { return l.toString(); } - } -} diff --git a/src/main/java/org/ibex/nestedvm/util/Seekable.java b/src/main/java/org/ibex/nestedvm/util/Seekable.java deleted file mode 100644 index 485d364..0000000 --- a/src/main/java/org/ibex/nestedvm/util/Seekable.java +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright 2000-2005 the Contributors, as shown in the revision logs. -// Licensed under the Apache Public Source License 2.0 ("the License"). -// You may not use this file except in compliance with the License. - -package org.ibex.nestedvm.util; - -import java.io.*; - -public abstract class Seekable { - public abstract int read(byte[] buf, int offset, int length) throws IOException; - public abstract int write(byte[] buf, int offset, int length) throws IOException; - public abstract int length() throws IOException; - public abstract void seek(int pos) throws IOException; - public abstract void close() throws IOException; - public abstract int pos() throws IOException; - - public void sync() throws IOException { - throw new IOException("sync not implemented for " + getClass()); - } - public void resize(long length) throws IOException { - throw new IOException("resize not implemented for " + getClass()); - } - /** If pos == 0 and size == 0 lock covers whole file. */ - public Lock lock(long pos, long size, boolean shared) throws IOException { - throw new IOException("lock not implemented for " + getClass()); - } - - public int read() throws IOException { - byte[] buf = new byte[1]; - int n = read(buf,0,1); - return n == -1 ? -1 : buf[0]&0xff; - } - - public int tryReadFully(byte[] buf, int off, int len) throws IOException { - int total = 0; - while(len > 0) { - int n = read(buf,off,len); - if(n == -1) break; - off += n; - len -= n; - total += n; - } - return total == 0 ? -1 : total; - } - - public static class ByteArray extends Seekable { - protected byte[] data; - protected int pos; - private final boolean writable; - - public ByteArray(byte[] data, boolean writable) { - this.data = data; - this.pos = 0; - this.writable = writable; - } - - public int read(byte[] buf, int off, int len) { - len = Math.min(len,data.length-pos); - if(len <= 0) return -1; - System.arraycopy(data,pos,buf,off,len); - pos += len; - return len; - } - - public int write(byte[] buf, int off, int len) throws IOException { - if(!writable) throw new IOException("read-only data"); - len = Math.min(len,data.length-pos); - if(len <= 0) throw new IOException("no space"); - System.arraycopy(buf,off,data,pos,len); - pos += len; - return len; - } - - public int length() { return data.length; } - public int pos() { return pos; } - public void seek(int pos) { this.pos = pos; } - public void close() { /*noop*/ } - } - - public static class File extends Seekable { - private final java.io.File file; - private final RandomAccessFile raf; - - public File(String fileName) throws IOException { this(fileName,false); } - public File(String fileName, boolean writable) throws IOException { this(new java.io.File(fileName),writable,false); } - - public File(java.io.File file, boolean writable, boolean truncate) throws IOException { - this.file = file; - String mode = writable ? "rw" : "r"; - raf = new RandomAccessFile(file,mode); - if (truncate) Platform.setFileLength(raf, 0); - } - - public int read(byte[] buf, int offset, int length) throws IOException { return raf.read(buf,offset,length); } - public int write(byte[] buf, int offset, int length) throws IOException { raf.write(buf,offset,length); return length; } - public void sync() throws IOException { raf.getFD().sync(); } - public void seek(int pos) throws IOException{ raf.seek(pos); } - public int pos() throws IOException { return (int) raf.getFilePointer(); } - public int length() throws IOException { return (int)raf.length(); } - public void close() throws IOException { raf.close(); } - public void resize(long length) throws IOException { Platform.setFileLength(raf, (int)length); } - public boolean equals(Object o) { - return o != null && o instanceof File - && file.equals(((File)o).file); - } - public Lock lock(long pos, long size, boolean shared) - throws IOException { - return Platform.lockFile(this, raf, pos, size, shared); - } - } - - public static class InputStream extends Seekable { - private byte[] buffer = new byte[4096]; - private int bytesRead = 0; - private boolean eof = false; - private int pos; - private java.io.InputStream is; - - public InputStream(java.io.InputStream is) { this.is = is; } - - public int read(byte[] outbuf, int off, int len) throws IOException { - if(pos >= bytesRead && !eof) readTo(pos + 1); - len = Math.min(len,bytesRead-pos); - if(len <= 0) return -1; - System.arraycopy(buffer,pos,outbuf,off,len); - pos += len; - return len; - } - - private void readTo(int target) throws IOException { - if(target >= buffer.length) { - byte[] buf2 = new byte[Math.max(buffer.length+Math.min(buffer.length,65536),target)]; - System.arraycopy(buffer,0,buf2,0,bytesRead); - buffer = buf2; - } - while(bytesRead < target) { - int n = is.read(buffer,bytesRead,buffer.length-bytesRead); - if(n == -1) { - eof = true; - break; - } - bytesRead += n; - } - } - - public int length() throws IOException { - while(!eof) readTo(bytesRead+4096); - return bytesRead; - } - - public int write(byte[] buf, int off, int len) throws IOException { throw new IOException("read-only"); } - public void seek(int pos) { this.pos = pos; } - public int pos() { return pos; } - public void close() throws IOException { is.close(); } - } - - public abstract static class Lock { - private Object owner = null; - - public abstract Seekable seekable(); - public abstract boolean isShared(); - public abstract boolean isValid(); - public abstract void release() throws IOException; - public abstract long position(); - public abstract long size(); - - public void setOwner(Object o) { owner = o; } - public Object getOwner() { return owner; } - - public final boolean contains(int start, int len) { - return start >= position() && position() + size() >= start + len; - } - - public final boolean contained(int start, int len) { - return start < position() && position() + size() < start + len; - } - - public final boolean overlaps(int start, int len) { - return contains(start, len) || contained(start, len); - } - } -} diff --git a/src/main/java/org/ibex/nestedvm/util/Sort.java b/src/main/java/org/ibex/nestedvm/util/Sort.java deleted file mode 100644 index 79fe029..0000000 --- a/src/main/java/org/ibex/nestedvm/util/Sort.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.ibex.nestedvm.util; - -public final class Sort { - private Sort() { } - - public interface Comparable { public int compareTo(Object o); } - public interface CompareFunc { public int compare(Object a, Object b); } - - private static final CompareFunc comparableCompareFunc = new CompareFunc() { - public int compare(Object a,Object b) { return ((Comparable)a).compareTo(b); } - }; - - public static void sort(Comparable[] a) { sort(a,comparableCompareFunc); } - public static void sort(Object[] a, CompareFunc c) { sort(a,c,0,a.length-1); } - - private static void sort(Object[] a, CompareFunc c, int start, int end) { - Object tmp; - if(start >= end) return; - if(end-start <= 6) { - for(int i=start+1;i<=end;i++) { - tmp = a[i]; - int j; - for(j=i-1;j>=start;j--) { - if(c.compare(a[j],tmp) <= 0) break; - a[j+1] = a[j]; - } - a[j+1] = tmp; - } - return; - } - - Object pivot = a[end]; - int lo = start - 1; - int hi = end; - - do { - while((lo < hi) && c.compare(a[++lo],pivot) < 0) { } - while((hi > lo) && c.compare(a[--hi],pivot) > 0) { } - tmp = a[lo]; a[lo] = a[hi]; a[hi] = tmp; - } while(lo < hi); - - tmp = a[lo]; a[lo] = a[end]; a[end] = tmp; - - sort(a, c, start, lo-1); - sort(a, c, lo+1, end); - } -}