]>
Commit | Line | Data |
---|---|---|
850202e1 JK |
1 | # |
2 | # gdb helper commands and functions for Linux kernel debugging | |
3 | # | |
4 | # module tools | |
5 | # | |
6 | # Copyright (c) Siemens AG, 2013 | |
7 | # | |
8 | # Authors: | |
9 | # Jan Kiszka <jan.kiszka@siemens.com> | |
10 | # | |
11 | # This work is licensed under the terms of the GNU GPL version 2. | |
12 | # | |
13 | ||
14 | import gdb | |
15 | ||
5403727f | 16 | from linux import cpus, utils |
850202e1 JK |
17 | |
18 | ||
19 | module_type = utils.CachedType("struct module") | |
20 | ||
21 | ||
fffb944c JK |
22 | def module_list(): |
23 | global module_type | |
24 | module_ptr_type = module_type.get_type().pointer() | |
25 | modules = gdb.parse_and_eval("modules") | |
26 | entry = modules['next'] | |
27 | end_of_list = modules.address | |
7b599ef5 | 28 | |
fffb944c JK |
29 | while entry != end_of_list: |
30 | yield utils.container_of(entry, module_ptr_type, "list") | |
31 | entry = entry['next'] | |
276d97d9 | 32 | |
7b599ef5 JK |
33 | |
34 | def find_module_by_name(name): | |
fffb944c | 35 | for module in module_list(): |
7b599ef5 JK |
36 | if module['name'].string() == name: |
37 | return module | |
38 | return None | |
39 | ||
40 | ||
41 | class LxModule(gdb.Function): | |
42 | """Find module by name and return the module variable. | |
43 | ||
44 | $lx_module("MODULE"): Given the name MODULE, iterate over all loaded modules | |
45 | of the target and return that module variable which MODULE matches.""" | |
46 | ||
47 | def __init__(self): | |
48 | super(LxModule, self).__init__("lx_module") | |
49 | ||
50 | def invoke(self, mod_name): | |
51 | mod_name = mod_name.string() | |
52 | module = find_module_by_name(mod_name) | |
53 | if module: | |
54 | return module.dereference() | |
55 | else: | |
56 | raise gdb.GdbError("Unable to find MODULE " + mod_name) | |
57 | ||
58 | ||
59 | LxModule() | |
5403727f JK |
60 | |
61 | ||
62 | class LxLsmod(gdb.Command): | |
63 | """List currently loaded modules.""" | |
64 | ||
65 | _module_use_type = utils.CachedType("struct module_use") | |
66 | ||
67 | def __init__(self): | |
68 | super(LxLsmod, self).__init__("lx-lsmod", gdb.COMMAND_DATA) | |
69 | ||
70 | def invoke(self, arg, from_tty): | |
71 | gdb.write( | |
72 | "Address{0} Module Size Used by\n".format( | |
73 | " " if utils.get_long_type().sizeof == 8 else "")) | |
74 | ||
fffb944c | 75 | for module in module_list(): |
5403727f JK |
76 | gdb.write("{address} {name:<19} {size:>8} {ref}".format( |
77 | address=str(module['module_core']).split()[0], | |
78 | name=module['name'].string(), | |
276d97d9 | 79 | size=str(module['core_size']), |
ca3f172c | 80 | ref=str(module['refcnt']['counter']))) |
5403727f JK |
81 | |
82 | source_list = module['source_list'] | |
83 | t = self._module_use_type.get_type().pointer() | |
84 | entry = source_list['next'] | |
85 | first = True | |
86 | while entry != source_list.address: | |
87 | use = utils.container_of(entry, t, "source_list") | |
88 | gdb.write("{separator}{name}".format( | |
89 | separator=" " if first else ",", | |
90 | name=use['source']['name'].string())) | |
91 | first = False | |
92 | entry = entry['next'] | |
93 | gdb.write("\n") | |
94 | ||
95 | ||
96 | LxLsmod() |