0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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()