These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / 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     return int(p['lo']) + (int(p['hi']) << 64)
25
26 class MtreeCommand(gdb.Command):
27     '''Display the memory tree hierarchy'''
28     def __init__(self):
29         gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
30                              gdb.COMPLETE_NONE)
31         self.queue = []
32     def invoke(self, arg, from_tty):
33         self.seen = set()
34         self.queue_root('address_space_memory')
35         self.queue_root('address_space_io')
36         self.process_queue()
37     def queue_root(self, varname):
38         ptr = gdb.parse_and_eval(varname)['root']
39         self.queue.append(ptr)
40     def process_queue(self):
41         while self.queue:
42             ptr = self.queue.pop(0)
43             if int(ptr) in self.seen:
44                 continue
45             self.print_item(ptr)
46     def print_item(self, ptr, offset = gdb.Value(0), level = 0):
47         self.seen.add(int(ptr))
48         addr = ptr['addr']
49         addr += offset
50         size = int128(ptr['size'])
51         alias = ptr['alias']
52         klass = ''
53         if not isnull(alias):
54             klass = ' (alias)'
55         elif not isnull(ptr['ops']):
56             klass = ' (I/O)'
57         elif bool(ptr['ram']):
58             klass = ' (RAM)'
59         gdb.write('%s%016x-%016x %s%s (@ %s)\n'
60                   % ('  ' * level,
61                      int(addr),
62                      int(addr + (size - 1)),
63                      ptr['name'].string(),
64                      klass,
65                      ptr,
66                      ),
67                   gdb.STDOUT)
68         if not isnull(alias):
69             gdb.write('%s    alias: %s@%016x (@ %s)\n' %
70                       ('  ' * level,
71                        alias['name'].string(),
72                        ptr['alias_offset'],
73                        alias,
74                        ),
75                       gdb.STDOUT)
76             self.queue.append(alias)
77         subregion = ptr['subregions']['tqh_first']
78         level += 1
79         while not isnull(subregion):
80             self.print_item(subregion, addr, level)
81             subregion = subregion['subregions_link']['tqe_next']
82