193b1b365SPeter Maydell#!/usr/bin/python 293b1b365SPeter Maydell 393b1b365SPeter Maydell# GDB debugging support 493b1b365SPeter Maydell# 593b1b365SPeter Maydell# Copyright 2012 Red Hat, Inc. and/or its affiliates 693b1b365SPeter Maydell# 793b1b365SPeter Maydell# Authors: 893b1b365SPeter Maydell# Avi Kivity <avi@redhat.com> 993b1b365SPeter Maydell# 1093b1b365SPeter Maydell# This work is licensed under the terms of the GNU GPL, version 2. See 1193b1b365SPeter Maydell# the COPYING file in the top-level directory. 1293b1b365SPeter Maydell# 1393b1b365SPeter Maydell# Contributions after 2012-01-13 are licensed under the terms of the 1493b1b365SPeter Maydell# GNU GPL, version 2 or (at your option) any later version. 1593b1b365SPeter Maydell 1693b1b365SPeter Maydell# 'qemu mtree' -- display the memory hierarchy 1793b1b365SPeter Maydell 1893b1b365SPeter Maydellimport gdb 1993b1b365SPeter Maydell 2093b1b365SPeter Maydelldef isnull(ptr): 2193b1b365SPeter Maydell return ptr == gdb.Value(0).cast(ptr.type) 2293b1b365SPeter Maydell 2393b1b365SPeter Maydelldef int128(p): 24*d6b69132SYang Wei return int(p['lo']) + (int(p['hi']) << 64) 2593b1b365SPeter Maydell 2693b1b365SPeter Maydellclass MtreeCommand(gdb.Command): 2793b1b365SPeter Maydell '''Display the memory tree hierarchy''' 2893b1b365SPeter Maydell def __init__(self): 2993b1b365SPeter Maydell gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA, 3093b1b365SPeter Maydell gdb.COMPLETE_NONE) 3193b1b365SPeter Maydell self.queue = [] 3293b1b365SPeter Maydell def invoke(self, arg, from_tty): 3393b1b365SPeter Maydell self.seen = set() 3493b1b365SPeter Maydell self.queue_root('address_space_memory') 3593b1b365SPeter Maydell self.queue_root('address_space_io') 3693b1b365SPeter Maydell self.process_queue() 3793b1b365SPeter Maydell def queue_root(self, varname): 3893b1b365SPeter Maydell ptr = gdb.parse_and_eval(varname)['root'] 3993b1b365SPeter Maydell self.queue.append(ptr) 4093b1b365SPeter Maydell def process_queue(self): 4193b1b365SPeter Maydell while self.queue: 4293b1b365SPeter Maydell ptr = self.queue.pop(0) 43*d6b69132SYang Wei if int(ptr) in self.seen: 4493b1b365SPeter Maydell continue 4593b1b365SPeter Maydell self.print_item(ptr) 4693b1b365SPeter Maydell def print_item(self, ptr, offset = gdb.Value(0), level = 0): 47*d6b69132SYang Wei self.seen.add(int(ptr)) 4893b1b365SPeter Maydell addr = ptr['addr'] 4993b1b365SPeter Maydell addr += offset 5093b1b365SPeter Maydell size = int128(ptr['size']) 5193b1b365SPeter Maydell alias = ptr['alias'] 5293b1b365SPeter Maydell klass = '' 5393b1b365SPeter Maydell if not isnull(alias): 5493b1b365SPeter Maydell klass = ' (alias)' 5593b1b365SPeter Maydell elif not isnull(ptr['ops']): 5693b1b365SPeter Maydell klass = ' (I/O)' 5793b1b365SPeter Maydell elif bool(ptr['ram']): 5893b1b365SPeter Maydell klass = ' (RAM)' 5993b1b365SPeter Maydell gdb.write('%s%016x-%016x %s%s (@ %s)\n' 6093b1b365SPeter Maydell % (' ' * level, 61*d6b69132SYang Wei int(addr), 62*d6b69132SYang Wei int(addr + (size - 1)), 6393b1b365SPeter Maydell ptr['name'].string(), 6493b1b365SPeter Maydell klass, 6593b1b365SPeter Maydell ptr, 6693b1b365SPeter Maydell ), 6793b1b365SPeter Maydell gdb.STDOUT) 6893b1b365SPeter Maydell if not isnull(alias): 6993b1b365SPeter Maydell gdb.write('%s alias: %s@%016x (@ %s)\n' % 7093b1b365SPeter Maydell (' ' * level, 7193b1b365SPeter Maydell alias['name'].string(), 7293b1b365SPeter Maydell ptr['alias_offset'], 7393b1b365SPeter Maydell alias, 7493b1b365SPeter Maydell ), 7593b1b365SPeter Maydell gdb.STDOUT) 7693b1b365SPeter Maydell self.queue.append(alias) 7793b1b365SPeter Maydell subregion = ptr['subregions']['tqh_first'] 7893b1b365SPeter Maydell level += 1 7993b1b365SPeter Maydell while not isnull(subregion): 8093b1b365SPeter Maydell self.print_item(subregion, addr, level) 8193b1b365SPeter Maydell subregion = subregion['subregions_link']['tqe_next'] 8293b1b365SPeter Maydell 83