xref: /xnu-8796.121.2/tools/lldbmacros/kmemory/vm.py (revision c54f35ca767986246321eb901baf8f5ff7923f6a)
1*c54f35caSApple OSS Distributionsfrom __future__ import absolute_import, division, print_function
2*c54f35caSApple OSS Distributions
3*c54f35caSApple OSS Distributionsfrom builtins import range
4*c54f35caSApple OSS Distributionsfrom builtins import object
5*c54f35caSApple OSS Distributions
6*c54f35caSApple OSS Distributionsimport six
7*c54f35caSApple OSS Distributionsimport struct
8*c54f35caSApple OSS Distributions
9*c54f35caSApple OSS Distributionsfrom core import (
10*c54f35caSApple OSS Distributions    gettype,
11*c54f35caSApple OSS Distributions    xnu_format,
12*c54f35caSApple OSS Distributions    SBValueFormatter,
13*c54f35caSApple OSS Distributions)
14*c54f35caSApple OSS Distributionsfrom core.collections import (
15*c54f35caSApple OSS Distributions    RB_HEAD,
16*c54f35caSApple OSS Distributions)
17*c54f35caSApple OSS Distributions
18*c54f35caSApple OSS Distributionsfrom .kmem   import MemoryRange
19*c54f35caSApple OSS Distributionsfrom .btlog  import BTLog, BTLibrary
20*c54f35caSApple OSS Distributionsfrom .whatis import *
21*c54f35caSApple OSS Distributions
22*c54f35caSApple OSS Distributions
23*c54f35caSApple OSS Distributions@SBValueFormatter.converter("vm_prot")
24*c54f35caSApple OSS Distributionsdef vm_prot_converter(prot):
25*c54f35caSApple OSS Distributions    PROT_STR = "-rw?x"
26*c54f35caSApple OSS Distributions    return PROT_STR[prot & 1] + PROT_STR[prot & 2] + PROT_STR[prot & 4]
27*c54f35caSApple OSS Distributions
28*c54f35caSApple OSS Distributions
29*c54f35caSApple OSS Distributionsclass VMMap(object):
30*c54f35caSApple OSS Distributions    """ Helper class to manipulate a vm_map_t """
31*c54f35caSApple OSS Distributions
32*c54f35caSApple OSS Distributions    def __init__(self, vm_map):
33*c54f35caSApple OSS Distributions        self.sbv = vm_map
34*c54f35caSApple OSS Distributions        self.rb  = RB_HEAD(
35*c54f35caSApple OSS Distributions            vm_map.chkGetValueForExpressionPath(".hdr.rb_head_store"),
36*c54f35caSApple OSS Distributions            "entry",
37*c54f35caSApple OSS Distributions            self.entry_compare
38*c54f35caSApple OSS Distributions        )
39*c54f35caSApple OSS Distributions
40*c54f35caSApple OSS Distributions        vme_type = gettype('struct vm_map_entry')
41*c54f35caSApple OSS Distributions        self.to_entry = vme_type.xContainerOfTransform('store')
42*c54f35caSApple OSS Distributions
43*c54f35caSApple OSS Distributions    def entry_compare(self, rb_entry, address):
44*c54f35caSApple OSS Distributions        vme = self.to_entry(rb_entry)
45*c54f35caSApple OSS Distributions
46*c54f35caSApple OSS Distributions        if vme.xGetScalarByPath(".links.end") <= address:
47*c54f35caSApple OSS Distributions            return 1
48*c54f35caSApple OSS Distributions        if address < vme.xGetScalarByPath(".links.start"):
49*c54f35caSApple OSS Distributions            return -1
50*c54f35caSApple OSS Distributions        return 0
51*c54f35caSApple OSS Distributions
52*c54f35caSApple OSS Distributions    def find(self, address):
53*c54f35caSApple OSS Distributions        ent = self.rb.find(address)
54*c54f35caSApple OSS Distributions        return self.to_entry(ent) if ent else None
55*c54f35caSApple OSS Distributions
56*c54f35caSApple OSS Distributions    def describe(self, verbose=False):
57*c54f35caSApple OSS Distributions        fmt = (
58*c54f35caSApple OSS Distributions            "VM Map Info\n"
59*c54f35caSApple OSS Distributions            " vm map               : {&v:#x} \n"
60*c54f35caSApple OSS Distributions            " pmap                 : {$v.pmap:#x} \n"
61*c54f35caSApple OSS Distributions            " vm size              : {$v.size|human_size} ({$v.size:,d} bytes) \n"
62*c54f35caSApple OSS Distributions            " entries              : {$v.hdr.nentries} \n"
63*c54f35caSApple OSS Distributions            " map range            : "
64*c54f35caSApple OSS Distributions                "{$v.hdr.links.start:#x} - {$v.hdr.links.end:#x}\n"
65*c54f35caSApple OSS Distributions            " map pgshift          : {$v.hdr.page_shift}\n"
66*c54f35caSApple OSS Distributions        )
67*c54f35caSApple OSS Distributions        print(xnu_format(fmt, self, v=self.sbv))
68*c54f35caSApple OSS Distributions
69*c54f35caSApple OSS Distributions
70*c54f35caSApple OSS Distributionsclass VMMapEntry(MemoryObject):
71*c54f35caSApple OSS Distributions    """ Memory Object for a kernel map memory entry """
72*c54f35caSApple OSS Distributions
73*c54f35caSApple OSS Distributions    MO_KIND = "kernel map entry"
74*c54f35caSApple OSS Distributions
75*c54f35caSApple OSS Distributions    def __init__(self, kmem, address, vm_map):
76*c54f35caSApple OSS Distributions        super(VMMapEntry, self).__init__(kmem, address)
77*c54f35caSApple OSS Distributions        self.vm_map = vm_map
78*c54f35caSApple OSS Distributions        self.sbv    = vm_map.find(address)
79*c54f35caSApple OSS Distributions
80*c54f35caSApple OSS Distributions    @property
81*c54f35caSApple OSS Distributions    def object_range(self):
82*c54f35caSApple OSS Distributions        sbv = self.sbv
83*c54f35caSApple OSS Distributions        if sbv:
84*c54f35caSApple OSS Distributions            return MemoryRange(
85*c54f35caSApple OSS Distributions                sbv.xGetScalarByPath('.links.start'),
86*c54f35caSApple OSS Distributions                sbv.xGetScalarByPath('.links.end')
87*c54f35caSApple OSS Distributions            )
88*c54f35caSApple OSS Distributions
89*c54f35caSApple OSS Distributions        base = self.address & ~self.kmem.page_mask
90*c54f35caSApple OSS Distributions        return MemoryRange(base, base + self.kmem.page_size)
91*c54f35caSApple OSS Distributions
92*c54f35caSApple OSS Distributions    @property
93*c54f35caSApple OSS Distributions    def vme_offset(self):
94*c54f35caSApple OSS Distributions        return self.sbv.xGetScalarByName('vme_offset') << 12
95*c54f35caSApple OSS Distributions
96*c54f35caSApple OSS Distributions    @property
97*c54f35caSApple OSS Distributions    def vme_object_type(self):
98*c54f35caSApple OSS Distributions        sbv = self.sbv
99*c54f35caSApple OSS Distributions        if sbv.xGetScalarByName('is_sub_map'):
100*c54f35caSApple OSS Distributions            return "submap"
101*c54f35caSApple OSS Distributions        if sbv.xGetScalarByName('vme_kernel_object'):
102*c54f35caSApple OSS Distributions            return "kobject"
103*c54f35caSApple OSS Distributions        return "vm object"
104*c54f35caSApple OSS Distributions
105*c54f35caSApple OSS Distributions    @property
106*c54f35caSApple OSS Distributions    def vme_object(self):
107*c54f35caSApple OSS Distributions        kmem = self.kmem
108*c54f35caSApple OSS Distributions        sbv  = self.sbv
109*c54f35caSApple OSS Distributions
110*c54f35caSApple OSS Distributions        if sbv.xGetScalarByName('is_sub_map'):
111*c54f35caSApple OSS Distributions            addr = sbv.xGetScalarByName('vme_submap') << 2
112*c54f35caSApple OSS Distributions            return (addr, kmem.vm_map_type)
113*c54f35caSApple OSS Distributions
114*c54f35caSApple OSS Distributions        if sbv.xGetScalarByName('vme_kernel_object'):
115*c54f35caSApple OSS Distributions            return (kmem.vm_kobject.GetLoadAddress(), kmem.vmo_type)
116*c54f35caSApple OSS Distributions
117*c54f35caSApple OSS Distributions        packed = sbv.xGetScalarByName('vme_object_or_delta')
118*c54f35caSApple OSS Distributions        addr   = kmem.vm_page_packing.unpack(packed)
119*c54f35caSApple OSS Distributions        return (addr, kmem.vmo_type)
120*c54f35caSApple OSS Distributions
121*c54f35caSApple OSS Distributions    @property
122*c54f35caSApple OSS Distributions    def pages(self):
123*c54f35caSApple OSS Distributions        return self.object_range.size >> self.kmem.page_shift
124*c54f35caSApple OSS Distributions
125*c54f35caSApple OSS Distributions    def describe(self, verbose=False):
126*c54f35caSApple OSS Distributions
127*c54f35caSApple OSS Distributions        self.vm_map.describe()
128*c54f35caSApple OSS Distributions
129*c54f35caSApple OSS Distributions        if not self.sbv:
130*c54f35caSApple OSS Distributions            fmt = (
131*c54f35caSApple OSS Distributions                "Kernel Map Entry Info\n"
132*c54f35caSApple OSS Distributions                " No memory mapped at this address\n"
133*c54f35caSApple OSS Distributions            )
134*c54f35caSApple OSS Distributions            print(xnu_format(fmt))
135*c54f35caSApple OSS Distributions            return
136*c54f35caSApple OSS Distributions
137*c54f35caSApple OSS Distributions        fmt = (
138*c54f35caSApple OSS Distributions            "VM Map Entry Info\n"
139*c54f35caSApple OSS Distributions            " vm entry             : {&v:#x}\n"
140*c54f35caSApple OSS Distributions            " start / end          : "
141*c54f35caSApple OSS Distributions                "{$v.links.start:#x} - {$v.links.end:#x} "
142*c54f35caSApple OSS Distributions                "({0.pages:,d} pages)\n"
143*c54f35caSApple OSS Distributions            " vm tag               : {$v.vme_alias|vm_kern_tag}\n"
144*c54f35caSApple OSS Distributions            " vm range id          : {range_id}\n"
145*c54f35caSApple OSS Distributions            " protection           : "
146*c54f35caSApple OSS Distributions                "{$v.protection|vm_prot}/{$v.max_protection|vm_prot}\n"
147*c54f35caSApple OSS Distributions            " vm object            : "
148*c54f35caSApple OSS Distributions                "{0.vme_object_type} ({0.vme_object[0]:#x})\n"
149*c54f35caSApple OSS Distributions            " entry offset         : {0.vme_offset:#x}\n"
150*c54f35caSApple OSS Distributions        )
151*c54f35caSApple OSS Distributions        print(xnu_format(fmt, self, v=self.sbv,
152*c54f35caSApple OSS Distributions            range_id=next(
153*c54f35caSApple OSS Distributions                i
154*c54f35caSApple OSS Distributions                for i, r in enumerate(self.kmem.kmem_ranges)
155*c54f35caSApple OSS Distributions                if r.contains(self.address)
156*c54f35caSApple OSS Distributions            )
157*c54f35caSApple OSS Distributions        ))
158*c54f35caSApple OSS Distributions
159*c54f35caSApple OSS Distributions
160*c54f35caSApple OSS Distributions@whatis_provider
161*c54f35caSApple OSS Distributionsclass KernelMapWhatisProvider(WhatisProvider):
162*c54f35caSApple OSS Distributions    """
163*c54f35caSApple OSS Distributions    Whatis Provider for the kernel map ranges
164*c54f35caSApple OSS Distributions    """
165*c54f35caSApple OSS Distributions
166*c54f35caSApple OSS Distributions    def claims(self, address):
167*c54f35caSApple OSS Distributions        return any(r.contains(address) for r in self.kmem.kmem_ranges)
168*c54f35caSApple OSS Distributions
169*c54f35caSApple OSS Distributions    def lookup(self, address):
170*c54f35caSApple OSS Distributions        return VMMapEntry(self.kmem, address, VMMap(self.kmem.kernel_map))
171*c54f35caSApple OSS Distributions
172*c54f35caSApple OSS Distributions
173*c54f35caSApple OSS Distributions__all__ = [
174*c54f35caSApple OSS Distributions    VMMap.__name__,
175*c54f35caSApple OSS Distributions    VMMapEntry.__name__,
176*c54f35caSApple OSS Distributions    KernelMapWhatisProvider.__name__,
177*c54f35caSApple OSS Distributions]
178