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