1 # 1 # 2 # gdb helper commands and functions for Linux 2 # gdb helper commands and functions for Linux kernel debugging 3 # 3 # 4 # module tools 4 # module tools 5 # 5 # 6 # Copyright (c) Siemens AG, 2013 6 # Copyright (c) Siemens AG, 2013 7 # 7 # 8 # Authors: 8 # Authors: 9 # Jan Kiszka <jan.kiszka@siemens.com> 9 # Jan Kiszka <jan.kiszka@siemens.com> 10 # 10 # 11 # This work is licensed under the terms of the 11 # This work is licensed under the terms of the GNU GPL version 2. 12 # 12 # 13 13 14 import gdb 14 import gdb 15 15 16 from linux import cpus, utils, lists, constant 16 from linux import cpus, utils, lists, constants 17 17 18 18 19 module_type = utils.CachedType("struct module" 19 module_type = utils.CachedType("struct module") 20 20 21 21 22 def module_list(): 22 def module_list(): 23 global module_type 23 global module_type 24 modules = utils.gdb_eval_or_none("modules" 24 modules = utils.gdb_eval_or_none("modules") 25 if modules is None: 25 if modules is None: 26 return 26 return 27 27 28 module_ptr_type = module_type.get_type().p 28 module_ptr_type = module_type.get_type().pointer() 29 29 30 for module in lists.list_for_each_entry(mo 30 for module in lists.list_for_each_entry(modules, module_ptr_type, "list"): 31 yield module 31 yield module 32 32 33 33 34 def find_module_by_name(name): 34 def find_module_by_name(name): 35 for module in module_list(): 35 for module in module_list(): 36 if module['name'].string() == name: 36 if module['name'].string() == name: 37 return module 37 return module 38 return None 38 return None 39 39 40 40 41 class LxModule(gdb.Function): 41 class LxModule(gdb.Function): 42 """Find module by name and return the modu 42 """Find module by name and return the module variable. 43 43 44 $lx_module("MODULE"): Given the name MODULE, i 44 $lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules 45 of the target and return that module variable 45 of the target and return that module variable which MODULE matches.""" 46 46 47 def __init__(self): 47 def __init__(self): 48 super(LxModule, self).__init__("lx_mod 48 super(LxModule, self).__init__("lx_module") 49 49 50 def invoke(self, mod_name): 50 def invoke(self, mod_name): 51 mod_name = mod_name.string() 51 mod_name = mod_name.string() 52 module = find_module_by_name(mod_name) 52 module = find_module_by_name(mod_name) 53 if module: 53 if module: 54 return module.dereference() 54 return module.dereference() 55 else: 55 else: 56 raise gdb.GdbError("Unable to find 56 raise gdb.GdbError("Unable to find MODULE " + mod_name) 57 57 58 58 59 LxModule() 59 LxModule() 60 60 61 61 62 class LxLsmod(gdb.Command): 62 class LxLsmod(gdb.Command): 63 """List currently loaded modules.""" 63 """List currently loaded modules.""" 64 64 65 _module_use_type = utils.CachedType("struc 65 _module_use_type = utils.CachedType("struct module_use") 66 66 67 def __init__(self): 67 def __init__(self): 68 super(LxLsmod, self).__init__("lx-lsmo 68 super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) 69 69 70 def invoke(self, arg, from_tty): 70 def invoke(self, arg, from_tty): 71 gdb.write( 71 gdb.write( 72 "Address{0} Module 72 "Address{0} Module Size Used by\n".format( 73 " " if utils.get_long_t 73 " " if utils.get_long_type().sizeof == 8 else "")) 74 74 75 for module in module_list(): 75 for module in module_list(): 76 text = module['mem'][constants.LX_ 76 text = module['mem'][constants.LX_MOD_TEXT] 77 text_addr = str(text['base']).spli 77 text_addr = str(text['base']).split()[0] 78 total_size = 0 78 total_size = 0 79 79 80 for i in range(constants.LX_MOD_TE 80 for i in range(constants.LX_MOD_TEXT, constants.LX_MOD_RO_AFTER_INIT + 1): 81 total_size += module['mem'][i] 81 total_size += module['mem'][i]['size'] 82 82 83 gdb.write("{address} {name:<19} {s 83 gdb.write("{address} {name:<19} {size:>8} {ref}".format( 84 address=text_addr, 84 address=text_addr, 85 name=module['name'].string(), 85 name=module['name'].string(), 86 size=str(total_size), 86 size=str(total_size), 87 ref=str(module['refcnt']['coun 87 ref=str(module['refcnt']['counter'] - 1))) 88 88 89 t = self._module_use_type.get_type 89 t = self._module_use_type.get_type().pointer() 90 first = True 90 first = True 91 sources = module['source_list'] 91 sources = module['source_list'] 92 for use in lists.list_for_each_ent 92 for use in lists.list_for_each_entry(sources, t, "source_list"): 93 gdb.write("{separator}{name}". 93 gdb.write("{separator}{name}".format( 94 separator=" " if first els 94 separator=" " if first else ",", 95 name=use['source']['name'] 95 name=use['source']['name'].string())) 96 first = False 96 first = False 97 97 98 gdb.write("\n") 98 gdb.write("\n") 99 99 100 LxLsmod() 100 LxLsmod() 101 101 102 def help(): 102 def help(): 103 t = """Usage: lx-getmod-by-textaddr [Hexim 103 t = """Usage: lx-getmod-by-textaddr [Heximal Address] 104 Example: lx-getmod-by-textaddr 0xffff80000 104 Example: lx-getmod-by-textaddr 0xffff800002d305ac\n""" 105 gdb.write("Unrecognized command\n") 105 gdb.write("Unrecognized command\n") 106 raise gdb.GdbError(t) 106 raise gdb.GdbError(t) 107 107 108 class LxFindTextAddrinMod(gdb.Command): 108 class LxFindTextAddrinMod(gdb.Command): 109 '''Look up loaded kernel module by text ad 109 '''Look up loaded kernel module by text address.''' 110 110 111 def __init__(self): 111 def __init__(self): 112 super(LxFindTextAddrinMod, self).__ini 112 super(LxFindTextAddrinMod, self).__init__('lx-getmod-by-textaddr', gdb.COMMAND_SUPPORT) 113 113 114 def invoke(self, arg, from_tty): 114 def invoke(self, arg, from_tty): 115 args = gdb.string_to_argv(arg) 115 args = gdb.string_to_argv(arg) 116 116 117 if len(args) != 1: 117 if len(args) != 1: 118 help() 118 help() 119 119 120 addr = gdb.Value(int(args[0], 16)).cas 120 addr = gdb.Value(int(args[0], 16)).cast(utils.get_ulong_type()) 121 for mod in module_list(): 121 for mod in module_list(): 122 mod_text_start = mod['mem'][consta 122 mod_text_start = mod['mem'][constants.LX_MOD_TEXT]['base'] 123 mod_text_end = mod_text_start + mo 123 mod_text_end = mod_text_start + mod['mem'][constants.LX_MOD_TEXT]['size'].cast(utils.get_ulong_type()) 124 124 125 if addr >= mod_text_start and addr 125 if addr >= mod_text_start and addr < mod_text_end: 126 s = "0x%x" % addr + " is in " 126 s = "0x%x" % addr + " is in " + mod['name'].string() + ".ko\n" 127 gdb.write(s) 127 gdb.write(s) 128 return 128 return 129 gdb.write("0x%x is not in any module t 129 gdb.write("0x%x is not in any module text section\n" % addr) 130 130 131 LxFindTextAddrinMod() 131 LxFindTextAddrinMod()
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.