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")
38ulong_type = CachedType("unsigned long")
39uint_type = CachedType("unsigned int")
40atomic_long_type = CachedType("atomic_long_t")
41size_t_type = CachedType("size_t")
42struct_page_type = CachedType("struct page")
43
44def get_uint_type():
45 global uint_type
46 return uint_type.get_type()
47
48def get_page_type():
49 global struct_page_type
50 return struct_page_type.get_type()
51
52def get_long_type():
53 global long_type
54 return long_type.get_type()
55
56def get_ulong_type():
57 global ulong_type
58 return ulong_type.get_type()
59
60def get_size_t_type():
61 global size_t_type
62 return size_t_type.get_type()
63
64def offset_of(typeobj, field):
65 element = gdb.Value(0).cast(typeobj)
66 return int(str(element[field].address).split()[0], 16)
67
68
69def container_of(ptr, typeobj, member):
70 return (ptr.cast(get_long_type()) -
71 offset_of(typeobj, member)).cast(typeobj)
72
73
74class ContainerOf(gdb.Function):
75 """Return pointer to containing data structure.
76
77$container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the
78data structure of the type TYPE in which PTR is the address of ELEMENT.
79Note that TYPE and ELEMENT have to be quoted as strings."""
80
81 def __init__(self):
82 super(ContainerOf, self).__init__("container_of")
83
84 def invoke(self, ptr, typename, elementname):
85 return container_of(ptr, gdb.lookup_type(typename.string()).pointer(),
86 elementname.string())
87
88
89ContainerOf()
90
91
92BIG_ENDIAN = 0
93LITTLE_ENDIAN = 1
94target_endianness = None
95
96
97def get_target_endianness():
98 global target_endianness
99 if target_endianness is None:
100 endian = gdb.execute("show endian", to_string=True)
101 if "little endian" in endian:
102 target_endianness = LITTLE_ENDIAN
103 elif "big endian" in endian:
104 target_endianness = BIG_ENDIAN
105 else:
106 raise gdb.GdbError("unknown endianness '{0}'".format(str(endian)))
107 return target_endianness
108
109
110def read_memoryview(inf, start, length):
111 m = inf.read_memory(start, length)
112 if type(m) is memoryview:
113 return m
114 return memoryview(m)
115
116
117def read_u16(buffer, offset):
118 buffer_val = buffer[offset:offset + 2]
119 value = [0, 0]
120
121 if type(buffer_val[0]) is str:
122 value[0] = ord(buffer_val[0])
123 value[1] = ord(buffer_val[1])
124 else:
125 value[0] = buffer_val[0]
126 value[1] = buffer_val[1]
127
128 if get_target_endianness() == LITTLE_ENDIAN:
129 return value[0] + (value[1] << 8)
130 else:
131 return value[1] + (value[0] << 8)
132
133
134def read_u32(buffer, offset):
135 if get_target_endianness() == LITTLE_ENDIAN:
136 return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16)
137 else:
138 return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16)
139
140
141def read_u64(buffer, offset):
142 if get_target_endianness() == LITTLE_ENDIAN:
143 return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32)
144 else:
145 return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32)
146
147
148def read_ulong(buffer, offset):
149 if get_long_type().sizeof == 8:
150 return read_u64(buffer, offset)
151 else:
152 return read_u32(buffer, offset)
153
154atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
155atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
156
157def read_atomic_long(buffer, offset):
158 global atomic_long_counter_offset
159 global atomic_long_counter_sizeof
160
161 if atomic_long_counter_sizeof == 8:
162 return read_u64(buffer, offset + atomic_long_counter_offset)
163 else:
164 return read_u32(buffer, offset + atomic_long_counter_offset)
165
166target_arch = None
167
168
169def is_target_arch(arch):
170 if hasattr(gdb.Frame, 'architecture'):
171 return arch in gdb.newest_frame().architecture().name()
172 else:
173 global target_arch
174 if target_arch is None:
175 target_arch = gdb.execute("show architecture", to_string=True)
176 return arch in target_arch
177
178
179GDBSERVER_QEMU = 0
180GDBSERVER_KGDB = 1
181gdbserver_type = None
182
183
184def get_gdbserver_type():
185 def exit_handler(event):
186 global gdbserver_type
187 gdbserver_type = None
188 gdb.events.exited.disconnect(exit_handler)
189
190 def probe_qemu():
191 try:
192 return gdb.execute("monitor info version", to_string=True) != ""
193 except gdb.error:
194 return False
195
196 def probe_kgdb():
197 try:
198 thread_info = gdb.execute("info thread 2", to_string=True)
199 return "shadowCPU0" in thread_info
200 except gdb.error:
201 return False
202
203 global gdbserver_type
204 if gdbserver_type is None:
205 if probe_qemu():
206 gdbserver_type = GDBSERVER_QEMU
207 elif probe_kgdb():
208 gdbserver_type = GDBSERVER_KGDB
209 if gdbserver_type is not None and hasattr(gdb, 'events'):
210 gdb.events.exited.connect(exit_handler)
211 return gdbserver_type
212
213
214def gdb_eval_or_none(expresssion):
215 try:
216 return gdb.parse_and_eval(expresssion)
217 except gdb.error:
218 return None