162306a36Sopenharmony_ci# 262306a36Sopenharmony_ci# gdb helper commands and functions for Linux kernel debugging 362306a36Sopenharmony_ci# 462306a36Sopenharmony_ci# module tools 562306a36Sopenharmony_ci# 662306a36Sopenharmony_ci# Copyright (c) Siemens AG, 2013 762306a36Sopenharmony_ci# 862306a36Sopenharmony_ci# Authors: 962306a36Sopenharmony_ci# Jan Kiszka <jan.kiszka@siemens.com> 1062306a36Sopenharmony_ci# 1162306a36Sopenharmony_ci# This work is licensed under the terms of the GNU GPL version 2. 1262306a36Sopenharmony_ci# 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciimport gdb 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cifrom linux import cpus, utils, lists, constants 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cimodule_type = utils.CachedType("struct module") 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cidef module_list(): 2362306a36Sopenharmony_ci global module_type 2462306a36Sopenharmony_ci modules = utils.gdb_eval_or_none("modules") 2562306a36Sopenharmony_ci if modules is None: 2662306a36Sopenharmony_ci return 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci module_ptr_type = module_type.get_type().pointer() 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci for module in lists.list_for_each_entry(modules, module_ptr_type, "list"): 3162306a36Sopenharmony_ci yield module 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cidef find_module_by_name(name): 3562306a36Sopenharmony_ci for module in module_list(): 3662306a36Sopenharmony_ci if module['name'].string() == name: 3762306a36Sopenharmony_ci return module 3862306a36Sopenharmony_ci return None 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciclass LxModule(gdb.Function): 4262306a36Sopenharmony_ci """Find module by name and return the module variable. 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci$lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules 4562306a36Sopenharmony_ciof the target and return that module variable which MODULE matches.""" 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci def __init__(self): 4862306a36Sopenharmony_ci super(LxModule, self).__init__("lx_module") 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci def invoke(self, mod_name): 5162306a36Sopenharmony_ci mod_name = mod_name.string() 5262306a36Sopenharmony_ci module = find_module_by_name(mod_name) 5362306a36Sopenharmony_ci if module: 5462306a36Sopenharmony_ci return module.dereference() 5562306a36Sopenharmony_ci else: 5662306a36Sopenharmony_ci raise gdb.GdbError("Unable to find MODULE " + mod_name) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ciLxModule() 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ciclass LxLsmod(gdb.Command): 6362306a36Sopenharmony_ci """List currently loaded modules.""" 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci _module_use_type = utils.CachedType("struct module_use") 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci def __init__(self): 6862306a36Sopenharmony_ci super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci def invoke(self, arg, from_tty): 7162306a36Sopenharmony_ci gdb.write( 7262306a36Sopenharmony_ci "Address{0} Module Size Used by\n".format( 7362306a36Sopenharmony_ci " " if utils.get_long_type().sizeof == 8 else "")) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci for module in module_list(): 7662306a36Sopenharmony_ci text = module['mem'][constants.LX_MOD_TEXT] 7762306a36Sopenharmony_ci text_addr = str(text['base']).split()[0] 7862306a36Sopenharmony_ci total_size = 0 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci for i in range(constants.LX_MOD_TEXT, constants.LX_MOD_RO_AFTER_INIT + 1): 8162306a36Sopenharmony_ci total_size += module['mem'][i]['size'] 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci gdb.write("{address} {name:<19} {size:>8} {ref}".format( 8462306a36Sopenharmony_ci address=text_addr, 8562306a36Sopenharmony_ci name=module['name'].string(), 8662306a36Sopenharmony_ci size=str(total_size), 8762306a36Sopenharmony_ci ref=str(module['refcnt']['counter'] - 1))) 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci t = self._module_use_type.get_type().pointer() 9062306a36Sopenharmony_ci first = True 9162306a36Sopenharmony_ci sources = module['source_list'] 9262306a36Sopenharmony_ci for use in lists.list_for_each_entry(sources, t, "source_list"): 9362306a36Sopenharmony_ci gdb.write("{separator}{name}".format( 9462306a36Sopenharmony_ci separator=" " if first else ",", 9562306a36Sopenharmony_ci name=use['source']['name'].string())) 9662306a36Sopenharmony_ci first = False 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci gdb.write("\n") 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ciLxLsmod() 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cidef help(): 10362306a36Sopenharmony_ci t = """Usage: lx-getmod-by-textaddr [Heximal Address] 10462306a36Sopenharmony_ci Example: lx-getmod-by-textaddr 0xffff800002d305ac\n""" 10562306a36Sopenharmony_ci gdb.write("Unrecognized command\n") 10662306a36Sopenharmony_ci raise gdb.GdbError(t) 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ciclass LxFindTextAddrinMod(gdb.Command): 10962306a36Sopenharmony_ci '''Look up loaded kernel module by text address.''' 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci def __init__(self): 11262306a36Sopenharmony_ci super(LxFindTextAddrinMod, self).__init__('lx-getmod-by-textaddr', gdb.COMMAND_SUPPORT) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci def invoke(self, arg, from_tty): 11562306a36Sopenharmony_ci args = gdb.string_to_argv(arg) 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if len(args) != 1: 11862306a36Sopenharmony_ci help() 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci addr = gdb.Value(int(args[0], 16)).cast(utils.get_ulong_type()) 12162306a36Sopenharmony_ci for mod in module_list(): 12262306a36Sopenharmony_ci mod_text_start = mod['mem'][constants.LX_MOD_TEXT]['base'] 12362306a36Sopenharmony_ci mod_text_end = mod_text_start + mod['mem'][constants.LX_MOD_TEXT]['size'].cast(utils.get_ulong_type()) 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci if addr >= mod_text_start and addr < mod_text_end: 12662306a36Sopenharmony_ci s = "0x%x" % addr + " is in " + mod['name'].string() + ".ko\n" 12762306a36Sopenharmony_ci gdb.write(s) 12862306a36Sopenharmony_ci return 12962306a36Sopenharmony_ci gdb.write("0x%x is not in any module text section\n" % addr) 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ciLxFindTextAddrinMod() 132