Moved NestedVM directly into codebase because tracking the external jar was a PITA

This commit is contained in:
Brendan Robert 2015-09-05 14:27:02 -05:00
parent f7ee8272b5
commit 063ad95325
12 changed files with 6456 additions and 7 deletions

Binary file not shown.

View File

@ -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>

View 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);
}
}

View 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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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;
}

View 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");
}
}*/
}

View 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();
}
}*/
}

View 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(); }
}
}

View 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);
}
}
}

View 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);
}
}