mirror of
https://github.com/cahirwpz/amigaos-cross-toolchain
synced 2025-11-22 19:53:11 +00:00
Decode HUNK_INDEX.
This commit is contained in:
@ -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)
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
from collections import namedtuple
|
||||
import os
|
||||
import struct
|
||||
|
||||
|
||||
HunkMap = {
|
||||
@ -24,9 +26,7 @@ HunkMap = {
|
||||
'HUNK_INDEX': 1019,
|
||||
'HUNK_RELOC32SHORT': 1020,
|
||||
'HUNK_RELRELOC32': 1021,
|
||||
'HUNK_ABSRELOC16': 1022,
|
||||
'HUNK_PPC_CODE': 1257,
|
||||
'HUNK_RELRELOC26': 1260
|
||||
'HUNK_ABSRELOC16': 1022
|
||||
}
|
||||
|
||||
HunkExtMap = {
|
||||
@ -44,8 +44,7 @@ HunkExtMap = {
|
||||
'EXT_RELREF32': 136, # 32 bit PC-relative reference to symbol
|
||||
'EXT_RELCOMMON': 137, # 32 bit PC-relative reference to COMMON block
|
||||
'EXT_ABSREF16': 138, # 16 bit absolute reference to symbol
|
||||
'EXT_ABSREF8': 139, # 8 bit absolute reference to symbol
|
||||
'EXT_RELREF26': 229
|
||||
'EXT_ABSREF8': 139 # 8 bit absolute reference to symbol
|
||||
}
|
||||
|
||||
# Any hunks that have the HUNKB_ADVISORY bit set will be ignored if they
|
||||
@ -92,7 +91,7 @@ def GetHunkFlags(number):
|
||||
return flags
|
||||
|
||||
|
||||
class Hunk(namedtuple('Hunk', 'name data flags')):
|
||||
class Hunk(namedtuple('Hunk', 'name kind data flags')):
|
||||
def __repr__(self):
|
||||
if self.data:
|
||||
if self.flags:
|
||||
@ -105,3 +104,34 @@ class Hunk(namedtuple('Hunk', 'name data flags')):
|
||||
|
||||
|
||||
Header = namedtuple('Header', 'residents hunks first last specifiers')
|
||||
|
||||
|
||||
class HunkFile(object):
|
||||
def __init__(self):
|
||||
self._file = None
|
||||
|
||||
def open(self, path, mode='r'):
|
||||
self._file = open(path, mode)
|
||||
|
||||
def close(self):
|
||||
self._file.close()
|
||||
|
||||
def readLong(self):
|
||||
return struct.unpack_from('>I', self._file.read(4))[0]
|
||||
|
||||
def readWord(self):
|
||||
return struct.unpack_from('>H', self._file.read(2))[0]
|
||||
|
||||
def readInt(self):
|
||||
return struct.unpack_from('>i', self._file.read(4))[0]
|
||||
|
||||
def readBytes(self, n=None):
|
||||
if n is None:
|
||||
n = self.readLong() * 4
|
||||
return self._file.read(n)
|
||||
|
||||
def readString(self, n=None):
|
||||
return self.readBytes(n).strip('\0')
|
||||
|
||||
def skip(self, n):
|
||||
self._file.seek(n, os.SEEK_CUR)
|
||||
|
||||
Reference in New Issue
Block a user