From 5e7792c11fcd786bef0d56737d5e43aad877738e Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 7 Feb 2021 23:50:53 -0800 Subject: [PATCH] [scripts] Add GDB j6tw page table walker Added the command "j6tw " which takes any arguments that evaluate to addresses or integers. It displays the full breakdown of the page table walk for the given address, with flags. --- assets/debugging/jsix.elf-gdb.py | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/assets/debugging/jsix.elf-gdb.py b/assets/debugging/jsix.elf-gdb.py index 3619827..ef686cd 100644 --- a/assets/debugging/jsix.elf-gdb.py +++ b/assets/debugging/jsix.elf-gdb.py @@ -56,8 +56,77 @@ class PrintBacktraceCommand(gdb.Command): return +class TableWalkCommand(gdb.Command): + def __init__(self): + super().__init__("j6tw", gdb.COMMAND_DATA) + + def invoke(self, arg, from_tty): + args = gdb.string_to_argv(arg) + if len(args) < 2: + raise Exception("Must be: j6tw ") + + pml4 = int(gdb.parse_and_eval(args[0])) + addr = int(gdb.parse_and_eval(args[1])) + + indices = [ + (addr >> 39) & 0x1ff, + (addr >> 30) & 0x1ff, + (addr >> 21) & 0x1ff, + (addr >> 12) & 0x1ff, + ] + + names = ["PML4", "PDP", "PD", "PT"] + + table_flags = [ + (0x0001, "present"), + (0x0002, "write"), + (0x0004, "user"), + (0x0008, "pwt"), + (0x0010, "pcd"), + (0x0020, "accessed"), + (0x0040, "dirty"), + (0x0080, "largepage"), + (0x0100, "global"), + (0x1080, "pat"), + ((1<<63), "xd"), + ] + + page_flags = [ + (0x0001, "present"), + (0x0002, "write"), + (0x0004, "user"), + (0x0008, "pwt"), + (0x0010, "pcd"), + (0x0020, "accessed"), + (0x0040, "dirty"), + (0x0080, "pat"), + (0x0100, "global"), + ((1<<63), "xd"), + ] + + flagsets = [table_flags, table_flags, table_flags, page_flags] + + table = pml4 + entry = 0 + for i in range(len(indices)): + entry = int(gdb.parse_and_eval(f'((uint64_t*){table})[{indices[i]}]')) + flagset = flagsets[i] + flag_names = " | ".join([f[1] for f in flagset if (entry & f[0]) == f[0]]) + + print(f"{names[i]:>4}: {table:016x}") + print(f" index: {indices[i]:3} {entry:016x}") + print(f" flags: {flag_names}") + + if (entry & 1) == 0 or (i < 3 and (entry & 0x80)): + break + + table = (entry & 0x7ffffffffffffe00) | 0xffffc00000000000 + + + PrintStackCommand() PrintBacktraceCommand() +TableWalkCommand() gdb.execute("target remote :1234") gdb.execute("display/i $rip")