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