Файловый менеджер - Редактировать - /var/www/html/linux.zip
Ðазад
PK ! ��]� � rbtree.pynu �[��� # SPDX-License-Identifier: GPL-2.0 # # Copyright 2019 Google LLC. import gdb from linux import utils rb_root_type = utils.CachedType("struct rb_root") rb_node_type = utils.CachedType("struct rb_node") def rb_first(root): if root.type == rb_root_type.get_type(): node = root.address.cast(rb_root_type.get_type().pointer()) elif root.type != rb_root_type.get_type().pointer(): raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) node = root['rb_node'] if node == 0: return None while node['rb_left']: node = node['rb_left'] return node def rb_last(root): if root.type == rb_root_type.get_type(): node = root.address.cast(rb_root_type.get_type().pointer()) elif root.type != rb_root_type.get_type().pointer(): raise gdb.GdbError("Must be struct rb_root not {}".format(root.type)) node = root['rb_node'] if node == 0: return None while node['rb_right']: node = node['rb_right'] return node def rb_parent(node): parent = gdb.Value(node['__rb_parent_color'] & ~3) return parent.cast(rb_node_type.get_type().pointer()) def rb_empty_node(node): return node['__rb_parent_color'] == node.address def rb_next(node): if node.type == rb_node_type.get_type(): node = node.address.cast(rb_node_type.get_type().pointer()) elif node.type != rb_node_type.get_type().pointer(): raise gdb.GdbError("Must be struct rb_node not {}".format(node.type)) if rb_empty_node(node): return None if node['rb_right']: node = node['rb_right'] while node['rb_left']: node = node['rb_left'] return node parent = rb_parent(node) while parent and node == parent['rb_right']: node = parent parent = rb_parent(node) return parent def rb_prev(node): if node.type == rb_node_type.get_type(): node = node.address.cast(rb_node_type.get_type().pointer()) elif node.type != rb_node_type.get_type().pointer(): raise gdb.GdbError("Must be struct rb_node not {}".format(node.type)) if rb_empty_node(node): return None if node['rb_left']: node = node['rb_left'] while node['rb_right']: node = node['rb_right'] return node.dereference() parent = rb_parent(node) while parent and node == parent['rb_left'].dereference(): node = parent parent = rb_parent(node) return parent class LxRbFirst(gdb.Function): """Lookup and return a node from an RBTree $lx_rb_first(root): Return the node at the given index. If index is omitted, the root node is dereferenced and returned.""" def __init__(self): super(LxRbFirst, self).__init__("lx_rb_first") def invoke(self, root): result = rb_first(root) if result is None: raise gdb.GdbError("No entry in tree") return result LxRbFirst() class LxRbLast(gdb.Function): """Lookup and return a node from an RBTree. $lx_rb_last(root): Return the node at the given index. If index is omitted, the root node is dereferenced and returned.""" def __init__(self): super(LxRbLast, self).__init__("lx_rb_last") def invoke(self, root): result = rb_last(root) if result is None: raise gdb.GdbError("No entry in tree") return result LxRbLast() class LxRbNext(gdb.Function): """Lookup and return a node from an RBTree. $lx_rb_next(node): Return the node at the given index. If index is omitted, the root node is dereferenced and returned.""" def __init__(self): super(LxRbNext, self).__init__("lx_rb_next") def invoke(self, node): result = rb_next(node) if result is None: raise gdb.GdbError("No entry in tree") return result LxRbNext() class LxRbPrev(gdb.Function): """Lookup and return a node from an RBTree. $lx_rb_prev(node): Return the node at the given index. If index is omitted, the root node is dereferenced and returned.""" def __init__(self): super(LxRbPrev, self).__init__("lx_rb_prev") def invoke(self, node): result = rb_prev(node) if result is None: raise gdb.GdbError("No entry in tree") return result LxRbPrev() PK ! �&�1 1 config.pynu �[��� # SPDX-License-Identifier: GPL-2.0 # # Copyright 2019 Google LLC. import gdb import zlib from linux import utils class LxConfigDump(gdb.Command): """Output kernel config to the filename specified as the command argument. Equivalent to 'zcat /proc/config.gz > config.txt' on a running target""" def __init__(self): super(LxConfigDump, self).__init__("lx-configdump", gdb.COMMAND_DATA, gdb.COMPLETE_FILENAME) def invoke(self, arg, from_tty): if len(arg) == 0: filename = "config.txt" else: filename = arg try: py_config_ptr = gdb.parse_and_eval("&kernel_config_data") py_config_ptr_end = gdb.parse_and_eval("&kernel_config_data_end") py_config_size = py_config_ptr_end - py_config_ptr except gdb.error as e: raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?") inf = gdb.inferiors()[0] zconfig_buf = utils.read_memoryview(inf, py_config_ptr, py_config_size).tobytes() config_buf = zlib.decompress(zconfig_buf, 16) with open(filename, 'wb') as f: f.write(config_buf) gdb.write("Dumped config to " + filename + "\n") LxConfigDump() PK ! :.�P P utils.pynu �[��� # # gdb helper commands and functions for Linux kernel debugging # # common utilities # # Copyright (c) Siemens AG, 2011-2013 # # Authors: # Jan Kiszka <jan.kiszka@siemens.com> # # This work is licensed under the terms of the GNU GPL version 2. # import gdb class CachedType: def __init__(self, name): self._type = None self._name = name def _new_objfile_handler(self, event): self._type = None gdb.events.new_objfile.disconnect(self._new_objfile_handler) def get_type(self): if self._type is None: self._type = gdb.lookup_type(self._name) if self._type is None: raise gdb.GdbError( "cannot resolve type '{0}'".format(self._name)) if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'): gdb.events.new_objfile.connect(self._new_objfile_handler) return self._type long_type = CachedType("long") atomic_long_type = CachedType("atomic_long_t") def get_long_type(): global long_type return long_type.get_type() def offset_of(typeobj, field): element = gdb.Value(0).cast(typeobj) return int(str(element[field].address).split()[0], 16) def container_of(ptr, typeobj, member): return (ptr.cast(get_long_type()) - offset_of(typeobj, member)).cast(typeobj) class ContainerOf(gdb.Function): """Return pointer to containing data structure. $container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the data structure of the type TYPE in which PTR is the address of ELEMENT. Note that TYPE and ELEMENT have to be quoted as strings.""" def __init__(self): super(ContainerOf, self).__init__("container_of") def invoke(self, ptr, typename, elementname): return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), elementname.string()) ContainerOf() BIG_ENDIAN = 0 LITTLE_ENDIAN = 1 target_endianness = None def get_target_endianness(): global target_endianness if target_endianness is None: endian = gdb.execute("show endian", to_string=True) if "little endian" in endian: target_endianness = LITTLE_ENDIAN elif "big endian" in endian: target_endianness = BIG_ENDIAN else: raise gdb.GdbError("unknown endianness '{0}'".format(str(endian))) return target_endianness def read_memoryview(inf, start, length): m = inf.read_memory(start, length) if type(m) is memoryview: return m return memoryview(m) def read_u16(buffer, offset): buffer_val = buffer[offset:offset + 2] value = [0, 0] if type(buffer_val[0]) is str: value[0] = ord(buffer_val[0]) value[1] = ord(buffer_val[1]) else: value[0] = buffer_val[0] value[1] = buffer_val[1] if get_target_endianness() == LITTLE_ENDIAN: return value[0] + (value[1] << 8) else: return value[1] + (value[0] << 8) def read_u32(buffer, offset): if get_target_endianness() == LITTLE_ENDIAN: return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16) else: return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16) def read_u64(buffer, offset): if get_target_endianness() == LITTLE_ENDIAN: return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32) else: return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32) def read_ulong(buffer, offset): if get_long_type().sizeof == 8: return read_u64(buffer, offset) else: return read_u32(buffer, offset) atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof def read_atomic_long(buffer, offset): global atomic_long_counter_offset global atomic_long_counter_sizeof if atomic_long_counter_sizeof == 8: return read_u64(buffer, offset + atomic_long_counter_offset) else: return read_u32(buffer, offset + atomic_long_counter_offset) target_arch = None def is_target_arch(arch): if hasattr(gdb.Frame, 'architecture'): return arch in gdb.newest_frame().architecture().name() else: global target_arch if target_arch is None: target_arch = gdb.execute("show architecture", to_string=True) return arch in target_arch GDBSERVER_QEMU = 0 GDBSERVER_KGDB = 1 gdbserver_type = None def get_gdbserver_type(): def exit_handler(event): global gdbserver_type gdbserver_type = None gdb.events.exited.disconnect(exit_handler) def probe_qemu(): try: return gdb.execute("monitor info version", to_string=True) != "" except gdb.error: return False def probe_kgdb(): try: thread_info = gdb.execute("info thread 2", to_string=True) return "shadowCPU0" in thread_info except gdb.error: return False global gdbserver_type if gdbserver_type is None: if probe_qemu(): gdbserver_type = GDBSERVER_QEMU elif probe_kgdb(): gdbserver_type = GDBSERVER_KGDB if gdbserver_type is not None and hasattr(gdb, 'events'): gdb.events.exited.connect(exit_handler) return gdbserver_type def gdb_eval_or_none(expresssion): try: return gdb.parse_and_eval(expresssion) except gdb.error: return None def dentry_name(d): parent = d['d_parent'] if parent == d or parent == 0: return "" p = dentry_name(d['d_parent']) + "/" return p + d['d_iname'].string() PK ! ��g� � device.pynu �[��� # SPDX-License-Identifier: GPL-2.0 # # Copyright (c) NXP 2019 import gdb from linux.utils import CachedType from linux.utils import container_of from linux.lists import list_for_each_entry device_private_type = CachedType('struct device_private') device_type = CachedType('struct device') subsys_private_type = CachedType('struct subsys_private') kobject_type = CachedType('struct kobject') kset_type = CachedType('struct kset') bus_type = CachedType('struct bus_type') class_type = CachedType('struct class') def dev_name(dev): dev_init_name = dev['init_name'] if dev_init_name: return dev_init_name.string() return dev['kobj']['name'].string() def kset_for_each_object(kset): return list_for_each_entry(kset['list'], kobject_type.get_type().pointer(), "entry") def for_each_bus(): for kobj in kset_for_each_object(gdb.parse_and_eval('bus_kset')): subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') yield subsys_priv['bus'] def for_each_class(): for kobj in kset_for_each_object(gdb.parse_and_eval('class_kset')): subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') yield subsys_priv['class'] def get_bus_by_name(name): for item in for_each_bus(): if item['name'].string() == name: return item raise gdb.GdbError("Can't find bus type {!r}".format(name)) def get_class_by_name(name): for item in for_each_class(): if item['name'].string() == name: return item raise gdb.GdbError("Can't find device class {!r}".format(name)) klist_type = CachedType('struct klist') klist_node_type = CachedType('struct klist_node') def klist_for_each(klist): return list_for_each_entry(klist['k_list'], klist_node_type.get_type().pointer(), 'n_node') def bus_for_each_device(bus): for kn in klist_for_each(bus['p']['klist_devices']): dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_bus') yield dp['device'] def class_for_each_device(cls): for kn in klist_for_each(cls['p']['klist_devices']): dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_class') yield dp['device'] def device_for_each_child(dev): for kn in klist_for_each(dev['p']['klist_children']): dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_parent') yield dp['device'] def _show_device(dev, level=0, recursive=False): gdb.write('{}dev {}:\t{}\n'.format('\t' * level, dev_name(dev), dev)) if recursive: for child in device_for_each_child(dev): _show_device(child, level + 1, recursive) class LxDeviceListBus(gdb.Command): '''Print devices on a bus (or all buses if not specified)''' def __init__(self): super(LxDeviceListBus, self).__init__('lx-device-list-bus', gdb.COMMAND_DATA) def invoke(self, arg, from_tty): if not arg: for bus in for_each_bus(): gdb.write('bus {}:\t{}\n'.format(bus['name'].string(), bus)) for dev in bus_for_each_device(bus): _show_device(dev, level=1) else: bus = get_bus_by_name(arg) if not bus: raise gdb.GdbError("Can't find bus {!r}".format(arg)) for dev in bus_for_each_device(bus): _show_device(dev) class LxDeviceListClass(gdb.Command): '''Print devices in a class (or all classes if not specified)''' def __init__(self): super(LxDeviceListClass, self).__init__('lx-device-list-class', gdb.COMMAND_DATA) def invoke(self, arg, from_tty): if not arg: for cls in for_each_class(): gdb.write("class {}:\t{}\n".format(cls['name'].string(), cls)) for dev in class_for_each_device(cls): _show_device(dev, level=1) else: cls = get_class_by_name(arg) for dev in class_for_each_device(cls): _show_device(dev) class LxDeviceListTree(gdb.Command): '''Print a device and its children recursively''' def __init__(self): super(LxDeviceListTree, self).__init__('lx-device-list-tree', gdb.COMMAND_DATA) def invoke(self, arg, from_tty): if not arg: raise gdb.GdbError('Please provide pointer to struct device') dev = gdb.parse_and_eval(arg) if dev.type != device_type.get_type().pointer(): raise gdb.GdbError('Please provide pointer to struct device') _show_device(dev, level=0, recursive=True) class LxDeviceFindByBusName(gdb.Function): '''Find struct device by bus and name (both strings)''' def __init__(self): super(LxDeviceFindByBusName, self).__init__('lx_device_find_by_bus_name') def invoke(self, bus, name): name = name.string() bus = get_bus_by_name(bus.string()) for dev in bus_for_each_device(bus): if dev_name(dev) == name: return dev class LxDeviceFindByClassName(gdb.Function): '''Find struct device by class and name (both strings)''' def __init__(self): super(LxDeviceFindByClassName, self).__init__('lx_device_find_by_class_name') def invoke(self, cls, name): name = name.string() cls = get_class_by_name(cls.string()) for dev in class_for_each_device(cls): if dev_name(dev) == name: return dev LxDeviceListBus() LxDeviceListClass() LxDeviceListTree() LxDeviceFindByBusName() LxDeviceFindByClassName() PK ! ]��� � lists.pynu �[��� # # gdb helper commands and functions for Linux kernel debugging # # list tools # # Copyright (c) Thiebaud Weksteen, 2015 # # Authors: # Thiebaud Weksteen <thiebaud@weksteen.fr> # # This work is licensed under the terms of the GNU GPL version 2. # import gdb from linux import utils list_head = utils.CachedType("struct list_head") hlist_head = utils.CachedType("struct hlist_head") hlist_node = utils.CachedType("struct hlist_node") def list_for_each(head): if head.type == list_head.get_type().pointer(): head = head.dereference() elif head.type != list_head.get_type(): raise TypeError("Must be struct list_head not {}" .format(head.type)) if head['next'] == 0: gdb.write("list_for_each: Uninitialized list '{}' treated as empty\n" .format(head.address)) return node = head['next'].dereference() while node.address != head.address: yield node.address node = node['next'].dereference() def list_for_each_entry(head, gdbtype, member): for node in list_for_each(head): yield utils.container_of(node, gdbtype, member) def hlist_for_each(head): if head.type == hlist_head.get_type().pointer(): head = head.dereference() elif head.type != hlist_head.get_type(): raise TypeError("Must be struct hlist_head not {}" .format(head.type)) node = head['first'].dereference() while node.address: yield node.address node = node['next'].dereference() def hlist_for_each_entry(head, gdbtype, member): for node in hlist_for_each(head): yield utils.container_of(node, gdbtype, member) def list_check(head): nb = 0 if (head.type == list_head.get_type().pointer()): head = head.dereference() elif (head.type != list_head.get_type()): raise gdb.GdbError('argument must be of type (struct list_head [*])') c = head try: gdb.write("Starting with: {}\n".format(c)) except gdb.MemoryError: gdb.write('head is not accessible\n') return while True: p = c['prev'].dereference() n = c['next'].dereference() try: if p['next'] != c.address: gdb.write('prev.next != current: ' 'current@{current_addr}={current} ' 'prev@{p_addr}={p}\n'.format( current_addr=c.address, current=c, p_addr=p.address, p=p, )) return except gdb.MemoryError: gdb.write('prev is not accessible: ' 'current@{current_addr}={current}\n'.format( current_addr=c.address, current=c )) return try: if n['prev'] != c.address: gdb.write('next.prev != current: ' 'current@{current_addr}={current} ' 'next@{n_addr}={n}\n'.format( current_addr=c.address, current=c, n_addr=n.address, n=n, )) return except gdb.MemoryError: gdb.write('next is not accessible: ' 'current@{current_addr}={current}\n'.format( current_addr=c.address, current=c )) return c = n nb += 1 if c == head: gdb.write("list is consistent: {} node(s)\n".format(nb)) return class LxListChk(gdb.Command): """Verify a list consistency""" def __init__(self): super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION) def invoke(self, arg, from_tty): argv = gdb.string_to_argv(arg) if len(argv) != 1: raise gdb.GdbError("lx-list-check takes one argument") list_check(gdb.parse_and_eval(argv[0])) LxListChk() PK ! �-��< < constants.py.innu �[��� /* * gdb helper commands and functions for Linux kernel debugging * * Kernel constants derived from include files. * * Copyright (c) 2016 Linaro Ltd * * Authors: * Kieran Bingham <kieran.bingham@linaro.org> * * This work is licensed under the terms of the GNU GPL version 2. * */ #include <linux/clk-provider.h> #include <linux/fs.h> #include <linux/hrtimer.h> #include <linux/mount.h> #include <linux/of_fdt.h> #include <linux/threads.h> /* We need to stringify expanded macros so that they can be parsed */ #define STRING(x) #x #define XSTRING(x) STRING(x) #define LX_VALUE(x) LX_##x = x #define LX_GDBPARSED(x) LX_##x = gdb.parse_and_eval(XSTRING(x)) /* * IS_ENABLED generates (a || b) which is not compatible with python * We can only switch on configuration items we know are available * Therefore - IS_BUILTIN() is more appropriate */ #define LX_CONFIG(x) LX_##x = IS_BUILTIN(x) /* The build system will take care of deleting everything above this marker */ <!-- end-c-headers --> import gdb LX_CONFIG(CONFIG_DEBUG_INFO_REDUCED) /* linux/clk-provider.h */ if IS_BUILTIN(CONFIG_COMMON_CLK): LX_GDBPARSED(CLK_GET_RATE_NOCACHE) /* linux/fs.h */ LX_GDBPARSED(SB_RDONLY) LX_GDBPARSED(SB_SYNCHRONOUS) LX_GDBPARSED(SB_MANDLOCK) LX_GDBPARSED(SB_DIRSYNC) LX_GDBPARSED(SB_NOATIME) LX_GDBPARSED(SB_NODIRATIME) /* linux/htimer.h */ LX_GDBPARSED(hrtimer_resolution) /* linux/mount.h */ LX_VALUE(MNT_NOSUID) LX_VALUE(MNT_NODEV) LX_VALUE(MNT_NOEXEC) LX_VALUE(MNT_NOATIME) LX_VALUE(MNT_NODIRATIME) LX_VALUE(MNT_RELATIME) /* linux/threads.h */ LX_VALUE(NR_CPUS) /* linux/of_fdt.h> */ LX_VALUE(OF_DT_HEADER) /* Kernel Configs */ LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS) LX_CONFIG(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) LX_CONFIG(CONFIG_HIGH_RES_TIMERS) LX_CONFIG(CONFIG_NR_CPUS) LX_CONFIG(CONFIG_OF) LX_CONFIG(CONFIG_TICK_ONESHOT) PK ! 1�� � dmesg.pynu �[��� # # gdb helper commands and functions for Linux kernel debugging # # kernel log buffer dump # # Copyright (c) Siemens AG, 2011, 2012 # # Authors: # Jan Kiszka <jan.kiszka@siemens.com> # # This work is licensed under the terms of the GNU GPL version 2. # import gdb import sys from linux import utils printk_info_type = utils.CachedType("struct printk_info") prb_data_blk_lpos_type = utils.CachedType("struct prb_data_blk_lpos") prb_desc_type = utils.CachedType("struct prb_desc") prb_desc_ring_type = utils.CachedType("struct prb_desc_ring") prb_data_ring_type = utils.CachedType("struct prb_data_ring") printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer") class LxDmesg(gdb.Command): """Print Linux kernel log buffer.""" def __init__(self): super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): inf = gdb.inferiors()[0] # read in prb structure prb_addr = int(str(gdb.parse_and_eval("(void *)'printk.c'::prb")).split()[0], 16) sz = printk_ringbuffer_type.get_type().sizeof prb = utils.read_memoryview(inf, prb_addr, sz).tobytes() # read in descriptor ring structure off = printk_ringbuffer_type.get_type()['desc_ring'].bitpos // 8 addr = prb_addr + off sz = prb_desc_ring_type.get_type().sizeof desc_ring = utils.read_memoryview(inf, addr, sz).tobytes() # read in descriptor count, size, and address off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8 desc_ring_count = 1 << utils.read_u32(desc_ring, off) desc_sz = prb_desc_type.get_type().sizeof off = prb_desc_ring_type.get_type()['descs'].bitpos // 8 desc_addr = utils.read_ulong(desc_ring, off) # read in info size and address info_sz = printk_info_type.get_type().sizeof off = prb_desc_ring_type.get_type()['infos'].bitpos // 8 info_addr = utils.read_ulong(desc_ring, off) # read in text data ring structure off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8 addr = prb_addr + off sz = prb_data_ring_type.get_type().sizeof text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes() # read in text data size and address off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8 text_data_sz = 1 << utils.read_u32(text_data_ring, off) off = prb_data_ring_type.get_type()['data'].bitpos // 8 text_data_addr = utils.read_ulong(text_data_ring, off) sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8 off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8 begin_off = off + (prb_data_blk_lpos_type.get_type()['begin'].bitpos // 8) next_off = off + (prb_data_blk_lpos_type.get_type()['next'].bitpos // 8) ts_off = printk_info_type.get_type()['ts_nsec'].bitpos // 8 len_off = printk_info_type.get_type()['text_len'].bitpos // 8 # definitions from kernel/printk/printk_ringbuffer.h desc_committed = 1 desc_finalized = 2 desc_sv_bits = utils.get_long_type().sizeof * 8 desc_flags_shift = desc_sv_bits - 2 desc_flags_mask = 3 << desc_flags_shift desc_id_mask = ~desc_flags_mask # read in tail and head descriptor ids off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8 tail_id = utils.read_atomic_long(desc_ring, off) off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8 head_id = utils.read_atomic_long(desc_ring, off) did = tail_id while True: ind = did % desc_ring_count desc_off = desc_sz * ind info_off = info_sz * ind desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes() # skip non-committed record state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift) if state != desc_committed and state != desc_finalized: if did == head_id: break did = (did + 1) & desc_id_mask continue begin = utils.read_ulong(desc, begin_off) % text_data_sz end = utils.read_ulong(desc, next_off) % text_data_sz info = utils.read_memoryview(inf, info_addr + info_off, info_sz).tobytes() # handle data-less record if begin & 1 == 1: text = "" else: # handle wrapping data block if begin > end: begin = 0 # skip over descriptor id text_start = begin + utils.get_long_type().sizeof text_len = utils.read_u16(info, len_off) # handle truncated message if end - text_start < text_len: text_len = end - text_start text_data = utils.read_memoryview(inf, text_data_addr + text_start, text_len).tobytes() text = text_data[0:text_len].decode(encoding='utf8', errors='replace') time_stamp = utils.read_u64(info, ts_off) for line in text.splitlines(): msg = u"[{time:12.6f}] {line}\n".format( time=time_stamp / 1000000000.0, line=line) # With python2 gdb.write will attempt to convert unicode to # ascii and might fail so pass an utf8-encoded str instead. if sys.hexversion < 0x03000000: msg = msg.encode(encoding='utf8', errors='replace') gdb.write(msg) if did == head_id: break did = (did + 1) & desc_id_mask LxDmesg() PK ! #�{XF F clk.pynu �[��� # SPDX-License-Identifier: GPL-2.0 # # Copyright (c) NXP 2019 import gdb import sys from linux import utils, lists, constants clk_core_type = utils.CachedType("struct clk_core") def clk_core_for_each_child(hlist_head): return lists.hlist_for_each_entry(hlist_head, clk_core_type.get_type().pointer(), "child_node") class LxClkSummary(gdb.Command): """Print clk tree summary Output is a subset of /sys/kernel/debug/clk/clk_summary No calls are made during printing, instead a (c) if printed after values which are cached and potentially out of date""" def __init__(self): super(LxClkSummary, self).__init__("lx-clk-summary", gdb.COMMAND_DATA) def show_subtree(self, clk, level): gdb.write("%*s%-*s %7d %8d %8d %11lu%s\n" % ( level * 3 + 1, "", 30 - level * 3, clk['name'].string(), clk['enable_count'], clk['prepare_count'], clk['protect_count'], clk['rate'], '(c)' if clk['flags'] & constants.LX_CLK_GET_RATE_NOCACHE else ' ')) for child in clk_core_for_each_child(clk['children']): self.show_subtree(child, level + 1) def invoke(self, arg, from_tty): if utils.gdb_eval_or_none("clk_root_list") is None: raise gdb.GdbError("No clocks registered") gdb.write(" enable prepare protect \n") gdb.write(" clock count count count rate \n") gdb.write("------------------------------------------------------------------------\n") for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_root_list")): self.show_subtree(clk, 0) for clk in clk_core_for_each_child(gdb.parse_and_eval("clk_orphan_list")): self.show_subtree(clk, 0) LxClkSummary() class LxClkCoreLookup(gdb.Function): """Find struct clk_core by name""" def __init__(self): super(LxClkCoreLookup, self).__init__("lx_clk_core_lookup") def lookup_hlist(self, hlist_head, name): for child in clk_core_for_each_child(hlist_head): if child['name'].string() == name: return child result = self.lookup_hlist(child['children'], name) if result: return result def invoke(self, name): name = name.string() return (self.lookup_hlist(gdb.parse_and_eval("clk_root_list"), name) or self.lookup_hlist(gdb.parse_and_eval("clk_orphan_list"), name)) LxClkCoreLookup() PK ! ��O� � symbols.pynu �[��� # # gdb helper commands and functions for Linux kernel debugging # # load kernel and module symbols # # Copyright (c) Siemens AG, 2011-2013 # # Authors: # Jan Kiszka <jan.kiszka@siemens.com> # # This work is licensed under the terms of the GNU GPL version 2. # import gdb import os import re from linux import modules, utils if hasattr(gdb, 'Breakpoint'): class LoadModuleBreakpoint(gdb.Breakpoint): def __init__(self, spec, gdb_command): super(LoadModuleBreakpoint, self).__init__(spec, internal=True) self.silent = True self.gdb_command = gdb_command def stop(self): module = gdb.parse_and_eval("mod") module_name = module['name'].string() cmd = self.gdb_command # enforce update if object file is not found cmd.module_files_updated = False # Disable pagination while reporting symbol (re-)loading. # The console input is blocked in this context so that we would # get stuck waiting for the user to acknowledge paged output. show_pagination = gdb.execute("show pagination", to_string=True) pagination = show_pagination.endswith("on.\n") gdb.execute("set pagination off") if module_name in cmd.loaded_modules: gdb.write("refreshing all symbols to reload module " "'{0}'\n".format(module_name)) cmd.load_all_symbols() else: cmd.load_module_symbols(module) # restore pagination state gdb.execute("set pagination %s" % ("on" if pagination else "off")) return False class LxSymbols(gdb.Command): """(Re-)load symbols of Linux kernel and currently loaded modules. The kernel (vmlinux) is taken from the current working directly. Modules (.ko) are scanned recursively, starting in the same directory. Optionally, the module search path can be extended by a space separated list of paths passed to the lx-symbols command.""" module_paths = [] module_files = [] module_files_updated = False loaded_modules = [] breakpoint = None def __init__(self): super(LxSymbols, self).__init__("lx-symbols", gdb.COMMAND_FILES, gdb.COMPLETE_FILENAME) def _update_module_files(self): self.module_files = [] for path in self.module_paths: gdb.write("scanning for modules in {0}\n".format(path)) for root, dirs, files in os.walk(path): for name in files: if name.endswith(".ko") or name.endswith(".ko.debug"): self.module_files.append(root + "/" + name) self.module_files_updated = True def _get_module_file(self, module_name): module_pattern = ".*/{0}\.ko(?:.debug)?$".format( module_name.replace("_", r"[_\-]")) for name in self.module_files: if re.match(module_pattern, name) and os.path.exists(name): return name return None def _section_arguments(self, module): try: sect_attrs = module['sect_attrs'].dereference() except gdb.error: return "" attrs = sect_attrs['attrs'] section_name_to_address = { attrs[n]['battr']['attr']['name'].string(): attrs[n]['address'] for n in range(int(sect_attrs['nsections']))} args = [] for section_name in [".data", ".data..read_mostly", ".rodata", ".bss", ".text", ".text.hot", ".text.unlikely"]: address = section_name_to_address.get(section_name) if address: args.append(" -s {name} {addr}".format( name=section_name, addr=str(address))) return "".join(args) def load_module_symbols(self, module): module_name = module['name'].string() module_addr = str(module['core_layout']['base']).split()[0] module_file = self._get_module_file(module_name) if not module_file and not self.module_files_updated: self._update_module_files() module_file = self._get_module_file(module_name) if module_file: if utils.is_target_arch('s390'): # Module text is preceded by PLT stubs on s390. module_arch = module['arch'] plt_offset = int(module_arch['plt_offset']) plt_size = int(module_arch['plt_size']) module_addr = hex(int(module_addr, 0) + plt_offset + plt_size) gdb.write("loading @{addr}: {filename}\n".format( addr=module_addr, filename=module_file)) cmdline = "add-symbol-file {filename} {addr}{sections}".format( filename=module_file, addr=module_addr, sections=self._section_arguments(module)) gdb.execute(cmdline, to_string=True) if module_name not in self.loaded_modules: self.loaded_modules.append(module_name) else: gdb.write("no module object found for '{0}'\n".format(module_name)) def load_all_symbols(self): gdb.write("loading vmlinux\n") # Dropping symbols will disable all breakpoints. So save their states # and restore them afterward. saved_states = [] if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None: for bp in gdb.breakpoints(): saved_states.append({'breakpoint': bp, 'enabled': bp.enabled}) # drop all current symbols and reload vmlinux orig_vmlinux = 'vmlinux' for obj in gdb.objfiles(): if obj.filename.endswith('vmlinux'): orig_vmlinux = obj.filename gdb.execute("symbol-file", to_string=True) gdb.execute("symbol-file {0}".format(orig_vmlinux)) self.loaded_modules = [] module_list = modules.module_list() if not module_list: gdb.write("no modules found\n") else: [self.load_module_symbols(module) for module in module_list] for saved_state in saved_states: saved_state['breakpoint'].enabled = saved_state['enabled'] def invoke(self, arg, from_tty): self.module_paths = [os.path.abspath(os.path.expanduser(p)) for p in arg.split()] self.module_paths.append(os.getcwd()) # enforce update self.module_files = [] self.module_files_updated = False self.load_all_symbols() if hasattr(gdb, 'Breakpoint'): if self.breakpoint is not None: self.breakpoint.delete() self.breakpoint = None self.breakpoint = LoadModuleBreakpoint( "kernel/module.c:do_init_module", self) else: gdb.write("Note: symbol update on module loading not supported " "with this gdb version\n") LxSymbols() PK ! �cg�% % modules.pynu �[��� # # gdb helper commands and functions for Linux kernel debugging # # module tools # # Copyright (c) Siemens AG, 2013 # # Authors: # Jan Kiszka <jan.kiszka@siemens.com> # # This work is licensed under the terms of the GNU GPL version 2. # import gdb from linux import cpus, utils, lists module_type = utils.CachedType("struct module") def module_list(): global module_type modules = utils.gdb_eval_or_none("modules") if modules is None: return module_ptr_type = module_type.get_type().pointer() for module in lists.list_for_each_entry(modules, module_ptr_type, "list"): yield module def find_module_by_name(name): for module in module_list(): if module['name'].string() == name: return module return None class LxModule(gdb.Function): """Find module by name and return the module variable. $lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules of the target and return that module variable which MODULE matches.""" def __init__(self): super(LxModule, self).__init__("lx_module") def invoke(self, mod_name): mod_name = mod_name.string() module = find_module_by_name(mod_name) if module: return module.dereference() else: raise gdb.GdbError("Unable to find MODULE " + mod_name) LxModule() class LxLsmod(gdb.Command): """List currently loaded modules.""" _module_use_type = utils.CachedType("struct module_use") def __init__(self): super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): gdb.write( "Address{0} Module Size Used by\n".format( " " if utils.get_long_type().sizeof == 8 else "")) for module in module_list(): layout = module['core_layout'] gdb.write("{address} {name:<19} {size:>8} {ref}".format( address=str(layout['base']).split()[0], name=module['name'].string(), size=str(layout['size']), ref=str(module['refcnt']['counter'] - 1))) t = self._module_use_type.get_type().pointer() first = True sources = module['source_list'] for use in lists.list_for_each_entry(sources, t, "source_list"): gdb.write("{separator}{name}".format( separator=" " if first else ",", name=use['source']['name'].string())) first = False gdb.write("\n") LxLsmod() PK ! z%�z� � cpus.pynu �[��� # # gdb helper commands and functions for Linux kernel debugging # # per-cpu tools # # Copyright (c) Siemens AG, 2011-2013 # # Authors: # Jan Kiszka <jan.kiszka@siemens.com> # # This work is licensed under the terms of the GNU GPL version 2. # import gdb from linux import tasks, utils task_type = utils.CachedType("struct task_struct") MAX_CPUS = 4096 def get_current_cpu(): if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU: return gdb.selected_thread().num - 1 elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB: tid = gdb.selected_thread().ptid[2] if tid > (0x100000000 - MAX_CPUS - 2): return 0x100000000 - tid - 2 else: return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu'] else: raise gdb.GdbError("Sorry, obtaining the current CPU is not yet " "supported with this gdb server.") def per_cpu(var_ptr, cpu): if cpu == -1: cpu = get_current_cpu() if utils.is_target_arch("sparc:v9"): offset = gdb.parse_and_eval( "trap_block[{0}].__per_cpu_base".format(str(cpu))) else: try: offset = gdb.parse_and_eval( "__per_cpu_offset[{0}]".format(str(cpu))) except gdb.error: # !CONFIG_SMP case offset = 0 pointer = var_ptr.cast(utils.get_long_type()) + offset return pointer.cast(var_ptr.type).dereference() cpu_mask = {} def cpu_mask_invalidate(event): global cpu_mask cpu_mask = {} gdb.events.stop.disconnect(cpu_mask_invalidate) if hasattr(gdb.events, 'new_objfile'): gdb.events.new_objfile.disconnect(cpu_mask_invalidate) def cpu_list(mask_name): global cpu_mask mask = None if mask_name in cpu_mask: mask = cpu_mask[mask_name] if mask is None: mask = gdb.parse_and_eval(mask_name + ".bits") if hasattr(gdb, 'events'): cpu_mask[mask_name] = mask gdb.events.stop.connect(cpu_mask_invalidate) if hasattr(gdb.events, 'new_objfile'): gdb.events.new_objfile.connect(cpu_mask_invalidate) bits_per_entry = mask[0].type.sizeof * 8 num_entries = mask.type.sizeof * 8 / bits_per_entry entry = -1 bits = 0 while True: while bits == 0: entry += 1 if entry == num_entries: return bits = mask[entry] if bits != 0: bit = 0 break while bits & 1 == 0: bits >>= 1 bit += 1 cpu = entry * bits_per_entry + bit bits >>= 1 bit += 1 yield int(cpu) def each_online_cpu(): for cpu in cpu_list("__cpu_online_mask"): yield cpu def each_present_cpu(): for cpu in cpu_list("__cpu_present_mask"): yield cpu def each_possible_cpu(): for cpu in cpu_list("__cpu_possible_mask"): yield cpu def each_active_cpu(): for cpu in cpu_list("__cpu_active_mask"): yield cpu class LxCpus(gdb.Command): """List CPU status arrays Displays the known state of each CPU based on the kernel masks and can help identify the state of hotplugged CPUs""" def __init__(self): super(LxCpus, self).__init__("lx-cpus", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): gdb.write("Possible CPUs : {}\n".format(list(each_possible_cpu()))) gdb.write("Present CPUs : {}\n".format(list(each_present_cpu()))) gdb.write("Online CPUs : {}\n".format(list(each_online_cpu()))) gdb.write("Active CPUs : {}\n".format(list(each_active_cpu()))) LxCpus() class PerCpu(gdb.Function): """Return per-cpu variable. $lx_per_cpu("VAR"[, CPU]): Return the per-cpu variable called VAR for the given CPU number. If CPU is omitted, the CPU of the current context is used. Note that VAR has to be quoted as string.""" def __init__(self): super(PerCpu, self).__init__("lx_per_cpu") def invoke(self, var_name, cpu=-1): var_ptr = gdb.parse_and_eval("&" + var_name.string()) return per_cpu(var_ptr, cpu) PerCpu() def get_current_task(cpu): task_ptr_type = task_type.get_type().pointer() if utils.is_target_arch("x86"): var_ptr = gdb.parse_and_eval("¤t_task") return per_cpu(var_ptr, cpu).dereference() elif utils.is_target_arch("aarch64"): current_task_addr = gdb.parse_and_eval("$SP_EL0") if((current_task_addr >> 63) != 0): current_task = current_task_addr.cast(task_ptr_type) return current_task.dereference() else: raise gdb.GdbError("Sorry, obtaining the current task is not allowed " "while running in userspace(EL0)") else: raise gdb.GdbError("Sorry, obtaining the current task is not yet " "supported with this arch") class LxCurrentFunc(gdb.Function): """Return current task. $lx_current([CPU]): Return the per-cpu task variable for the given CPU number. If CPU is omitted, the CPU of the current context is used.""" def __init__(self): super(LxCurrentFunc, self).__init__("lx_current") def invoke(self, cpu=-1): return get_current_task(cpu) LxCurrentFunc() PK ! N��Z+"