GNU Linux-libre 4.9.309-gnu1
[releases.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 ContainerOf()
70
71
72 BIG_ENDIAN = 0
73 LITTLE_ENDIAN = 1
74 target_endianness = None
75
76
77 def 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
90 def read_memoryview(inf, start, length):
91     return memoryview(inf.read_memory(start, length))
92
93
94 def read_u16(buffer):
95     value = [0, 0]
96
97     if type(buffer[0]) is str:
98         value[0] = ord(buffer[0])
99         value[1] = ord(buffer[1])
100     else:
101         value[0] = buffer[0]
102         value[1] = buffer[1]
103
104     if get_target_endianness() == LITTLE_ENDIAN:
105         return value[0] + (value[1] << 8)
106     else:
107         return value[1] + (value[0] << 8)
108
109
110 def read_u32(buffer):
111     if get_target_endianness() == LITTLE_ENDIAN:
112         return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16)
113     else:
114         return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16)
115
116
117 def read_u64(buffer):
118     if get_target_endianness() == LITTLE_ENDIAN:
119         return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32)
120     else:
121         return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32)
122
123
124 target_arch = None
125
126
127 def is_target_arch(arch):
128     if hasattr(gdb.Frame, 'architecture'):
129         return arch in gdb.newest_frame().architecture().name()
130     else:
131         global target_arch
132         if target_arch is None:
133             target_arch = gdb.execute("show architecture", to_string=True)
134         return arch in target_arch
135
136
137 GDBSERVER_QEMU = 0
138 GDBSERVER_KGDB = 1
139 gdbserver_type = None
140
141
142 def get_gdbserver_type():
143     def exit_handler(event):
144         global gdbserver_type
145         gdbserver_type = None
146         gdb.events.exited.disconnect(exit_handler)
147
148     def probe_qemu():
149         try:
150             return gdb.execute("monitor info version", to_string=True) != ""
151         except:
152             return False
153
154     def probe_kgdb():
155         try:
156             thread_info = gdb.execute("info thread 2", to_string=True)
157             return "shadowCPU0" in thread_info
158         except:
159             return False
160
161     global gdbserver_type
162     if gdbserver_type is None:
163         if probe_qemu():
164             gdbserver_type = GDBSERVER_QEMU
165         elif probe_kgdb():
166             gdbserver_type = GDBSERVER_KGDB
167         if gdbserver_type is not None and hasattr(gdb, 'events'):
168             gdb.events.exited.connect(exit_handler)
169     return gdbserver_type
170
171
172 def gdb_eval_or_none(expresssion):
173     try:
174         return gdb.parse_and_eval(expresssion)
175     except:
176         return None
177
178
179 def dentry_name(d):
180     parent = d['d_parent']
181     if parent == d or parent == 0:
182         return ""
183     p = dentry_name(d['d_parent']) + "/"
184     return p + d['d_iname'].string()