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