Skip to content

Commit 20518ca

Browse files
committed
Page fault cleanup
1 parent 97aa183 commit 20518ca

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

panda/python/examples/fault.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,23 @@
22

33
panda = Panda(generic="arm")
44
#panda = Panda(generic="i386")
5-
#panda = Panda(generic="x86_64")
5+
#panda = Panda(generic="x86_64") # Infinte faults
66
#panda = Panda(generic="mips64")
77

88
panda.load_plugin("syscalls2", {"load-info": True})
99

10+
paged_in = 0
11+
faulted = 0
12+
faulted_then_resolved = 0
13+
faulted_then_failed = 0
14+
1015
@panda.queue_blocking
1116
def drive():
1217
panda.revert_sync('root')
13-
print(panda.run_serial_cmd("md5sum $(which whoami); find /etc/ | md5sum; apt-get update -yy"))
18+
try:
19+
print(panda.run_serial_cmd("md5sum $(which whoami); find /etc/ | md5sum; timeout 10s apt-get update -yy"))
20+
except Exception as e:
21+
print("EXN:", e)
1422
panda.end_analysis()
1523

1624
last_fault = None
@@ -24,10 +32,14 @@ def fault(panda, cpu, addr, pc):
2432

2533
@panda.ppp("syscalls2", "on_all_sys_enter2")
2634
def all_sys(cpu, pc, call, rp):
35+
if call == panda.ffi.NULL:
36+
print("CALL ISNULL")
37+
return
2738
args = panda.ffi.cast("target_ulong**", rp.args)
39+
asid = panda.current_asid(cpu)
2840

2941
sc_name = panda.ffi.string(call.name).decode() if call.name != panda.ffi.NULL else 'err'
30-
print(f"{pc:#08x} (from block starting at {panda.current_pc(cpu):#08x}): {sc_name}(", end="")
42+
print(f"{pc:#08x} {asid:#08x} (from block starting at {panda.current_pc(cpu):#08x}): {sc_name}(", end="")
3143
if call.nargs == 0:
3244
print(")", end="")
3345

@@ -38,7 +50,7 @@ def all_sys(cpu, pc, call, rp):
3850

3951
if call.argt[i] not in [0x20, 0x21, 0x22]:
4052
val = int(panda.ffi.cast("unsigned int", args[i]))
41-
print(hex(val), end="")
53+
print(hex(val), end=sep)
4254
continue
4355

4456
# It's a pointer type
@@ -47,16 +59,23 @@ def all_sys(cpu, pc, call, rp):
4759
# Probably not a pointer?
4860
print(hex(addr), end="")
4961
else:
62+
global faulted, faulted_then_resolved, faulted_then_failed
5063
try:
5164
s = panda.read_str(cpu, addr)
65+
if addr == last_fault: # faulted before, then resolved
66+
s += f"(PANDA: read now works faulted_then_resolved now {faulted_then_resolved+1})"
67+
faulted_then_resolved += 1
5268
except ValueError:
5369
# This argument can't be read - let's raise a fault on it
54-
if last_fault != addr:
55-
print(f"{addr:#x} => Can't read - INJECT PANDA PAGE FAULT") # newline
70+
if last_fault != addr: # fault on new address
71+
print(f"{addr:#x} => Can't read - INJECT PANDA PAGE FAULT, faulted is now {faulted+1}") # newline
72+
faulted += 1
5673
fault(panda, cpu, addr, pc)
5774
return # Raised a fault, hope it's gonna work
5875
else:
59-
s = "still can't read"
76+
# faulted then failed
77+
faulted_then_failed += 1
78+
s = f"still can't read (faulted_then_failed now {faulted_then_failed+1}"
6079

6180
# No fault
6281
print(f"{addr:#x} => {repr(s)}", end="")
@@ -72,3 +91,5 @@ def all_ret(cpu, pc, call, rp):
7291
# XXX: with TB chaining there's a gap between when the syscall happens and our injected PF is handled
7392
#panda.disable_tb_chaining()
7493
panda.run()
94+
95+
print(f"\nFINISHED!\nTotal of {faulted} faults seen\n\t{faulted_then_resolved} resolved\n\t{faulted_then_failed} failed")

panda/src/panda_api.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,16 +303,21 @@ void panda_page_fault(CPUState* cpu, target_ulong address, target_ulong retaddr)
303303
// instead of restarting the block
304304
env->eip = retaddr;
305305
tlb_fill(cpu, address, MMU_DATA_LOAD, 0, retaddr);
306-
//#elif defined (TARGET_ARM)
307-
// CPUARMState *env = cpu->env_ptr;
308-
// env->pc = retaddr;
309-
// tlb_fill(cpu, address, MMU_DATA_LOAD, 0, retaddr);
306+
#elif defined (TARGET_ARM)
307+
CPUARMState *env = cpu->env_ptr;
308+
if (is_a64(env)) {
309+
env->pc = retaddr; // PC for aarch64
310+
} else {
311+
env->regs[15] = retaddr; // PC for arm32
312+
}
313+
tlb_fill(cpu, address, MMU_DATA_LOAD, 0, retaddr);
310314

311315
#elif defined(TARGET_MIPS)
312316
CPUMIPSState *env = cpu->env_ptr;
313317
env->active_tc.PC = retaddr;
314318
tlb_fill(cpu, address, MMU_DATA_LOAD, 0, retaddr);
315319
#else
316-
printf("ERROR: Unsupported architecture for panda_page_fault\n");
320+
printf("\n\nnERROR: Unsupported architecture for panda_page_fault!!\n\n");
321+
assert(0);
317322
#endif
318323
}

0 commit comments

Comments
 (0)