Unifying the Lunaix's Physical Memory Model (#28)
[lunaix-os.git] / lunaix-os / scripts / gdb / lunadbg / pte_utils.py
1 from .commands import LunadbgCommand
2 from .structs.pagetable import PageTable, PageTableEntry
3 from .pp import MyPrettyPrinter
4 from gdb import parse_and_eval, lookup_type
5
6 class PteInterpreter(LunadbgCommand):
7     def __init__(self) -> None:
8         super().__init__("pte")
9
10         self._parser.description = "Interpret the PTE based on give raw value or ptep"
11         self._parser.add_argument("val")
12         self._parser.add_argument("--va", action='store_true', default=False,
13                                     help="treat the given as virtual address")
14         
15         self._parser.add_argument("--ptep", action='store_true', default=False,
16                                     help="treat the given as ptep")
17         
18         self._parser.add_argument('-l', "--at-level", type=int, default=-1,
19                                     help="translation level that the given virtual address located")
20
21         self._parser.add_argument('-m', "--mnt", default=-1,
22                                     help="vms mount point that the given virtual address located")
23     
24     @staticmethod
25     def print_pte(pp, pte_val, level):
26         pte = PageTableEntry.from_pteval(pte_val, level)
27         pp.print(pte)
28
29     @staticmethod
30     def print_ptep(pp, ptep, level):
31         pte = PageTableEntry(ptep, level)
32         pp.print(pte)
33
34     def on_execute(self, parsed, gdb_args, from_tty):
35         pp     = MyPrettyPrinter()
36
37         val  = int(parse_and_eval(parsed.val))
38         lvl =  parsed.at_level
39         if not parsed.va:
40             PteInterpreter.print_pte(pp, val, lvl)
41             return
42         
43         if not parsed.ptep:
44             ptep = PageTable.mkptep_at(parsed.mnt, val, lvl)
45             PteInterpreter.print_ptep(pp, ptep, lvl)
46             return
47         
48         PteInterpreter.print_ptep(pp, val, lvl)
49
50 class PtepInterpreter(LunadbgCommand):
51     def __init__(self) -> None:
52         super().__init__("ptep")
53         
54         self._parser.description = "Manipulate the pte pointer"
55         self._parser.add_argument("ptep")
56         self._parser.add_argument("--pfn", action='store_true', default=False,
57                                     help="get the pfn (relative to mount point) implied by this ptep")
58         
59         self._parser.add_argument("--vfn", action='store_true', default=False,
60                                     help="get the vfn implied by this ptep")
61         
62         self._parser.add_argument("--level", action='store_true', default=False,
63                                     help="estimate the translation level implied by this ptep")
64         
65         self._parser.add_argument("--to-level", type=int, default=None,
66                                     help="convert given ptep to specified level before any other processing")
67         
68         self._parser.add_argument("--sn", action='store_true', default=False,
69                                     help="shift the ptep to next translation level")
70         
71         self._parser.add_argument("--sp", action='store_true', default=False,
72                                     help="shift the ptep to previous translation level")
73         
74
75     def on_execute(self, parsed, gdb_args, from_tty):
76         pp     = MyPrettyPrinter()
77
78         ptep = int(parse_and_eval(parsed.ptep))
79         if parsed.to_level is not None:
80             ptep = PageTable.get_lntep(ptep, parsed.to_level)
81             pp.printf("ptep: 0x%016x", ptep)
82
83         if parsed.pfn:
84             ptep = PageTable.get_pfn(ptep)
85             pp.set_prefix("pfn: ")
86         elif parsed.vfn:
87             ptep = PageTable.get_vfn(ptep)
88             pp.set_prefix("vfn: ")
89         elif parsed.level:
90             l, m = PageTable.ptep_infer_level(ptep)
91             pp.printf("Level %d ptep (mnt=0x%016x, vfn=%d)", l, m, PageTable.get_vfn(ptep))
92             return
93         elif parsed.sn:
94             ptep = PageTable.shift_ptep_nextlevel(ptep)
95         elif parsed.sp:
96             ptep = PageTable.shift_ptep_prevlevel(ptep)
97         
98         pp.printf("0x%016x", ptep)