12b514827SJan Kiszka# 22b514827SJan Kiszka# gdb helper commands and functions for Linux kernel debugging 32b514827SJan Kiszka# 42b514827SJan Kiszka# common utilities 52b514827SJan Kiszka# 62b514827SJan Kiszka# Copyright (c) Siemens AG, 2011-2013 72b514827SJan Kiszka# 82b514827SJan Kiszka# Authors: 92b514827SJan Kiszka# Jan Kiszka <jan.kiszka@siemens.com> 102b514827SJan Kiszka# 112b514827SJan Kiszka# This work is licensed under the terms of the GNU GPL version 2. 122b514827SJan Kiszka# 132b514827SJan Kiszka 142b514827SJan Kiszkaimport gdb 152b514827SJan Kiszka 162b514827SJan Kiszka 172b514827SJan Kiszkaclass CachedType: 182b514827SJan Kiszka def __init__(self, name): 192b514827SJan Kiszka self._type = None 202b514827SJan Kiszka self._name = name 212b514827SJan Kiszka 222b514827SJan Kiszka def _new_objfile_handler(self, event): 232b514827SJan Kiszka self._type = None 242b514827SJan Kiszka gdb.events.new_objfile.disconnect(self._new_objfile_handler) 252b514827SJan Kiszka 262b514827SJan Kiszka def get_type(self): 272b514827SJan Kiszka if self._type is None: 282b514827SJan Kiszka self._type = gdb.lookup_type(self._name) 292b514827SJan Kiszka if self._type is None: 302b514827SJan Kiszka raise gdb.GdbError( 312b514827SJan Kiszka "cannot resolve type '{0}'".format(self._name)) 322b514827SJan Kiszka if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'): 332b514827SJan Kiszka gdb.events.new_objfile.connect(self._new_objfile_handler) 342b514827SJan Kiszka return self._type 35b0fecd8cSJan Kiszka 36b0fecd8cSJan Kiszka 37b0fecd8cSJan Kiszkalong_type = CachedType("long") 38*4d040cbcSKuan-Ying Leeulong_type = CachedType("unsigned long") 39*4d040cbcSKuan-Ying Leeuint_type = CachedType("unsigned int") 40e3c8d33eSAntonio Borneoatomic_long_type = CachedType("atomic_long_t") 41*4d040cbcSKuan-Ying Leesize_t_type = CachedType("size_t") 42*4d040cbcSKuan-Ying Leestruct_page_type = CachedType("struct page") 43*4d040cbcSKuan-Ying Lee 44*4d040cbcSKuan-Ying Leedef get_uint_type(): 45*4d040cbcSKuan-Ying Lee global uint_type 46*4d040cbcSKuan-Ying Lee return uint_type.get_type() 47*4d040cbcSKuan-Ying Lee 48*4d040cbcSKuan-Ying Leedef get_page_type(): 49*4d040cbcSKuan-Ying Lee global struct_page_type 50*4d040cbcSKuan-Ying Lee return struct_page_type.get_type() 51b0fecd8cSJan Kiszka 52b0fecd8cSJan Kiszkadef get_long_type(): 53b0fecd8cSJan Kiszka global long_type 54b0fecd8cSJan Kiszka return long_type.get_type() 55b0fecd8cSJan Kiszka 56*4d040cbcSKuan-Ying Leedef get_ulong_type(): 57*4d040cbcSKuan-Ying Lee global ulong_type 58*4d040cbcSKuan-Ying Lee return ulong_type.get_type() 59*4d040cbcSKuan-Ying Lee 60*4d040cbcSKuan-Ying Leedef get_size_t_type(): 61*4d040cbcSKuan-Ying Lee global size_t_type 62*4d040cbcSKuan-Ying Lee return size_t_type.get_type() 63*4d040cbcSKuan-Ying Lee 64b0fecd8cSJan Kiszkadef offset_of(typeobj, field): 65b0fecd8cSJan Kiszka element = gdb.Value(0).cast(typeobj) 66b0fecd8cSJan Kiszka return int(str(element[field].address).split()[0], 16) 67b0fecd8cSJan Kiszka 68b0fecd8cSJan Kiszka 69b0fecd8cSJan Kiszkadef container_of(ptr, typeobj, member): 70b0fecd8cSJan Kiszka return (ptr.cast(get_long_type()) - 71b0fecd8cSJan Kiszka offset_of(typeobj, member)).cast(typeobj) 72b0fecd8cSJan Kiszka 73b0fecd8cSJan Kiszka 74b0fecd8cSJan Kiszkaclass ContainerOf(gdb.Function): 75b0fecd8cSJan Kiszka """Return pointer to containing data structure. 76b0fecd8cSJan Kiszka 77b0fecd8cSJan Kiszka$container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the 78b0fecd8cSJan Kiszkadata structure of the type TYPE in which PTR is the address of ELEMENT. 79b0fecd8cSJan KiszkaNote that TYPE and ELEMENT have to be quoted as strings.""" 80b0fecd8cSJan Kiszka 81b0fecd8cSJan Kiszka def __init__(self): 82b0fecd8cSJan Kiszka super(ContainerOf, self).__init__("container_of") 83b0fecd8cSJan Kiszka 84b0fecd8cSJan Kiszka def invoke(self, ptr, typename, elementname): 85b0fecd8cSJan Kiszka return container_of(ptr, gdb.lookup_type(typename.string()).pointer(), 86b0fecd8cSJan Kiszka elementname.string()) 87b0fecd8cSJan Kiszka 88494dbe02SStephen Boyd 89b0fecd8cSJan KiszkaContainerOf() 907f994963SJan Kiszka 917f994963SJan Kiszka 927f994963SJan KiszkaBIG_ENDIAN = 0 937f994963SJan KiszkaLITTLE_ENDIAN = 1 947f994963SJan Kiszkatarget_endianness = None 957f994963SJan Kiszka 967f994963SJan Kiszka 977f994963SJan Kiszkadef get_target_endianness(): 987f994963SJan Kiszka global target_endianness 997f994963SJan Kiszka if target_endianness is None: 1007f994963SJan Kiszka endian = gdb.execute("show endian", to_string=True) 1017f994963SJan Kiszka if "little endian" in endian: 1027f994963SJan Kiszka target_endianness = LITTLE_ENDIAN 1037f994963SJan Kiszka elif "big endian" in endian: 1047f994963SJan Kiszka target_endianness = BIG_ENDIAN 1057f994963SJan Kiszka else: 106a2e73c48SThiébaud Weksteen raise gdb.GdbError("unknown endianness '{0}'".format(str(endian))) 1077f994963SJan Kiszka return target_endianness 10878e87817SJan Kiszka 10978e87817SJan Kiszka 110321958d9SDom Cotedef read_memoryview(inf, start, length): 1117362042fSPeng Liu m = inf.read_memory(start, length) 1127362042fSPeng Liu if type(m) is memoryview: 1137362042fSPeng Liu return m 1147362042fSPeng Liu return memoryview(m) 115321958d9SDom Cote 116321958d9SDom Cote 117ca210ba3SJoel Colledgedef read_u16(buffer, offset): 118ca210ba3SJoel Colledge buffer_val = buffer[offset:offset + 2] 119321958d9SDom Cote value = [0, 0] 120321958d9SDom Cote 121ca210ba3SJoel Colledge if type(buffer_val[0]) is str: 122ca210ba3SJoel Colledge value[0] = ord(buffer_val[0]) 123ca210ba3SJoel Colledge value[1] = ord(buffer_val[1]) 12478e87817SJan Kiszka else: 125ca210ba3SJoel Colledge value[0] = buffer_val[0] 126ca210ba3SJoel Colledge value[1] = buffer_val[1] 127321958d9SDom Cote 128321958d9SDom Cote if get_target_endianness() == LITTLE_ENDIAN: 129321958d9SDom Cote return value[0] + (value[1] << 8) 130321958d9SDom Cote else: 131321958d9SDom Cote return value[1] + (value[0] << 8) 13278e87817SJan Kiszka 13378e87817SJan Kiszka 134ca210ba3SJoel Colledgedef read_u32(buffer, offset): 13578e87817SJan Kiszka if get_target_endianness() == LITTLE_ENDIAN: 136ca210ba3SJoel Colledge return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16) 13778e87817SJan Kiszka else: 138ca210ba3SJoel Colledge return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16) 13978e87817SJan Kiszka 14078e87817SJan Kiszka 141ca210ba3SJoel Colledgedef read_u64(buffer, offset): 14278e87817SJan Kiszka if get_target_endianness() == LITTLE_ENDIAN: 143ca210ba3SJoel Colledge return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32) 14478e87817SJan Kiszka else: 145ca210ba3SJoel Colledge return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32) 146b24e2d21SJan Kiszka 147b24e2d21SJan Kiszka 1483e0d075cSJohn Ognessdef read_ulong(buffer, offset): 1493e0d075cSJohn Ogness if get_long_type().sizeof == 8: 1503e0d075cSJohn Ogness return read_u64(buffer, offset) 1513e0d075cSJohn Ogness else: 1523e0d075cSJohn Ogness return read_u32(buffer, offset) 1533e0d075cSJohn Ogness 154e3c8d33eSAntonio Borneoatomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos 155e3c8d33eSAntonio Borneoatomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof 156e3c8d33eSAntonio Borneo 157e3c8d33eSAntonio Borneodef read_atomic_long(buffer, offset): 158e3c8d33eSAntonio Borneo global atomic_long_counter_offset 159e3c8d33eSAntonio Borneo global atomic_long_counter_sizeof 160e3c8d33eSAntonio Borneo 161e3c8d33eSAntonio Borneo if atomic_long_counter_sizeof == 8: 162e3c8d33eSAntonio Borneo return read_u64(buffer, offset + atomic_long_counter_offset) 163e3c8d33eSAntonio Borneo else: 164e3c8d33eSAntonio Borneo return read_u32(buffer, offset + atomic_long_counter_offset) 1653e0d075cSJohn Ogness 166b24e2d21SJan Kiszkatarget_arch = None 167b24e2d21SJan Kiszka 168b24e2d21SJan Kiszka 169b24e2d21SJan Kiszkadef is_target_arch(arch): 170b24e2d21SJan Kiszka if hasattr(gdb.Frame, 'architecture'): 171b24e2d21SJan Kiszka return arch in gdb.newest_frame().architecture().name() 172b24e2d21SJan Kiszka else: 173b24e2d21SJan Kiszka global target_arch 174b24e2d21SJan Kiszka if target_arch is None: 175b24e2d21SJan Kiszka target_arch = gdb.execute("show architecture", to_string=True) 176b24e2d21SJan Kiszka return arch in target_arch 177a4d86792SJan Kiszka 178a4d86792SJan Kiszka 179a4d86792SJan KiszkaGDBSERVER_QEMU = 0 180a4d86792SJan KiszkaGDBSERVER_KGDB = 1 181a4d86792SJan Kiszkagdbserver_type = None 182a4d86792SJan Kiszka 183a4d86792SJan Kiszka 184a4d86792SJan Kiszkadef get_gdbserver_type(): 185a4d86792SJan Kiszka def exit_handler(event): 186a4d86792SJan Kiszka global gdbserver_type 187a4d86792SJan Kiszka gdbserver_type = None 188a4d86792SJan Kiszka gdb.events.exited.disconnect(exit_handler) 189a4d86792SJan Kiszka 190a4d86792SJan Kiszka def probe_qemu(): 191a4d86792SJan Kiszka try: 192a4d86792SJan Kiszka return gdb.execute("monitor info version", to_string=True) != "" 193494dbe02SStephen Boyd except gdb.error: 194a4d86792SJan Kiszka return False 195a4d86792SJan Kiszka 196a4d86792SJan Kiszka def probe_kgdb(): 197a4d86792SJan Kiszka try: 198a4d86792SJan Kiszka thread_info = gdb.execute("info thread 2", to_string=True) 199a4d86792SJan Kiszka return "shadowCPU0" in thread_info 200494dbe02SStephen Boyd except gdb.error: 201a4d86792SJan Kiszka return False 202a4d86792SJan Kiszka 203a4d86792SJan Kiszka global gdbserver_type 204a4d86792SJan Kiszka if gdbserver_type is None: 205a4d86792SJan Kiszka if probe_qemu(): 206a4d86792SJan Kiszka gdbserver_type = GDBSERVER_QEMU 207a4d86792SJan Kiszka elif probe_kgdb(): 208a4d86792SJan Kiszka gdbserver_type = GDBSERVER_KGDB 2096ad18b73SThiébaud Weksteen if gdbserver_type is not None and hasattr(gdb, 'events'): 210a4d86792SJan Kiszka gdb.events.exited.connect(exit_handler) 211a4d86792SJan Kiszka return gdbserver_type 212e78f3d70SKieran Bingham 213e78f3d70SKieran Bingham 214e78f3d70SKieran Binghamdef gdb_eval_or_none(expresssion): 215e78f3d70SKieran Bingham try: 216e78f3d70SKieran Bingham return gdb.parse_and_eval(expresssion) 217494dbe02SStephen Boyd except gdb.error: 218e78f3d70SKieran Bingham return None 219