~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/gdb/linux/utils.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 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 "shadowCPU" 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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php