Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#
2# gdb helper commands and functions for Linux kernel debugging
3#
4# common utilities
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 GNU GPL version 2.
12#
13
14import gdb
15
16
17class CachedType:
18 def __init__(self, name):
19 self._type = None
20 self._name = name
21
22 def _new_objfile_handler(self, event):
23 self._type = None
24 gdb.events.new_objfile.disconnect(self._new_objfile_handler)
25
26 def get_type(self):
27 if self._type is None:
28 self._type = gdb.lookup_type(self._name)
29 if self._type is None:
30 raise gdb.GdbError(
31 "cannot resolve type '{0}'".format(self._name))
32 if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'):
33 gdb.events.new_objfile.connect(self._new_objfile_handler)
34 return self._type
35
36
37long_type = CachedType("long")
38atomic_long_type = CachedType("atomic_long_t")
39
40def get_long_type():
41 global long_type
42 return long_type.get_type()
43
44def offset_of(typeobj, field):
45 element = gdb.Value(0).cast(typeobj)
46 return int(str(element[field].address).split()[0], 16)
47
48
49def container_of(ptr, typeobj, member):
50 return (ptr.cast(get_long_type()) -
51 offset_of(typeobj, member)).cast(typeobj)
52
53
54class ContainerOf(gdb.Function):
55 """Return pointer to containing data structure.
56
57$container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the
58data structure of the type TYPE in which PTR is the address of ELEMENT.
59Note that TYPE and ELEMENT have to be quoted as strings."""
60
61 def __init__(self):
62 super(ContainerOf, self).__init__("container_of")
63
64 def invoke(self, ptr, typename, elementname):
65 return container_of(ptr, gdb.lookup_type(typename.string()).pointer(),
66 elementname.string())
67
68
69ContainerOf()
70
71
72BIG_ENDIAN = 0
73LITTLE_ENDIAN = 1
74target_endianness = None
75
76
77def get_target_endianness():
78 global target_endianness
79 if target_endianness is None:
80 endian = gdb.execute("show endian", to_string=True)
81 if "little endian" in endian:
82 target_endianness = LITTLE_ENDIAN
83 elif "big endian" in endian:
84 target_endianness = BIG_ENDIAN
85 else:
86 raise gdb.GdbError("unknown endianness '{0}'".format(str(endian)))
87 return target_endianness
88
89
90def read_memoryview(inf, start, length):
91 m = inf.read_memory(start, length)
92 if type(m) is memoryview:
93 return m
94 return memoryview(m)
95
96
97def read_u16(buffer, offset):
98 buffer_val = buffer[offset:offset + 2]
99 value = [0, 0]
100
101 if type(buffer_val[0]) is str:
102 value[0] = ord(buffer_val[0])
103 value[1] = ord(buffer_val[1])
104 else:
105 value[0] = buffer_val[0]
106 value[1] = buffer_val[1]
107
108 if get_target_endianness() == LITTLE_ENDIAN:
109 return value[0] + (value[1] << 8)
110 else:
111 return value[1] + (value[0] << 8)
112
113
114def read_u32(buffer, offset):
115 if get_target_endianness() == LITTLE_ENDIAN:
116 return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16)
117 else:
118 return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16)
119
120
121def read_u64(buffer, offset):
122 if get_target_endianness() == LITTLE_ENDIAN:
123 return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32)
124 else:
125 return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32)
126
127
128def read_ulong(buffer, offset):
129 if get_long_type().sizeof == 8:
130 return read_u64(buffer, offset)
131 else:
132 return read_u32(buffer, offset)
133
134atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
135atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
136
137def read_atomic_long(buffer, offset):
138 global atomic_long_counter_offset
139 global atomic_long_counter_sizeof
140
141 if atomic_long_counter_sizeof == 8:
142 return read_u64(buffer, offset + atomic_long_counter_offset)
143 else:
144 return read_u32(buffer, offset + atomic_long_counter_offset)
145
146target_arch = None
147
148
149def is_target_arch(arch):
150 if hasattr(gdb.Frame, 'architecture'):
151 return arch in gdb.newest_frame().architecture().name()
152 else:
153 global target_arch
154 if target_arch is None:
155 target_arch = gdb.execute("show architecture", to_string=True)
156 return arch in target_arch
157
158
159GDBSERVER_QEMU = 0
160GDBSERVER_KGDB = 1
161gdbserver_type = None
162
163
164def get_gdbserver_type():
165 def exit_handler(event):
166 global gdbserver_type
167 gdbserver_type = None
168 gdb.events.exited.disconnect(exit_handler)
169
170 def probe_qemu():
171 try:
172 return gdb.execute("monitor info version", to_string=True) != ""
173 except gdb.error:
174 return False
175
176 def probe_kgdb():
177 try:
178 thread_info = gdb.execute("info thread 2", to_string=True)
179 return "shadowCPU0" in thread_info
180 except gdb.error:
181 return False
182
183 global gdbserver_type
184 if gdbserver_type is None:
185 if probe_qemu():
186 gdbserver_type = GDBSERVER_QEMU
187 elif probe_kgdb():
188 gdbserver_type = GDBSERVER_KGDB
189 if gdbserver_type is not None and hasattr(gdb, 'events'):
190 gdb.events.exited.connect(exit_handler)
191 return gdbserver_type
192
193
194def gdb_eval_or_none(expresssion):
195 try:
196 return gdb.parse_and_eval(expresssion)
197 except gdb.error:
198 return None