~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/gdb/linux/proc.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 # SPDX-License-Identifier: GPL-2.0
  2 #
  3 # gdb helper commands and functions for Linux kernel debugging
  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 GNU GPL version 2.
 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 the current kernel.
 27         Equivalent to cat /proc/cmdline on a running target"""
 28 
 29     def __init__(self):
 30         super(LxCmdLine, self).__init__("lx-cmdline", gdb.COMMAND_DATA)
 31 
 32     def invoke(self, arg, from_tty):
 33         gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n")
 34 
 35 
 36 LxCmdLine()
 37 
 38 
 39 class LxVersion(gdb.Command):
 40     """ Report the Linux Version of the current kernel.
 41         Equivalent to cat /proc/version on a running target"""
 42 
 43     def __init__(self):
 44         super(LxVersion, self).__init__("lx-version", gdb.COMMAND_DATA)
 45 
 46     def invoke(self, arg, from_tty):
 47         # linux_banner should contain a newline
 48         gdb.write(gdb.parse_and_eval("(char *)linux_banner").string())
 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(child, depth + 1):
 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_str)
 72         width = 4 if resource['end'] < 0x10000 else 8
 73         # Iterate straight to the first child
 74         for res, depth in get_resources(resource['child'], 0):
 75             start = int(res['start'])
 76             end = int(res['end'])
 77             gdb.write(" " * depth * 2 +
 78                       "{0:0{1}x}-".format(start, width) +
 79                       "{0:0{1}x} : ".format(end, width) +
 80                       res['name'].string() + "\n")
 81 
 82 
 83 class LxIOMem(gdb.Command):
 84     """Identify the IO memory resource locations defined by the kernel
 85 
 86 Equivalent to cat /proc/iomem on a running target"""
 87 
 88     def __init__(self):
 89         super(LxIOMem, self).__init__("lx-iomem", gdb.COMMAND_DATA)
 90 
 91     def invoke(self, arg, from_tty):
 92         return show_lx_resources("iomem_resource")
 93 
 94 
 95 LxIOMem()
 96 
 97 
 98 class LxIOPorts(gdb.Command):
 99     """Identify the IO port resource locations defined by the kernel
100 
101 Equivalent to cat /proc/ioports on a running target"""
102 
103     def __init__(self):
104         super(LxIOPorts, self).__init__("lx-ioports", gdb.COMMAND_DATA)
105 
106     def invoke(self, arg, from_tty):
107         return show_lx_resources("ioport_resource")
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: ",nodiratime"}
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: ",noatime",
134             constants.LX_MNT_NODIRATIME: ",nodiratime",
135             constants.LX_MNT_RELATIME: ",relatime"}
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 process namespace.
143 
144 Equivalent to cat /proc/mounts on a running target
145 An integer value can be supplied to display the mount
146 values of that process namespace"""
147 
148     def __init__(self):
149         super(LxMounts, self).__init__("lx-mounts", gdb.COMMAND_DATA)
150 
151     # Equivalent to proc_namespace.c:show_vfsmnt
152     # However, that has the ability to call into s_op functions
153     # whereas we cannot and must make do with the information we can obtain.
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 PID as integer value")
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 a process with PID {}"
167                                .format(pid))
168 
169         namespace = task['nsproxy']['mnt_ns']
170         if not namespace:
171             raise gdb.GdbError("No namespace for current process")
172 
173         gdb.write("{:^18} {:^15} {:>9} {} {} options\n".format(
174                   "mount", "super_block", "devname", "pathname", "fstype"))
175 
176         for mnt in rbtree.rb_inorder_for_each_entry(namespace['mounts'], mount_ptr_type, "mnt_node"):
177             devname = mnt['mnt_devname'].string()
178             devname = devname if devname else "none"
179 
180             pathname = ""
181             parent = mnt
182             while True:
183                 mntpoint = parent['mnt_mountpoint']
184                 pathname = vfs.dentry_name(mntpoint) + pathname
185                 if (parent == parent['mnt_parent']):
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']['name'].string()
194             s_flags = int(superblock['s_flags'])
195             m_flags = int(mnt['mnt']['mnt_flags'])
196             rd = "ro" if (s_flags & constants.LX_SB_RDONLY) else "rw"
197 
198             gdb.write("{} {} {} {} {} {}{}{} 0 0\n".format(
199                       mnt.format_string(), superblock.format_string(), devname,
200                       pathname, fstype, rd, info_opts(FS_INFO, s_flags),
201                       info_opts(MNT_INFO, m_flags)))
202 
203 
204 LxMounts()
205 
206 
207 class LxFdtDump(gdb.Command):
208     """Output Flattened Device Tree header and dump FDT blob to the filename
209        specified as the command argument. Equivalent to
210        'cat /proc/fdt > fdtdump.dtb' on a running target"""
211 
212     def __init__(self):
213         super(LxFdtDump, self).__init__("lx-fdtdump", gdb.COMMAND_DATA,
214                                         gdb.COMPLETE_FILENAME)
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_header_be,
227                                        fdt_header['magic'],
228                                        fdt_header['totalsize'],
229                                        fdt_header['off_dt_struct'],
230                                        fdt_header['off_dt_strings'],
231                                        fdt_header['off_mem_rsvmap'],
232                                        fdt_header['version'],
233                                        fdt_header['last_comp_version']))
234 
235     def invoke(self, arg, from_tty):
236 
237         if not constants.LX_CONFIG_OF:
238             raise gdb.GdbError("Kernel not compiled with CONFIG_OF\n")
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 *) initial_boot_params")
247         py_fdt_header = py_fdt_header_ptr.dereference()
248 
249         fdt_header = self.fdthdr_to_cpu(py_fdt_header)
250 
251         if fdt_header[0] != constants.LX_OF_DT_HEADER:
252             raise gdb.GdbError("No flattened device tree magic found\n")
253 
254         gdb.write("fdt_magic:         0x{:02X}\n".format(fdt_header[0]))
255         gdb.write("fdt_totalsize:     0x{:02X}\n".format(fdt_header[1]))
256         gdb.write("off_dt_struct:     0x{:02X}\n".format(fdt_header[2]))
257         gdb.write("off_dt_strings:    0x{:02X}\n".format(fdt_header[3]))
258         gdb.write("off_mem_rsvmap:    0x{:02X}\n".format(fdt_header[4]))
259         gdb.write("version:           {}\n".format(fdt_header[5]))
260         gdb.write("last_comp_version: {}\n".format(fdt_header[6]))
261 
262         inf = gdb.inferiors()[0]
263         fdt_buf = utils.read_memoryview(inf, py_fdt_header_ptr,
264                                         fdt_header[1]).tobytes()
265 
266         try:
267             f = open(filename, 'wb')
268         except gdb.error:
269             raise gdb.GdbError("Could not open file to dump fdt")
270 
271         f.write(fdt_buf)
272         f.close()
273 
274         gdb.write("Dumped fdt blob to " + filename + "\n")
275 
276 
277 LxFdtDump()

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php