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*8037fa55SAlex Bennée '''Read an Int128 type to a python integer. 25*8037fa55SAlex Bennée 26*8037fa55SAlex Bennée QEMU can be built with native Int128 support so we need to detect 27*8037fa55SAlex Bennée if the value is a structure or the native type. 28*8037fa55SAlex Bennée ''' 29*8037fa55SAlex Bennée if p.type.code == gdb.TYPE_CODE_STRUCT: 30d6b69132SYang Wei return int(p['lo']) + (int(p['hi']) << 64) 31*8037fa55SAlex Bennée else: 32*8037fa55SAlex Bennée return int(("%s" % p), 16) 3393b1b365SPeter Maydell 3493b1b365SPeter Maydellclass MtreeCommand(gdb.Command): 3593b1b365SPeter Maydell '''Display the memory tree hierarchy''' 3693b1b365SPeter Maydell def __init__(self): 3793b1b365SPeter Maydell gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA, 3893b1b365SPeter Maydell gdb.COMPLETE_NONE) 3993b1b365SPeter Maydell self.queue = [] 4093b1b365SPeter Maydell def invoke(self, arg, from_tty): 4193b1b365SPeter Maydell self.seen = set() 4293b1b365SPeter Maydell self.queue_root('address_space_memory') 4393b1b365SPeter Maydell self.queue_root('address_space_io') 4493b1b365SPeter Maydell self.process_queue() 4593b1b365SPeter Maydell def queue_root(self, varname): 4693b1b365SPeter Maydell ptr = gdb.parse_and_eval(varname)['root'] 4793b1b365SPeter Maydell self.queue.append(ptr) 4893b1b365SPeter Maydell def process_queue(self): 4993b1b365SPeter Maydell while self.queue: 5093b1b365SPeter Maydell ptr = self.queue.pop(0) 51d6b69132SYang Wei if int(ptr) in self.seen: 5293b1b365SPeter Maydell continue 5393b1b365SPeter Maydell self.print_item(ptr) 5493b1b365SPeter Maydell def print_item(self, ptr, offset = gdb.Value(0), level = 0): 55d6b69132SYang Wei self.seen.add(int(ptr)) 5693b1b365SPeter Maydell addr = ptr['addr'] 5793b1b365SPeter Maydell addr += offset 5893b1b365SPeter Maydell size = int128(ptr['size']) 5993b1b365SPeter Maydell alias = ptr['alias'] 6093b1b365SPeter Maydell klass = '' 6193b1b365SPeter Maydell if not isnull(alias): 6293b1b365SPeter Maydell klass = ' (alias)' 6393b1b365SPeter Maydell elif not isnull(ptr['ops']): 6493b1b365SPeter Maydell klass = ' (I/O)' 6593b1b365SPeter Maydell elif bool(ptr['ram']): 6693b1b365SPeter Maydell klass = ' (RAM)' 6793b1b365SPeter Maydell gdb.write('%s%016x-%016x %s%s (@ %s)\n' 6893b1b365SPeter Maydell % (' ' * level, 69d6b69132SYang Wei int(addr), 70d6b69132SYang Wei int(addr + (size - 1)), 7193b1b365SPeter Maydell ptr['name'].string(), 7293b1b365SPeter Maydell klass, 7393b1b365SPeter Maydell ptr, 7493b1b365SPeter Maydell ), 7593b1b365SPeter Maydell gdb.STDOUT) 7693b1b365SPeter Maydell if not isnull(alias): 7793b1b365SPeter Maydell gdb.write('%s alias: %s@%016x (@ %s)\n' % 7893b1b365SPeter Maydell (' ' * level, 7993b1b365SPeter Maydell alias['name'].string(), 80*8037fa55SAlex Bennée int(ptr['alias_offset']), 8193b1b365SPeter Maydell alias, 8293b1b365SPeter Maydell ), 8393b1b365SPeter Maydell gdb.STDOUT) 8493b1b365SPeter Maydell self.queue.append(alias) 8593b1b365SPeter Maydell subregion = ptr['subregions']['tqh_first'] 8693b1b365SPeter Maydell level += 1 8793b1b365SPeter Maydell while not isnull(subregion): 8893b1b365SPeter Maydell self.print_item(subregion, addr, level) 8993b1b365SPeter Maydell subregion = subregion['subregions_link']['tqe_next'] 9093b1b365SPeter Maydell 91