debug.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #!/usr/bin/env python2
  2. import struct
  3. import binascii
  4. TYPES = {
  5. (0x700, 0x400): 'splice',
  6. (0x7ff, 0x401): 'create',
  7. (0x7ff, 0x4ff): 'delete',
  8. (0x700, 0x000): 'name',
  9. (0x7ff, 0x001): 'name reg',
  10. (0x7ff, 0x002): 'name dir',
  11. (0x7ff, 0x0ff): 'name superblock',
  12. (0x700, 0x200): 'struct',
  13. (0x7ff, 0x200): 'struct dir',
  14. (0x7ff, 0x202): 'struct ctz',
  15. (0x7ff, 0x201): 'struct inline',
  16. (0x700, 0x300): 'userattr',
  17. (0x700, 0x600): 'tail',
  18. (0x7ff, 0x600): 'tail soft',
  19. (0x7ff, 0x601): 'tail hard',
  20. (0x700, 0x700): 'gstate',
  21. (0x7ff, 0x7ff): 'gstate move',
  22. (0x700, 0x500): 'crc',
  23. }
  24. def typeof(type):
  25. for prefix in range(12):
  26. mask = 0x7ff & ~((1 << prefix)-1)
  27. if (mask, type & mask) in TYPES:
  28. return TYPES[mask, type & mask] + (
  29. ' %0*x' % (prefix/4, type & ((1 << prefix)-1))
  30. if prefix else '')
  31. else:
  32. return '%02x' % type
  33. def main(*blocks):
  34. # find most recent block
  35. file = None
  36. rev = None
  37. crc = None
  38. versions = []
  39. for block in blocks:
  40. try:
  41. nfile = open(block, 'rb')
  42. ndata = nfile.read(4)
  43. ncrc = binascii.crc32(ndata)
  44. nrev, = struct.unpack('<I', ndata)
  45. assert rev != nrev
  46. if not file or ((rev - nrev) & 0x80000000):
  47. file = nfile
  48. rev = nrev
  49. crc = ncrc
  50. versions.append((nrev, '%s (rev %d)' % (block, nrev)))
  51. except (IOError, struct.error):
  52. pass
  53. if not file:
  54. print 'Bad metadata pair {%s}' % ', '.join(blocks)
  55. return 1
  56. print "--- %s ---" % ', '.join(v for _,v in sorted(versions, reverse=True))
  57. # go through each tag, print useful information
  58. print "%-4s %-8s %-14s %3s %4s %s" % (
  59. 'off', 'tag', 'type', 'id', 'len', 'dump')
  60. tag = 0xffffffff
  61. off = 4
  62. while True:
  63. try:
  64. data = file.read(4)
  65. crc = binascii.crc32(data, crc)
  66. ntag, = struct.unpack('>I', data)
  67. except struct.error:
  68. break
  69. tag ^= ntag
  70. off += 4
  71. type = (tag & 0x7ff00000) >> 20
  72. id = (tag & 0x000ffc00) >> 10
  73. size = (tag & 0x000003ff) >> 0
  74. iscrc = (type & 0x700) == 0x500
  75. data = file.read(size if size != 0x3ff else 0)
  76. if iscrc:
  77. crc = binascii.crc32(data[:4], crc)
  78. else:
  79. crc = binascii.crc32(data, crc)
  80. print '%04x: %08x %-15s %3s %4s %-23s %-8s' % (
  81. off, tag,
  82. typeof(type) + (' bad!' if iscrc and ~crc else ''),
  83. hex(id)[2:] if id != 0x3ff else '.',
  84. size if size != 0x3ff else 'x',
  85. ' '.join('%02x' % ord(c) for c in data[:8]),
  86. ''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8]))
  87. off += size if size != 0x3ff else 0
  88. if iscrc:
  89. crc = 0
  90. tag ^= (type & 1) << 31
  91. return 0
  92. if __name__ == "__main__":
  93. import sys
  94. sys.exit(main(*sys.argv[1:]))