]> Git Repo - linux.git/blob - scripts/gdb/linux/utils.py
Merge patch "RISC-V: Add ptrace support for vectors"
[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 ulong_type = CachedType("unsigned long")
39 uint_type = CachedType("unsigned int")
40 atomic_long_type = CachedType("atomic_long_t")
41 size_t_type = CachedType("size_t")
42 struct_page_type = CachedType("struct page")
43
44 def get_uint_type():
45     global uint_type
46     return uint_type.get_type()
47
48 def get_page_type():
49     global struct_page_type
50     return struct_page_type.get_type()
51
52 def get_long_type():
53     global long_type
54     return long_type.get_type()
55
56 def get_ulong_type():
57     global ulong_type
58     return ulong_type.get_type()
59
60 def get_size_t_type():
61     global size_t_type
62     return size_t_type.get_type()
63
64 def offset_of(typeobj, field):
65     element = gdb.Value(0).cast(typeobj)
66     return int(str(element[field].address).split()[0], 16)
67
68
69 def container_of(ptr, typeobj, member):
70     return (ptr.cast(get_long_type()) -
71             offset_of(typeobj, member)).cast(typeobj)
72
73
74 class ContainerOf(gdb.Function):
75     """Return pointer to containing data structure.
76
77 $container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the
78 data structure of the type TYPE in which PTR is the address of ELEMENT.
79 Note 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
89 ContainerOf()
90
91
92 BIG_ENDIAN = 0
93 LITTLE_ENDIAN = 1
94 target_endianness = None
95
96
97 def 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
110 def 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
117 def 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
134 def 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
141 def 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
148 def 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
154 atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
155 atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
156
157 def 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
166 target_arch = None
167
168
169 def 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
179 GDBSERVER_QEMU = 0
180 GDBSERVER_KGDB = 1
181 gdbserver_type = None
182
183
184 def 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
214 def gdb_eval_or_none(expresssion):
215     try:
216         return gdb.parse_and_eval(expresssion)
217     except gdb.error:
218         return None
This page took 0.043857 seconds and 4 git commands to generate.