#!/usr/bin/env python3 # sem_slots.py - read or write the per-channel u32 completion counters of a # guest process (verification and fallback for the host's counter publish). # # Usage: # sudo python3 sem_slots.py [count] # read # sudo python3 sem_slots.py [count] --write # write # # The slots are 16 bytes apart (one u32 per channel). Reading needs pagemap/ # mem access as root; writing uses /proc//mem and mirrors the gdb poke # used in earlier sessions (e.g. --write 1 to arm every waiter). import os import sys def main(): if len(sys.argv) < 3: print(__doc__) return 1 pid = int(sys.argv[1]) first = int(sys.argv[2], 16) count = 20 write_val = None i = 3 while i < len(sys.argv): if sys.argv[i] == '--write': write_val = int(sys.argv[i + 1], 0) i += 2 continue count = int(sys.argv[i], 0) i += 1 flags = os.O_RDWR if write_val is not None else os.O_RDONLY mem = os.open('/proc/%d/mem' % pid, flags) try: for n in range(count): va = first + n * 16 if write_val is not None: os.pwrite(mem, write_val.to_bytes(4, 'little'), va) print('idx=%d VA=0x%x written=%u' % (n, va, write_val)) else: v = int.from_bytes(os.pread(mem, 4, va), 'little') print('idx=%d VA=0x%x val=%u' % (n, va, v)) finally: os.close(mem) return 0 if __name__ == '__main__': sys.exit(main())