qemu/scripts/qemugdb/mtree.py
<<
>>
Prefs
   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
  18import gdb
  19
  20def isnull(ptr):
  21    return ptr == gdb.Value(0).cast(ptr.type)
  22
  23def int128(p):
  24    return int(p['lo']) + (int(p['hi']) << 64)
  25
  26class 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
  83