xref: /OK3568_Linux_fs/kernel/scripts/gdb/linux/utils.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# gdb helper commands and functions for Linux kernel debugging
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun#  common utilities
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun# Copyright (c) Siemens AG, 2011-2013
7*4882a593Smuzhiyun#
8*4882a593Smuzhiyun# Authors:
9*4882a593Smuzhiyun#  Jan Kiszka <jan.kiszka@siemens.com>
10*4882a593Smuzhiyun#
11*4882a593Smuzhiyun# This work is licensed under the terms of the GNU GPL version 2.
12*4882a593Smuzhiyun#
13*4882a593Smuzhiyun
14*4882a593Smuzhiyunimport gdb
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunclass CachedType:
18*4882a593Smuzhiyun    def __init__(self, name):
19*4882a593Smuzhiyun        self._type = None
20*4882a593Smuzhiyun        self._name = name
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun    def _new_objfile_handler(self, event):
23*4882a593Smuzhiyun        self._type = None
24*4882a593Smuzhiyun        gdb.events.new_objfile.disconnect(self._new_objfile_handler)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun    def get_type(self):
27*4882a593Smuzhiyun        if self._type is None:
28*4882a593Smuzhiyun            self._type = gdb.lookup_type(self._name)
29*4882a593Smuzhiyun            if self._type is None:
30*4882a593Smuzhiyun                raise gdb.GdbError(
31*4882a593Smuzhiyun                    "cannot resolve type '{0}'".format(self._name))
32*4882a593Smuzhiyun            if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'):
33*4882a593Smuzhiyun                gdb.events.new_objfile.connect(self._new_objfile_handler)
34*4882a593Smuzhiyun        return self._type
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun
37*4882a593Smuzhiyunlong_type = CachedType("long")
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun
40*4882a593Smuzhiyundef get_long_type():
41*4882a593Smuzhiyun    global long_type
42*4882a593Smuzhiyun    return long_type.get_type()
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun
45*4882a593Smuzhiyundef offset_of(typeobj, field):
46*4882a593Smuzhiyun    element = gdb.Value(0).cast(typeobj)
47*4882a593Smuzhiyun    return int(str(element[field].address).split()[0], 16)
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun
50*4882a593Smuzhiyundef container_of(ptr, typeobj, member):
51*4882a593Smuzhiyun    return (ptr.cast(get_long_type()) -
52*4882a593Smuzhiyun            offset_of(typeobj, member)).cast(typeobj)
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun
55*4882a593Smuzhiyunclass ContainerOf(gdb.Function):
56*4882a593Smuzhiyun    """Return pointer to containing data structure.
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun$container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the
59*4882a593Smuzhiyundata structure of the type TYPE in which PTR is the address of ELEMENT.
60*4882a593SmuzhiyunNote that TYPE and ELEMENT have to be quoted as strings."""
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun    def __init__(self):
63*4882a593Smuzhiyun        super(ContainerOf, self).__init__("container_of")
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun    def invoke(self, ptr, typename, elementname):
66*4882a593Smuzhiyun        return container_of(ptr, gdb.lookup_type(typename.string()).pointer(),
67*4882a593Smuzhiyun                            elementname.string())
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun
70*4882a593SmuzhiyunContainerOf()
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun
73*4882a593SmuzhiyunBIG_ENDIAN = 0
74*4882a593SmuzhiyunLITTLE_ENDIAN = 1
75*4882a593Smuzhiyuntarget_endianness = None
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun
78*4882a593Smuzhiyundef get_target_endianness():
79*4882a593Smuzhiyun    global target_endianness
80*4882a593Smuzhiyun    if target_endianness is None:
81*4882a593Smuzhiyun        endian = gdb.execute("show endian", to_string=True)
82*4882a593Smuzhiyun        if "little endian" in endian:
83*4882a593Smuzhiyun            target_endianness = LITTLE_ENDIAN
84*4882a593Smuzhiyun        elif "big endian" in endian:
85*4882a593Smuzhiyun            target_endianness = BIG_ENDIAN
86*4882a593Smuzhiyun        else:
87*4882a593Smuzhiyun            raise gdb.GdbError("unknown endianness '{0}'".format(str(endian)))
88*4882a593Smuzhiyun    return target_endianness
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun
91*4882a593Smuzhiyundef read_memoryview(inf, start, length):
92*4882a593Smuzhiyun    return memoryview(inf.read_memory(start, length))
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun
95*4882a593Smuzhiyundef read_u16(buffer, offset):
96*4882a593Smuzhiyun    buffer_val = buffer[offset:offset + 2]
97*4882a593Smuzhiyun    value = [0, 0]
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun    if type(buffer_val[0]) is str:
100*4882a593Smuzhiyun        value[0] = ord(buffer_val[0])
101*4882a593Smuzhiyun        value[1] = ord(buffer_val[1])
102*4882a593Smuzhiyun    else:
103*4882a593Smuzhiyun        value[0] = buffer_val[0]
104*4882a593Smuzhiyun        value[1] = buffer_val[1]
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun    if get_target_endianness() == LITTLE_ENDIAN:
107*4882a593Smuzhiyun        return value[0] + (value[1] << 8)
108*4882a593Smuzhiyun    else:
109*4882a593Smuzhiyun        return value[1] + (value[0] << 8)
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun
112*4882a593Smuzhiyundef read_u32(buffer, offset):
113*4882a593Smuzhiyun    if get_target_endianness() == LITTLE_ENDIAN:
114*4882a593Smuzhiyun        return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16)
115*4882a593Smuzhiyun    else:
116*4882a593Smuzhiyun        return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16)
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun
119*4882a593Smuzhiyundef read_u64(buffer, offset):
120*4882a593Smuzhiyun    if get_target_endianness() == LITTLE_ENDIAN:
121*4882a593Smuzhiyun        return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32)
122*4882a593Smuzhiyun    else:
123*4882a593Smuzhiyun        return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32)
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun
126*4882a593Smuzhiyundef read_ulong(buffer, offset):
127*4882a593Smuzhiyun    if get_long_type().sizeof == 8:
128*4882a593Smuzhiyun        return read_u64(buffer, offset)
129*4882a593Smuzhiyun    else:
130*4882a593Smuzhiyun        return read_u32(buffer, offset)
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun
133*4882a593Smuzhiyuntarget_arch = None
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun
136*4882a593Smuzhiyundef is_target_arch(arch):
137*4882a593Smuzhiyun    if hasattr(gdb.Frame, 'architecture'):
138*4882a593Smuzhiyun        return arch in gdb.newest_frame().architecture().name()
139*4882a593Smuzhiyun    else:
140*4882a593Smuzhiyun        global target_arch
141*4882a593Smuzhiyun        if target_arch is None:
142*4882a593Smuzhiyun            target_arch = gdb.execute("show architecture", to_string=True)
143*4882a593Smuzhiyun        return arch in target_arch
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun
146*4882a593SmuzhiyunGDBSERVER_QEMU = 0
147*4882a593SmuzhiyunGDBSERVER_KGDB = 1
148*4882a593Smuzhiyungdbserver_type = None
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun
151*4882a593Smuzhiyundef get_gdbserver_type():
152*4882a593Smuzhiyun    def exit_handler(event):
153*4882a593Smuzhiyun        global gdbserver_type
154*4882a593Smuzhiyun        gdbserver_type = None
155*4882a593Smuzhiyun        gdb.events.exited.disconnect(exit_handler)
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun    def probe_qemu():
158*4882a593Smuzhiyun        try:
159*4882a593Smuzhiyun            return gdb.execute("monitor info version", to_string=True) != ""
160*4882a593Smuzhiyun        except gdb.error:
161*4882a593Smuzhiyun            return False
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun    def probe_kgdb():
164*4882a593Smuzhiyun        try:
165*4882a593Smuzhiyun            thread_info = gdb.execute("info thread 2", to_string=True)
166*4882a593Smuzhiyun            return "shadowCPU0" in thread_info
167*4882a593Smuzhiyun        except gdb.error:
168*4882a593Smuzhiyun            return False
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun    global gdbserver_type
171*4882a593Smuzhiyun    if gdbserver_type is None:
172*4882a593Smuzhiyun        if probe_qemu():
173*4882a593Smuzhiyun            gdbserver_type = GDBSERVER_QEMU
174*4882a593Smuzhiyun        elif probe_kgdb():
175*4882a593Smuzhiyun            gdbserver_type = GDBSERVER_KGDB
176*4882a593Smuzhiyun        if gdbserver_type is not None and hasattr(gdb, 'events'):
177*4882a593Smuzhiyun            gdb.events.exited.connect(exit_handler)
178*4882a593Smuzhiyun    return gdbserver_type
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun
181*4882a593Smuzhiyundef gdb_eval_or_none(expresssion):
182*4882a593Smuzhiyun    try:
183*4882a593Smuzhiyun        return gdb.parse_and_eval(expresssion)
184*4882a593Smuzhiyun    except gdb.error:
185*4882a593Smuzhiyun        return None
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun
188*4882a593Smuzhiyundef dentry_name(d):
189*4882a593Smuzhiyun    parent = d['d_parent']
190*4882a593Smuzhiyun    if parent == d or parent == 0:
191*4882a593Smuzhiyun        return ""
192*4882a593Smuzhiyun    p = dentry_name(d['d_parent']) + "/"
193*4882a593Smuzhiyun    return p + d['d_iname'].string()
194