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