Decode HUNK_INDEX.

This commit is contained in:
Krystian Bacławski
2013-05-26 22:26:36 +02:00
parent 4f51dc13b8
commit 290d742c4e
2 changed files with 148 additions and 28 deletions
+112 -22
View File
@@ -144,6 +144,66 @@ class HunkParser(object):
self.index += length + 4
return ''
def ReadIndex(self):
length = self.ReadLong() * 4
last = self.index + length
strsize = self.ReadWord()
strdata = self.ReadBytes(strsize)
names = {}
s = 0
while True:
e = strdata.find('\0', s, strsize)
if e == -1:
break
if e > s:
names[s] = strdata[s:e]
s = e + 1
units = []
while self.index < last:
unit_name = names[self.ReadWord()]
first_hunk = self.ReadWord() * 4
hunks_count = self.ReadWord()
hunks = []
for i in range(hunks_count):
h_name = names[self.ReadWord()]
h_size = self.ReadWord() * 4
h_type = self.ReadWord()
refs_count = self.ReadWord()
refs = []
for i in range(refs_count):
n = self.ReadWord()
try:
refs.append(names[n])
except KeyError:
refs.append(names[n + 1])
symbols_count = self.ReadWord()
symbols = []
for i in range(symbols_count):
s_name = names[self.ReadWord()]
s_value = self.ReadWord()
s_type = self.ReadWord()
symbols.append((s_name, s_value, s_type))
hunks.append((h_name, h_size, h_type, refs, symbols))
units.append((unit_name, first_hunk, hunks))
return units
def Parse(self):
executable = None
hunks = []
@@ -161,34 +221,45 @@ class HunkParser(object):
if executable is None:
executable = (name == 'HUNK_HEADER')
kind = 'binary'
if name in ['HUNK_END', 'HUNK_BREAK']:
data = None
kind = 'separator'
elif name == 'HUNK_EXT':
data = self.ReadHunkExt()
elif name == 'HUNK_SYMBOL':
data = self.ReadSymbols()
kind = 'symbols'
elif name == 'HUNK_HEADER':
data = self.ReadHeader()
kind = 'header'
elif name == 'HUNK_INDEX':
data = self.ReadIndex()
kind = 'index'
elif name in ['HUNK_NAME', 'HUNK_UNIT']:
data = self.ReadString()
elif name in ['HUNK_CODE', 'HUNK_PPC_CODE', 'HUNK_DATA', 'HUNK_DEBUG',
'HUNK_INDEX']:
kind = 'string'
elif name in ['HUNK_CODE', 'HUNK_PPC_CODE', 'HUNK_DATA', 'HUNK_DEBUG']:
data = self.ReadBytes()
elif name == 'HUNK_OVERLAY':
data = self.ReadOverlay()
elif name in ['HUNK_BSS', 'HUNK_LIB']:
data = self.ReadLong() * 4
kind = 'container'
elif name in ['HUNK_RELOC32', 'HUNK_RELOC16', 'HUNK_RELOC8']:
data = self.ReadRelocs()
kind = 'relocs'
elif name in ['HUNK_DREL32', 'HUNK_DREL16', 'HUNK_DREL8']:
if executable:
data = self.ReadShortRelocs()
else:
data = self.ReadRelocs()
kind = 'relocs'
else:
raise NotImplementedError('%s not handled.' % name)
hunks.append(Hunk(name, data, flags))
hunks.append(Hunk(name, kind, data, flags))
return hunks
@@ -199,27 +270,46 @@ if __name__ == '__main__':
parser = HunkParser(hunkfile)
for hunk in parser.Parse():
print hunk.name
if hunk.name == 'HUNK_EXT':
if hunk.kind == 'separator':
print ''
elif hunk.kind == 'header':
print hunk.data
elif hunk.name == 'HUNK_EXT':
for name, symbols in hunk.data.items():
print ' ', name
sl = max(len(s) for s, _ in symbols)
for symbol, value in symbols:
print ' ', symbol.ljust(sl, ' '), '=', value
elif hunk.name == 'HUNK_END':
print ''
elif hunk.data:
if isinstance(hunk.data, dict):
for k, nums in hunk.data.items():
prefix = ' %d: ' % k
print textwrap.fill(', '.join(str(n) for n in nums),
width=80,
initial_indent=prefix,
subsequent_indent=' ' * len(prefix))
elif isinstance(hunk.data, str):
util.hexdump(hunk.data)
elif isinstance(hunk.data, list):
namelen = max(len(name) for name, _ in hunk.data) + 1
for name, offset in hunk.data:
print ' {0}: {1}'.format(name.ljust(namelen, ' '), offset)
else:
print ' ', repr(hunk.data)
elif hunk.kind == 'relocs':
for k, nums in hunk.data.items():
prefix = ' %d: ' % k
print textwrap.fill('[' + ', '.join(str(n) for n in nums) + ']',
width=68,
initial_indent=prefix,
subsequent_indent=' ' * (len(prefix) + 1))
elif hunk.kind == 'binary':
util.hexdump(hunk.data)
elif hunk.kind == 'symbols':
namelen = max(len(name) for name, _ in hunk.data) + 1
for name, offset in hunk.data:
print ' {0}: {1}'.format(name.ljust(namelen, ' '), offset)
elif hunk.kind == 'string':
print ' ', hunk.data
elif hunk.kind == 'index':
for u in hunk.data:
print ' ', 'UNIT', repr(u[0]), u[1]
for h in u[2]:
print ' ', GetHunkName(h[2]), repr(h[0]), h[1]
if h[3]:
print ' ', 'REFS'
for s in sorted(h[3]):
print ' ', s
if h[4]:
print ' ', 'DEFS'
l = max(len(s[0]) for s in h[4])
for s in sorted(h[4], key=lambda x: x[1]):
print ' ', s[0].ljust(l), '=', s[1]
print ''
else:
print ' ', repr(hunk.data)