diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 02:38:09 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 02:38:09 -0400 |
| commit | 76d26984a74bfa4983bf891943eb8b6e52e9c653 (patch) | |
| tree | e0a83040566a59973082fbe8b840f0d4e51d1d4f /tools/guest-diag | |
| parent | 5e1caa2fd07a3a98b3fd481c81a5a1f7cce208be (diff) | |
| download | open-iov-76d26984a74bfa4983bf891943eb8b6e52e9c653.tar.gz open-iov-76d26984a74bfa4983bf891943eb8b6e52e9c653.zip | |
guest-diag: bpz13 - dump FUN_003e35f0 clock-arg validation at the failing call
Diffstat (limited to 'tools/guest-diag')
| -rw-r--r-- | tools/guest-diag/bpz13.py | 100 | ||||
| -rwxr-xr-x | tools/guest-diag/push_guest_tools.sh | 1 |
2 files changed, 101 insertions, 0 deletions
diff --git a/tools/guest-diag/bpz13.py b/tools/guest-diag/bpz13.py new file mode 100644 index 0000000..6f2aa8f --- /dev/null +++ b/tools/guest-diag/bpz13.py @@ -0,0 +1,100 @@ +# gdb script: dump FUN_003e35f0 args at the call from FUN_00e0e970 (file +# 0xd0e970 -> call site 0xd0eb65, caller return 0xd0eb6a). +# +# bpz12 named the failing call: FUN_00e0e970 -> FUN_003e35f0 returned +# nonzero (forced to status 1). FUN_003e35f0 is a clock/step calculator +# whose first early returns are: +# if (param_5 < 1) return 1; (param_5 = dev+0xf5c) +# if ((int)param_2[2] < 1) return 1; ... param_2[6], param_2[8], param_2[10] +# This script prints all args + which condition fires. +# +# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/bpz13.py +import gdb +import time + +out = gdb.execute("info proc mappings", to_string=True) +base = None +for line in out.splitlines(): + if "libcuda" in line and "r-xp" in line: + f = line.split() + base = int(f[0], 16) - int(f[3], 16) + break +print("BASE=0x%x" % (base or 0)) +if base is None: + raise SystemExit + +gdb.execute("set pagination off") +gdb.execute("set confirm off") + +ENTRY = base + 0x2e35f0 +CALLER_RET = base + 0xd0eb6a +gdb.execute("break *0x%x" % ENTRY) + +def rd(addr, size, fmt="unsigned int"): + try: + return int(gdb.parse_and_eval("*(%s*)0x%x" % (fmt, addr))) + except Exception: + return None + +t0 = time.time() +for hit in range(200): + try: + gdb.execute("continue") + except gdb.error as e: + print("CONTINUE_END %s" % e) + break + ret = rd(int(gdb.parse_and_eval("$rsp")), 8, "unsigned long") + if ret != CALLER_RET: + print("skip FUN_003e35f0 call from 0x%x (not our caller)" % (ret or 0)) + continue + rdi = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff + rsi = int(gdb.parse_and_eval("$rsi")) & 0xffffffffffffffff + rdx = int(gdb.parse_and_eval("$rdx")) & 0xffffffffffffffff + rcx = int(gdb.parse_and_eval("$rcx")) & 0xffffffffffffffff + r8 = int(gdb.parse_and_eval("$r8d")) & 0xffffffff + r9 = int(gdb.parse_and_eval("$r9")) & 0xffffffffffffffff + print("CALL t=%.3f rdi=0x%x rsi=0x%x rdx=0x%x rcx=0x%x param_5(r8d)=0x%x r9=0x%x" + % (time.time() - t0, rdi, rsi, rdx, rcx, r8, r9)) + print("param_1 dwords:", [rd(rdi + 4 * i, 4) for i in range(8)]) + p2 = [rd(rsi + 4 * i, 4) for i in range(16)] + print("param_2 dwords[0..15]:", p2) + print("param_2 qwords at +0x20,+0x28: 0x%x 0x%x" % + (rd(rsi + 0x20, 8, "unsigned long") or 0xdead, + rd(rsi + 0x28, 8, "unsigned long") or 0xdead)) + print("param_3 dwords[0..3]:", [rd(rdx + 4 * i, 4) for i in range(4)]) + print("param_4 dwords[0..3]:", [rd(rcx + 4 * i, 4) for i in range(4)]) + conds = [] + if r8 < 1: + conds.append("param_5<1") + if (p2[2] or 0) & 0x80000000 or (p2[2] or 0) < 1: + conds.append("(int)param_2[2]<1") + if (p2[3] or 0) & 0x80000000 or (p2[3] or 0) < 1: + conds.append("(int)param_2[3]<1") + if (p2[4] or 0) & 0x80000000 or (p2[4] or 0) < 1: + conds.append("(int)param_2[4]<1") + if (p2[5] or 0) & 0x80000000 or (p2[5] or 0) < 1: + conds.append("(int)param_2[5]<1") + if (p2[6] or 0) & 0x80000000 or (p2[6] or 0) < 1: + conds.append("(int)param_2[6]<1") + if (rd(rsi + 0x20, 8, "unsigned long") or 0) == 0: + conds.append("param_2[+0x20]==0") + if (rd(rsi + 0x28, 8, "unsigned long") or 0) == 0: + conds.append("param_2[+0x28]==0") + if (p2[0xc] or 0) & 0x80000000 or (p2[0xc] or 0) < 1: + conds.append("(int)param_2[0xc]<1") + p3 = rd(rdx, 4) + if p3 is None or p3 < 1: + conds.append("param_3[0]<1") + if (rd(rdx + 4, 4) or 0) < 0: + conds.append("param_3[1]<0") + print("EARLY-RETURN-1 CONDITIONS:", conds or "none") + try: + print(gdb.execute("bt 4", to_string=True)) + except Exception: + pass + break + +try: + gdb.execute("detach") +except Exception: + pass diff --git a/tools/guest-diag/push_guest_tools.sh b/tools/guest-diag/push_guest_tools.sh index 7045c08..df3e64a 100755 --- a/tools/guest-diag/push_guest_tools.sh +++ b/tools/guest-diag/push_guest_tools.sh @@ -40,6 +40,7 @@ push_b64 "$HERE/bpz9.py" /tmp/bpz9.py push_b64 "$HERE/bpz10.py" /tmp/bpz10.py push_b64 "$HERE/bpz11.py" /tmp/bpz11.py push_b64 "$HERE/bpz12.py" /tmp/bpz12.py +push_b64 "$HERE/bpz13.py" /tmp/bpz13.py push_b64 "$HERE/invd.py" /tmp/invd.py push_b64 "$HERE/bpwait.py" /tmp/bpwait.py push_b64 "$HERE/ctx999.py" /tmp/ctx999.py |
