+from gdb import Type, Value, lookup_type
+from . import KernelStruct
+from ..utils import get_dnode_path
+
+class MemRegion(KernelStruct):
+ def __init__(self, gdb_inferior: Value) -> None:
+ super().__init__(gdb_inferior, MemRegion)
+ self.__attr = self._kstruct["attr"]
+
+ @staticmethod
+ def get_type() -> Type:
+ return lookup_type("struct mm_region").pointer()
+
+ def print_abstract(self, pp, *args):
+ self.print_detailed(pp, *args)
+
+ def print_simple(self, pp, *args):
+ self.print_detailed(pp, *args)
+
+ def print_detailed(self, pp, *args):
+ pp.print( "0x%x...0x%x [0x%x]"%(
+ self._kstruct['start'], self._kstruct['end'],
+ self._kstruct['end'] - self._kstruct['start']))
+
+ pp.printf("attributes: %s (0x%x)", ", ".join([self.get_vmr_kind(), self.get_protection()]), self.__attr)
+
+ file = self._kstruct["mfile"]
+ if file == 0:
+ pp.print("anonymous region")
+ else:
+ pp.print("file mapped:")
+ ppp = pp.next_level()
+ ppp.print("dnode: %s @0x%x"%(get_dnode_path(file["dnode"]), file))
+ ppp.print("range: 0x%x+0x%x"%(self._kstruct["foff"], self._kstruct["flen"]))
+
+ def get_protection(self):
+ attr_str = []
+ if (self.__attr & (1 << 2)):
+ attr_str.append("R")
+ if (self.__attr & (1 << 3)):
+ attr_str.append("W")
+ if (self.__attr & (1 << 4)):
+ attr_str.append("X")
+ return ''.join(attr_str)
+
+ def get_vmr_kind(self):
+ """
+ #define REGION_TYPE_CODE (1 << 16)
+ #define REGION_TYPE_GENERAL (2 << 16)
+ #define REGION_TYPE_HEAP (3 << 16)
+ #define REGION_TYPE_STACK (4 << 16)
+ """
+ types = ["exec", "data", "heap", "stack"]
+ attr = ((self.__attr >> 16) & 0xf) - 1
+ if attr >= len(types):
+ return "unknown kind %d"%attr
+ return types[attr]
+
+
+
\ No newline at end of file