1 # SPDX-License-Identifier: GPL-2.0 2 # 3 # gdb helper commands and functions for Linux 4 # 5 # Kernel proc information reader 6 # 7 # Copyright (c) 2016 Linaro Ltd 8 # 9 # Authors: 10 # Kieran Bingham <kieran.bingham@linaro.org> 11 # 12 # This work is licensed under the terms of the 13 # 14 15 import gdb 16 from linux import constants 17 from linux import utils 18 from linux import tasks 19 from linux import lists 20 from linux import vfs 21 from linux import rbtree 22 from struct import * 23 24 25 class LxCmdLine(gdb.Command): 26 """ Report the Linux Commandline used in t 27 Equivalent to cat /proc/cmdline on a r 28 29 def __init__(self): 30 super(LxCmdLine, self).__init__("lx-cm 31 32 def invoke(self, arg, from_tty): 33 gdb.write(gdb.parse_and_eval("saved_co 34 35 36 LxCmdLine() 37 38 39 class LxVersion(gdb.Command): 40 """ Report the Linux Version of the curren 41 Equivalent to cat /proc/version on a r 42 43 def __init__(self): 44 super(LxVersion, self).__init__("lx-ve 45 46 def invoke(self, arg, from_tty): 47 # linux_banner should contain a newlin 48 gdb.write(gdb.parse_and_eval("(char *) 49 50 51 LxVersion() 52 53 54 # Resource Structure Printers 55 # /proc/iomem 56 # /proc/ioports 57 58 def get_resources(resource, depth): 59 while resource: 60 yield resource, depth 61 62 child = resource['child'] 63 if child: 64 for res, deep in get_resources(chi 65 yield res, deep 66 67 resource = resource['sibling'] 68 69 70 def show_lx_resources(resource_str): 71 resource = gdb.parse_and_eval(resource 72 width = 4 if resource['end'] < 0x10000 73 # Iterate straight to the first child 74 for res, depth in get_resources(resour 75 start = int(res['start']) 76 end = int(res['end']) 77 gdb.write(" " * depth * 2 + 78 "{0:0{1}x}-".format(star 79 "{0:0{1}x} : ".format(en 80 res['name'].string() + " 81 82 83 class LxIOMem(gdb.Command): 84 """Identify the IO memory resource locatio 85 86 Equivalent to cat /proc/iomem on a running tar 87 88 def __init__(self): 89 super(LxIOMem, self).__init__("lx-iome 90 91 def invoke(self, arg, from_tty): 92 return show_lx_resources("iomem_resour 93 94 95 LxIOMem() 96 97 98 class LxIOPorts(gdb.Command): 99 """Identify the IO port resource locations 100 101 Equivalent to cat /proc/ioports on a running t 102 103 def __init__(self): 104 super(LxIOPorts, self).__init__("lx-io 105 106 def invoke(self, arg, from_tty): 107 return show_lx_resources("ioport_resou 108 109 110 LxIOPorts() 111 112 113 # Mount namespace viewer 114 # /proc/mounts 115 116 def info_opts(lst, opt): 117 opts = "" 118 for key, string in lst.items(): 119 if opt & key: 120 opts += string 121 return opts 122 123 124 FS_INFO = {constants.LX_SB_SYNCHRONOUS: ",sync 125 constants.LX_SB_MANDLOCK: ",mand", 126 constants.LX_SB_DIRSYNC: ",dirsync" 127 constants.LX_SB_NOATIME: ",noatime" 128 constants.LX_SB_NODIRATIME: ",nodir 129 130 MNT_INFO = {constants.LX_MNT_NOSUID: ",nosuid" 131 constants.LX_MNT_NODEV: ",nodev", 132 constants.LX_MNT_NOEXEC: ",noexec" 133 constants.LX_MNT_NOATIME: ",noatim 134 constants.LX_MNT_NODIRATIME: ",nod 135 constants.LX_MNT_RELATIME: ",relat 136 137 mount_type = utils.CachedType("struct mount") 138 mount_ptr_type = mount_type.get_type().pointer 139 140 141 class LxMounts(gdb.Command): 142 """Report the VFS mounts of the current pr 143 144 Equivalent to cat /proc/mounts on a running ta 145 An integer value can be supplied to display th 146 values of that process namespace""" 147 148 def __init__(self): 149 super(LxMounts, self).__init__("lx-mou 150 151 # Equivalent to proc_namespace.c:show_vfsm 152 # However, that has the ability to call in 153 # whereas we cannot and must make do with 154 def invoke(self, arg, from_tty): 155 argv = gdb.string_to_argv(arg) 156 if len(argv) >= 1: 157 try: 158 pid = int(argv[0]) 159 except gdb.error: 160 raise gdb.GdbError("Provide a 161 else: 162 pid = 1 163 164 task = tasks.get_task_by_pid(pid) 165 if not task: 166 raise gdb.GdbError("Couldn't find 167 .format(pid)) 168 169 namespace = task['nsproxy']['mnt_ns'] 170 if not namespace: 171 raise gdb.GdbError("No namespace f 172 173 gdb.write("{:^18} {:^15} {:>9} {} {} o 174 "mount", "super_block", "dev 175 176 for mnt in rbtree.rb_inorder_for_each_ 177 devname = mnt['mnt_devname'].strin 178 devname = devname if devname else 179 180 pathname = "" 181 parent = mnt 182 while True: 183 mntpoint = parent['mnt_mountpo 184 pathname = vfs.dentry_name(mnt 185 if (parent == parent['mnt_pare 186 break 187 parent = parent['mnt_parent'] 188 189 if (pathname == ""): 190 pathname = "/" 191 192 superblock = mnt['mnt']['mnt_sb'] 193 fstype = superblock['s_type']['nam 194 s_flags = int(superblock['s_flags' 195 m_flags = int(mnt['mnt']['mnt_flag 196 rd = "ro" if (s_flags & constants. 197 198 gdb.write("{} {} {} {} {} {}{}{} 0 199 mnt.format_string(), sup 200 pathname, fstype, rd, in 201 info_opts(MNT_INFO, m_fl 202 203 204 LxMounts() 205 206 207 class LxFdtDump(gdb.Command): 208 """Output Flattened Device Tree header and 209 specified as the command argument. Equi 210 'cat /proc/fdt > fdtdump.dtb' on a runn 211 212 def __init__(self): 213 super(LxFdtDump, self).__init__("lx-fd 214 gdb.CO 215 216 def fdthdr_to_cpu(self, fdt_header): 217 218 fdt_header_be = ">IIIIIII" 219 fdt_header_le = "<IIIIIII" 220 221 if utils.get_target_endianness() == 1: 222 output_fmt = fdt_header_le 223 else: 224 output_fmt = fdt_header_be 225 226 return unpack(output_fmt, pack(fdt_hea 227 fdt_hea 228 fdt_hea 229 fdt_hea 230 fdt_hea 231 fdt_hea 232 fdt_hea 233 fdt_hea 234 235 def invoke(self, arg, from_tty): 236 237 if not constants.LX_CONFIG_OF: 238 raise gdb.GdbError("Kernel not com 239 240 if len(arg) == 0: 241 filename = "fdtdump.dtb" 242 else: 243 filename = arg 244 245 py_fdt_header_ptr = gdb.parse_and_eval 246 "(const struct fdt_header *) initi 247 py_fdt_header = py_fdt_header_ptr.dere 248 249 fdt_header = self.fdthdr_to_cpu(py_fdt 250 251 if fdt_header[0] != constants.LX_OF_DT 252 raise gdb.GdbError("No flattened d 253 254 gdb.write("fdt_magic: 0x{:02X} 255 gdb.write("fdt_totalsize: 0x{:02X} 256 gdb.write("off_dt_struct: 0x{:02X} 257 gdb.write("off_dt_strings: 0x{:02X} 258 gdb.write("off_mem_rsvmap: 0x{:02X} 259 gdb.write("version: {}\n".fo 260 gdb.write("last_comp_version: {}\n".fo 261 262 inf = gdb.inferiors()[0] 263 fdt_buf = utils.read_memoryview(inf, p 264 fdt_he 265 266 try: 267 f = open(filename, 'wb') 268 except gdb.error: 269 raise gdb.GdbError("Could not open 270 271 f.write(fdt_buf) 272 f.close() 273 274 gdb.write("Dumped fdt blob to " + file 275 276 277 LxFdtDump()
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.