m1n1/proxyclient/find_regs.py
Hector Martin 30e14f1a0b find_regs: Modular version of find_all_regs.py
Signed-off-by: Hector Martin <marcan@marcan.st>
2021-05-22 03:21:01 +09:00

98 lines
2.6 KiB
Python

#!/usr/bin/python3
import asm, struct
import sysreg
from proxyutils import GuardedHeap
def _all():
for op1 in range(1 << 3):
for CRn in (0b1011, 0b1111):
for CRm in range(1 << 4):
for op2 in range(1 << 3):
yield 3, op1, CRn, CRm, op2
dynamic_regs = [
sysreg.CNTVCT_ALIAS_EL0,
sysreg.CNTPCT_ALIAS_EL0,
]
impdef_regs = list(_all())
static_regs = [i for i in _all() if i not in dynamic_regs]
def find_regs(u, regs=None, block=1024, call=None, values=True):
if regs is None:
regs = impdef_regs
p = u.proxy
iface = u.iface
data_len = 8 * block
with GuardedHeap(u.heap) as heap:
data_buffer = heap.malloc(data_len)
template = asm.ARMAsm("""
mov x2, x0
mrs x2, s3_0_c0_c0_0
str x2, [x1], #8
""", 0x1000)
mov, mrs, st = struct.unpack("3I", template.data)
data = []
BAD = 0xacce5515abad1dea
OOPS = 0xdeadc0dedeadc0de
rblock = []
iregs = iter(regs)
while True:
insns = []
bregs = []
for i in iregs:
op0, op1, CRn, CRm, op2 = enc = sysreg.sysreg_parse(i)
bregs.append(enc)
assert op0 == 3
insns.extend((mov, mrs | (op1 << 16) | (CRn << 12) | (CRm << 8) | (op2 << 5), st))
if len(bregs) >= block:
break
if not bregs:
break
p.memset64(data_buffer, OOPS, data_len)
u.exec(insns, BAD, data_buffer, call=call, silent=True, ignore_exceptions=True)
data = iface.readmem(data_buffer, 8 * len(bregs))
for reg, val in zip(bregs, struct.unpack(f"<{len(bregs)}Q", data)):
if val == OOPS:
raise Exception(f"Failed to execute reg-finder code at {reg}")
if val != BAD:
if values:
yield reg, val
else:
yield reg
if __name__ == "__main__":
from setup import *
p.iodev_set_usage(IODEV.FB, 0)
for reg, val in find_regs(u):
print(f"{sysreg_name(reg)} ({', '.join(map(str, reg))}) = 0x{val:x}")
try:
u.msr(reg, v, silent=True)
except:
print(" - READONLY")
try:
u.mrs(reg, silent=True, call="el1")
except:
print(" - ### EL2 only ###")
try:
u.mrs(reg, silent=True, call="el0")
except:
pass
else:
print(" - *** EL0 accessible ***")