A Total Overhaul on the Lunaix's Virtual Memory Model (#26)
[lunaix-os.git] / lunaix-os / scripts / gdb / lunadbg / pte_utils.py
diff --git a/lunaix-os/scripts/gdb/lunadbg/pte_utils.py b/lunaix-os/scripts/gdb/lunadbg/pte_utils.py
new file mode 100644 (file)
index 0000000..051bb48
--- /dev/null
@@ -0,0 +1,98 @@
+from .commands import LunadbgCommand
+from .structs.pagetable import PageTable, PageTableEntry
+from .pp import MyPrettyPrinter
+from gdb import parse_and_eval, lookup_type
+
+class PteInterpreter(LunadbgCommand):
+    def __init__(self) -> None:
+        super().__init__("pte")
+
+        self._parser.description = "Interpret the PTE based on give raw value or ptep"
+        self._parser.add_argument("val")
+        self._parser.add_argument("--va", action='store_true', default=False,
+                                    help="treat the given as virtual address")
+        
+        self._parser.add_argument("--ptep", action='store_true', default=False,
+                                    help="treat the given as ptep")
+        
+        self._parser.add_argument('-l', "--at-level", type=int, default=-1,
+                                    help="translation level that the given virtual address located")
+
+        self._parser.add_argument('-m', "--mnt", default=-1,
+                                    help="vms mount point that the given virtual address located")
+    
+    @staticmethod
+    def print_pte(pp, pte_val, level):
+        pte = PageTableEntry.from_pteval(pte_val, level)
+        pp.print(pte)
+
+    @staticmethod
+    def print_ptep(pp, ptep, level):
+        pte = PageTableEntry(ptep, level)
+        pp.print(pte)
+
+    def on_execute(self, parsed, gdb_args, from_tty):
+        pp     = MyPrettyPrinter()
+
+        val  = int(parse_and_eval(parsed.val))
+        lvl =  parsed.at_level
+        if not parsed.va:
+            PteInterpreter.print_pte(pp, val, lvl)
+            return
+        
+        if not parsed.ptep:
+            ptep = PageTable.mkptep_at(parsed.mnt, val, lvl)
+            PteInterpreter.print_ptep(pp, ptep, lvl)
+            return
+        
+        PteInterpreter.print_ptep(pp, val, lvl)
+
+class PtepInterpreter(LunadbgCommand):
+    def __init__(self) -> None:
+        super().__init__("ptep")
+        
+        self._parser.description = "Manipulate the pte pointer"
+        self._parser.add_argument("ptep")
+        self._parser.add_argument("--pfn", action='store_true', default=False,
+                                    help="get the pfn (relative to mount point) implied by this ptep")
+        
+        self._parser.add_argument("--vfn", action='store_true', default=False,
+                                    help="get the vfn implied by this ptep")
+        
+        self._parser.add_argument("--level", action='store_true', default=False,
+                                    help="estimate the translation level implied by this ptep")
+        
+        self._parser.add_argument("--to-level", type=int, default=None,
+                                    help="convert given ptep to specified level before any other processing")
+        
+        self._parser.add_argument("--sn", action='store_true', default=False,
+                                    help="shift the ptep to next translation level")
+        
+        self._parser.add_argument("--sp", action='store_true', default=False,
+                                    help="shift the ptep to previous translation level")
+        
+
+    def on_execute(self, parsed, gdb_args, from_tty):
+        pp     = MyPrettyPrinter()
+
+        ptep = int(parse_and_eval(parsed.ptep))
+        if parsed.to_level is not None:
+            ptep = PageTable.get_lntep(ptep, parsed.to_level)
+            pp.printf("ptep: 0x%016x", ptep)
+
+        if parsed.pfn:
+            ptep = PageTable.get_pfn(ptep)
+            pp.set_prefix("pfn: ")
+        elif parsed.vfn:
+            ptep = PageTable.get_vfn(ptep)
+            pp.set_prefix("vfn: ")
+        elif parsed.level:
+            l, m = PageTable.ptep_infer_level(ptep)
+            pp.printf("Level %d ptep (mnt=0x%016x, vfn=%d)", l, m, PageTable.get_vfn(ptep))
+            return
+        elif parsed.sn:
+            ptep = PageTable.shift_ptep_nextlevel(ptep)
+        elif parsed.sp:
+            ptep = PageTable.shift_ptep_prevlevel(ptep)
+        
+        pp.printf("0x%016x", ptep)