forked from Apple-2-Tools/jace
Moved NestedVM directly into codebase because tracking the external jar was a PITA
This commit is contained in:
parent
f7ee8272b5
commit
063ad95325
BIN
lib/nestedvm.jar
BIN
lib/nestedvm.jar
Binary file not shown.
7
pom.xml
7
pom.xml
@ -141,13 +141,6 @@
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>megacz</groupId>
|
||||
<artifactId>nestedvm</artifactId>
|
||||
<version>2014.12.3</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/lib/nestedvm.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
787
src/main/java/org/ibex/nestedvm/Interpreter.java
Normal file
787
src/main/java/org/ibex/nestedvm/Interpreter.java
Normal file
@ -0,0 +1,787 @@
|
||||
// Copyright 2000-2005 the Contributors, as shown in the revision logs.
|
||||
// Licensed under the Apache Public Source License 2.0 ("the License").
|
||||
// You may not use this file except in compliance with the License.
|
||||
|
||||
// Copyright 2003 Brian Alliet
|
||||
// Based on org.xwt.imp.MIPS by Adam Megacz
|
||||
// Portions Copyright 2003 Adam Megacz
|
||||
|
||||
package org.ibex.nestedvm;
|
||||
|
||||
import org.ibex.nestedvm.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class Interpreter extends UnixRuntime implements Cloneable {
|
||||
// Registers
|
||||
private int[] registers = new int[32];
|
||||
private int hi,lo;
|
||||
|
||||
// Floating Point Registers
|
||||
private int[] fpregs = new int[32];
|
||||
// 24-31 - unused
|
||||
// 23 - conditional bit
|
||||
// 18-22 - unused
|
||||
// 12-17 - cause bits (unimplemented)
|
||||
// 7-11 - enables bits (unimplemented)
|
||||
// 2-6 - flags (unimplemented)
|
||||
// 0-1 - rounding mode (only implemented for fixed point conversions)
|
||||
private int fcsr;
|
||||
|
||||
private int pc;
|
||||
|
||||
// The filename if the binary we're running
|
||||
public String image;
|
||||
private ELF.Symtab symtab;
|
||||
|
||||
// Register Operations
|
||||
private final void setFC(boolean b) { fcsr = (fcsr&~0x800000) | (b ? 0x800000 : 0x000000); }
|
||||
private final int roundingMode() { return fcsr & 3; /* bits 0-1 */ }
|
||||
private final double getDouble(int r) {
|
||||
return Double.longBitsToDouble(((fpregs[r+1]&0xffffffffL) << 32) | (fpregs[r]&0xffffffffL));
|
||||
}
|
||||
private final void setDouble(int r, double d) {
|
||||
long l = Double.doubleToLongBits(d);
|
||||
fpregs[r+1] = (int)(l >>> 32); fpregs[r] = (int)l;
|
||||
}
|
||||
private final float getFloat(int r) { return Float.intBitsToFloat(fpregs[r]); }
|
||||
private final void setFloat(int r, float f) { fpregs[r] = Float.floatToRawIntBits(f); }
|
||||
|
||||
protected void _execute() throws ExecutionException {
|
||||
try {
|
||||
runSome();
|
||||
} catch(ExecutionException e) {
|
||||
e.setLocation(toHex(pc) + ": " + sourceLine(pc));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
Interpreter r = (Interpreter) super.clone();
|
||||
r.registers = (int[]) registers.clone();
|
||||
r.fpregs = (int[]) fpregs.clone();
|
||||
return r;
|
||||
}
|
||||
|
||||
// Main interpretor
|
||||
// the return value is meaningless, its just to catch people typing "return" by accident
|
||||
private final int runSome() throws FaultException,ExecutionException {
|
||||
final int PAGE_WORDS = (1<<pageShift)>>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<<pageShift);
|
||||
int pageWords = (1<<pageShift) >> 2;
|
||||
for(int i=0;i<pheaders.length;i++) {
|
||||
ELF.PHeader ph = pheaders[i];
|
||||
if(ph.type != ELF.PT_LOAD) continue;
|
||||
int memsize = ph.memsz;
|
||||
int filesize = ph.filesz;
|
||||
if(memsize == 0) continue;
|
||||
if(memsize < 0) throw new IOException("pheader size too large");
|
||||
int addr = ph.vaddr;
|
||||
if(addr == 0x0) throw new IOException("pheader vaddr == 0x0");
|
||||
brk = max(addr+memsize,brk);
|
||||
|
||||
for(int j=0;j<memsize+pageSize-1;j+=pageSize) {
|
||||
int page = (j+addr) >>> 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<Integer,String> 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<Integer,String>();
|
||||
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);
|
||||
}
|
||||
}
|
46
src/main/java/org/ibex/nestedvm/Registers.java
Normal file
46
src/main/java/org/ibex/nestedvm/Registers.java
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2000-2005 the Contributors, as shown in the revision logs.
|
||||
// Licensed under the Apache Public Source License 2.0 ("the License").
|
||||
// You may not use this file except in compliance with the License.
|
||||
|
||||
package org.ibex.nestedvm;
|
||||
|
||||
interface Registers {
|
||||
// Register Names
|
||||
public final static int ZERO = 0; // Immutable, hardwired to 0
|
||||
public final static int AT = 1; // Reserved for assembler
|
||||
public final static int K0 = 26; // Reserved for kernel
|
||||
public final static int K1 = 27; // Reserved for kernel
|
||||
public final static int GP = 28; // Global pointer (the middle of .sdata/.sbss)
|
||||
public final static int SP = 29; // Stack pointer
|
||||
public final static int FP = 30; // Frame Pointer
|
||||
public final static int RA = 31; // Return Address
|
||||
|
||||
// Return values (caller saved)
|
||||
public final static int V0 = 2;
|
||||
public final static int V1 = 3;
|
||||
// Argument Registers (caller saved)
|
||||
public final static int A0 = 4;
|
||||
public final static int A1 = 5;
|
||||
public final static int A2 = 6;
|
||||
public final static int A3 = 7;
|
||||
// Temporaries (caller saved)
|
||||
public final static int T0 = 8;
|
||||
public final static int T1 = 9;
|
||||
public final static int T2 = 10;
|
||||
public final static int T3 = 11;
|
||||
public final static int T4 = 12;
|
||||
public final static int T5 = 13;
|
||||
public final static int T6 = 14;
|
||||
public final static int T7 = 15;
|
||||
public final static int T8 = 24;
|
||||
public final static int T9 = 25;
|
||||
// Saved (callee saved)
|
||||
public final static int S0 = 16;
|
||||
public final static int S1 = 17;
|
||||
public final static int S2 = 18;
|
||||
public final static int S3 = 19;
|
||||
public final static int S4 = 20;
|
||||
public final static int S5 = 21;
|
||||
public final static int S6 = 22;
|
||||
public final static int S7 = 23;
|
||||
}
|
1566
src/main/java/org/ibex/nestedvm/Runtime.java
Normal file
1566
src/main/java/org/ibex/nestedvm/Runtime.java
Normal file
File diff suppressed because it is too large
Load Diff
2512
src/main/java/org/ibex/nestedvm/UnixRuntime.java
Normal file
2512
src/main/java/org/ibex/nestedvm/UnixRuntime.java
Normal file
File diff suppressed because it is too large
Load Diff
480
src/main/java/org/ibex/nestedvm/UsermodeConstants.java
Normal file
480
src/main/java/org/ibex/nestedvm/UsermodeConstants.java
Normal file
@ -0,0 +1,480 @@
|
||||
// THIS FILE IS AUTOGENERATED! DO NOT EDIT!
|
||||
// run "make rebuild-constants" if it needs to be updated
|
||||
|
||||
package org.ibex.nestedvm;
|
||||
public interface UsermodeConstants {
|
||||
public static final int SYS_null = 0;
|
||||
public static final int SYS_exit = 1;
|
||||
public static final int SYS_pause = 2;
|
||||
public static final int SYS_open = 3;
|
||||
public static final int SYS_close = 4;
|
||||
public static final int SYS_read = 5;
|
||||
public static final int SYS_write = 6;
|
||||
public static final int SYS_sbrk = 7;
|
||||
public static final int SYS_fstat = 8;
|
||||
public static final int SYS_lseek = 10;
|
||||
public static final int SYS_kill = 11;
|
||||
public static final int SYS_getpid = 12;
|
||||
public static final int SYS_calljava = 13;
|
||||
public static final int SYS_stat = 14;
|
||||
public static final int SYS_gettimeofday = 15;
|
||||
public static final int SYS_sleep = 16;
|
||||
public static final int SYS_times = 17;
|
||||
public static final int SYS_mkdir = 18;
|
||||
public static final int SYS_getpagesize = 19;
|
||||
public static final int SYS_unlink = 20;
|
||||
public static final int SYS_utime = 21;
|
||||
public static final int SYS_chdir = 22;
|
||||
public static final int SYS_pipe = 23;
|
||||
public static final int SYS_dup2 = 24;
|
||||
public static final int SYS_fork = 25;
|
||||
public static final int SYS_waitpid = 26;
|
||||
public static final int SYS_getcwd = 27;
|
||||
public static final int SYS_exec = 28;
|
||||
public static final int SYS_fcntl = 29;
|
||||
public static final int SYS_rmdir = 30;
|
||||
public static final int SYS_sysconf = 31;
|
||||
public static final int SYS_readlink = 32;
|
||||
public static final int SYS_lstat = 33;
|
||||
public static final int SYS_symlink = 34;
|
||||
public static final int SYS_link = 35;
|
||||
public static final int SYS_getdents = 36;
|
||||
public static final int SYS_memcpy = 37;
|
||||
public static final int SYS_memset = 38;
|
||||
public static final int SYS_dup = 39;
|
||||
public static final int SYS_vfork = 40;
|
||||
public static final int SYS_chroot = 41;
|
||||
public static final int SYS_mknod = 42;
|
||||
public static final int SYS_lchown = 43;
|
||||
public static final int SYS_ftruncate = 44;
|
||||
public static final int SYS_usleep = 45;
|
||||
public static final int SYS_getppid = 46;
|
||||
public static final int SYS_mkfifo = 47;
|
||||
public static final int SYS_klogctl = 51;
|
||||
public static final int SYS_realpath = 52;
|
||||
public static final int SYS_sysctl = 53;
|
||||
public static final int SYS_setpriority = 54;
|
||||
public static final int SYS_getpriority = 55;
|
||||
public static final int SYS_socket = 56;
|
||||
public static final int SYS_connect = 57;
|
||||
public static final int SYS_resolve_hostname = 58;
|
||||
public static final int SYS_accept = 59;
|
||||
public static final int SYS_setsockopt = 60;
|
||||
public static final int SYS_getsockopt = 61;
|
||||
public static final int SYS_listen = 62;
|
||||
public static final int SYS_bind = 63;
|
||||
public static final int SYS_shutdown = 64;
|
||||
public static final int SYS_sendto = 65;
|
||||
public static final int SYS_recvfrom = 66;
|
||||
public static final int SYS_select = 67;
|
||||
public static final int SYS_getuid = 68;
|
||||
public static final int SYS_getgid = 69;
|
||||
public static final int SYS_geteuid = 70;
|
||||
public static final int SYS_getegid = 71;
|
||||
public static final int SYS_getgroups = 72;
|
||||
public static final int SYS_umask = 73;
|
||||
public static final int SYS_chmod = 74;
|
||||
public static final int SYS_fchmod = 75;
|
||||
public static final int SYS_chown = 76;
|
||||
public static final int SYS_fchown = 77;
|
||||
public static final int SYS_access = 78;
|
||||
public static final int SYS_alarm = 79;
|
||||
public static final int SYS_setuid = 80;
|
||||
public static final int SYS_setgid = 81;
|
||||
public static final int SYS_send = 82;
|
||||
public static final int SYS_recv = 83;
|
||||
public static final int SYS_getsockname = 84;
|
||||
public static final int SYS_getpeername = 85;
|
||||
public static final int SYS_seteuid = 86;
|
||||
public static final int SYS_setegid = 87;
|
||||
public static final int SYS_setgroups = 88;
|
||||
public static final int SYS_resolve_ip = 89;
|
||||
public static final int SYS_setsid = 90;
|
||||
public static final int SYS_fsync = 91;
|
||||
public static final int AF_UNIX = 1;
|
||||
public static final int AF_INET = 2;
|
||||
public static final int SOCK_STREAM = 1;
|
||||
public static final int SOCK_DGRAM = 2;
|
||||
public static final int HOST_NOT_FOUND = 1;
|
||||
public static final int TRY_AGAIN = 2;
|
||||
public static final int NO_RECOVERY = 3;
|
||||
public static final int NO_DATA = 4;
|
||||
public static final int SOL_SOCKET = 0xffff;
|
||||
public static final int SO_REUSEADDR = 0x0004;
|
||||
public static final int SO_KEEPALIVE = 0x0008;
|
||||
public static final int SO_BROADCAST = 0x0020;
|
||||
public static final int SO_TYPE = 0x1008;
|
||||
public static final int SHUT_RD = 0;
|
||||
public static final int SHUT_WR = 1;
|
||||
public static final int SHUT_RDWR = 2;
|
||||
public static final int INADDR_ANY = 0;
|
||||
public static final int INADDR_LOOPBACK = 0x7f000001;
|
||||
public static final int INADDR_BROADCAST = 0xffffffff;
|
||||
public static final int EPERM = 1; /* Not super-user */
|
||||
public static final int ENOENT = 2; /* No such file or directory */
|
||||
public static final int ESRCH = 3; /* No such process */
|
||||
public static final int EINTR = 4; /* Interrupted system call */
|
||||
public static final int EIO = 5; /* I/O error */
|
||||
public static final int ENXIO = 6; /* No such device or address */
|
||||
public static final int E2BIG = 7; /* Arg list too long */
|
||||
public static final int ENOEXEC = 8; /* Exec format error */
|
||||
public static final int EBADF = 9; /* Bad file number */
|
||||
public static final int ECHILD = 10; /* No children */
|
||||
public static final int EAGAIN = 11; /* No more processes */
|
||||
public static final int ENOMEM = 12; /* Not enough core */
|
||||
public static final int EACCES = 13; /* Permission denied */
|
||||
public static final int EFAULT = 14; /* Bad address */
|
||||
public static final int ENOTBLK = 15; /* Block device required */
|
||||
public static final int EBUSY = 16; /* Mount device busy */
|
||||
public static final int EEXIST = 17; /* File exists */
|
||||
public static final int EXDEV = 18; /* Cross-device link */
|
||||
public static final int ENODEV = 19; /* No such device */
|
||||
public static final int ENOTDIR = 20; /* Not a directory */
|
||||
public static final int EISDIR = 21; /* Is a directory */
|
||||
public static final int EINVAL = 22; /* Invalid argument */
|
||||
public static final int ENFILE = 23; /* Too many open files in system */
|
||||
public static final int EMFILE = 24; /* Too many open files */
|
||||
public static final int ENOTTY = 25; /* Not a typewriter */
|
||||
public static final int ETXTBSY = 26; /* Text file busy */
|
||||
public static final int EFBIG = 27; /* File too large */
|
||||
public static final int ENOSPC = 28; /* No space left on device */
|
||||
public static final int ESPIPE = 29; /* Illegal seek */
|
||||
public static final int EROFS = 30; /* Read only file system */
|
||||
public static final int EMLINK = 31; /* Too many links */
|
||||
public static final int EPIPE = 32; /* Broken pipe */
|
||||
public static final int EDOM = 33; /* Math arg out of domain of func */
|
||||
public static final int ERANGE = 34; /* Math result not representable */
|
||||
public static final int ENOMSG = 35; /* No message of desired type */
|
||||
public static final int EIDRM = 36; /* Identifier removed */
|
||||
public static final int ECHRNG = 37; /* Channel number out of range */
|
||||
public static final int EL2NSYNC = 38; /* Level 2 not synchronized */
|
||||
public static final int EL3HLT = 39; /* Level 3 halted */
|
||||
public static final int EL3RST = 40; /* Level 3 reset */
|
||||
public static final int ELNRNG = 41; /* Link number out of range */
|
||||
public static final int EUNATCH = 42; /* Protocol driver not attached */
|
||||
public static final int ENOCSI = 43; /* No CSI structure available */
|
||||
public static final int EL2HLT = 44; /* Level 2 halted */
|
||||
public static final int EDEADLK = 45; /* Deadlock condition */
|
||||
public static final int ENOLCK = 46; /* No record locks available */
|
||||
public static final int EBADE = 50; /* Invalid exchange */
|
||||
public static final int EBADR = 51; /* Invalid request descriptor */
|
||||
public static final int EXFULL = 52; /* Exchange full */
|
||||
public static final int ENOANO = 53; /* No anode */
|
||||
public static final int EBADRQC = 54; /* Invalid request code */
|
||||
public static final int EBADSLT = 55; /* Invalid slot */
|
||||
public static final int EDEADLOCK = 56; /* File locking deadlock error */
|
||||
public static final int EBFONT = 57; /* Bad font file fmt */
|
||||
public static final int ENOSTR = 60; /* Device not a stream */
|
||||
public static final int ENODATA = 61; /* No data (for no delay io) */
|
||||
public static final int ETIME = 62; /* Timer expired */
|
||||
public static final int ENOSR = 63; /* Out of streams resources */
|
||||
public static final int ENONET = 64; /* Machine is not on the network */
|
||||
public static final int ENOPKG = 65; /* Package not installed */
|
||||
public static final int EREMOTE = 66; /* The object is remote */
|
||||
public static final int ENOLINK = 67; /* The link has been severed */
|
||||
public static final int EADV = 68; /* Advertise error */
|
||||
public static final int ESRMNT = 69; /* Srmount error */
|
||||
public static final int ECOMM = 70; /* Communication error on send */
|
||||
public static final int EPROTO = 71; /* Protocol error */
|
||||
public static final int EMULTIHOP = 74; /* Multihop attempted */
|
||||
public static final int ELBIN = 75; /* Inode is remote (not really error) */
|
||||
public static final int EDOTDOT = 76; /* Cross mount point (not really error) */
|
||||
public static final int EBADMSG = 77; /* Trying to read unreadable message */
|
||||
public static final int EFTYPE = 79; /* Inappropriate file type or format */
|
||||
public static final int ENOTUNIQ = 80; /* Given log. name not unique */
|
||||
public static final int EBADFD = 81; /* f.d. invalid for this operation */
|
||||
public static final int EREMCHG = 82; /* Remote address changed */
|
||||
public static final int ELIBACC = 83; /* Can't access a needed shared lib */
|
||||
public static final int ELIBBAD = 84; /* Accessing a corrupted shared lib */
|
||||
public static final int ELIBSCN = 85; /* .lib section in a.out corrupted */
|
||||
public static final int ELIBMAX = 86; /* Attempting to link in too many libs */
|
||||
public static final int ELIBEXEC = 87; /* Attempting to exec a shared library */
|
||||
public static final int ENOSYS = 88; /* Function not implemented */
|
||||
public static final int ENMFILE = 89; /* No more files */
|
||||
public static final int ENOTEMPTY = 90; /* Directory not empty */
|
||||
public static final int ENAMETOOLONG = 91; /* File or path name too long */
|
||||
public static final int ELOOP = 92; /* Too many symbolic links */
|
||||
public static final int EOPNOTSUPP = 95; /* Operation not supported on transport endpoint */
|
||||
public static final int EPFNOSUPPORT = 96; /* Protocol family not supported */
|
||||
public static final int ECONNRESET = 104; /* Connection reset by peer */
|
||||
public static final int ENOBUFS = 105; /* No buffer space available */
|
||||
public static final int EAFNOSUPPORT = 106; /* Address family not supported by protocol family */
|
||||
public static final int EPROTOTYPE = 107; /* Protocol wrong type for socket */
|
||||
public static final int ENOTSOCK = 108; /* Socket operation on non-socket */
|
||||
public static final int ENOPROTOOPT = 109; /* Protocol not available */
|
||||
public static final int ESHUTDOWN = 110; /* Can't send after socket shutdown */
|
||||
public static final int ECONNREFUSED = 111; /* Connection refused */
|
||||
public static final int EADDRINUSE = 112; /* Address already in use */
|
||||
public static final int ECONNABORTED = 113; /* Connection aborted */
|
||||
public static final int ENETUNREACH = 114; /* Network is unreachable */
|
||||
public static final int ENETDOWN = 115; /* Network interface is not configured */
|
||||
public static final int ETIMEDOUT = 116; /* Connection timed out */
|
||||
public static final int EHOSTDOWN = 117; /* Host is down */
|
||||
public static final int EHOSTUNREACH = 118; /* Host is unreachable */
|
||||
public static final int EINPROGRESS = 119; /* Connection already in progress */
|
||||
public static final int EALREADY = 120; /* Socket already connected */
|
||||
public static final int EDESTADDRREQ = 121; /* Destination address required */
|
||||
public static final int EMSGSIZE = 122; /* Message too long */
|
||||
public static final int EPROTONOSUPPORT = 123; /* Unknown protocol */
|
||||
public static final int ESOCKTNOSUPPORT = 124; /* Socket type not supported */
|
||||
public static final int EADDRNOTAVAIL = 125; /* Address not available */
|
||||
public static final int ENETRESET = 126;
|
||||
public static final int EISCONN = 127; /* Socket is already connected */
|
||||
public static final int ENOTCONN = 128; /* Socket is not connected */
|
||||
public static final int ETOOMANYREFS = 129;
|
||||
public static final int EPROCLIM = 130;
|
||||
public static final int EUSERS = 131;
|
||||
public static final int EDQUOT = 132;
|
||||
public static final int ESTALE = 133;
|
||||
public static final int ENOTSUP = 134; /* Not supported */
|
||||
public static final int ENOMEDIUM = 135; /* No medium (in tape drive) */
|
||||
public static final int ENOSHARE = 136; /* No such host or network path */
|
||||
public static final int ECASECLASH = 137; /* Filename exists with different case */
|
||||
public static final int EILSEQ = 138;
|
||||
public static final int EOVERFLOW = 139; /* Value too large for defined data type */
|
||||
public static final int __ELASTERROR = 2000; /* Users can add values starting here */
|
||||
public static final int F_OK = 0;
|
||||
public static final int R_OK = 4;
|
||||
public static final int W_OK = 2;
|
||||
public static final int X_OK = 1;
|
||||
public static final int SEEK_SET = 0;
|
||||
public static final int SEEK_CUR = 1;
|
||||
public static final int SEEK_END = 2;
|
||||
public static final int STDIN_FILENO = 0; /* standard input file descriptor */
|
||||
public static final int STDOUT_FILENO = 1; /* standard output file descriptor */
|
||||
public static final int STDERR_FILENO = 2; /* standard error file descriptor */
|
||||
public static final int _SC_ARG_MAX = 0;
|
||||
public static final int _SC_CHILD_MAX = 1;
|
||||
public static final int _SC_CLK_TCK = 2;
|
||||
public static final int _SC_NGROUPS_MAX = 3;
|
||||
public static final int _SC_OPEN_MAX = 4;
|
||||
public static final int _SC_JOB_CONTROL = 5;
|
||||
public static final int _SC_SAVED_IDS = 6;
|
||||
public static final int _SC_VERSION = 7;
|
||||
public static final int _SC_PAGESIZE = 8;
|
||||
public static final int _SC_NPROCESSORS_CONF = 9;
|
||||
public static final int _SC_NPROCESSORS_ONLN = 10;
|
||||
public static final int _SC_PHYS_PAGES = 11;
|
||||
public static final int _SC_AVPHYS_PAGES = 12;
|
||||
public static final int _SC_MQ_OPEN_MAX = 13;
|
||||
public static final int _SC_MQ_PRIO_MAX = 14;
|
||||
public static final int _SC_RTSIG_MAX = 15;
|
||||
public static final int _SC_SEM_NSEMS_MAX = 16;
|
||||
public static final int _SC_SEM_VALUE_MAX = 17;
|
||||
public static final int _SC_SIGQUEUE_MAX = 18;
|
||||
public static final int _SC_TIMER_MAX = 19;
|
||||
public static final int _SC_TZNAME_MAX = 20;
|
||||
public static final int _SC_ASYNCHRONOUS_IO = 21;
|
||||
public static final int _SC_FSYNC = 22;
|
||||
public static final int _SC_MAPPED_FILES = 23;
|
||||
public static final int _SC_MEMLOCK = 24;
|
||||
public static final int _SC_MEMLOCK_RANGE = 25;
|
||||
public static final int _SC_MEMORY_PROTECTION = 26;
|
||||
public static final int _SC_MESSAGE_PASSING = 27;
|
||||
public static final int _SC_PRIORITIZED_IO = 28;
|
||||
public static final int _SC_REALTIME_SIGNALS = 29;
|
||||
public static final int _SC_SEMAPHORES = 30;
|
||||
public static final int _SC_SHARED_MEMORY_OBJECTS = 31;
|
||||
public static final int _SC_SYNCHRONIZED_IO = 32;
|
||||
public static final int _SC_TIMERS = 33;
|
||||
public static final int _SC_AIO_LISTIO_MAX = 34;
|
||||
public static final int _SC_AIO_MAX = 35;
|
||||
public static final int _SC_AIO_PRIO_DELTA_MAX = 36;
|
||||
public static final int _SC_DELAYTIMER_MAX = 37;
|
||||
public static final int _SC_THREAD_KEYS_MAX = 38;
|
||||
public static final int _SC_THREAD_STACK_MIN = 39;
|
||||
public static final int _SC_THREAD_THREADS_MAX = 40;
|
||||
public static final int _SC_TTY_NAME_MAX = 41;
|
||||
public static final int _SC_THREADS = 42;
|
||||
public static final int _SC_THREAD_ATTR_STACKADDR = 43;
|
||||
public static final int _SC_THREAD_ATTR_STACKSIZE = 44;
|
||||
public static final int _SC_THREAD_PRIORITY_SCHEDULING = 45;
|
||||
public static final int _SC_THREAD_PRIO_INHERIT = 46;
|
||||
public static final int _SC_THREAD_PRIO_PROTECT = 47;
|
||||
public static final int _SC_THREAD_PROCESS_SHARED = 48;
|
||||
public static final int _SC_THREAD_SAFE_FUNCTIONS = 49;
|
||||
public static final int _SC_GETGR_R_SIZE_MAX = 50;
|
||||
public static final int _SC_GETPW_R_SIZE_MAX = 51;
|
||||
public static final int _SC_LOGIN_NAME_MAX = 52;
|
||||
public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS = 53;
|
||||
public static final int _SC_STREAM_MAX = 100;
|
||||
public static final int _SC_PRIORITY_SCHEDULING = 101;
|
||||
public static final int _PC_LINK_MAX = 0;
|
||||
public static final int _PC_MAX_CANON = 1;
|
||||
public static final int _PC_MAX_INPUT = 2;
|
||||
public static final int _PC_NAME_MAX = 3;
|
||||
public static final int _PC_PATH_MAX = 4;
|
||||
public static final int _PC_PIPE_BUF = 5;
|
||||
public static final int _PC_CHOWN_RESTRICTED = 6;
|
||||
public static final int _PC_NO_TRUNC = 7;
|
||||
public static final int _PC_VDISABLE = 8;
|
||||
public static final int _PC_ASYNC_IO = 9;
|
||||
public static final int _PC_PRIO_IO = 10;
|
||||
public static final int _PC_SYNC_IO = 11;
|
||||
public static final int _PC_POSIX_PERMISSIONS = 90;
|
||||
public static final int _PC_POSIX_SECURITY = 91;
|
||||
public static final int MAXPATHLEN = 1024;
|
||||
public static final int ARG_MAX = 65536; /* max bytes for an exec function */
|
||||
public static final int CHILD_MAX = 40; /* max simultaneous processes */
|
||||
public static final int LINK_MAX = 32767; /* max file link count */
|
||||
public static final int MAX_CANON = 255; /* max bytes in term canon input line */
|
||||
public static final int MAX_INPUT = 255; /* max bytes in terminal input */
|
||||
public static final int NAME_MAX = 255; /* max bytes in a file name */
|
||||
public static final int NGROUPS_MAX = 16; /* max supplemental group id's */
|
||||
public static final int OPEN_MAX = 64; /* max open files per process */
|
||||
public static final int PATH_MAX = 1024; /* max bytes in pathname */
|
||||
public static final int PIPE_BUF = 512; /* max bytes for atomic pipe writes */
|
||||
public static final int IOV_MAX = 1024; /* max elements in i/o vector */
|
||||
public static final int BC_BASE_MAX = 99; /* max ibase/obase values in bc(1) */
|
||||
public static final int BC_DIM_MAX = 2048; /* max array elements in bc(1) */
|
||||
public static final int BC_SCALE_MAX = 99; /* max scale value in bc(1) */
|
||||
public static final int BC_STRING_MAX = 1000; /* max const string length in bc(1) */
|
||||
public static final int COLL_WEIGHTS_MAX = 0; /* max weights for order keyword */
|
||||
public static final int EXPR_NEST_MAX = 32; /* max expressions nested in expr(1) */
|
||||
public static final int LINE_MAX = 2048; /* max bytes in an input line */
|
||||
public static final int RE_DUP_MAX = 255; /* max RE's in interval notation */
|
||||
public static final int CTL_MAXNAME = 12;
|
||||
public static final int CTL_UNSPEC = 0; /* unused */
|
||||
public static final int CTL_KERN = 1; /* "high kernel": proc, limits */
|
||||
public static final int CTL_VM = 2; /* virtual memory */
|
||||
public static final int CTL_VFS = 3; /* file system, mount type is next */
|
||||
public static final int CTL_NET = 4; /* network, see socket.h */
|
||||
public static final int CTL_DEBUG = 5; /* debugging parameters */
|
||||
public static final int CTL_HW = 6; /* generic cpu/io */
|
||||
public static final int CTL_MACHDEP = 7; /* machine dependent */
|
||||
public static final int CTL_USER = 8; /* user-level */
|
||||
public static final int CTL_P1003_1B = 9; /* POSIX 1003.1B */
|
||||
public static final int CTL_MAXID = 10; /* number of valid top-level ids */
|
||||
public static final int KERN_OSTYPE = 1; /* string: system version */
|
||||
public static final int KERN_OSRELEASE = 2; /* string: system release */
|
||||
public static final int KERN_OSREV = 3; /* int: system revision */
|
||||
public static final int KERN_VERSION = 4; /* string: compile time info */
|
||||
public static final int KERN_MAXVNODES = 5; /* int: max vnodes */
|
||||
public static final int KERN_MAXPROC = 6; /* int: max processes */
|
||||
public static final int KERN_MAXFILES = 7; /* int: max open files */
|
||||
public static final int KERN_ARGMAX = 8; /* int: max arguments to exec */
|
||||
public static final int KERN_SECURELVL = 9; /* int: system security level */
|
||||
public static final int KERN_HOSTNAME = 10; /* string: hostname */
|
||||
public static final int KERN_HOSTID = 11; /* int: host identifier */
|
||||
public static final int KERN_CLOCKRATE = 12; /* struct: struct clockrate */
|
||||
public static final int KERN_VNODE = 13; /* struct: vnode structures */
|
||||
public static final int KERN_PROC = 14; /* struct: process entries */
|
||||
public static final int KERN_FILE = 15; /* struct: file entries */
|
||||
public static final int KERN_PROF = 16; /* node: kernel profiling info */
|
||||
public static final int KERN_POSIX1 = 17; /* int: POSIX.1 version */
|
||||
public static final int KERN_NGROUPS = 18; /* int: # of supplemental group ids */
|
||||
public static final int KERN_JOB_CONTROL = 19; /* int: is job control available */
|
||||
public static final int KERN_SAVED_IDS = 20; /* int: saved set-user/group-ID */
|
||||
public static final int KERN_BOOTTIME = 21; /* struct: time kernel was booted */
|
||||
public static final int KERN_NISDOMAINNAME = 22; /* string: YP domain name */
|
||||
public static final int KERN_UPDATEINTERVAL = 23; /* int: update process sleep time */
|
||||
public static final int KERN_OSRELDATE = 24; /* int: OS release date */
|
||||
public static final int KERN_NTP_PLL = 25; /* node: NTP PLL control */
|
||||
public static final int KERN_BOOTFILE = 26; /* string: name of booted kernel */
|
||||
public static final int KERN_MAXFILESPERPROC = 27; /* int: max open files per proc */
|
||||
public static final int KERN_MAXPROCPERUID = 28; /* int: max processes per uid */
|
||||
public static final int KERN_DUMPDEV = 29; /* dev_t: device to dump on */
|
||||
public static final int KERN_IPC = 30; /* node: anything related to IPC */
|
||||
public static final int KERN_DUMMY = 31; /* unused */
|
||||
public static final int KERN_PS_STRINGS = 32; /* int: address of PS_STRINGS */
|
||||
public static final int KERN_USRSTACK = 33; /* int: address of USRSTACK */
|
||||
public static final int KERN_LOGSIGEXIT = 34; /* int: do we log sigexit procs? */
|
||||
public static final int KERN_MAXID = 35; /* number of valid kern ids */
|
||||
public static final int KERN_PROC_ALL = 0; /* everything */
|
||||
public static final int KERN_PROC_PID = 1; /* by process id */
|
||||
public static final int KERN_PROC_PGRP = 2; /* by process group id */
|
||||
public static final int KERN_PROC_SESSION = 3; /* by session of pid */
|
||||
public static final int KERN_PROC_TTY = 4; /* by controlling tty */
|
||||
public static final int KERN_PROC_UID = 5; /* by effective uid */
|
||||
public static final int KERN_PROC_RUID = 6; /* by real uid */
|
||||
public static final int KERN_PROC_ARGS = 7; /* get/set arguments/proctitle */
|
||||
public static final int KIPC_MAXSOCKBUF = 1; /* int: max size of a socket buffer */
|
||||
public static final int KIPC_SOCKBUF_WASTE = 2; /* int: wastage factor in sockbuf */
|
||||
public static final int KIPC_SOMAXCONN = 3; /* int: max length of connection q */
|
||||
public static final int KIPC_MAX_LINKHDR = 4; /* int: max length of link header */
|
||||
public static final int KIPC_MAX_PROTOHDR = 5; /* int: max length of network header */
|
||||
public static final int KIPC_MAX_HDR = 6; /* int: max total length of headers */
|
||||
public static final int KIPC_MAX_DATALEN = 7; /* int: max length of data? */
|
||||
public static final int KIPC_MBSTAT = 8; /* struct: mbuf usage statistics */
|
||||
public static final int KIPC_NMBCLUSTERS = 9; /* int: maximum mbuf clusters */
|
||||
public static final int HW_MACHINE = 1; /* string: machine class */
|
||||
public static final int HW_MODEL = 2; /* string: specific machine model */
|
||||
public static final int HW_NCPU = 3; /* int: number of cpus */
|
||||
public static final int HW_BYTEORDER = 4; /* int: machine byte order */
|
||||
public static final int HW_PHYSMEM = 5; /* int: total memory */
|
||||
public static final int HW_USERMEM = 6; /* int: non-kernel memory */
|
||||
public static final int HW_PAGESIZE = 7; /* int: software page size */
|
||||
public static final int HW_DISKNAMES = 8; /* strings: disk drive names */
|
||||
public static final int HW_DISKSTATS = 9; /* struct: diskstats[] */
|
||||
public static final int HW_FLOATINGPT = 10; /* int: has HW floating point? */
|
||||
public static final int HW_MACHINE_ARCH = 11; /* string: machine architecture */
|
||||
public static final int HW_MAXID = 12; /* number of valid hw ids */
|
||||
public static final int USER_CS_PATH = 1; /* string: _CS_PATH */
|
||||
public static final int USER_BC_BASE_MAX = 2; /* int: BC_BASE_MAX */
|
||||
public static final int USER_BC_DIM_MAX = 3; /* int: BC_DIM_MAX */
|
||||
public static final int USER_BC_SCALE_MAX = 4; /* int: BC_SCALE_MAX */
|
||||
public static final int USER_BC_STRING_MAX = 5; /* int: BC_STRING_MAX */
|
||||
public static final int USER_COLL_WEIGHTS_MAX = 6; /* int: COLL_WEIGHTS_MAX */
|
||||
public static final int USER_EXPR_NEST_MAX = 7; /* int: EXPR_NEST_MAX */
|
||||
public static final int USER_LINE_MAX = 8; /* int: LINE_MAX */
|
||||
public static final int USER_RE_DUP_MAX = 9; /* int: RE_DUP_MAX */
|
||||
public static final int USER_POSIX2_VERSION = 10; /* int: POSIX2_VERSION */
|
||||
public static final int USER_POSIX2_C_BIND = 11; /* int: POSIX2_C_BIND */
|
||||
public static final int USER_POSIX2_C_DEV = 12; /* int: POSIX2_C_DEV */
|
||||
public static final int USER_POSIX2_CHAR_TERM = 13; /* int: POSIX2_CHAR_TERM */
|
||||
public static final int USER_POSIX2_FORT_DEV = 14; /* int: POSIX2_FORT_DEV */
|
||||
public static final int USER_POSIX2_FORT_RUN = 15; /* int: POSIX2_FORT_RUN */
|
||||
public static final int USER_POSIX2_LOCALEDEF = 16; /* int: POSIX2_LOCALEDEF */
|
||||
public static final int USER_POSIX2_SW_DEV = 17; /* int: POSIX2_SW_DEV */
|
||||
public static final int USER_POSIX2_UPE = 18; /* int: POSIX2_UPE */
|
||||
public static final int USER_STREAM_MAX = 19; /* int: POSIX2_STREAM_MAX */
|
||||
public static final int USER_TZNAME_MAX = 20; /* int: POSIX2_TZNAME_MAX */
|
||||
public static final int USER_MAXID = 21; /* number of valid user ids */
|
||||
public static final int CTL_P1003_1B_ASYNCHRONOUS_IO = 1; /* boolean */
|
||||
public static final int CTL_P1003_1B_MAPPED_FILES = 2; /* boolean */
|
||||
public static final int CTL_P1003_1B_MEMLOCK = 3; /* boolean */
|
||||
public static final int CTL_P1003_1B_MEMLOCK_RANGE = 4; /* boolean */
|
||||
public static final int CTL_P1003_1B_MEMORY_PROTECTION = 5; /* boolean */
|
||||
public static final int CTL_P1003_1B_MESSAGE_PASSING = 6; /* boolean */
|
||||
public static final int CTL_P1003_1B_PRIORITIZED_IO = 7; /* boolean */
|
||||
public static final int CTL_P1003_1B_PRIORITY_SCHEDULING = 8; /* boolean */
|
||||
public static final int CTL_P1003_1B_REALTIME_SIGNALS = 9; /* boolean */
|
||||
public static final int CTL_P1003_1B_SEMAPHORES = 10; /* boolean */
|
||||
public static final int CTL_P1003_1B_FSYNC = 11; /* boolean */
|
||||
public static final int CTL_P1003_1B_SHARED_MEMORY_OBJECTS = 12; /* boolean */
|
||||
public static final int CTL_P1003_1B_SYNCHRONIZED_IO = 13; /* boolean */
|
||||
public static final int CTL_P1003_1B_TIMERS = 14; /* boolean */
|
||||
public static final int CTL_P1003_1B_AIO_LISTIO_MAX = 15; /* int */
|
||||
public static final int CTL_P1003_1B_AIO_MAX = 16; /* int */
|
||||
public static final int CTL_P1003_1B_AIO_PRIO_DELTA_MAX = 17; /* int */
|
||||
public static final int CTL_P1003_1B_DELAYTIMER_MAX = 18; /* int */
|
||||
public static final int CTL_P1003_1B_MQ_OPEN_MAX = 19; /* int */
|
||||
public static final int CTL_P1003_1B_PAGESIZE = 20; /* int */
|
||||
public static final int CTL_P1003_1B_RTSIG_MAX = 21; /* int */
|
||||
public static final int CTL_P1003_1B_SEM_NSEMS_MAX = 22; /* int */
|
||||
public static final int CTL_P1003_1B_SEM_VALUE_MAX = 23; /* int */
|
||||
public static final int CTL_P1003_1B_SIGQUEUE_MAX = 24; /* int */
|
||||
public static final int CTL_P1003_1B_TIMER_MAX = 25; /* int */
|
||||
public static final int CTL_P1003_1B_MAXID = 26;
|
||||
public static final int F_UNLKSYS = 4;
|
||||
public static final int F_CNVT = 12;
|
||||
public static final int F_SETFD = 2;
|
||||
public static final int F_SETFL = 4;
|
||||
public static final int F_SETLK = 8;
|
||||
public static final int F_SETOWN = 6;
|
||||
public static final int F_RDLCK = 1;
|
||||
public static final int F_WRLCK = 2;
|
||||
public static final int F_SETLKW = 9;
|
||||
public static final int F_GETFD = 1;
|
||||
public static final int F_DUPFD = 0;
|
||||
public static final int O_WRONLY = 1;
|
||||
public static final int F_RSETLKW = 13;
|
||||
public static final int O_RDWR = 2;
|
||||
public static final int F_RGETLK = 10;
|
||||
public static final int O_RDONLY = 0;
|
||||
public static final int F_UNLCK = 3;
|
||||
public static final int F_GETOWN = 5;
|
||||
public static final int F_RSETLK = 11;
|
||||
public static final int F_GETFL = 3;
|
||||
public static final int F_GETLK = 7;
|
||||
}
|
388
src/main/java/org/ibex/nestedvm/util/ELF.java
Normal file
388
src/main/java/org/ibex/nestedvm/util/ELF.java
Normal file
@ -0,0 +1,388 @@
|
||||
// Copyright 2000-2005 the Contributors, as shown in the revision logs.
|
||||
// Licensed under the Apache Public Source License 2.0 ("the License").
|
||||
// You may not use this file except in compliance with the License.
|
||||
|
||||
package org.ibex.nestedvm.util;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class ELF {
|
||||
private static final int ELF_MAGIC = 0x7f454c46; // '\177', 'E', 'L', 'F'
|
||||
|
||||
public static final int ELFCLASSNONE = 0;
|
||||
public static final int ELFCLASS32 = 1;
|
||||
public static final int ELFCLASS64 = 2;
|
||||
|
||||
public static final int ELFDATANONE = 0;
|
||||
public static final int ELFDATA2LSB = 1;
|
||||
public static final int ELFDATA2MSB = 2;
|
||||
|
||||
public static final int SHT_SYMTAB = 2;
|
||||
public static final int SHT_STRTAB = 3;
|
||||
public static final int SHT_NOBITS = 8;
|
||||
|
||||
public static final int SHF_WRITE = 1;
|
||||
public static final int SHF_ALLOC = 2;
|
||||
public static final int SHF_EXECINSTR = 4;
|
||||
|
||||
public static final int PF_X = 0x1;
|
||||
public static final int PF_W = 0x2;
|
||||
public static final int PF_R = 0x4;
|
||||
|
||||
public static final int PT_LOAD = 1;
|
||||
|
||||
public static final short ET_EXEC = 2;
|
||||
public static final short EM_MIPS = 8;
|
||||
|
||||
|
||||
private Seekable data;
|
||||
|
||||
public ELFIdent ident;
|
||||
public ELFHeader header;
|
||||
public PHeader[] pheaders;
|
||||
public SHeader[] sheaders;
|
||||
|
||||
private byte[] stringTable;
|
||||
|
||||
private boolean sectionReaderActive;
|
||||
|
||||
|
||||
private void readFully(byte[] buf) throws IOException {
|
||||
int len = buf.length;
|
||||
int pos = 0;
|
||||
while(len > 0) {
|
||||
int n = data.read(buf,pos,len);
|
||||
if(n == -1) throw new IOException("EOF");
|
||||
pos += n;
|
||||
len -= n;
|
||||
}
|
||||
}
|
||||
|
||||
private int readIntBE() throws IOException {
|
||||
byte[] buf = new byte[4];
|
||||
readFully(buf);
|
||||
return ((buf[0]&0xff)<<24)|((buf[1]&0xff)<<16)|((buf[2]&0xff)<<8)|((buf[3]&0xff)<<0);
|
||||
}
|
||||
private int readInt() throws IOException {
|
||||
int x = readIntBE();
|
||||
if(ident!=null && ident.data == ELFDATA2LSB)
|
||||
x = ((x<<24)&0xff000000) | ((x<<8)&0xff0000) | ((x>>>8)&0xff00) | ((x>>24)&0xff);
|
||||
return x;
|
||||
}
|
||||
|
||||
private short readShortBE() throws IOException {
|
||||
byte[] buf = new byte[2];
|
||||
readFully(buf);
|
||||
return (short)(((buf[0]&0xff)<<8)|((buf[1]&0xff)<<0));
|
||||
}
|
||||
private short readShort() throws IOException {
|
||||
short x = readShortBE();
|
||||
if(ident!=null && ident.data == ELFDATA2LSB)
|
||||
x = (short)((((x<<8)&0xff00) | ((x>>8)&0xff))&0xffff);
|
||||
return x;
|
||||
}
|
||||
|
||||
private byte readByte() throws IOException {
|
||||
byte[] buf = new byte[1];
|
||||
readFully(buf);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
public class ELFIdent {
|
||||
public byte klass;
|
||||
public byte data;
|
||||
public byte osabi;
|
||||
public byte abiversion;
|
||||
|
||||
ELFIdent() throws IOException {
|
||||
if(readIntBE() != ELF_MAGIC) throw new ELFException("Bad Magic");
|
||||
|
||||
klass = readByte();
|
||||
if(klass != ELFCLASS32) throw new ELFException("org.ibex.nestedvm.util.ELF does not suport 64-bit binaries");
|
||||
|
||||
data = readByte();
|
||||
if(data != ELFDATA2LSB && data != ELFDATA2MSB) throw new ELFException("Unknown byte order");
|
||||
|
||||
readByte(); // version
|
||||
osabi = readByte();
|
||||
abiversion = readByte();
|
||||
for(int i=0;i<7;i++) readByte(); // padding
|
||||
}
|
||||
}
|
||||
|
||||
public class ELFHeader {
|
||||
public short type;
|
||||
public short machine;
|
||||
public int version;
|
||||
public int entry;
|
||||
public int phoff;
|
||||
public int shoff;
|
||||
public int flags;
|
||||
public short ehsize;
|
||||
public short phentsize;
|
||||
public short phnum;
|
||||
public short shentsize;
|
||||
public short shnum;
|
||||
public short shstrndx;
|
||||
|
||||
ELFHeader() throws IOException {
|
||||
type = readShort();
|
||||
machine = readShort();
|
||||
version = readInt();
|
||||
if(version != 1) throw new ELFException("version != 1");
|
||||
entry = readInt();
|
||||
phoff = readInt();
|
||||
shoff = readInt();
|
||||
flags = readInt();
|
||||
ehsize = readShort();
|
||||
phentsize = readShort();
|
||||
phnum = readShort();
|
||||
shentsize = readShort();
|
||||
shnum = readShort();
|
||||
shstrndx = readShort();
|
||||
}
|
||||
}
|
||||
|
||||
public class PHeader {
|
||||
public int type;
|
||||
public int offset;
|
||||
public int vaddr;
|
||||
public int paddr;
|
||||
public int filesz;
|
||||
public int memsz;
|
||||
public int flags;
|
||||
public int align;
|
||||
|
||||
PHeader() throws IOException {
|
||||
type = readInt();
|
||||
offset = readInt();
|
||||
vaddr = readInt();
|
||||
paddr = readInt();
|
||||
filesz = readInt();
|
||||
memsz = readInt();
|
||||
flags = readInt();
|
||||
align = readInt();
|
||||
if(filesz > memsz) throw new ELFException("ELF inconsistency: filesz > memsz (" + toHex(filesz) + " > " + toHex(memsz) + ")");
|
||||
}
|
||||
|
||||
public boolean writable() { return (flags & PF_W) != 0; }
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new BufferedInputStream(new SectionInputStream(
|
||||
offset,offset+filesz));
|
||||
}
|
||||
}
|
||||
|
||||
public class SHeader {
|
||||
int nameidx;
|
||||
public String name;
|
||||
public int type;
|
||||
public int flags;
|
||||
public int addr;
|
||||
public int offset;
|
||||
public int size;
|
||||
public int link;
|
||||
public int info;
|
||||
public int addralign;
|
||||
public int entsize;
|
||||
|
||||
SHeader() throws IOException {
|
||||
nameidx = readInt();
|
||||
type = readInt();
|
||||
flags = readInt();
|
||||
addr = readInt();
|
||||
offset = readInt();
|
||||
size = readInt();
|
||||
link = readInt();
|
||||
info = readInt();
|
||||
addralign = readInt();
|
||||
entsize = readInt();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new BufferedInputStream(new SectionInputStream(
|
||||
offset, type == SHT_NOBITS ? 0 : offset+size));
|
||||
}
|
||||
|
||||
public boolean isText() { return name.equals(".text"); }
|
||||
public boolean isData() { return name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"); }
|
||||
public boolean isBSS() { return name.equals(".bss") || name.equals(".sbss"); }
|
||||
}
|
||||
|
||||
public ELF(String file) throws IOException, ELFException { this(new Seekable.File(file,false)); }
|
||||
public ELF(Seekable data) throws IOException, ELFException {
|
||||
this.data = data;
|
||||
ident = new ELFIdent();
|
||||
header = new ELFHeader();
|
||||
pheaders = new PHeader[header.phnum];
|
||||
for(int i=0;i<header.phnum;i++) {
|
||||
data.seek(header.phoff+i*header.phentsize);
|
||||
pheaders[i] = new PHeader();
|
||||
}
|
||||
sheaders = new SHeader[header.shnum];
|
||||
for(int i=0;i<header.shnum;i++) {
|
||||
data.seek(header.shoff+i*header.shentsize);
|
||||
sheaders[i] = new SHeader();
|
||||
}
|
||||
if(header.shstrndx < 0 || header.shstrndx >= 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<header.shnum;i++) {
|
||||
SHeader s = sheaders[i];
|
||||
s.name = getString(s.nameidx);
|
||||
}
|
||||
}
|
||||
|
||||
private String getString(int off) { return getString(off,stringTable); }
|
||||
private String getString(int off,byte[] strtab) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if(off < 0 || off >= strtab.length) return "<invalid strtab entry>";
|
||||
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<sheaders.length;i++)
|
||||
if(sheaders[i].name.equals(name))
|
||||
return sheaders[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
public class ELFException extends IOException { ELFException(String s) { super(s); } }
|
||||
|
||||
private class SectionInputStream extends InputStream {
|
||||
private int pos;
|
||||
private int maxpos;
|
||||
SectionInputStream(int start, int end) throws IOException {
|
||||
if(sectionReaderActive)
|
||||
throw new IOException("Section reader already active");
|
||||
sectionReaderActive = true;
|
||||
pos = start;
|
||||
data.seek(pos);
|
||||
maxpos = end;
|
||||
}
|
||||
|
||||
private int bytesLeft() { return maxpos - pos; }
|
||||
public int read() throws IOException {
|
||||
byte[] buf = new byte[1];
|
||||
return read(buf,0,1) == -1 ? -1 : (buf[0]&0xff);
|
||||
}
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
int n = data.read(b,off,Math.min(len,bytesLeft())); if(n > 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<count;i++) symbols[i] = new Symbol(strtab);
|
||||
}
|
||||
|
||||
public Symbol getSymbol(String name) {
|
||||
Symbol sym = null;
|
||||
for(int i=0;i<symbols.length;i++) {
|
||||
if(symbols[i].name.equals(name)) {
|
||||
if(sym == null)
|
||||
sym = symbols[i];
|
||||
else
|
||||
System.err.println("WARNING: Multiple symbol matches for " + name);
|
||||
}
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
public Symbol getGlobalSymbol(String name) {
|
||||
for(int i=0;i<symbols.length;i++)
|
||||
if(symbols[i].binding == Symbol.STB_GLOBAL && symbols[i].name.equals(name))
|
||||
return symbols[i];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class Symbol {
|
||||
public String name;
|
||||
public int addr;
|
||||
public int size;
|
||||
public byte info;
|
||||
public byte type;
|
||||
public byte binding;
|
||||
public byte other;
|
||||
public short shndx;
|
||||
public SHeader sheader;
|
||||
|
||||
public final static int STT_FUNC = 2;
|
||||
public final static int STB_GLOBAL = 1;
|
||||
|
||||
Symbol(byte[] strtab) throws IOException {
|
||||
name = getString(readInt(),strtab);
|
||||
addr = readInt();
|
||||
size = readInt();
|
||||
info = readByte();
|
||||
type = (byte)(info&0xf);
|
||||
binding = (byte)(info>>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<elf.pheaders.length;i++) {
|
||||
ELF.PHeader ph = elf.pheaders[i];
|
||||
System.out.println("PHeader " + toHex(i));
|
||||
System.out.println("\tOffset: " + ph.offset);
|
||||
System.out.println("\tVaddr: " + toHex(ph.vaddr));
|
||||
System.out.println("\tFile Size: " + ph.filesz);
|
||||
System.out.println("\tMem Size: " + ph.memsz);
|
||||
}
|
||||
for(int i=0;i<elf.sheaders.length;i++) {
|
||||
ELF.SHeader sh = elf.sheaders[i];
|
||||
System.out.println("SHeader " + toHex(i));
|
||||
System.out.println("\tName: " + sh.name);
|
||||
System.out.println("\tOffset: " + sh.offset);
|
||||
System.out.println("\tAddr: " + toHex(sh.addr));
|
||||
System.out.println("\tSize: " + sh.size);
|
||||
System.out.println("\tType: " + toHex(sh.type));
|
||||
}
|
||||
Symtab symtab = elf.getSymtab();
|
||||
if(symtab != null) {
|
||||
System.out.println("Symbol table:");
|
||||
for(int i=0;i<symtab.symbols.length;i++)
|
||||
System.out.println("\t" + symtab.symbols[i].name + " -> " + toHex(symtab.symbols[i].addr));
|
||||
} else {
|
||||
System.out.println("Symbol table: None");
|
||||
}
|
||||
}*/
|
||||
}
|
207
src/main/java/org/ibex/nestedvm/util/InodeCache.java
Normal file
207
src/main/java/org/ibex/nestedvm/util/InodeCache.java
Normal file
@ -0,0 +1,207 @@
|
||||
// Copyright 2000-2005 the Contributors, as shown in the revision logs.
|
||||
// Licensed under the Apache Public Source License 2.0 ("the License").
|
||||
// You may not use this file except in compliance with the License.
|
||||
|
||||
package org.ibex.nestedvm.util;
|
||||
|
||||
// Based on the various org.xwt.util.* classes by Adam Megacz
|
||||
|
||||
public class InodeCache {
|
||||
private static final Object PLACEHOLDER = new Object();
|
||||
private static final short SHORT_PLACEHOLDER = -2;
|
||||
private static final short SHORT_NULL = -1;
|
||||
private static final int LOAD_FACTOR = 2;
|
||||
|
||||
private final int maxSize;
|
||||
private final int totalSlots;
|
||||
private final int maxUsedSlots;
|
||||
|
||||
private final Object[] keys;
|
||||
private final short[] next;
|
||||
private final short[] prev;
|
||||
private final short[] inodes;
|
||||
private final short[] reverse;
|
||||
|
||||
private int size, usedSlots;
|
||||
private short mru, lru;
|
||||
|
||||
public InodeCache() { this(1024); }
|
||||
public InodeCache(int maxSize) {
|
||||
this.maxSize = maxSize;
|
||||
totalSlots = maxSize*LOAD_FACTOR*2 + 3;
|
||||
maxUsedSlots = totalSlots / LOAD_FACTOR;
|
||||
if(totalSlots > Short.MAX_VALUE) throw new IllegalArgumentException("cache size too large");
|
||||
keys = new Object[totalSlots];
|
||||
next = new short[totalSlots];
|
||||
prev = new short[totalSlots];
|
||||
inodes = new short[totalSlots];
|
||||
reverse = new short[totalSlots];
|
||||
clear();
|
||||
}
|
||||
|
||||
private static void fill(Object[] a,Object o) { for(int i=0;i<a.length;i++) a[i] = o; }
|
||||
private static void fill(short[] a, short s) { for(int i=0;i<a.length;i++) a[i] = s; }
|
||||
public final void clear() {
|
||||
size = usedSlots = 0;
|
||||
mru = lru = -1;
|
||||
fill(keys,null);
|
||||
fill(inodes,SHORT_NULL);
|
||||
fill(reverse,SHORT_NULL);
|
||||
}
|
||||
|
||||
public final short get(Object key) {
|
||||
int hc = key.hashCode() & 0x7fffffff;
|
||||
int dest = hc % totalSlots;
|
||||
int odest = dest;
|
||||
int tries = 1;
|
||||
boolean plus = true;
|
||||
Object k;
|
||||
int placeholder = -1;
|
||||
|
||||
while((k = keys[dest]) != null) {
|
||||
if(k == PLACEHOLDER) {
|
||||
if(placeholder == -1) placeholder = dest;
|
||||
} else if(k.equals(key)) {
|
||||
short inode = inodes[dest];
|
||||
if(dest == mru) return inode;
|
||||
if(lru == dest) {
|
||||
lru = next[lru];
|
||||
} else {
|
||||
short p = prev[dest];
|
||||
short n = next[dest];
|
||||
next[p] = n;
|
||||
prev[n] = p;
|
||||
}
|
||||
prev[dest] = mru;
|
||||
next[mru] = (short) dest;
|
||||
mru = (short) dest;
|
||||
return inode;
|
||||
}
|
||||
dest = Math.abs((odest + (plus ? 1 : -1) * tries * tries) % totalSlots);
|
||||
if(!plus) tries++;
|
||||
plus = !plus;
|
||||
}
|
||||
|
||||
// not found
|
||||
int slot;
|
||||
if(placeholder == -1) {
|
||||
// new slot
|
||||
slot = dest;
|
||||
if(usedSlots == maxUsedSlots) {
|
||||
clear();
|
||||
return get(key);
|
||||
}
|
||||
usedSlots++;
|
||||
} else {
|
||||
// reuse a placeholder
|
||||
slot = placeholder;
|
||||
}
|
||||
|
||||
if(size == maxSize) {
|
||||
// cache is full
|
||||
keys[lru] = PLACEHOLDER;
|
||||
inodes[lru] = SHORT_PLACEHOLDER;
|
||||
lru = next[lru];
|
||||
} else {
|
||||
if(size == 0) lru = (short) slot;
|
||||
size++;
|
||||
}
|
||||
|
||||
int inode;
|
||||
OUTER: for(inode = hc & 0x7fff;;inode++) {
|
||||
dest = inode % totalSlots;
|
||||
odest = dest;
|
||||
tries = 1;
|
||||
plus = true;
|
||||
placeholder = -1;
|
||||
int r;
|
||||
while((r = reverse[dest]) != SHORT_NULL) {
|
||||
int i = inodes[r];
|
||||
if(i == SHORT_PLACEHOLDER) {
|
||||
if(placeholder == -1) placeholder = dest;
|
||||
} else if(i == inode) {
|
||||
continue OUTER;
|
||||
}
|
||||
dest = Math.abs((odest + (plus ? 1 : -1) * tries * tries) % totalSlots);
|
||||
if(!plus) tries++;
|
||||
plus = !plus;
|
||||
}
|
||||
// found a free inode
|
||||
if(placeholder != -1) dest = placeholder;
|
||||
break OUTER;
|
||||
}
|
||||
keys[slot] = key;
|
||||
reverse[dest] = (short) slot;
|
||||
inodes[slot] = (short) inode;
|
||||
if(mru != -1) {
|
||||
prev[slot] = mru;
|
||||
next[mru] = (short) slot;
|
||||
}
|
||||
mru = (short) slot;
|
||||
return (short) inode;
|
||||
}
|
||||
|
||||
public Object reverse(short inode) {
|
||||
int dest = inode % totalSlots;
|
||||
int odest = dest;
|
||||
int tries = 1;
|
||||
boolean plus = true;
|
||||
int r;
|
||||
while((r = reverse[dest]) != SHORT_NULL) {
|
||||
if(inodes[r] == inode) return keys[r];
|
||||
dest = Math.abs((odest + (plus ? 1 : -1) * tries * tries) % totalSlots);
|
||||
if(!plus) tries++;
|
||||
plus = !plus;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*private void dump() {
|
||||
System.err.println("Size " + size);
|
||||
System.err.println("UsedSlots " + usedSlots);
|
||||
System.err.println("MRU " + mru);
|
||||
System.err.println("LRU " + lru);
|
||||
if(size == 0) return;
|
||||
for(int i=mru;;i=prev[i]) {
|
||||
System.err.println("" + i + ": " + keys[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<totalSlots;i++) {
|
||||
if(keys[i] == null) freeKeys++;
|
||||
if(keys[i] == PLACEHOLDER) placeholderKeys++;
|
||||
if(reverse[i] == SHORT_NULL) freeReverse++;
|
||||
}
|
||||
System.err.println("Keys: " + freeKeys + "/" + placeholderKeys);
|
||||
System.err.println("Reverse: " + freeReverse);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
InodeCache c = new InodeCache();
|
||||
java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
|
||||
String s;
|
||||
boolean good = false;
|
||||
try {
|
||||
while((s = br.readLine()) != null) {
|
||||
if(s.charAt(0) == '#') {
|
||||
short n = Short.parseShort(s.substring(1));
|
||||
System.err.println("" + n + " -> " + 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();
|
||||
}
|
||||
}*/
|
||||
}
|
241
src/main/java/org/ibex/nestedvm/util/Platform.java
Normal file
241
src/main/java/org/ibex/nestedvm/util/Platform.java
Normal file
@ -0,0 +1,241 @@
|
||||
// Copyright 2000-2005 the Contributors, as shown in the revision logs.
|
||||
// Licensed under the Apache Public Source License 2.0 ("the License").
|
||||
// You may not use this file except in compliance with the License.
|
||||
|
||||
package org.ibex.nestedvm.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
import java.text.DateFormatSymbols;
|
||||
|
||||
/*
|
||||
GCCLASS_HINT: org.ibex.nestedvm.util.Platform.<clinit> org.ibex.nestedvm.util.Platform$Jdk11.<init>
|
||||
GCCLASS_HINT: org.ibex.nestedvm.util.Platform.<clinit> org.ibex.nestedvm.util.Platform$Jdk12.<init>
|
||||
GCCLASS_HINT: org.ibex.nestedvm.util.Platform.<clinit> org.ibex.nestedvm.util.Platform$Jdk13.<init>
|
||||
GCCLASS_HINT: org.ibex.nestedvm.util.Platform.<clinit> org.ibex.nestedvm.util.Platform$Jdk14.<init>
|
||||
*/
|
||||
|
||||
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<zs.length;i++)
|
||||
if(zs[i][0].equals(id))
|
||||
return zs[i][dst ? (showlong ? 3 : 4) : (showlong ? 1 : 2)];
|
||||
StringBuffer sb = new StringBuffer("GMT");
|
||||
int off = tz.getRawOffset() / 1000;
|
||||
if(off < 0) { sb.append("-"); off = -off; }
|
||||
else sb.append("+");
|
||||
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);
|
||||
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<File,Boolean> known = new Hashtable<File,Boolean>();
|
||||
for(int i=0;i<rootProps.length;i++) {
|
||||
String prop = getProperty(rootProps[i]);
|
||||
if(prop == null) continue;
|
||||
for(;;) {
|
||||
String path = prop;
|
||||
int p;
|
||||
if((p = prop.indexOf(File.pathSeparatorChar)) != -1) {
|
||||
path = prop.substring(0,p);
|
||||
prop = prop.substring(p+1);
|
||||
}
|
||||
File root = getRoot(new File(path));
|
||||
//System.err.println(rootProps[i] + ": " + path + " -> " + 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(); }
|
||||
}
|
||||
}
|
182
src/main/java/org/ibex/nestedvm/util/Seekable.java
Normal file
182
src/main/java/org/ibex/nestedvm/util/Seekable.java
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2000-2005 the Contributors, as shown in the revision logs.
|
||||
// Licensed under the Apache Public Source License 2.0 ("the License").
|
||||
// You may not use this file except in compliance with the License.
|
||||
|
||||
package org.ibex.nestedvm.util;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public abstract class Seekable {
|
||||
public abstract int read(byte[] buf, int offset, int length) throws IOException;
|
||||
public abstract int write(byte[] buf, int offset, int length) throws IOException;
|
||||
public abstract int length() throws IOException;
|
||||
public abstract void seek(int pos) throws IOException;
|
||||
public abstract void close() throws IOException;
|
||||
public abstract int pos() throws IOException;
|
||||
|
||||
public void sync() throws IOException {
|
||||
throw new IOException("sync not implemented for " + getClass());
|
||||
}
|
||||
public void resize(long length) throws IOException {
|
||||
throw new IOException("resize not implemented for " + getClass());
|
||||
}
|
||||
/** If pos == 0 and size == 0 lock covers whole file. */
|
||||
public Lock lock(long pos, long size, boolean shared) throws IOException {
|
||||
throw new IOException("lock not implemented for " + getClass());
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
byte[] buf = new byte[1];
|
||||
int n = read(buf,0,1);
|
||||
return n == -1 ? -1 : buf[0]&0xff;
|
||||
}
|
||||
|
||||
public int tryReadFully(byte[] buf, int off, int len) throws IOException {
|
||||
int total = 0;
|
||||
while(len > 0) {
|
||||
int n = read(buf,off,len);
|
||||
if(n == -1) break;
|
||||
off += n;
|
||||
len -= n;
|
||||
total += n;
|
||||
}
|
||||
return total == 0 ? -1 : total;
|
||||
}
|
||||
|
||||
public static class ByteArray extends Seekable {
|
||||
protected byte[] data;
|
||||
protected int pos;
|
||||
private final boolean writable;
|
||||
|
||||
public ByteArray(byte[] data, boolean writable) {
|
||||
this.data = data;
|
||||
this.pos = 0;
|
||||
this.writable = writable;
|
||||
}
|
||||
|
||||
public int read(byte[] buf, int off, int len) {
|
||||
len = Math.min(len,data.length-pos);
|
||||
if(len <= 0) return -1;
|
||||
System.arraycopy(data,pos,buf,off,len);
|
||||
pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
public int write(byte[] buf, int off, int len) throws IOException {
|
||||
if(!writable) throw new IOException("read-only data");
|
||||
len = Math.min(len,data.length-pos);
|
||||
if(len <= 0) throw new IOException("no space");
|
||||
System.arraycopy(buf,off,data,pos,len);
|
||||
pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
public int length() { return data.length; }
|
||||
public int pos() { return pos; }
|
||||
public void seek(int pos) { this.pos = pos; }
|
||||
public void close() { /*noop*/ }
|
||||
}
|
||||
|
||||
public static class File extends Seekable {
|
||||
private final java.io.File file;
|
||||
private final RandomAccessFile raf;
|
||||
|
||||
public File(String fileName) throws IOException { this(fileName,false); }
|
||||
public File(String fileName, boolean writable) throws IOException { this(new java.io.File(fileName),writable,false); }
|
||||
|
||||
public File(java.io.File file, boolean writable, boolean truncate) throws IOException {
|
||||
this.file = file;
|
||||
String mode = writable ? "rw" : "r";
|
||||
raf = new RandomAccessFile(file,mode);
|
||||
if (truncate) Platform.setFileLength(raf, 0);
|
||||
}
|
||||
|
||||
public int read(byte[] buf, int offset, int length) throws IOException { return raf.read(buf,offset,length); }
|
||||
public int write(byte[] buf, int offset, int length) throws IOException { raf.write(buf,offset,length); return length; }
|
||||
public void sync() throws IOException { raf.getFD().sync(); }
|
||||
public void seek(int pos) throws IOException{ raf.seek(pos); }
|
||||
public int pos() throws IOException { return (int) raf.getFilePointer(); }
|
||||
public int length() throws IOException { return (int)raf.length(); }
|
||||
public void close() throws IOException { raf.close(); }
|
||||
public void resize(long length) throws IOException { Platform.setFileLength(raf, (int)length); }
|
||||
public boolean equals(Object o) {
|
||||
return o != null && o instanceof File
|
||||
&& file.equals(((File)o).file);
|
||||
}
|
||||
public Lock lock(long pos, long size, boolean shared)
|
||||
throws IOException {
|
||||
return Platform.lockFile(this, raf, pos, size, shared);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InputStream extends Seekable {
|
||||
private byte[] buffer = new byte[4096];
|
||||
private int bytesRead = 0;
|
||||
private boolean eof = false;
|
||||
private int pos;
|
||||
private java.io.InputStream is;
|
||||
|
||||
public InputStream(java.io.InputStream is) { this.is = is; }
|
||||
|
||||
public int read(byte[] outbuf, int off, int len) throws IOException {
|
||||
if(pos >= bytesRead && !eof) readTo(pos + 1);
|
||||
len = Math.min(len,bytesRead-pos);
|
||||
if(len <= 0) return -1;
|
||||
System.arraycopy(buffer,pos,outbuf,off,len);
|
||||
pos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
private void readTo(int target) throws IOException {
|
||||
if(target >= buffer.length) {
|
||||
byte[] buf2 = new byte[Math.max(buffer.length+Math.min(buffer.length,65536),target)];
|
||||
System.arraycopy(buffer,0,buf2,0,bytesRead);
|
||||
buffer = buf2;
|
||||
}
|
||||
while(bytesRead < target) {
|
||||
int n = is.read(buffer,bytesRead,buffer.length-bytesRead);
|
||||
if(n == -1) {
|
||||
eof = true;
|
||||
break;
|
||||
}
|
||||
bytesRead += n;
|
||||
}
|
||||
}
|
||||
|
||||
public int length() throws IOException {
|
||||
while(!eof) readTo(bytesRead+4096);
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
public int write(byte[] buf, int off, int len) throws IOException { throw new IOException("read-only"); }
|
||||
public void seek(int pos) { this.pos = pos; }
|
||||
public int pos() { return pos; }
|
||||
public void close() throws IOException { is.close(); }
|
||||
}
|
||||
|
||||
public abstract static class Lock {
|
||||
private Object owner = null;
|
||||
|
||||
public abstract Seekable seekable();
|
||||
public abstract boolean isShared();
|
||||
public abstract boolean isValid();
|
||||
public abstract void release() throws IOException;
|
||||
public abstract long position();
|
||||
public abstract long size();
|
||||
|
||||
public void setOwner(Object o) { owner = o; }
|
||||
public Object getOwner() { return owner; }
|
||||
|
||||
public final boolean contains(int start, int len) {
|
||||
return start >= position() && position() + size() >= start + len;
|
||||
}
|
||||
|
||||
public final boolean contained(int start, int len) {
|
||||
return start < position() && position() + size() < start + len;
|
||||
}
|
||||
|
||||
public final boolean overlaps(int start, int len) {
|
||||
return contains(start, len) || contained(start, len);
|
||||
}
|
||||
}
|
||||
}
|
47
src/main/java/org/ibex/nestedvm/util/Sort.java
Normal file
47
src/main/java/org/ibex/nestedvm/util/Sort.java
Normal file
@ -0,0 +1,47 @@
|
||||
package org.ibex.nestedvm.util;
|
||||
|
||||
public final class Sort {
|
||||
private Sort() { }
|
||||
|
||||
public interface Comparable { public int compareTo(Object o); }
|
||||
public interface CompareFunc { public int compare(Object a, Object b); }
|
||||
|
||||
private static final CompareFunc comparableCompareFunc = new CompareFunc() {
|
||||
public int compare(Object a,Object b) { return ((Comparable)a).compareTo(b); }
|
||||
};
|
||||
|
||||
public static void sort(Comparable[] a) { sort(a,comparableCompareFunc); }
|
||||
public static void sort(Object[] a, CompareFunc c) { sort(a,c,0,a.length-1); }
|
||||
|
||||
private static void sort(Object[] a, CompareFunc c, int start, int end) {
|
||||
Object tmp;
|
||||
if(start >= end) return;
|
||||
if(end-start <= 6) {
|
||||
for(int i=start+1;i<=end;i++) {
|
||||
tmp = a[i];
|
||||
int j;
|
||||
for(j=i-1;j>=start;j--) {
|
||||
if(c.compare(a[j],tmp) <= 0) break;
|
||||
a[j+1] = a[j];
|
||||
}
|
||||
a[j+1] = tmp;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Object pivot = a[end];
|
||||
int lo = start - 1;
|
||||
int hi = end;
|
||||
|
||||
do {
|
||||
while((lo < hi) && c.compare(a[++lo],pivot) < 0) { }
|
||||
while((hi > lo) && c.compare(a[--hi],pivot) > 0) { }
|
||||
tmp = a[lo]; a[lo] = a[hi]; a[hi] = tmp;
|
||||
} while(lo < hi);
|
||||
|
||||
tmp = a[lo]; a[lo] = a[end]; a[end] = tmp;
|
||||
|
||||
sort(a, c, start, lo-1);
|
||||
sort(a, c, lo+1, end);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user