mirror of
https://frontier.innolan.net/github/amigaos-cross-toolchain6.git
synced 2024-10-19 10:29:55 +00:00
Factor out some functionality to separate file.
This commit is contained in:
+11
-114
@@ -1,115 +1,12 @@
|
||||
#!/usr/bin/env python2.7 -B
|
||||
|
||||
from collections import namedtuple, defaultdict
|
||||
import inspect
|
||||
from collections import defaultdict
|
||||
import struct
|
||||
import sys
|
||||
import textwrap
|
||||
from objtools import util
|
||||
|
||||
|
||||
class HunkMap(object):
|
||||
# Any hunks that have the HUNKB_ADVISORY bit set will be ignored if they
|
||||
# aren't understood. When ignored, they're treated like HUNK_DEBUG hunks.
|
||||
# NOTE: this handling of HUNKB_ADVISORY started as of V39 dos.library! If
|
||||
# lading such executables is attempted under <V39 dos, it will fail with a
|
||||
# bad hunk type.
|
||||
HUNKB_ADVISORY = 29
|
||||
HUNKB_CHIP = 30
|
||||
HUNKB_FAST = 31
|
||||
HUNKF_ADVISORY = 1 << HUNKB_ADVISORY
|
||||
HUNKF_CHIP = 1 << HUNKB_CHIP
|
||||
HUNKF_FAST = 1 << HUNKB_FAST
|
||||
|
||||
HUNK_UNIT = 999
|
||||
HUNK_NAME = 1000
|
||||
HUNK_CODE = 1001
|
||||
HUNK_DATA = 1002
|
||||
HUNK_BSS = 1003
|
||||
HUNK_RELOC32 = 1004
|
||||
HUNK_RELOC16 = 1005
|
||||
HUNK_RELOC8 = 1006
|
||||
HUNK_EXT = 1007
|
||||
HUNK_SYMBOL = 1008
|
||||
HUNK_DEBUG = 1009
|
||||
HUNK_END = 1010
|
||||
HUNK_HEADER = 1011
|
||||
HUNK_OVERLAY = 1013
|
||||
HUNK_BREAK = 1014
|
||||
HUNK_DREL32 = 1015
|
||||
HUNK_DREL16 = 1016
|
||||
HUNK_DREL8 = 1017
|
||||
HUNK_LIB = 1018
|
||||
HUNK_INDEX = 1019
|
||||
HUNK_RELOC32SHORT = 1020
|
||||
HUNK_RELRELOC32 = 1021
|
||||
HUNK_ABSRELOC16 = 1022
|
||||
HUNK_PPC_CODE = 1257
|
||||
HUNK_RELRELOC26 = 1260
|
||||
|
||||
@classmethod
|
||||
def GetName(cls, number):
|
||||
number &= 0x1fffffff
|
||||
|
||||
for name, value in inspect.getmembers(cls):
|
||||
if name.startswith('HUNK_'):
|
||||
if value == number:
|
||||
return name
|
||||
|
||||
raise ValueError('Unknown Hunk: %d' % number)
|
||||
|
||||
@classmethod
|
||||
def GetFlags(cls, number):
|
||||
flags = []
|
||||
|
||||
for name, value in inspect.getmembers(cls):
|
||||
if name.startswith('HUNKF_'):
|
||||
if value & number:
|
||||
flags.append(name)
|
||||
|
||||
return flags
|
||||
|
||||
|
||||
class HunkExtMap(object):
|
||||
EXT_SYMB = 0 # symbol table
|
||||
EXT_DEF = 1 # relocatable definition
|
||||
EXT_ABS = 2 # Absolute definition
|
||||
EXT_RES = 3 # no longer supported
|
||||
EXT_REF32 = 129 # 32 bit absolute reference to symbol
|
||||
EXT_COMMON = 130 # 32 bit absolute reference to COMMON block
|
||||
EXT_REF16 = 131 # 16 bit PC-relative reference to symbol
|
||||
EXT_REF8 = 132 # 8 bit PC-relative reference to symbol
|
||||
EXT_DEXT32 = 133 # 32 bit data relative reference
|
||||
EXT_DEXT16 = 134 # 16 bit data relative reference
|
||||
EXT_DEXT8 = 135 # 8 bit data relative reference
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def GetName(cls, number):
|
||||
for name, value in inspect.getmembers(cls):
|
||||
if name.startswith('EXT_'):
|
||||
if value == number:
|
||||
return name
|
||||
raise ValueError('Unknown HunkExt: %d' % number)
|
||||
|
||||
|
||||
class Hunk(namedtuple('Hunk', 'name data flags')):
|
||||
def __repr__(self):
|
||||
if self.data:
|
||||
if self.flags:
|
||||
flags = ', flags=%s' % '|'.join(self.flags)
|
||||
else:
|
||||
flags = ''
|
||||
return '%s(%r%s)' % (self.name, self.data, flags)
|
||||
else:
|
||||
return self.name
|
||||
|
||||
|
||||
Header = namedtuple('Header', 'residents hunks first last specifiers')
|
||||
from objtools.hunk import (GetHunkName, GetHunkExtName, GetHunkFlags, Hunk,
|
||||
Header)
|
||||
|
||||
|
||||
class HunkParser(object):
|
||||
@@ -118,17 +15,17 @@ class HunkParser(object):
|
||||
self.index = 0
|
||||
|
||||
def ReadLong(self):
|
||||
data = struct.unpack('>I', self.data[self.index:self.index + 4])[0]
|
||||
data = struct.unpack_from('>I', self.data, self.index)[0]
|
||||
self.index += 4
|
||||
return data
|
||||
|
||||
def ReadWord(self):
|
||||
data = struct.unpack('>H', self.data[self.index:self.index + 2])[0]
|
||||
data = struct.unpack_from('>H', self.data, self.index)[0]
|
||||
self.index += 2
|
||||
return data
|
||||
|
||||
def ReadInt(self):
|
||||
data = struct.unpack('>i', self.data[self.index:self.index + 4])[0]
|
||||
data = struct.unpack_from('>i', self.data, self.index)[0]
|
||||
self.index += 4
|
||||
return data
|
||||
|
||||
@@ -176,7 +73,7 @@ class HunkParser(object):
|
||||
break
|
||||
|
||||
length = (longs & 0xffffff) * 4
|
||||
extName = HunkExtMap.GetName(longs >> 24)
|
||||
extName = GetHunkExtName(longs >> 24)
|
||||
|
||||
if extName in ['EXT_DEF', 'EXT_ABS', 'EXT_REL']:
|
||||
data = self.ReadSymbol(length)
|
||||
@@ -201,7 +98,7 @@ class HunkParser(object):
|
||||
|
||||
hunkRef = self.ReadLong()
|
||||
offsets = [self.ReadLong() for i in range(longs)]
|
||||
relocs.update({hunkRef: offsets})
|
||||
relocs[hunkRef] = offsets
|
||||
|
||||
return relocs
|
||||
|
||||
@@ -217,7 +114,7 @@ class HunkParser(object):
|
||||
|
||||
hunkRef = self.ReadWord()
|
||||
offsets = [self.ReadWord() for i in range(words)]
|
||||
relocs.update({hunkRef: offsets})
|
||||
relocs[hunkRef] = offsets
|
||||
|
||||
if (self.index - start) & 3:
|
||||
self.index += 2
|
||||
@@ -255,8 +152,8 @@ class HunkParser(object):
|
||||
hunkId = self.ReadLong()
|
||||
|
||||
try:
|
||||
flags = HunkMap.GetFlags(hunkId)
|
||||
name = HunkMap.GetName(hunkId)
|
||||
flags = GetHunkFlags(hunkId)
|
||||
name = GetHunkName(hunkId)
|
||||
except ValueError:
|
||||
print 'Parse error at position %d.' % self.index
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user