blob: 1553f68716cc277e98575eee24f12f5138c6aca1 [file] [log] [blame]
Jan Kiszka2b514822015-02-17 13:46:38 -08001#
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
Jan Kiszkab0fecd82015-02-17 13:46:41 -080035
36
37long_type = CachedType("long")
Antonio Borneo45382d62022-07-19 14:28:31 +020038atomic_long_type = CachedType("atomic_long_t")
Jan Kiszkab0fecd82015-02-17 13:46:41 -080039
40def get_long_type():
41 global long_type
42 return long_type.get_type()
43
Jan Kiszkab0fecd82015-02-17 13:46:41 -080044def 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
Stephen Boyd494dbe02019-05-14 15:46:02 -070068
Jan Kiszkab0fecd82015-02-17 13:46:41 -080069ContainerOf()
Jan Kiszka7f994962015-02-17 13:46:58 -080070
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:
ThiƩbaud Weksteena2e73c42015-06-30 14:58:16 -070086 raise gdb.GdbError("unknown endianness '{0}'".format(str(endian)))
Jan Kiszka7f994962015-02-17 13:46:58 -080087 return target_endianness
Jan Kiszka78e87812015-02-17 13:47:01 -080088
89
Dom Cote321958d2016-05-23 16:25:16 -070090def read_memoryview(inf, start, length):
91 return memoryview(inf.read_memory(start, length))
92
93
Joel Colledgeca210ba2019-10-18 20:19:26 -070094def read_u16(buffer, offset):
95 buffer_val = buffer[offset:offset + 2]
Dom Cote321958d2016-05-23 16:25:16 -070096 value = [0, 0]
97
Joel Colledgeca210ba2019-10-18 20:19:26 -070098 if type(buffer_val[0]) is str:
99 value[0] = ord(buffer_val[0])
100 value[1] = ord(buffer_val[1])
Jan Kiszka78e87812015-02-17 13:47:01 -0800101 else:
Joel Colledgeca210ba2019-10-18 20:19:26 -0700102 value[0] = buffer_val[0]
103 value[1] = buffer_val[1]
Dom Cote321958d2016-05-23 16:25:16 -0700104
105 if get_target_endianness() == LITTLE_ENDIAN:
106 return value[0] + (value[1] << 8)
107 else:
108 return value[1] + (value[0] << 8)
Jan Kiszka78e87812015-02-17 13:47:01 -0800109
110
Joel Colledgeca210ba2019-10-18 20:19:26 -0700111def read_u32(buffer, offset):
Jan Kiszka78e87812015-02-17 13:47:01 -0800112 if get_target_endianness() == LITTLE_ENDIAN:
Joel Colledgeca210ba2019-10-18 20:19:26 -0700113 return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16)
Jan Kiszka78e87812015-02-17 13:47:01 -0800114 else:
Joel Colledgeca210ba2019-10-18 20:19:26 -0700115 return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16)
Jan Kiszka78e87812015-02-17 13:47:01 -0800116
117
Joel Colledgeca210ba2019-10-18 20:19:26 -0700118def read_u64(buffer, offset):
Jan Kiszka78e87812015-02-17 13:47:01 -0800119 if get_target_endianness() == LITTLE_ENDIAN:
Joel Colledgeca210ba2019-10-18 20:19:26 -0700120 return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32)
Jan Kiszka78e87812015-02-17 13:47:01 -0800121 else:
Joel Colledgeca210ba2019-10-18 20:19:26 -0700122 return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32)
Jan Kiszkab24e2d22015-02-17 13:47:12 -0800123
124
John Ogness3e0d0752020-08-14 23:31:24 +0206125def read_ulong(buffer, offset):
126 if get_long_type().sizeof == 8:
127 return read_u64(buffer, offset)
128 else:
129 return read_u32(buffer, offset)
130
Antonio Borneo45382d62022-07-19 14:28:31 +0200131atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
132atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
133
134def read_atomic_long(buffer, offset):
135 global atomic_long_counter_offset
136 global atomic_long_counter_sizeof
137
138 if atomic_long_counter_sizeof == 8:
139 return read_u64(buffer, offset + atomic_long_counter_offset)
140 else:
141 return read_u32(buffer, offset + atomic_long_counter_offset)
John Ogness3e0d0752020-08-14 23:31:24 +0206142
Jan Kiszkab24e2d22015-02-17 13:47:12 -0800143target_arch = None
144
145
146def is_target_arch(arch):
147 if hasattr(gdb.Frame, 'architecture'):
148 return arch in gdb.newest_frame().architecture().name()
149 else:
150 global target_arch
151 if target_arch is None:
152 target_arch = gdb.execute("show architecture", to_string=True)
153 return arch in target_arch
Jan Kiszkaa4d86792015-02-17 13:47:18 -0800154
155
156GDBSERVER_QEMU = 0
157GDBSERVER_KGDB = 1
158gdbserver_type = None
159
160
161def get_gdbserver_type():
162 def exit_handler(event):
163 global gdbserver_type
164 gdbserver_type = None
165 gdb.events.exited.disconnect(exit_handler)
166
167 def probe_qemu():
168 try:
169 return gdb.execute("monitor info version", to_string=True) != ""
Stephen Boyd494dbe02019-05-14 15:46:02 -0700170 except gdb.error:
Jan Kiszkaa4d86792015-02-17 13:47:18 -0800171 return False
172
173 def probe_kgdb():
174 try:
175 thread_info = gdb.execute("info thread 2", to_string=True)
176 return "shadowCPU0" in thread_info
Stephen Boyd494dbe02019-05-14 15:46:02 -0700177 except gdb.error:
Jan Kiszkaa4d86792015-02-17 13:47:18 -0800178 return False
179
180 global gdbserver_type
181 if gdbserver_type is None:
182 if probe_qemu():
183 gdbserver_type = GDBSERVER_QEMU
184 elif probe_kgdb():
185 gdbserver_type = GDBSERVER_KGDB
ThiƩbaud Weksteen6ad18b72015-06-30 14:58:18 -0700186 if gdbserver_type is not None and hasattr(gdb, 'events'):
Jan Kiszkaa4d86792015-02-17 13:47:18 -0800187 gdb.events.exited.connect(exit_handler)
188 return gdbserver_type
Kieran Binghame78f3d72016-05-23 16:24:48 -0700189
190
191def gdb_eval_or_none(expresssion):
192 try:
193 return gdb.parse_and_eval(expresssion)
Stephen Boyd494dbe02019-05-14 15:46:02 -0700194 except gdb.error:
Kieran Binghame78f3d72016-05-23 16:24:48 -0700195 return None
Kieran Bingham74627cf2016-05-23 16:24:53 -0700196
197
198def dentry_name(d):
199 parent = d['d_parent']
200 if parent == d or parent == 0:
201 return ""
202 p = dentry_name(d['d_parent']) + "/"
203 return p + d['d_iname'].string()