From 063ad953259bfbec2ab414067838fda4654b943f Mon Sep 17 00:00:00 2001 From: Brendan Robert Date: Sat, 5 Sep 2015 14:27:02 -0500 Subject: [PATCH] Moved NestedVM directly into codebase because tracking the external jar was a PITA --- lib/nestedvm.jar | Bin 273899 -> 0 bytes pom.xml | 7 - .../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 + 12 files changed, 6456 insertions(+), 7 deletions(-) delete mode 100644 lib/nestedvm.jar create mode 100644 src/main/java/org/ibex/nestedvm/Interpreter.java create mode 100644 src/main/java/org/ibex/nestedvm/Registers.java create mode 100644 src/main/java/org/ibex/nestedvm/Runtime.java create mode 100644 src/main/java/org/ibex/nestedvm/UnixRuntime.java create mode 100644 src/main/java/org/ibex/nestedvm/UsermodeConstants.java create mode 100644 src/main/java/org/ibex/nestedvm/util/ELF.java create mode 100644 src/main/java/org/ibex/nestedvm/util/InodeCache.java create mode 100644 src/main/java/org/ibex/nestedvm/util/Platform.java create mode 100644 src/main/java/org/ibex/nestedvm/util/Seekable.java create mode 100644 src/main/java/org/ibex/nestedvm/util/Sort.java diff --git a/lib/nestedvm.jar b/lib/nestedvm.jar deleted file mode 100644 index 92914171a90e339df005e0cf25880354a207b491..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 273899 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

FbDz+buD8_4)%A20VoR8W`w({T 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 z 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%0AclB0Va3!IC>{;F1H%K>AJMkwDGx1$sVqguJ3B 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 OqGZ5!8EYVreflections 0.9.9 - - megacz - nestedvm - 2014.12.3 - system - ${project.basedir}/lib/nestedvm.jar - junit junit diff --git a/src/main/java/org/ibex/nestedvm/Interpreter.java b/src/main/java/org/ibex/nestedvm/Interpreter.java new file mode 100644 index 0000000..719aa74 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/Interpreter.java @@ -0,0 +1,787 @@ +// 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 new file mode 100644 index 0000000..a441af5 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/Registers.java @@ -0,0 +1,46 @@ +// 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 new file mode 100644 index 0000000..2c599a0 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/Runtime.java @@ -0,0 +1,1566 @@ +// 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 new file mode 100644 index 0000000..eaf3466 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/UnixRuntime.java @@ -0,0 +1,2512 @@ +// 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 new file mode 100644 index 0000000..0385965 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/UsermodeConstants.java @@ -0,0 +1,480 @@ +// 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 new file mode 100644 index 0000000..2f97071 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/util/ELF.java @@ -0,0 +1,388 @@ +// 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 new file mode 100644 index 0000000..02913de --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/util/InodeCache.java @@ -0,0 +1,207 @@ +// 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 new file mode 100644 index 0000000..775af41 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/util/Platform.java @@ -0,0 +1,241 @@ +// 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 new file mode 100644 index 0000000..485d364 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/util/Seekable.java @@ -0,0 +1,182 @@ +// 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 new file mode 100644 index 0000000..79fe029 --- /dev/null +++ b/src/main/java/org/ibex/nestedvm/util/Sort.java @@ -0,0 +1,47 @@ +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); + } +}