xref: /openbmc/linux/scripts/gdb/linux/utils.py (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
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