1850202e1SJan Kiszka# 2850202e1SJan Kiszka# gdb helper commands and functions for Linux kernel debugging 3850202e1SJan Kiszka# 4850202e1SJan Kiszka# module tools 5850202e1SJan Kiszka# 6850202e1SJan Kiszka# Copyright (c) Siemens AG, 2013 7850202e1SJan Kiszka# 8850202e1SJan Kiszka# Authors: 9850202e1SJan Kiszka# Jan Kiszka <[email protected]> 10850202e1SJan Kiszka# 11850202e1SJan Kiszka# This work is licensed under the terms of the GNU GPL version 2. 12850202e1SJan Kiszka# 13850202e1SJan Kiszka 14850202e1SJan Kiszkaimport gdb 15850202e1SJan Kiszka 16b4aff751SPankaj Raghavfrom linux import cpus, utils, lists, constants 17850202e1SJan Kiszka 18850202e1SJan Kiszka 19850202e1SJan Kiszkamodule_type = utils.CachedType("struct module") 20850202e1SJan Kiszka 21850202e1SJan Kiszka 22*2c259a91SEtienne Buiradef has_modules(): 23*2c259a91SEtienne Buira return utils.gdb_eval_or_none("modules") is not None 24*2c259a91SEtienne Buira 25fffb944cSJan Kiszkadef module_list(): 26850202e1SJan Kiszka global module_type 27958ef8a0SKieran Bingham modules = utils.gdb_eval_or_none("modules") 28958ef8a0SKieran Bingham if modules is None: 29958ef8a0SKieran Bingham return 30958ef8a0SKieran Bingham 31fffb944cSJan Kiszka module_ptr_type = module_type.get_type().pointer() 32850202e1SJan Kiszka 33619ccaf3SKieran Bingham for module in lists.list_for_each_entry(modules, module_ptr_type, "list"): 34619ccaf3SKieran Bingham yield module 35276d97d9SPantelis Koukousoulas 367b599ef5SJan Kiszka 377b599ef5SJan Kiszkadef find_module_by_name(name): 38fffb944cSJan Kiszka for module in module_list(): 397b599ef5SJan Kiszka if module['name'].string() == name: 407b599ef5SJan Kiszka return module 417b599ef5SJan Kiszka return None 427b599ef5SJan Kiszka 437b599ef5SJan Kiszka 447b599ef5SJan Kiszkaclass LxModule(gdb.Function): 457b599ef5SJan Kiszka """Find module by name and return the module variable. 467b599ef5SJan Kiszka 477b599ef5SJan Kiszka$lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules 487b599ef5SJan Kiszkaof the target and return that module variable which MODULE matches.""" 497b599ef5SJan Kiszka 507b599ef5SJan Kiszka def __init__(self): 517b599ef5SJan Kiszka super(LxModule, self).__init__("lx_module") 527b599ef5SJan Kiszka 537b599ef5SJan Kiszka def invoke(self, mod_name): 547b599ef5SJan Kiszka mod_name = mod_name.string() 557b599ef5SJan Kiszka module = find_module_by_name(mod_name) 567b599ef5SJan Kiszka if module: 577b599ef5SJan Kiszka return module.dereference() 587b599ef5SJan Kiszka else: 597b599ef5SJan Kiszka raise gdb.GdbError("Unable to find MODULE " + mod_name) 607b599ef5SJan Kiszka 617b599ef5SJan Kiszka 627b599ef5SJan KiszkaLxModule() 635403727fSJan Kiszka 645403727fSJan Kiszka 655403727fSJan Kiszkaclass LxLsmod(gdb.Command): 665403727fSJan Kiszka """List currently loaded modules.""" 675403727fSJan Kiszka 685403727fSJan Kiszka _module_use_type = utils.CachedType("struct module_use") 695403727fSJan Kiszka 705403727fSJan Kiszka def __init__(self): 715403727fSJan Kiszka super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) 725403727fSJan Kiszka 735403727fSJan Kiszka def invoke(self, arg, from_tty): 745403727fSJan Kiszka gdb.write( 755403727fSJan Kiszka "Address{0} Module Size Used by\n".format( 765403727fSJan Kiszka " " if utils.get_long_type().sizeof == 8 else "")) 775403727fSJan Kiszka 78fffb944cSJan Kiszka for module in module_list(): 79fb40b053SKuan-Ying Lee text = module['mem'][constants.LX_MOD_TEXT] 80fb40b053SKuan-Ying Lee text_addr = str(text['base']).split()[0] 81fb40b053SKuan-Ying Lee total_size = 0 82fb40b053SKuan-Ying Lee 83fb40b053SKuan-Ying Lee for i in range(constants.LX_MOD_TEXT, constants.LX_MOD_RO_AFTER_INIT + 1): 84fb40b053SKuan-Ying Lee total_size += module['mem'][i]['size'] 85fb40b053SKuan-Ying Lee 865403727fSJan Kiszka gdb.write("{address} {name:<19} {size:>8} {ref}".format( 87fb40b053SKuan-Ying Lee address=text_addr, 885403727fSJan Kiszka name=module['name'].string(), 89fb40b053SKuan-Ying Lee size=str(total_size), 900c22fde8SJan Kiszka ref=str(module['refcnt']['counter'] - 1))) 915403727fSJan Kiszka 925403727fSJan Kiszka t = self._module_use_type.get_type().pointer() 935403727fSJan Kiszka first = True 94619ccaf3SKieran Bingham sources = module['source_list'] 95619ccaf3SKieran Bingham for use in lists.list_for_each_entry(sources, t, "source_list"): 965403727fSJan Kiszka gdb.write("{separator}{name}".format( 975403727fSJan Kiszka separator=" " if first else ",", 985403727fSJan Kiszka name=use['source']['name'].string())) 995403727fSJan Kiszka first = False 100619ccaf3SKieran Bingham 1015403727fSJan Kiszka gdb.write("\n") 1025403727fSJan Kiszka 1035403727fSJan KiszkaLxLsmod() 10482141540SKuan-Ying Lee 10582141540SKuan-Ying Leedef help(): 10682141540SKuan-Ying Lee t = """Usage: lx-getmod-by-textaddr [Heximal Address] 10782141540SKuan-Ying Lee Example: lx-getmod-by-textaddr 0xffff800002d305ac\n""" 10882141540SKuan-Ying Lee gdb.write("Unrecognized command\n") 10982141540SKuan-Ying Lee raise gdb.GdbError(t) 11082141540SKuan-Ying Lee 11182141540SKuan-Ying Leeclass LxFindTextAddrinMod(gdb.Command): 11282141540SKuan-Ying Lee '''Look up loaded kernel module by text address.''' 11382141540SKuan-Ying Lee 11482141540SKuan-Ying Lee def __init__(self): 11582141540SKuan-Ying Lee super(LxFindTextAddrinMod, self).__init__('lx-getmod-by-textaddr', gdb.COMMAND_SUPPORT) 11682141540SKuan-Ying Lee 11782141540SKuan-Ying Lee def invoke(self, arg, from_tty): 11882141540SKuan-Ying Lee args = gdb.string_to_argv(arg) 11982141540SKuan-Ying Lee 12082141540SKuan-Ying Lee if len(args) != 1: 12182141540SKuan-Ying Lee help() 12282141540SKuan-Ying Lee 12382141540SKuan-Ying Lee addr = gdb.Value(int(args[0], 16)).cast(utils.get_ulong_type()) 12482141540SKuan-Ying Lee for mod in module_list(): 12582141540SKuan-Ying Lee mod_text_start = mod['mem'][constants.LX_MOD_TEXT]['base'] 12682141540SKuan-Ying Lee mod_text_end = mod_text_start + mod['mem'][constants.LX_MOD_TEXT]['size'].cast(utils.get_ulong_type()) 12782141540SKuan-Ying Lee 12882141540SKuan-Ying Lee if addr >= mod_text_start and addr < mod_text_end: 12982141540SKuan-Ying Lee s = "0x%x" % addr + " is in " + mod['name'].string() + ".ko\n" 13082141540SKuan-Ying Lee gdb.write(s) 13182141540SKuan-Ying Lee return 13282141540SKuan-Ying Lee gdb.write("0x%x is not in any module text section\n" % addr) 13382141540SKuan-Ying Lee 13482141540SKuan-Ying LeeLxFindTextAddrinMod() 135