def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: for tname in self.args.type: type_ = util.get_valid_type_by_name(self, tname) yield sdb.create_object('size_t', sdb.type_canonicalize_size(type_)) for obj in objs: yield sdb.create_object('size_t', sdb.type_canonicalize_size(obj.type_))
def walk(self, obj: drgn.Object) -> Iterable[drgn.Object]: offset = int(obj.list_offset) first_node = obj.list_head.address_of_() node = first_node.next while node != first_node: yield sdb.create_object("void *", int(node) - offset) node = node.next
def _call_one(self, obj: drgn.Object) -> Iterable[drgn.Object]: try: lhs = eval(self.lhs_code, {'__builtins__': None}, {'obj': obj}) rhs = eval(self.rhs_code, {'__builtins__': None}, {'obj': obj}) if not isinstance(lhs, drgn.Object): raise sdb.CommandInvalidInputError( self.name, "left hand side has unsupported type ({})".format( type(lhs).__name__)) if isinstance(rhs, str): lhs = lhs.string_().decode("utf-8") elif isinstance(rhs, int): rhs = sdb.create_object(lhs.type_, rhs) elif isinstance(rhs, bool): pass elif isinstance(rhs, drgn.Object): pass else: raise sdb.CommandInvalidInputError( self.name, "right hand side has unsupported type ({})".format( type(rhs).__name__)) if eval("lhs {} rhs".format(self.compare), {'__builtins__': None}, { 'lhs': lhs, 'rhs': rhs }): yield obj except (AttributeError, TypeError, ValueError) as err: raise sdb.CommandError(self.name, str(err))
def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: result = 0 for obj in objs: type_ = sdb.type_canonicalize(obj.type_) if type_.kind != drgn.TypeKind.INT and type_.kind != drgn.TypeKind.POINTER: raise sdb.CommandError( self.name, f"'{type_.type_name()}' is not an integer type") result += int(obj.value_()) yield sdb.create_object('uint64_t', result)
def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: for obj in objs: yield obj for addr in self.args.addrs: try: value_ = int(addr, 0) except ValueError: raise sdb.CommandInvalidInputError(self.name, addr) yield sdb.create_object("void *", value_)
def _helper(self, node: drgn.Object, offset: int) -> Iterable[drgn.Object]: if sdb.is_null(node): return lchild = node.avl_child[0] yield from self._helper(lchild, offset) obj = sdb.create_object("void *", int(node) - offset) yield obj rchild = node.avl_child[1] yield from self._helper(rchild, offset)
def sum_histograms( metaslabs: Iterable[drgn.Object]) -> Tuple[drgn.Object, int]: shift = -1 length = 1 first_time = True histsum: List[int] = [] for msp in metaslabs: if msp.ms_sm == sdb.get_typed_null(msp.ms_sm.type_): continue histogram = msp.ms_sm.sm_phys.smp_histogram if first_time: shift = int(msp.ms_sm.sm_shift) length = len(histogram) histsum = [0] * length assert length == len(histogram) assert shift == int(msp.ms_sm.sm_shift) for (bucket, value) in enumerate(histogram): histsum[bucket] += int(value) first_time = False return sdb.create_object(f'uint64_t[{length}]', histsum), shift
def for_each_onslab_object_in_slab(slab: drgn.Object) -> Iterable[drgn.Object]: assert sdb.type_canonical_name(slab.type_) == 'struct spl_kmem_slab *' cache = slab.sks_cache sks_size = spl_aligned_slab_size(cache) spl_obj_size = spl_aligned_obj_size(cache) for i in range(slab.sks_objs.value_()): obj = sdb.create_object('void *', slab.value_() + sks_size + (i * spl_obj_size)) # # If the sko_list of the object is empty, it means that # this object is not part of the slab's internal free list # and therefore it is allocated. NOTE: sko_list in the # actual code is not a list, but a link on a list. Thus, # the check below is not checking whether the "object # list" is empty for this slab, but rather whether the # link is part of any list. # sko = sko_from_obj(cache, obj) assert sko.sko_magic.value_() == 0x20202020 # SKO_MAGIC if linked_lists.is_list_empty(sko.sko_list): yield obj
def _val(self, start: int, idx: int) -> drgn.Object: location = start + (self.elem_size * idx) return sdb.create_object("void *", location)
def sko_from_obj(cache: drgn.Object, obj: drgn.Object) -> drgn.Object: assert sdb.type_canonical_name(cache.type_) == 'struct spl_kmem_cache *' cache_obj_align = cache.skc_obj_align.value_() return sdb.create_object( 'spl_kmem_obj_t *', obj.value_() + p2.p2roundup(object_size(cache), cache_obj_align))
def _call(self, objs: Iterable[drgn.Object]) -> Iterable[drgn.Object]: yield sdb.create_object('unsigned long long', sum(1 for _ in objs))