debug.py 2.6 KB

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