kernel/module.c: do not inline do_init_module()
[deliverable/linux.git] / scripts / gdb / linux / symbols.py
CommitLineData
66051720
JK
1#
2# gdb helper commands and functions for Linux kernel debugging
3#
4# load kernel and module symbols
5#
6# Copyright (c) Siemens AG, 2011-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
14import gdb
15import os
16import re
17import string
18
19from linux import modules, utils
20
21
22class LxSymbols(gdb.Command):
23 """(Re-)load symbols of Linux kernel and currently loaded modules.
24
25The kernel (vmlinux) is taken from the current working directly. Modules (.ko)
26are scanned recursively, starting in the same directory. Optionally, the module
27search path can be extended by a space separated list of paths passed to the
28lx-symbols command."""
29
30 module_paths = []
31 module_files = []
32 module_files_updated = False
33
34 def __init__(self):
35 super(LxSymbols, self).__init__("lx-symbols", gdb.COMMAND_FILES,
36 gdb.COMPLETE_FILENAME)
37
38 def _update_module_files(self):
39 self.module_files = []
40 for path in self.module_paths:
41 gdb.write("scanning for modules in {0}\n".format(path))
42 for root, dirs, files in os.walk(path):
43 for name in files:
44 if name.endswith(".ko"):
45 self.module_files.append(root + "/" + name)
46 self.module_files_updated = True
47
48 def _get_module_file(self, module_name):
49 module_pattern = ".*/{0}\.ko$".format(
50 string.replace(module_name, "_", r"[_\-]"))
51 for name in self.module_files:
52 if re.match(module_pattern, name) and os.path.exists(name):
53 return name
54 return None
55
56 def _section_arguments(self, module):
57 try:
58 sect_attrs = module['sect_attrs'].dereference()
59 except gdb.error:
60 return ""
61 attrs = sect_attrs['attrs']
62 section_name_to_address = {
63 attrs[n]['name'].string() : attrs[n]['address']
64 for n in range(sect_attrs['nsections'])}
65 args = []
66 for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]:
67 address = section_name_to_address.get(section_name)
68 if address:
69 args.append(" -s {name} {addr}".format(
70 name=section_name, addr=str(address)))
71 return "".join(args)
72
73 def load_module_symbols(self, module):
74 module_name = module['name'].string()
75 module_addr = str(module['module_core']).split()[0]
76
77 module_file = self._get_module_file(module_name)
78 if not module_file and not self.module_files_updated:
79 self._update_module_files()
80 module_file = self._get_module_file(module_name)
81
82 if module_file:
83 gdb.write("loading @{addr}: {filename}\n".format(
84 addr=module_addr, filename=module_file))
85 cmdline = "add-symbol-file {filename} {addr}{sections}".format(
86 filename=module_file,
87 addr=module_addr,
88 sections=self._section_arguments(module))
89 gdb.execute(cmdline, to_string=True)
90 else:
91 gdb.write("no module object found for '{0}'\n".format(module_name))
92
93 def load_all_symbols(self):
94 gdb.write("loading vmlinux\n")
95
96 # Dropping symbols will disable all breakpoints. So save their states
97 # and restore them afterward.
98 saved_states = []
99 if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None:
100 for bp in gdb.breakpoints():
101 saved_states.append({'breakpoint': bp, 'enabled': bp.enabled})
102
103 # drop all current symbols and reload vmlinux
104 gdb.execute("symbol-file", to_string=True)
105 gdb.execute("symbol-file vmlinux")
106
107 module_list = modules.ModuleList()
108 if not module_list:
109 gdb.write("no modules found\n")
110 else:
111 [self.load_module_symbols(module) for module in module_list]
112
113 for saved_state in saved_states:
114 saved_state['breakpoint'].enabled = saved_state['enabled']
115
116 def invoke(self, arg, from_tty):
117 self.module_paths = arg.split()
118 self.module_paths.append(os.getcwd())
119
120 # enforce update
121 self.module_files = []
122 self.module_files_updated = False
123
124 self.load_all_symbols()
125
126
127LxSymbols()
This page took 0.030401 seconds and 5 git commands to generate.