mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
This is a minor quality of life change to help debugging, specifically when debugging test failures. Before, the test framework used hex, while the log output used decimal. This was slightly annoying to convert between. Why not output lengths/offset in hex? I don't have a big reason. I find it easier to reason about lengths in decimal and ids (such as addresses or block numbers) in hex. But this may just be me.
113 lines
3.0 KiB
Python
Executable File
113 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python2
|
|
|
|
import struct
|
|
import binascii
|
|
|
|
TYPES = {
|
|
(0x700, 0x400): 'splice',
|
|
(0x7ff, 0x401): 'create',
|
|
(0x7ff, 0x4ff): 'delete',
|
|
(0x700, 0x000): 'name',
|
|
(0x7ff, 0x001): 'name reg',
|
|
(0x7ff, 0x002): 'name dir',
|
|
(0x7ff, 0x0ff): 'name superblock',
|
|
(0x700, 0x200): 'struct',
|
|
(0x7ff, 0x200): 'struct dir',
|
|
(0x7ff, 0x202): 'struct ctz',
|
|
(0x7ff, 0x201): 'struct inline',
|
|
(0x700, 0x300): 'userattr',
|
|
(0x700, 0x600): 'tail',
|
|
(0x7ff, 0x600): 'tail soft',
|
|
(0x7ff, 0x601): 'tail hard',
|
|
(0x700, 0x700): 'gstate',
|
|
(0x7ff, 0x7ff): 'gstate move',
|
|
(0x700, 0x500): 'crc',
|
|
}
|
|
|
|
def typeof(type):
|
|
for prefix in range(12):
|
|
mask = 0x7ff & ~((1 << prefix)-1)
|
|
if (mask, type & mask) in TYPES:
|
|
return TYPES[mask, type & mask] + (
|
|
' %0*x' % (prefix/4, type & ((1 << prefix)-1))
|
|
if prefix else '')
|
|
else:
|
|
return '%02x' % type
|
|
|
|
def main(*blocks):
|
|
# find most recent block
|
|
file = None
|
|
rev = None
|
|
crc = None
|
|
versions = []
|
|
|
|
for block in blocks:
|
|
try:
|
|
nfile = open(block, 'rb')
|
|
ndata = nfile.read(4)
|
|
ncrc = binascii.crc32(ndata)
|
|
nrev, = struct.unpack('<I', ndata)
|
|
|
|
assert rev != nrev
|
|
if not file or ((rev - nrev) & 0x80000000):
|
|
file = nfile
|
|
rev = nrev
|
|
crc = ncrc
|
|
|
|
versions.append((nrev, '%s (rev %d)' % (block, nrev)))
|
|
except (IOError, struct.error):
|
|
pass
|
|
|
|
if not file:
|
|
print 'Bad metadata pair {%s}' % ', '.join(blocks)
|
|
return 1
|
|
|
|
print "--- %s ---" % ', '.join(v for _,v in sorted(versions, reverse=True))
|
|
|
|
# go through each tag, print useful information
|
|
print "%-4s %-8s %-14s %3s %4s %s" % (
|
|
'off', 'tag', 'type', 'id', 'len', 'dump')
|
|
|
|
tag = 0xffffffff
|
|
off = 4
|
|
while True:
|
|
try:
|
|
data = file.read(4)
|
|
crc = binascii.crc32(data, crc)
|
|
ntag, = struct.unpack('>I', data)
|
|
except struct.error:
|
|
break
|
|
|
|
tag ^= ntag
|
|
off += 4
|
|
|
|
type = (tag & 0x7ff00000) >> 20
|
|
id = (tag & 0x000ffc00) >> 10
|
|
size = (tag & 0x000003ff) >> 0
|
|
iscrc = (type & 0x700) == 0x500
|
|
|
|
data = file.read(size if size != 0x3ff else 0)
|
|
if iscrc:
|
|
crc = binascii.crc32(data[:4], crc)
|
|
else:
|
|
crc = binascii.crc32(data, crc)
|
|
|
|
print '%04x: %08x %-15s %3s %4s %-23s %-8s' % (
|
|
off, tag,
|
|
typeof(type) + (' bad!' if iscrc and ~crc else ''),
|
|
hex(id)[2:] if id != 0x3ff else '.',
|
|
size if size != 0x3ff else 'x',
|
|
' '.join('%02x' % ord(c) for c in data[:8]),
|
|
''.join(c if c >= ' ' and c <= '~' else '.' for c in data[:8]))
|
|
|
|
off += size if size != 0x3ff else 0
|
|
if iscrc:
|
|
crc = 0
|
|
tag ^= (type & 1) << 31
|
|
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
sys.exit(main(*sys.argv[1:]))
|