]> Git Repo - linux.git/blob - scripts/gdb/linux/utils.py
Merge tag 'v5.7-rc1' into locking/kcsan, to resolve conflicts and refresh
[linux.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 <[email protected]>
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 target_arch = None
127
128
129 def is_target_arch(arch):
130     if hasattr(gdb.Frame, 'architecture'):
131         return arch in gdb.newest_frame().architecture().name()
132     else:
133         global target_arch
134         if target_arch is None:
135             target_arch = gdb.execute("show architecture", to_string=True)
136         return arch in target_arch
137
138
139 GDBSERVER_QEMU = 0
140 GDBSERVER_KGDB = 1
141 gdbserver_type = None
142
143
144 def get_gdbserver_type():
145     def exit_handler(event):
146         global gdbserver_type
147         gdbserver_type = None
148         gdb.events.exited.disconnect(exit_handler)
149
150     def probe_qemu():
151         try:
152             return gdb.execute("monitor info version", to_string=True) != ""
153         except gdb.error:
154             return False
155
156     def probe_kgdb():
157         try:
158             thread_info = gdb.execute("info thread 2", to_string=True)
159             return "shadowCPU0" in thread_info
160         except gdb.error:
161             return False
162
163     global gdbserver_type
164     if gdbserver_type is None:
165         if probe_qemu():
166             gdbserver_type = GDBSERVER_QEMU
167         elif probe_kgdb():
168             gdbserver_type = GDBSERVER_KGDB
169         if gdbserver_type is not None and hasattr(gdb, 'events'):
170             gdb.events.exited.connect(exit_handler)
171     return gdbserver_type
172
173
174 def gdb_eval_or_none(expresssion):
175     try:
176         return gdb.parse_and_eval(expresssion)
177     except gdb.error:
178         return None
179
180
181 def dentry_name(d):
182     parent = d['d_parent']
183     if parent == d or parent == 0:
184         return ""
185     p = dentry_name(d['d_parent']) + "/"
186     return p + d['d_iname'].string()
This page took 0.044169 seconds and 4 git commands to generate.