]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - scripts/gdb/linux/proc.py
scsi: cxgb4i: call neigh_event_send() to update MAC address
[mirror_ubuntu-artful-kernel.git] / scripts / gdb / linux / proc.py
1 #
2 # gdb helper commands and functions for Linux kernel debugging
3 #
4 # Kernel proc information reader
5 #
6 # Copyright (c) 2016 Linaro Ltd
7 #
8 # Authors:
9 # Kieran Bingham <kieran.bingham@linaro.org>
10 #
11 # This work is licensed under the terms of the GNU GPL version 2.
12 #
13
14 import gdb
15 from linux import constants
16 from linux import utils
17 from linux import tasks
18 from linux import lists
19
20
21 class LxCmdLine(gdb.Command):
22 """ Report the Linux Commandline used in the current kernel.
23 Equivalent to cat /proc/cmdline on a running target"""
24
25 def __init__(self):
26 super(LxCmdLine, self).__init__("lx-cmdline", gdb.COMMAND_DATA)
27
28 def invoke(self, arg, from_tty):
29 gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n")
30
31 LxCmdLine()
32
33
34 class LxVersion(gdb.Command):
35 """ Report the Linux Version of the current kernel.
36 Equivalent to cat /proc/version on a running target"""
37
38 def __init__(self):
39 super(LxVersion, self).__init__("lx-version", gdb.COMMAND_DATA)
40
41 def invoke(self, arg, from_tty):
42 # linux_banner should contain a newline
43 gdb.write(gdb.parse_and_eval("linux_banner").string())
44
45 LxVersion()
46
47
48 # Resource Structure Printers
49 # /proc/iomem
50 # /proc/ioports
51
52 def get_resources(resource, depth):
53 while resource:
54 yield resource, depth
55
56 child = resource['child']
57 if child:
58 for res, deep in get_resources(child, depth + 1):
59 yield res, deep
60
61 resource = resource['sibling']
62
63
64 def show_lx_resources(resource_str):
65 resource = gdb.parse_and_eval(resource_str)
66 width = 4 if resource['end'] < 0x10000 else 8
67 # Iterate straight to the first child
68 for res, depth in get_resources(resource['child'], 0):
69 start = int(res['start'])
70 end = int(res['end'])
71 gdb.write(" " * depth * 2 +
72 "{0:0{1}x}-".format(start, width) +
73 "{0:0{1}x} : ".format(end, width) +
74 res['name'].string() + "\n")
75
76
77 class LxIOMem(gdb.Command):
78 """Identify the IO memory resource locations defined by the kernel
79
80 Equivalent to cat /proc/iomem on a running target"""
81
82 def __init__(self):
83 super(LxIOMem, self).__init__("lx-iomem", gdb.COMMAND_DATA)
84
85 def invoke(self, arg, from_tty):
86 return show_lx_resources("iomem_resource")
87
88 LxIOMem()
89
90
91 class LxIOPorts(gdb.Command):
92 """Identify the IO port resource locations defined by the kernel
93
94 Equivalent to cat /proc/ioports on a running target"""
95
96 def __init__(self):
97 super(LxIOPorts, self).__init__("lx-ioports", gdb.COMMAND_DATA)
98
99 def invoke(self, arg, from_tty):
100 return show_lx_resources("ioport_resource")
101
102 LxIOPorts()
103
104
105 # Mount namespace viewer
106 # /proc/mounts
107
108 def info_opts(lst, opt):
109 opts = ""
110 for key, string in lst.items():
111 if opt & key:
112 opts += string
113 return opts
114
115
116 FS_INFO = {constants.LX_MS_SYNCHRONOUS: ",sync",
117 constants.LX_MS_MANDLOCK: ",mand",
118 constants.LX_MS_DIRSYNC: ",dirsync",
119 constants.LX_MS_NOATIME: ",noatime",
120 constants.LX_MS_NODIRATIME: ",nodiratime"}
121
122 MNT_INFO = {constants.LX_MNT_NOSUID: ",nosuid",
123 constants.LX_MNT_NODEV: ",nodev",
124 constants.LX_MNT_NOEXEC: ",noexec",
125 constants.LX_MNT_NOATIME: ",noatime",
126 constants.LX_MNT_NODIRATIME: ",nodiratime",
127 constants.LX_MNT_RELATIME: ",relatime"}
128
129 mount_type = utils.CachedType("struct mount")
130 mount_ptr_type = mount_type.get_type().pointer()
131
132
133 class LxMounts(gdb.Command):
134 """Report the VFS mounts of the current process namespace.
135
136 Equivalent to cat /proc/mounts on a running target
137 An integer value can be supplied to display the mount
138 values of that process namespace"""
139
140 def __init__(self):
141 super(LxMounts, self).__init__("lx-mounts", gdb.COMMAND_DATA)
142
143 # Equivalent to proc_namespace.c:show_vfsmnt
144 # However, that has the ability to call into s_op functions
145 # whereas we cannot and must make do with the information we can obtain.
146 def invoke(self, arg, from_tty):
147 argv = gdb.string_to_argv(arg)
148 if len(argv) >= 1:
149 try:
150 pid = int(argv[0])
151 except:
152 raise gdb.GdbError("Provide a PID as integer value")
153 else:
154 pid = 1
155
156 task = tasks.get_task_by_pid(pid)
157 if not task:
158 raise gdb.GdbError("Couldn't find a process with PID {}"
159 .format(pid))
160
161 namespace = task['nsproxy']['mnt_ns']
162 if not namespace:
163 raise gdb.GdbError("No namespace for current process")
164
165 for vfs in lists.list_for_each_entry(namespace['list'],
166 mount_ptr_type, "mnt_list"):
167 devname = vfs['mnt_devname'].string()
168 devname = devname if devname else "none"
169
170 pathname = ""
171 parent = vfs
172 while True:
173 mntpoint = parent['mnt_mountpoint']
174 pathname = utils.dentry_name(mntpoint) + pathname
175 if (parent == parent['mnt_parent']):
176 break
177 parent = parent['mnt_parent']
178
179 if (pathname == ""):
180 pathname = "/"
181
182 superblock = vfs['mnt']['mnt_sb']
183 fstype = superblock['s_type']['name'].string()
184 s_flags = int(superblock['s_flags'])
185 m_flags = int(vfs['mnt']['mnt_flags'])
186 rd = "ro" if (s_flags & constants.LX_MS_RDONLY) else "rw"
187
188 gdb.write(
189 "{} {} {} {}{}{} 0 0\n"
190 .format(devname,
191 pathname,
192 fstype,
193 rd,
194 info_opts(FS_INFO, s_flags),
195 info_opts(MNT_INFO, m_flags)))
196
197 LxMounts()