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 m = inf.read_memory(start, length) 92 if type(m) is memoryview: 93 return m 94 return memoryview(m) 95 96 97def read_u16(buffer, offset): 98 buffer_val = buffer[offset:offset + 2] 99 value = [0, 0] 100 101 if type(buffer_val[0]) is str: 102 value[0] = ord(buffer_val[0]) 103 value[1] = ord(buffer_val[1]) 104 else: 105 value[0] = buffer_val[0] 106 value[1] = buffer_val[1] 107 108 if get_target_endianness() == LITTLE_ENDIAN: 109 return value[0] + (value[1] << 8) 110 else: 111 return value[1] + (value[0] << 8) 112 113 114def read_u32(buffer, offset): 115 if get_target_endianness() == LITTLE_ENDIAN: 116 return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16) 117 else: 118 return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16) 119 120 121def read_u64(buffer, offset): 122 if get_target_endianness() == LITTLE_ENDIAN: 123 return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32) 124 else: 125 return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32) 126 127 128def read_ulong(buffer, offset): 129 if get_long_type().sizeof == 8: 130 return read_u64(buffer, offset) 131 else: 132 return read_u32(buffer, offset) 133 134atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos 135atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof 136 137def read_atomic_long(buffer, offset): 138 global atomic_long_counter_offset 139 global atomic_long_counter_sizeof 140 141 if atomic_long_counter_sizeof == 8: 142 return read_u64(buffer, offset + atomic_long_counter_offset) 143 else: 144 return read_u32(buffer, offset + atomic_long_counter_offset) 145 146target_arch = None 147 148 149def is_target_arch(arch): 150 if hasattr(gdb.Frame, 'architecture'): 151 return arch in gdb.newest_frame().architecture().name() 152 else: 153 global target_arch 154 if target_arch is None: 155 target_arch = gdb.execute("show architecture", to_string=True) 156 return arch in target_arch 157 158 159GDBSERVER_QEMU = 0 160GDBSERVER_KGDB = 1 161gdbserver_type = None 162 163 164def get_gdbserver_type(): 165 def exit_handler(event): 166 global gdbserver_type 167 gdbserver_type = None 168 gdb.events.exited.disconnect(exit_handler) 169 170 def probe_qemu(): 171 try: 172 return gdb.execute("monitor info version", to_string=True) != "" 173 except gdb.error: 174 return False 175 176 def probe_kgdb(): 177 try: 178 thread_info = gdb.execute("info thread 2", to_string=True) 179 return "shadowCPU0" in thread_info 180 except gdb.error: 181 return False 182 183 global gdbserver_type 184 if gdbserver_type is None: 185 if probe_qemu(): 186 gdbserver_type = GDBSERVER_QEMU 187 elif probe_kgdb(): 188 gdbserver_type = GDBSERVER_KGDB 189 if gdbserver_type is not None and hasattr(gdb, 'events'): 190 gdb.events.exited.connect(exit_handler) 191 return gdbserver_type 192 193 194def gdb_eval_or_none(expresssion): 195 try: 196 return gdb.parse_and_eval(expresssion) 197 except gdb.error: 198 return None 199 200 201def dentry_name(d): 202 parent = d['d_parent'] 203 if parent == d or parent == 0: 204 return "" 205 p = dentry_name(d['d_parent']) + "/" 206 return p + d['d_iname'].string() 207