debug.py 2.8 KB

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