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