aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/gdb
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-06-07 12:04:56 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-06-07 12:04:56 -0400
commitc853f18b640f3e58ba14ffb25e551be8af218209 (patch)
tree89adc65667f124c21f2104422fcaed991da450ab /scripts/gdb
parentaff093d4bbca91f543e24cde2135f393b8130f4b (diff)
parentaf8c34ce6ae32addda3788d54a7e340cad22516b (diff)
Merge tag 'v4.7-rc2' into v4l_for_linus
Linux 4.7-rc2 * tag 'v4.7-rc2': (10914 commits) Linux 4.7-rc2 devpts: Make each mount of devpts an independent filesystem. parisc: Move die_if_kernel() prototype into traps.h header parisc: Fix pagefault crash in unaligned __get_user() call parisc: Fix printk time during boot parisc: Fix backtrace on PA-RISC mm, page_alloc: recalculate the preferred zoneref if the context can ignore memory policies mm, page_alloc: reset zonelist iterator after resetting fair zone allocation policy mm, oom_reaper: do not use siglock in try_oom_reaper() mm, page_alloc: prevent infinite loop in buffered_rmqueue() checkpatch: reduce git commit description style false positives mm/z3fold.c: avoid modifying HEADLESS page and minor cleanup memcg: add RCU locking around css_for_each_descendant_pre() in memcg_offline_kmem() mm: check the return value of lookup_page_ext for all call sites kdump: fix dmesg gdbmacro to work with record based printk mm: fix overflow in vm_map_ram() Btrfs: deal with duplciates during extent_map insertion in btrfs_get_extent arm64: fix alignment when RANDOMIZE_TEXT_OFFSET is enabled arm64: move {PAGE,CONT}_SHIFT into Kconfig arm64: mm: dump: log span level ...
Diffstat (limited to 'scripts/gdb')
-rw-r--r--scripts/gdb/linux/Makefile12
-rw-r--r--scripts/gdb/linux/constants.py.in59
-rw-r--r--scripts/gdb/linux/cpus.py38
-rw-r--r--scripts/gdb/linux/dmesg.py11
-rw-r--r--scripts/gdb/linux/lists.py21
-rw-r--r--scripts/gdb/linux/modules.py24
-rw-r--r--scripts/gdb/linux/proc.py156
-rw-r--r--scripts/gdb/linux/radixtree.py97
-rw-r--r--scripts/gdb/linux/tasks.py19
-rw-r--r--scripts/gdb/linux/utils.py32
-rw-r--r--scripts/gdb/vmlinux-gdb.py2
11 files changed, 450 insertions, 21 deletions
diff --git a/scripts/gdb/linux/Makefile b/scripts/gdb/linux/Makefile
index 6cf1ecf61057..cd129e65d1ff 100644
--- a/scripts/gdb/linux/Makefile
+++ b/scripts/gdb/linux/Makefile
@@ -8,4 +8,14 @@ ifneq ($(KBUILD_SRC),)
8endif 8endif
9 @: 9 @:
10 10
11clean-files := *.pyc *.pyo $(if $(KBUILD_SRC),*.py) 11quiet_cmd_gen_constants_py = GEN $@
12 cmd_gen_constants_py = \
13 $(CPP) -E -x c -P $(c_flags) $< > $@ ;\
14 sed -i '1,/<!-- end-c-headers -->/d;' $@
15
16$(obj)/constants.py: $(SRCTREE)/$(obj)/constants.py.in
17 $(call if_changed,gen_constants_py)
18
19build_constants_py: $(obj)/constants.py
20
21clean-files := *.pyc *.pyo $(if $(KBUILD_SRC),*.py) $(obj)/constants.py
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
new file mode 100644
index 000000000000..07e6c2befe36
--- /dev/null
+++ b/scripts/gdb/linux/constants.py.in
@@ -0,0 +1,59 @@
1/*
2 * gdb helper commands and functions for Linux kernel debugging
3 *
4 * Kernel constants derived from include files.
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
15#include <linux/fs.h>
16#include <linux/mount.h>
17#include <linux/radix-tree.h>
18
19/* We need to stringify expanded macros so that they can be parsed */
20
21#define STRING(x) #x
22#define XSTRING(x) STRING(x)
23
24#define LX_VALUE(x) LX_##x = x
25#define LX_GDBPARSED(x) LX_##x = gdb.parse_and_eval(XSTRING(x))
26
27/*
28 * IS_ENABLED generates (a || b) which is not compatible with python
29 * We can only switch on configuration items we know are available
30 * Therefore - IS_BUILTIN() is more appropriate
31 */
32#define LX_CONFIG(x) LX_##x = IS_BUILTIN(x)
33
34/* The build system will take care of deleting everything above this marker */
35<!-- end-c-headers -->
36
37import gdb
38
39/* linux/fs.h */
40LX_VALUE(MS_RDONLY)
41LX_VALUE(MS_SYNCHRONOUS)
42LX_VALUE(MS_MANDLOCK)
43LX_VALUE(MS_DIRSYNC)
44LX_VALUE(MS_NOATIME)
45LX_VALUE(MS_NODIRATIME)
46
47/* linux/mount.h */
48LX_VALUE(MNT_NOSUID)
49LX_VALUE(MNT_NODEV)
50LX_VALUE(MNT_NOEXEC)
51LX_VALUE(MNT_NOATIME)
52LX_VALUE(MNT_NODIRATIME)
53LX_VALUE(MNT_RELATIME)
54
55/* linux/radix-tree.h */
56LX_VALUE(RADIX_TREE_INDIRECT_PTR)
57LX_GDBPARSED(RADIX_TREE_HEIGHT_MASK)
58LX_GDBPARSED(RADIX_TREE_MAP_SHIFT)
59LX_GDBPARSED(RADIX_TREE_MAP_MASK)
diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py
index 4297b83fedef..ca11e8df31b6 100644
--- a/scripts/gdb/linux/cpus.py
+++ b/scripts/gdb/linux/cpus.py
@@ -97,9 +97,47 @@ def cpu_list(mask_name):
97 bits >>= 1 97 bits >>= 1
98 bit += 1 98 bit += 1
99 99
100 yield int(cpu)
101
102
103def each_online_cpu():
104 for cpu in cpu_list("__cpu_online_mask"):
105 yield cpu
106
107
108def each_present_cpu():
109 for cpu in cpu_list("__cpu_present_mask"):
110 yield cpu
111
112
113def each_possible_cpu():
114 for cpu in cpu_list("__cpu_possible_mask"):
115 yield cpu
116
117
118def each_active_cpu():
119 for cpu in cpu_list("__cpu_active_mask"):
100 yield cpu 120 yield cpu
101 121
102 122
123class LxCpus(gdb.Command):
124 """List CPU status arrays
125
126Displays the known state of each CPU based on the kernel masks
127and can help identify the state of hotplugged CPUs"""
128
129 def __init__(self):
130 super(LxCpus, self).__init__("lx-cpus", gdb.COMMAND_DATA)
131
132 def invoke(self, arg, from_tty):
133 gdb.write("Possible CPUs : {}\n".format(list(each_possible_cpu())))
134 gdb.write("Present CPUs : {}\n".format(list(each_present_cpu())))
135 gdb.write("Online CPUs : {}\n".format(list(each_online_cpu())))
136 gdb.write("Active CPUs : {}\n".format(list(each_active_cpu())))
137
138LxCpus()
139
140
103class PerCpu(gdb.Function): 141class PerCpu(gdb.Function):
104 """Return per-cpu variable. 142 """Return per-cpu variable.
105 143
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
index 927d0d2a3145..f9b92ece7834 100644
--- a/scripts/gdb/linux/dmesg.py
+++ b/scripts/gdb/linux/dmesg.py
@@ -33,11 +33,12 @@ class LxDmesg(gdb.Command):
33 if log_first_idx < log_next_idx: 33 if log_first_idx < log_next_idx:
34 log_buf_2nd_half = -1 34 log_buf_2nd_half = -1
35 length = log_next_idx - log_first_idx 35 length = log_next_idx - log_first_idx
36 log_buf = inf.read_memory(start, length) 36 log_buf = utils.read_memoryview(inf, start, length).tobytes()
37 else: 37 else:
38 log_buf_2nd_half = log_buf_len - log_first_idx 38 log_buf_2nd_half = log_buf_len - log_first_idx
39 log_buf = inf.read_memory(start, log_buf_2nd_half) + \ 39 a = utils.read_memoryview(inf, start, log_buf_2nd_half)
40 inf.read_memory(log_buf_addr, log_next_idx) 40 b = utils.read_memoryview(inf, log_buf_addr, log_next_idx)
41 log_buf = a.tobytes() + b.tobytes()
41 42
42 pos = 0 43 pos = 0
43 while pos < log_buf.__len__(): 44 while pos < log_buf.__len__():
@@ -50,10 +51,10 @@ class LxDmesg(gdb.Command):
50 continue 51 continue
51 52
52 text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) 53 text_len = utils.read_u16(log_buf[pos + 10:pos + 12])
53 text = log_buf[pos + 16:pos + 16 + text_len] 54 text = log_buf[pos + 16:pos + 16 + text_len].decode()
54 time_stamp = utils.read_u64(log_buf[pos:pos + 8]) 55 time_stamp = utils.read_u64(log_buf[pos:pos + 8])
55 56
56 for line in memoryview(text).tobytes().splitlines(): 57 for line in text.splitlines():
57 gdb.write("[{time:12.6f}] {line}\n".format( 58 gdb.write("[{time:12.6f}] {line}\n".format(
58 time=time_stamp / 1000000000.0, 59 time=time_stamp / 1000000000.0,
59 line=line)) 60 line=line))
diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py
index 3a3775bc162b..2f335fbd86fd 100644
--- a/scripts/gdb/linux/lists.py
+++ b/scripts/gdb/linux/lists.py
@@ -18,6 +18,27 @@ from linux import utils
18list_head = utils.CachedType("struct list_head") 18list_head = utils.CachedType("struct list_head")
19 19
20 20
21def list_for_each(head):
22 if head.type == list_head.get_type().pointer():
23 head = head.dereference()
24 elif head.type != list_head.get_type():
25 raise gdb.GdbError("Must be struct list_head not {}"
26 .format(head.type))
27
28 node = head['next'].dereference()
29 while node.address != head.address:
30 yield node.address
31 node = node['next'].dereference()
32
33
34def list_for_each_entry(head, gdbtype, member):
35 for node in list_for_each(head):
36 if node.type != list_head.get_type().pointer():
37 raise TypeError("Type {} found. Expected struct list_head *."
38 .format(node.type))
39 yield utils.container_of(node, gdbtype, member)
40
41
21def list_check(head): 42def list_check(head):
22 nb = 0 43 nb = 0
23 if (head.type == list_head.get_type().pointer()): 44 if (head.type == list_head.get_type().pointer()):
diff --git a/scripts/gdb/linux/modules.py b/scripts/gdb/linux/modules.py
index 0a35d6dbfb80..441b23239896 100644
--- a/scripts/gdb/linux/modules.py
+++ b/scripts/gdb/linux/modules.py
@@ -13,7 +13,7 @@
13 13
14import gdb 14import gdb
15 15
16from linux import cpus, utils 16from linux import cpus, utils, lists
17 17
18 18
19module_type = utils.CachedType("struct module") 19module_type = utils.CachedType("struct module")
@@ -21,14 +21,14 @@ module_type = utils.CachedType("struct module")
21 21
22def module_list(): 22def module_list():
23 global module_type 23 global module_type
24 modules = utils.gdb_eval_or_none("modules")
25 if modules is None:
26 return
27
24 module_ptr_type = module_type.get_type().pointer() 28 module_ptr_type = module_type.get_type().pointer()
25 modules = gdb.parse_and_eval("modules")
26 entry = modules['next']
27 end_of_list = modules.address
28 29
29 while entry != end_of_list: 30 for module in lists.list_for_each_entry(modules, module_ptr_type, "list"):
30 yield utils.container_of(entry, module_ptr_type, "list") 31 yield module
31 entry = entry['next']
32 32
33 33
34def find_module_by_name(name): 34def find_module_by_name(name):
@@ -78,19 +78,17 @@ class LxLsmod(gdb.Command):
78 address=str(layout['base']).split()[0], 78 address=str(layout['base']).split()[0],
79 name=module['name'].string(), 79 name=module['name'].string(),
80 size=str(layout['size']), 80 size=str(layout['size']),
81 ref=str(module['refcnt']['counter']))) 81 ref=str(module['refcnt']['counter'] - 1)))
82 82
83 source_list = module['source_list']
84 t = self._module_use_type.get_type().pointer() 83 t = self._module_use_type.get_type().pointer()
85 entry = source_list['next']
86 first = True 84 first = True
87 while entry != source_list.address: 85 sources = module['source_list']
88 use = utils.container_of(entry, t, "source_list") 86 for use in lists.list_for_each_entry(sources, t, "source_list"):
89 gdb.write("{separator}{name}".format( 87 gdb.write("{separator}{name}".format(
90 separator=" " if first else ",", 88 separator=" " if first else ",",
91 name=use['source']['name'].string())) 89 name=use['source']['name'].string()))
92 first = False 90 first = False
93 entry = entry['next'] 91
94 gdb.write("\n") 92 gdb.write("\n")
95 93
96 94
diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
index 6e6709c1830c..38b1f09d1cd9 100644
--- a/scripts/gdb/linux/proc.py
+++ b/scripts/gdb/linux/proc.py
@@ -12,6 +12,10 @@
12# 12#
13 13
14import gdb 14import gdb
15from linux import constants
16from linux import utils
17from linux import tasks
18from linux import lists
15 19
16 20
17class LxCmdLine(gdb.Command): 21class LxCmdLine(gdb.Command):
@@ -39,3 +43,155 @@ class LxVersion(gdb.Command):
39 gdb.write(gdb.parse_and_eval("linux_banner").string()) 43 gdb.write(gdb.parse_and_eval("linux_banner").string())
40 44
41LxVersion() 45LxVersion()
46
47
48# Resource Structure Printers
49# /proc/iomem
50# /proc/ioports
51
52def 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
64def 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
77class LxIOMem(gdb.Command):
78 """Identify the IO memory resource locations defined by the kernel
79
80Equivalent 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
88LxIOMem()
89
90
91class LxIOPorts(gdb.Command):
92 """Identify the IO port resource locations defined by the kernel
93
94Equivalent 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
102LxIOPorts()
103
104
105# Mount namespace viewer
106# /proc/mounts
107
108def 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
116FS_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
122MNT_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
129mount_type = utils.CachedType("struct mount")
130mount_ptr_type = mount_type.get_type().pointer()
131
132
133class LxMounts(gdb.Command):
134 """Report the VFS mounts of the current process namespace.
135
136Equivalent to cat /proc/mounts on a running target
137An integer value can be supplied to display the mount
138values 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
197LxMounts()
diff --git a/scripts/gdb/linux/radixtree.py b/scripts/gdb/linux/radixtree.py
new file mode 100644
index 000000000000..0fdef4e2971a
--- /dev/null
+++ b/scripts/gdb/linux/radixtree.py
@@ -0,0 +1,97 @@
1#
2# gdb helper commands and functions for Linux kernel debugging
3#
4# Radix Tree Parser
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
14import gdb
15
16from linux import utils
17from linux import constants
18
19radix_tree_root_type = utils.CachedType("struct radix_tree_root")
20radix_tree_node_type = utils.CachedType("struct radix_tree_node")
21
22
23def is_indirect_ptr(node):
24 long_type = utils.get_long_type()
25 return (node.cast(long_type) & constants.LX_RADIX_TREE_INDIRECT_PTR)
26
27
28def indirect_to_ptr(node):
29 long_type = utils.get_long_type()
30 node_type = node.type
31 indirect_ptr = node.cast(long_type) & ~constants.LX_RADIX_TREE_INDIRECT_PTR
32 return indirect_ptr.cast(node_type)
33
34
35def maxindex(height):
36 height = height & constants.LX_RADIX_TREE_HEIGHT_MASK
37 return gdb.parse_and_eval("height_to_maxindex["+str(height)+"]")
38
39
40def lookup(root, index):
41 if root.type == radix_tree_root_type.get_type().pointer():
42 root = root.dereference()
43 elif root.type != radix_tree_root_type.get_type():
44 raise gdb.GdbError("Must be struct radix_tree_root not {}"
45 .format(root.type))
46
47 node = root['rnode']
48 if node is 0:
49 return None
50
51 if not (is_indirect_ptr(node)):
52 if (index > 0):
53 return None
54 return node
55
56 node = indirect_to_ptr(node)
57
58 height = node['path'] & constants.LX_RADIX_TREE_HEIGHT_MASK
59 if (index > maxindex(height)):
60 return None
61
62 shift = (height-1) * constants.LX_RADIX_TREE_MAP_SHIFT
63
64 while True:
65 new_index = (index >> shift) & constants.LX_RADIX_TREE_MAP_MASK
66 slot = node['slots'][new_index]
67
68 node = slot.cast(node.type.pointer()).dereference()
69 if node is 0:
70 return None
71
72 shift -= constants.LX_RADIX_TREE_MAP_SHIFT
73 height -= 1
74
75 if (height <= 0):
76 break
77
78 return node
79
80
81class LxRadixTree(gdb.Function):
82 """ Lookup and return a node from a RadixTree.
83
84$lx_radix_tree_lookup(root_node [, index]): Return the node at the given index.
85If index is omitted, the root node is dereferenced and returned."""
86
87 def __init__(self):
88 super(LxRadixTree, self).__init__("lx_radix_tree_lookup")
89
90 def invoke(self, root, index=0):
91 result = lookup(root, index)
92 if result is None:
93 raise gdb.GdbError("No entry in tree at index {}".format(index))
94
95 return result
96
97LxRadixTree()
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py
index 862a4ae24d49..1bf949c43b76 100644
--- a/scripts/gdb/linux/tasks.py
+++ b/scripts/gdb/linux/tasks.py
@@ -114,3 +114,22 @@ variable."""
114 114
115 115
116LxThreadInfoFunc() 116LxThreadInfoFunc()
117
118
119class LxThreadInfoByPidFunc (gdb.Function):
120 """Calculate Linux thread_info from task variable found by pid
121
122$lx_thread_info_by_pid(PID): Given PID, return the corresponding thread_info
123variable."""
124
125 def __init__(self):
126 super(LxThreadInfoByPidFunc, self).__init__("lx_thread_info_by_pid")
127
128 def invoke(self, pid):
129 task = get_task_by_pid(pid)
130 if task:
131 return get_thread_info(task.dereference())
132 else:
133 raise gdb.GdbError("No task of PID " + str(pid))
134
135LxThreadInfoByPidFunc()
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
index 0893b326a28b..50805874cfc3 100644
--- a/scripts/gdb/linux/utils.py
+++ b/scripts/gdb/linux/utils.py
@@ -87,11 +87,24 @@ def get_target_endianness():
87 return target_endianness 87 return target_endianness
88 88
89 89
90def read_memoryview(inf, start, length):
91 return memoryview(inf.read_memory(start, length))
92
93
90def read_u16(buffer): 94def read_u16(buffer):
95 value = [0, 0]
96
97 if type(buffer[0]) is str:
98 value[0] = ord(buffer[0])
99 value[1] = ord(buffer[1])
100 else:
101 value[0] = buffer[0]
102 value[1] = buffer[1]
103
91 if get_target_endianness() == LITTLE_ENDIAN: 104 if get_target_endianness() == LITTLE_ENDIAN:
92 return ord(buffer[0]) + (ord(buffer[1]) << 8) 105 return value[0] + (value[1] << 8)
93 else: 106 else:
94 return ord(buffer[1]) + (ord(buffer[0]) << 8) 107 return value[1] + (value[0] << 8)
95 108
96 109
97def read_u32(buffer): 110def read_u32(buffer):
@@ -154,3 +167,18 @@ def get_gdbserver_type():
154 if gdbserver_type is not None and hasattr(gdb, 'events'): 167 if gdbserver_type is not None and hasattr(gdb, 'events'):
155 gdb.events.exited.connect(exit_handler) 168 gdb.events.exited.connect(exit_handler)
156 return gdbserver_type 169 return gdbserver_type
170
171
172def gdb_eval_or_none(expresssion):
173 try:
174 return gdb.parse_and_eval(expresssion)
175 except:
176 return None
177
178
179def dentry_name(d):
180 parent = d['d_parent']
181 if parent == d or parent == 0:
182 return ""
183 p = dentry_name(d['d_parent']) + "/"
184 return p + d['d_iname'].string()
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index d5943eca19cd..3a80ad6eecad 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -30,3 +30,5 @@ else:
30 import linux.cpus 30 import linux.cpus
31 import linux.lists 31 import linux.lists
32 import linux.proc 32 import linux.proc
33 import linux.constants
34 import linux.radixtree