spapr: Workaround for broken radix guests
[qemu.git] / scripts / qemugdb / mtree.py
1 #!/usr/bin/python
2
3 # GDB debugging support
4 #
5 # Copyright 2012 Red Hat, Inc. and/or its affiliates
6 #
7 # Authors:
8 # Avi Kivity <avi@redhat.com>
9 #
10 # This work is licensed under the terms of the GNU GPL, version 2. See
11 # the COPYING file in the top-level directory.
12 #
13 # Contributions after 2012-01-13 are licensed under the terms of the
14 # GNU GPL, version 2 or (at your option) any later version.
15
16 # 'qemu mtree' -- display the memory hierarchy
17
18 import gdb
19
20 def isnull(ptr):
21 return ptr == gdb.Value(0).cast(ptr.type)
22
23 def int128(p):
24 '''Read an Int128 type to a python integer.
25
26 QEMU can be built with native Int128 support so we need to detect
27 if the value is a structure or the native type.
28 '''
29 if p.type.code == gdb.TYPE_CODE_STRUCT:
30 return int(p['lo']) + (int(p['hi']) << 64)
31 else:
32 return int(("%s" % p), 16)
33
34 class MtreeCommand(gdb.Command):
35 '''Display the memory tree hierarchy'''
36 def __init__(self):
37 gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
38 gdb.COMPLETE_NONE)
39 self.queue = []
40 def invoke(self, arg, from_tty):
41 self.seen = set()
42 self.queue_root('address_space_memory')
43 self.queue_root('address_space_io')
44 self.process_queue()
45 def queue_root(self, varname):
46 ptr = gdb.parse_and_eval(varname)['root']
47 self.queue.append(ptr)
48 def process_queue(self):
49 while self.queue:
50 ptr = self.queue.pop(0)
51 if int(ptr) in self.seen:
52 continue
53 self.print_item(ptr)
54 def print_item(self, ptr, offset = gdb.Value(0), level = 0):
55 self.seen.add(int(ptr))
56 addr = ptr['addr']
57 addr += offset
58 size = int128(ptr['size'])
59 alias = ptr['alias']
60 klass = ''
61 if not isnull(alias):
62 klass = ' (alias)'
63 elif not isnull(ptr['ops']):
64 klass = ' (I/O)'
65 elif bool(ptr['ram']):
66 klass = ' (RAM)'
67 gdb.write('%s%016x-%016x %s%s (@ %s)\n'
68 % (' ' * level,
69 int(addr),
70 int(addr + (size - 1)),
71 ptr['name'].string(),
72 klass,
73 ptr,
74 ),
75 gdb.STDOUT)
76 if not isnull(alias):
77 gdb.write('%s alias: %s@%016x (@ %s)\n' %
78 (' ' * level,
79 alias['name'].string(),
80 int(ptr['alias_offset']),
81 alias,
82 ),
83 gdb.STDOUT)
84 self.queue.append(alias)
85 subregion = ptr['subregions']['tqh_first']
86 level += 1
87 while not isnull(subregion):
88 self.print_item(subregion, addr, level)
89 subregion = subregion['subregions_link']['tqe_next']
90