Back to home page

OSCL-LXR

 
 

    


0001 #
0002 # gdb helper commands and functions for Linux kernel debugging
0003 #
0004 #  common utilities
0005 #
0006 # Copyright (c) Siemens AG, 2011-2013
0007 #
0008 # Authors:
0009 #  Jan Kiszka <jan.kiszka@siemens.com>
0010 #
0011 # This work is licensed under the terms of the GNU GPL version 2.
0012 #
0013 
0014 import gdb
0015 
0016 
0017 class CachedType:
0018     def __init__(self, name):
0019         self._type = None
0020         self._name = name
0021 
0022     def _new_objfile_handler(self, event):
0023         self._type = None
0024         gdb.events.new_objfile.disconnect(self._new_objfile_handler)
0025 
0026     def get_type(self):
0027         if self._type is None:
0028             self._type = gdb.lookup_type(self._name)
0029             if self._type is None:
0030                 raise gdb.GdbError(
0031                     "cannot resolve type '{0}'".format(self._name))
0032             if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'):
0033                 gdb.events.new_objfile.connect(self._new_objfile_handler)
0034         return self._type
0035 
0036 
0037 long_type = CachedType("long")
0038 atomic_long_type = CachedType("atomic_long_t")
0039 
0040 def get_long_type():
0041     global long_type
0042     return long_type.get_type()
0043 
0044 def offset_of(typeobj, field):
0045     element = gdb.Value(0).cast(typeobj)
0046     return int(str(element[field].address).split()[0], 16)
0047 
0048 
0049 def container_of(ptr, typeobj, member):
0050     return (ptr.cast(get_long_type()) -
0051             offset_of(typeobj, member)).cast(typeobj)
0052 
0053 
0054 class ContainerOf(gdb.Function):
0055     """Return pointer to containing data structure.
0056 
0057 $container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the
0058 data structure of the type TYPE in which PTR is the address of ELEMENT.
0059 Note that TYPE and ELEMENT have to be quoted as strings."""
0060 
0061     def __init__(self):
0062         super(ContainerOf, self).__init__("container_of")
0063 
0064     def invoke(self, ptr, typename, elementname):
0065         return container_of(ptr, gdb.lookup_type(typename.string()).pointer(),
0066                             elementname.string())
0067 
0068 
0069 ContainerOf()
0070 
0071 
0072 BIG_ENDIAN = 0
0073 LITTLE_ENDIAN = 1
0074 target_endianness = None
0075 
0076 
0077 def get_target_endianness():
0078     global target_endianness
0079     if target_endianness is None:
0080         endian = gdb.execute("show endian", to_string=True)
0081         if "little endian" in endian:
0082             target_endianness = LITTLE_ENDIAN
0083         elif "big endian" in endian:
0084             target_endianness = BIG_ENDIAN
0085         else:
0086             raise gdb.GdbError("unknown endianness '{0}'".format(str(endian)))
0087     return target_endianness
0088 
0089 
0090 def read_memoryview(inf, start, length):
0091     return memoryview(inf.read_memory(start, length))
0092 
0093 
0094 def read_u16(buffer, offset):
0095     buffer_val = buffer[offset:offset + 2]
0096     value = [0, 0]
0097 
0098     if type(buffer_val[0]) is str:
0099         value[0] = ord(buffer_val[0])
0100         value[1] = ord(buffer_val[1])
0101     else:
0102         value[0] = buffer_val[0]
0103         value[1] = buffer_val[1]
0104 
0105     if get_target_endianness() == LITTLE_ENDIAN:
0106         return value[0] + (value[1] << 8)
0107     else:
0108         return value[1] + (value[0] << 8)
0109 
0110 
0111 def read_u32(buffer, offset):
0112     if get_target_endianness() == LITTLE_ENDIAN:
0113         return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16)
0114     else:
0115         return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16)
0116 
0117 
0118 def read_u64(buffer, offset):
0119     if get_target_endianness() == LITTLE_ENDIAN:
0120         return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32)
0121     else:
0122         return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32)
0123 
0124 
0125 def read_ulong(buffer, offset):
0126     if get_long_type().sizeof == 8:
0127         return read_u64(buffer, offset)
0128     else:
0129         return read_u32(buffer, offset)
0130 
0131 atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
0132 atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
0133 
0134 def read_atomic_long(buffer, offset):
0135     global atomic_long_counter_offset
0136     global atomic_long_counter_sizeof
0137 
0138     if atomic_long_counter_sizeof == 8:
0139         return read_u64(buffer, offset + atomic_long_counter_offset)
0140     else:
0141         return read_u32(buffer, offset + atomic_long_counter_offset)
0142 
0143 target_arch = None
0144 
0145 
0146 def is_target_arch(arch):
0147     if hasattr(gdb.Frame, 'architecture'):
0148         return arch in gdb.newest_frame().architecture().name()
0149     else:
0150         global target_arch
0151         if target_arch is None:
0152             target_arch = gdb.execute("show architecture", to_string=True)
0153         return arch in target_arch
0154 
0155 
0156 GDBSERVER_QEMU = 0
0157 GDBSERVER_KGDB = 1
0158 gdbserver_type = None
0159 
0160 
0161 def get_gdbserver_type():
0162     def exit_handler(event):
0163         global gdbserver_type
0164         gdbserver_type = None
0165         gdb.events.exited.disconnect(exit_handler)
0166 
0167     def probe_qemu():
0168         try:
0169             return gdb.execute("monitor info version", to_string=True) != ""
0170         except gdb.error:
0171             return False
0172 
0173     def probe_kgdb():
0174         try:
0175             thread_info = gdb.execute("info thread 2", to_string=True)
0176             return "shadowCPU0" in thread_info
0177         except gdb.error:
0178             return False
0179 
0180     global gdbserver_type
0181     if gdbserver_type is None:
0182         if probe_qemu():
0183             gdbserver_type = GDBSERVER_QEMU
0184         elif probe_kgdb():
0185             gdbserver_type = GDBSERVER_KGDB
0186         if gdbserver_type is not None and hasattr(gdb, 'events'):
0187             gdb.events.exited.connect(exit_handler)
0188     return gdbserver_type
0189 
0190 
0191 def gdb_eval_or_none(expresssion):
0192     try:
0193         return gdb.parse_and_eval(expresssion)
0194     except gdb.error:
0195         return None
0196 
0197 
0198 def dentry_name(d):
0199     parent = d['d_parent']
0200     if parent == d or parent == 0:
0201         return ""
0202     p = dentry_name(d['d_parent']) + "/"
0203     return p + d['d_iname'].string()