Commit b5f17c3b authored by George Hotz's avatar George Hotz

write syscall handler in mips

parent a2315619
...@@ -29,8 +29,12 @@ contract MIPS { ...@@ -29,8 +29,12 @@ contract MIPS {
uint32 constant public REG_PC = REG_OFFSET + 0x20*4; uint32 constant public REG_PC = REG_OFFSET + 0x20*4;
uint32 constant public REG_HI = REG_OFFSET + 0x21*4; uint32 constant public REG_HI = REG_OFFSET + 0x21*4;
uint32 constant public REG_LO = REG_OFFSET + 0x22*4; uint32 constant public REG_LO = REG_OFFSET + 0x22*4;
uint32 constant public REG_HEAP = REG_OFFSET + 0x23*4;
uint64 constant public STORE_LINK = 0x100000000; uint64 constant public STORE_LINK = 0x100000000;
uint32 constant public HEAP_START = 0x20000000;
uint32 constant public BRK_START = 0x40000000;
constructor(IMIPSMemory _m) { constructor(IMIPSMemory _m) {
m = _m; m = _m;
} }
...@@ -66,6 +70,34 @@ contract MIPS { ...@@ -66,6 +70,34 @@ contract MIPS {
return stepNextPC(stateHash, pc, pc+4); return stepNextPC(stateHash, pc, pc+4);
} }
function handleSyscall(bytes32 stateHash) public view returns (bytes32) {
uint32 syscall_no = m.ReadMemory(stateHash, REG_OFFSET+2*4);
uint32 v0;
if (syscall_no == 4090) {
// mmap
uint32 a0 = m.ReadMemory(stateHash, REG_OFFSET+4*4);
if (a0 == 0) {
uint32 sz = m.ReadMemory(stateHash, REG_OFFSET+5*4);
uint32 hr = m.ReadMemory(stateHash, REG_HEAP);
v0 = HEAP_START + hr;
stateHash = m.WriteMemory(stateHash, REG_HEAP, hr+sz);
} else {
v0 = a0;
}
} else if (syscall_no == 4045) {
// brk
v0 = BRK_START;
} else if (syscall_no == 4120) {
// clone (not supported)
v0 = 1;
}
stateHash = m.WriteMemory(stateHash, REG_OFFSET+2*4, v0);
stateHash = m.WriteMemory(stateHash, REG_OFFSET+7*4, 0);
return stateHash;
}
// TODO: test ll and sc // TODO: test ll and sc
function stepNextPC(bytes32 stateHash, uint32 pc, uint64 nextPC) public view returns (bytes32) { function stepNextPC(bytes32 stateHash, uint32 pc, uint64 nextPC) public view returns (bytes32) {
uint32 insn = m.ReadMemory(stateHash, pc); uint32 insn = m.ReadMemory(stateHash, pc);
...@@ -162,6 +194,12 @@ contract MIPS { ...@@ -162,6 +194,12 @@ contract MIPS {
return stepNextPC(stateHash, uint32(nextPC), val | (func == 9 ? STORE_LINK : 0)); return stepNextPC(stateHash, uint32(nextPC), val | (func == 9 ? STORE_LINK : 0));
} }
// syscall (can read and write)
if (opcode == 0 && func == 0xC) {
//revert("unhandled syscall");
stateHash = handleSyscall(stateHash);
}
// lo and hi registers // lo and hi registers
// can write back // can write back
if (opcode == 0) { if (opcode == 0) {
...@@ -195,7 +233,6 @@ contract MIPS { ...@@ -195,7 +233,6 @@ contract MIPS {
} }
} }
// write back // write back
if (storeAddr != REG_ZERO) { if (storeAddr != REG_ZERO) {
stateHash = m.WriteMemory(stateHash, storeAddr, val); stateHash = m.WriteMemory(stateHash, storeAddr, val);
...@@ -207,10 +244,6 @@ contract MIPS { ...@@ -207,10 +244,6 @@ contract MIPS {
stateHash = m.WriteMemory(stateHash, REG_PC, uint32(nextPC)); stateHash = m.WriteMemory(stateHash, REG_PC, uint32(nextPC));
if (opcode == 0 && func == 0xC) {
revert("unhandled syscall");
}
return stateHash; return stateHash;
} }
......
...@@ -21,7 +21,6 @@ def hook_interrupt(uc, intno, user_data): ...@@ -21,7 +21,6 @@ def hook_interrupt(uc, intno, user_data):
raise unicorn.UcError(0) raise unicorn.UcError(0)
syscall_no = uc.reg_read(UC_MIPS_REG_V0) syscall_no = uc.reg_read(UC_MIPS_REG_V0)
uc.reg_write(UC_MIPS_REG_A3, 0)
v0 = 0 v0 = 0
if syscall_no == 4020: if syscall_no == 4020:
...@@ -51,7 +50,9 @@ def hook_interrupt(uc, intno, user_data): ...@@ -51,7 +50,9 @@ def hook_interrupt(uc, intno, user_data):
elif syscall_no == 4120: elif syscall_no == 4120:
v0 = 1 v0 = 1
print("clone not supported") print("clone not supported")
uc.reg_write(UC_MIPS_REG_V0, v0) uc.reg_write(UC_MIPS_REG_V0, v0)
uc.reg_write(UC_MIPS_REG_A3, 0)
mu.hook_add(UC_HOOK_INTR, hook_interrupt) mu.hook_add(UC_HOOK_INTR, hook_interrupt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment