summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/bpz21.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/bpz21.py')
-rw-r--r--tools/guest-diag/bpz21.py64
1 files changed, 64 insertions, 0 deletions
diff --git a/tools/guest-diag/bpz21.py b/tools/guest-diag/bpz21.py
new file mode 100644
index 0000000..f9809a7
--- /dev/null
+++ b/tools/guest-diag/bpz21.py
@@ -0,0 +1,64 @@
+# gdb script: dump param_2[] at FUN_00337e60 entry when called from
+# FUN_00550ff0 (file 0x450ff0). bpz20 showed FUN_00550ff0 -> FUN_00337e60
+# overwrites ds+0xe94 with param_2[0x23]; on the host that is 0x18 (24 TPC).
+# Launch under gdb (device init runs during cuInit).
+import gdb
+import time
+
+gdb.execute("set pagination off")
+gdb.execute("set confirm off")
+gdb.execute("set environment CDT_PAUSE=60")
+gdb.execute("set environment CDT_HOLD=900")
+gdb.execute("catch load libcuda.so")
+gdb.execute("run")
+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
+
+def rd(addr, n=4, fmt="unsigned int"):
+ try:
+ return int(gdb.parse_and_eval("*(%s*)0x%x" % (fmt, addr))) & ((1 << (8 * n)) - 1)
+ except Exception:
+ return None
+
+CALL_LO, CALL_HI = base + 0x450ff0, base + 0x451770
+gdb.execute("break *0x%x" % (base + 0x237e60))
+gdb.execute("break *0x%x" % (base + 0x2e3e80))
+CALLER_RET = base + 0xd0eae1
+t0 = time.time()
+for hit in range(400):
+ try:
+ gdb.execute("continue")
+ except gdb.error as e:
+ print("CONTINUE_END %s" % e)
+ break
+ rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff
+ if rip == base + 0x2e3e80:
+ ret = rd(int(gdb.parse_and_eval("$rsp")), 8, "unsigned long")
+ if ret != CALLER_RET:
+ continue
+ rdi = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff
+ ds = rd(rdi + 0x40, 8, "unsigned long")
+ print("TERMINATOR t=%.3f ds=0x%x e94=0x%x" % (time.time() - t0, ds or 0, rd(ds + 0xe94) or 0))
+ break
+ ret = rd(int(gdb.parse_and_eval("$rsp")), 8, "unsigned long")
+ if not (CALL_LO <= ret < CALL_HI):
+ continue
+ rsi = int(gdb.parse_and_eval("$rsi")) & 0xffffffffffffffff
+ d = [rd(rsi + 4 * k) for k in range(0x30)]
+ print("FUN_00550ff0->FUN_00337e60 t=%.3f caller=+0x%x p2[0x23]=0x%x" %
+ (time.time() - t0, ret - base, d[0x23] or 0))
+ print(" dwords[0..0x30]:", [hex(x or 0) for x in d])
+ break
+
+try:
+ gdb.execute("detach")
+except Exception:
+ pass