1 # 2 # gdb helper commands and functions for Linux 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 12 # 13 14 import gdb 15 import os 16 import re 17 18 from linux import modules, utils, constants 19 20 21 if hasattr(gdb, 'Breakpoint'): 22 class LoadModuleBreakpoint(gdb.Breakpoint) 23 def __init__(self, spec, gdb_command): 24 super(LoadModuleBreakpoint, self). 25 self.silent = True 26 self.gdb_command = gdb_command 27 28 def stop(self): 29 module = gdb.parse_and_eval("mod") 30 module_name = module['name'].strin 31 cmd = self.gdb_command 32 33 # enforce update if object file is 34 cmd.module_files_updated = False 35 36 # Disable pagination while reporti 37 # The console input is blocked in 38 # get stuck waiting for the user t 39 show_pagination = gdb.execute("sho 40 pagination = show_pagination.endsw 41 gdb.execute("set pagination off") 42 43 if module_name in cmd.loaded_modul 44 gdb.write("refreshing all symb 45 "'{0}'\n".format(mod 46 cmd.load_all_symbols() 47 else: 48 cmd.load_module_symbols(module 49 50 # restore pagination state 51 gdb.execute("set pagination %s" % 52 53 return False 54 55 56 class LxSymbols(gdb.Command): 57 """(Re-)load symbols of Linux kernel and c 58 59 The kernel (vmlinux) is taken from the current 60 are scanned recursively, starting in the same 61 search path can be extended by a space separat 62 lx-symbols command.""" 63 64 module_paths = [] 65 module_files = [] 66 module_files_updated = False 67 loaded_modules = [] 68 breakpoint = None 69 70 def __init__(self): 71 super(LxSymbols, self).__init__("lx-sy 72 gdb.CO 73 74 def _update_module_files(self): 75 self.module_files = [] 76 for path in self.module_paths: 77 gdb.write("scanning for modules in 78 for root, dirs, files in os.walk(p 79 for name in files: 80 if name.endswith(".ko") or 81 self.module_files.appe 82 self.module_files_updated = True 83 84 def _get_module_file(self, module_name): 85 module_pattern = r".*/{0}\.ko(?:.debug 86 module_name.replace("_", r"[_\-]") 87 for name in self.module_files: 88 if re.match(module_pattern, name) 89 return name 90 return None 91 92 def _section_arguments(self, module, modul 93 try: 94 sect_attrs = module['sect_attrs']. 95 except gdb.error: 96 return str(module_addr) 97 98 attrs = sect_attrs['attrs'] 99 section_name_to_address = { 100 attrs[n]['battr']['attr']['name']. 101 for n in range(int(sect_attrs['nse 102 103 textaddr = section_name_to_address.get 104 args = [] 105 for section_name in [".data", ".data.. 106 ".text.hot", ".te 107 address = section_name_to_address. 108 if address: 109 args.append(" -s {name} {addr} 110 name=section_name, addr=st 111 return "{textaddr} {sections}".format( 112 textaddr=textaddr, sections="".joi 113 114 def load_module_symbols(self, module): 115 module_name = module['name'].string() 116 module_addr = str(module['mem'][consta 117 118 module_file = self._get_module_file(mo 119 if not module_file and not self.module 120 self._update_module_files() 121 module_file = self._get_module_fil 122 123 if module_file: 124 if utils.is_target_arch('s390'): 125 # Module text is preceded by P 126 module_arch = module['arch'] 127 plt_offset = int(module_arch[' 128 plt_size = int(module_arch['pl 129 module_addr = hex(int(module_a 130 gdb.write("loading @{addr}: {filen 131 addr=module_addr, filename=mod 132 cmdline = "add-symbol-file {filena 133 filename=module_file, 134 sections=self._section_argumen 135 gdb.execute(cmdline, to_string=Tru 136 if module_name not in self.loaded_ 137 self.loaded_modules.append(mod 138 else: 139 gdb.write("no module object found 140 141 def load_all_symbols(self): 142 gdb.write("loading vmlinux\n") 143 144 # Dropping symbols will disable all br 145 # and restore them afterward. 146 saved_states = [] 147 if hasattr(gdb, 'breakpoints') and not 148 for bp in gdb.breakpoints(): 149 saved_states.append({'breakpoi 150 151 # drop all current symbols and reload 152 orig_vmlinux = 'vmlinux' 153 for obj in gdb.objfiles(): 154 if (obj.filename.endswith('vmlinux 155 obj.filename.endswith('vmlinux 156 orig_vmlinux = obj.filename 157 gdb.execute("symbol-file", to_string=T 158 gdb.execute("symbol-file {0}".format(o 159 160 self.loaded_modules = [] 161 module_list = modules.module_list() 162 if not module_list: 163 gdb.write("no modules found\n") 164 else: 165 [self.load_module_symbols(module) 166 167 for saved_state in saved_states: 168 saved_state['breakpoint'].enabled 169 170 def invoke(self, arg, from_tty): 171 self.module_paths = [os.path.abspath(o 172 for p in arg.spli 173 self.module_paths.append(os.getcwd()) 174 175 # enforce update 176 self.module_files = [] 177 self.module_files_updated = False 178 179 self.load_all_symbols() 180 181 if hasattr(gdb, 'Breakpoint'): 182 if self.breakpoint is not None: 183 self.breakpoint.delete() 184 self.breakpoint = None 185 self.breakpoint = LoadModuleBreakp 186 "kernel/module/main.c:do_init_ 187 else: 188 gdb.write("Note: symbol update on 189 "with this gdb version\n 190 191 192 LxSymbols()
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.