2
0

qemu-gdb.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/python
  2. # GDB debugging support
  3. #
  4. # Copyright 2012 Red Hat, Inc. and/or its affiliates
  5. #
  6. # Authors:
  7. # Avi Kivity <avi@redhat.com>
  8. #
  9. # This work is licensed under the terms of the GNU GPL, version 2. See
  10. # the COPYING file in the top-level directory.
  11. #
  12. # Contributions after 2012-01-13 are licensed under the terms of the
  13. # GNU GPL, version 2 or (at your option) any later version.
  14. import gdb
  15. def isnull(ptr):
  16. return ptr == gdb.Value(0).cast(ptr.type)
  17. def int128(p):
  18. return long(p['lo']) + (long(p['hi']) << 64)
  19. class QemuCommand(gdb.Command):
  20. '''Prefix for QEMU debug support commands'''
  21. def __init__(self):
  22. gdb.Command.__init__(self, 'qemu', gdb.COMMAND_DATA,
  23. gdb.COMPLETE_NONE, True)
  24. class MtreeCommand(gdb.Command):
  25. '''Display the memory tree hierarchy'''
  26. def __init__(self):
  27. gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
  28. gdb.COMPLETE_NONE)
  29. self.queue = []
  30. def invoke(self, arg, from_tty):
  31. self.seen = set()
  32. self.queue_root('address_space_memory')
  33. self.queue_root('address_space_io')
  34. self.process_queue()
  35. def queue_root(self, varname):
  36. ptr = gdb.parse_and_eval(varname)['root']
  37. self.queue.append(ptr)
  38. def process_queue(self):
  39. while self.queue:
  40. ptr = self.queue.pop(0)
  41. if long(ptr) in self.seen:
  42. continue
  43. self.print_item(ptr)
  44. def print_item(self, ptr, offset = gdb.Value(0), level = 0):
  45. self.seen.add(long(ptr))
  46. addr = ptr['addr']
  47. addr += offset
  48. size = int128(ptr['size'])
  49. alias = ptr['alias']
  50. klass = ''
  51. if not isnull(alias):
  52. klass = ' (alias)'
  53. elif not isnull(ptr['ops']):
  54. klass = ' (I/O)'
  55. elif bool(ptr['ram']):
  56. klass = ' (RAM)'
  57. gdb.write('%s%016x-%016x %s%s (@ %s)\n'
  58. % (' ' * level,
  59. long(addr),
  60. long(addr + (size - 1)),
  61. ptr['name'].string(),
  62. klass,
  63. ptr,
  64. ),
  65. gdb.STDOUT)
  66. if not isnull(alias):
  67. gdb.write('%s alias: %s@%016x (@ %s)\n' %
  68. (' ' * level,
  69. alias['name'].string(),
  70. ptr['alias_offset'],
  71. alias,
  72. ),
  73. gdb.STDOUT)
  74. self.queue.append(alias)
  75. subregion = ptr['subregions']['tqh_first']
  76. level += 1
  77. while not isnull(subregion):
  78. self.print_item(subregion, addr, level)
  79. subregion = subregion['subregions_link']['tqe_next']
  80. QemuCommand()
  81. MtreeCommand()