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