# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2026 Open-IOV contributors # gdb script: at the membar-WAR hook failure, read the device arch/impl and # test the FUN_0035a4d0(0x13, arch, rev) descriptor lookup in-process. # # Run #5: hook idx=3 (FUN_005d7e70) returned 0x3e7; its only 999 source is # `FUN_0035a4d0(0x13, *(u32*)(dev+0xc50), *(u32*)(dev+0xc54)) == 0` or the # ucode load failing. Break on the hook return; when the status is non-zero, # eval the lookup with the live values and scan nearby (arch, rev) pairs. # # Run: sudo gdb -p -batch -x /tmp/bpz6.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") for off in (0x4d20fe, 0x4d2101): gdb.execute("break *0x%x" % (base + off)) f = base + 0x35a4d0 def r64(a): try: return int(gdb.parse_and_eval("*(unsigned long *)0x%x" % a)) & 0xffffffffffffffff except Exception: return None def r32(a): try: return int(gdb.parse_and_eval("*(unsigned int *)0x%x" % a)) & 0xffffffff except Exception: return None def lookup(chip, rev): try: return int(gdb.parse_and_eval( "((void*(*)(long,int,int))0x%x)(0x13,%d,%d)" % (f, chip, rev))) & 0xffffffffffffffff except Exception as e: print(" call_fail chip=0x%x rev=0x%x: %s" % (chip, rev, e)) return None t0 = time.time() for hit in range(40): try: gdb.execute("continue") except gdb.error as e: print("CONTINUE_END %s" % e) break rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff off = rip - base if off == 0x4d20fe: try: rax = int(gdb.parse_and_eval("$rax")) & 0xffffffffffffffff print("CALL t=%.3f target_off=0x%x" % (time.time() - t0, (int(gdb.parse_and_eval( "*(unsigned long *)0x%x" % (rax + 8))) - base) & 0xffffffffffffffff)) except Exception as e: print("call_dump_fail %s" % e) continue rax = int(gdb.parse_and_eval("$rax")) & 0xffffffffffffffff print("RET t=%.3f eax=0x%x" % (time.time() - t0, rax & 0xffffffff)) if (rax & 0xffffffff) == 0: continue try: ctx = int(gdb.parse_and_eval("$rbx")) & 0xffffffffffffffff st = r64(ctx + 0x40) chip = r32(st + 0xc50) rev = r32(st + 0xc54) print("ctx=0x%x state=0x%x state+0xc50=0x%x (arch=0x%x) +0xc54=0x%x" % (ctx, st or 0, r64(st + 0xc50) or 0, chip or 0, rev or 0)) v = lookup(chip, rev) print("lookup(0x13,0x%x,0x%x) = 0x%x" % (chip, rev, v or 0)) if v: print(" desc+0x10=0x%x desc+0x18=0x%x" % (r64(v + 0x10) or 0, r64(v + 0x18) or 0)) print("scan:") for c in (0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x160, 0x170): for rv in range(0, 4): vv = lookup(c, rv) if vv: print(" chip=0x%x rev=0x%x -> 0x%x size=0x%x" % (c, rv, vv, r64(vv + 0x18) or 0)) except Exception as e: print("live_probe_fail %s" % e) break try: gdb.execute("detach") except Exception: pass