class Test(object): class nested(object): ulong_valid = False @classmethod def check_ulong(cls, gdbtype): cls.ulong_valid = True type_cbs = TypeCallbacks([('unsigned long', nested.check_ulong)])
def xfs_for_each_ail_log_item_typed(mp: gdb.Value) -> Iterable[gdb.Value]: """ Iterates over the XFS Active Item Log and returns each item, resolved to the specific type. Args: mp: The XFS mount to iterate. The value must be of type ``struct xfs_mount``. Yields: :obj:`gdb.Value`: Depending on type, the value will be any of the following types: - ``struct xfs_buf_log_item_type`` - ``struct xfs_inode_log_item_type`` - ``struct xfs_efi_log_item_type`` - ``struct xfs_efd_log_item_type`` - ``struct xfs_dq_logitem`` - ``int`` (for UNLINK item) Raises: :obj:`gdb.NotAvailableError`: The target value was not available. """ for item in types.xfs_for_each_ail_log_item(mp): yield types.xfs_log_item_typed(item) type_cbs = TypeCallbacks([('struct xfs_ail', XFS.detect_ail_version)])
def kmem_cache_from_name(name: str) -> KmemCache: try: return kmem_caches[name] except KeyError: raise KmemCacheNotFound(f"No kmem cache found for {name}.") def kmem_cache_get_all() -> ValuesView[KmemCache]: return kmem_caches.values() def slab_from_obj_addr(addr: int) -> Union[Slab, None]: page = page_from_addr(addr).compound_head() if not page.is_slab(): return None return Slab.from_page(page) type_cbs = TypeCallbacks([ ('struct page', Slab.check_page_type), ('struct slab', Slab.check_slab_type), ('kmem_bufctl_t', Slab.check_bufctl_type), ('freelist_idx_t', Slab.check_bufctl_type), ('struct kmem_cache', KmemCache.check_kmem_cache_type), ('struct alien_cache', KmemCache.setup_alien_cache_type) ]) symbol_cbs = SymbolCallbacks([('slab_caches', setup_slab_caches), ('cache_chain', setup_slab_caches)])
def __compound_head_uses_low_bit(self) -> int: return int(self.gdb_obj['compound_head']) - 1 def __compound_head(self) -> int: return self._compound_head() def compound_head(self) -> 'Page': if not self.is_tail(): return self return self.__class__.from_page_addr(self.__compound_head()) type_cbs = TypeCallbacks([('struct page', Page.setup_page_type), ('enum pageflags', Page.setup_pageflags), ('enum zone_type', Page.setup_zone_type), ('struct mem_section', Page.setup_mem_section)]) msymbol_cbs = MinimalSymbolCallbacks([('kernel_config_data', Page.setup_nodes_width)]) # TODO: this should better be generalized to some callback for # "config is available" without refering to the symbol name here symbol_cbs = SymbolCallbacks([('vmemmap_base', Page.setup_vmemmap_base), ('page_offset_base', Page.setup_directmap_base)]) def pfn_to_page(pfn: int) -> 'Page': return Page(Page.pfn_to_page(pfn), pfn) def page_from_addr(addr: int) -> 'Page':
try: mnt = mnt['mnt'].address except gdb.error: pass name = "" # Gone are the days where finding the root was as simple as # dentry == dentry->d_parent while dentry != root['dentry'] or mnt != root['mnt']: # pylint: disable=consider-using-in if dentry == mnt['mnt_root'] or dentry == dentry['d_parent']: if mount != mount['mnt_parent']: dentry = mount['mnt_mountpoint'] mount = mount['mnt_parent'] try: mnt = mount['mnt'].address except gdb.error: mnt = mount continue break name = "/" + dentry['d_name']['name'].string() + name dentry = dentry['d_parent'] if not name: name = '/' return name type_cbs = TypeCallbacks([('struct vfsmount', _check_mount_type)]) symbols_cbs = SymbolCallbacks([('init_task', Mount.check_task_interface)])
for field in enum_type.fields(): if field.enumval < nr_items: names[field.enumval] = field.name return (nr_items, names) @classmethod def get_stat_names(cls) -> List[str]: return cls.vm_stat_names @classmethod def get_event_names(cls) -> List[str]: return cls.vm_event_names @classmethod def get_events(cls) -> List[int]: nr = cls.nr_event_items events = [0] * nr for cpu in for_each_online_cpu(): states = get_percpu_var(cls.symbols.vm_event_states, cpu) for item in range(0, nr): events[item] += int(states["event"][item]) return events type_cbs = TypeCallbacks([('enum zone_stat_item', VmStat.check_enum_type), ('enum vm_event_item', VmStat.check_enum_type)])
def setup_thread_info(self, thread: gdb.InferiorThread) -> None: task = thread.info.task_struct thread_info = task['stack'].cast(types.thread_info_p_type) thread.info.set_thread_info(thread_info) @classmethod # pylint: disable=unused-argument def setup_inactive_task_frame_handler(cls, inactive: gdb.Type) -> None: cls.set_fetch_registers(_FRC_inactive_task_frame) @classmethod # pylint: disable=unused-argument def setup_thread_return_handler(cls, inactive: gdb.Type) -> None: cls.set_fetch_registers(_FRC_thread_return) @classmethod def get_stack_pointer(cls, thread_struct: gdb.Value) -> int: return int(thread_struct['sp']) type_cbs = TypeCallbacks([ ('struct inactive_task_frame', x86_64Architecture.setup_inactive_task_frame_handler) ]) msymbol_cbs = MinimalSymbolCallbacks([ ('thread_return', x86_64Architecture.setup_thread_return_handler) ]) register_arch(x86_64Architecture)
Args: inode: The ``struct inode`` for which to return the associated block device. The value must be of type ``struct inode``. Returns: :obj:`gdb.Value`: The ``struct block_device`` associated with the provided ``struct inode``. The value is of type ``struct inode``. """ if is_bdev_inode(inode): return inode_to_block_device(inode) return inode['i_sb']['s_bdev'].dereference() # pylint: disable=unused-argument def _check_types(result: gdb.Symbol) -> None: try: if symvals.part_type.type.unqualified() != types.device_type_type: raise TypeError("part_type expected to be {} not {}".format( symvals.device_type_type, types.part_type.type)) if symvals.disk_type.type.unqualified() != types.device_type_type: raise TypeError("disk_type expected to be {} not {}".format( symvals.device_type_type, types.disk_type.type)) except DelayedAttributeError: pass symbol_cbs = SymbolCallbacks([('disk_type', _check_types), ('part_type', _check_types)]) type_cbs = TypeCallbacks([('struct device_type', _check_types)])
gdbtype: The ``struct device`` type. """ if struct_has_member(gdbtype, 'knode_class'): cls._class_is_private = False @classmethod def class_is_private(cls) -> bool: """ Returns whether the class device uses ``struct device_private`` Meant to be used only be crash.types.classdev. """ return cls._class_is_private type_cbs = TypeCallbacks([('struct device', ClassdevState.setup_iterator_type)]) def for_each_class_device(class_struct: gdb.Value, subtype: gdb.Value = None) -> Iterable[gdb.Value]: """ Iterate over the list of class devices Args: class_struct: The class of devices to iterate subtype: A ``struct device_type *`` to use to filter the results. The value must be of type ``struct device_type *`` and will be used to compare against the ``type`` field of each ``struct device``. Yields: :obj:`gdb.Value`: A device on the class's device list. The value is
if not name in globals(): globals()[name] = 0 # Check struct request and define functions based on its current form in this # kernel def _check_struct_request(request_s: gdb.Type) -> None: global _rq_in_flight if struct_has_member(request_s, 'rq_state'): def _rq_in_flight(request: gdb.Value) -> bool: return (request['rq_state'] != types.enum_mq_rq_state_type['MQ_RQ_IDLE']) elif struct_has_member(request_s, 'atomic_flags'): def _rq_in_flight(request: gdb.Value) -> bool: return (request['atomic_flags'] & (1 << int( types.enum_rq_atomic_flags_type['REQ_ATOM_STARTED'].enumval)) != 0) else: def _rq_in_flight(request: gdb.Value) -> bool: return request['cmd_flags'] & REQ_STARTED != 0 # type: ignore symbol_cbs = SymbolCallbacks([('disk_type', _check_types), ('part_type', _check_types)]) type_cbs = TypeCallbacks([('struct device_type', _check_types), ('enum req_flag_bits', _export_req_flags), ('struct request', _check_struct_request)])