Flattener: lint
This commit is contained in:
parent
3d9bd36353
commit
7a767238da
|
@ -8,48 +8,54 @@ import string
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('src', help='rdump file')
|
parser.add_argument("src", help="rdump file")
|
||||||
parser.add_argument('dest', help='binary dest (may also create .txt file)')
|
parser.add_argument("dest", help="binary dest (may also create .txt file)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
with open(args.src, 'rb') as f:
|
with open(args.src, "rb") as f:
|
||||||
d = f.read()
|
d = f.read()
|
||||||
if f.name.endswith('.rdump'):
|
if f.name.endswith(".rdump"):
|
||||||
resources = list(macresources.parse_rez_code(d, original_file=f.name))
|
resources = list(macresources.parse_rez_code(d, original_file=f.name))
|
||||||
else:
|
else:
|
||||||
resources = list(macresources.parse_file(d))
|
resources = list(macresources.parse_file(d))
|
||||||
|
|
||||||
resources = [r for r in resources if r.type == b'CODE' and r.id >= 0]
|
resources = [r for r in resources if r.type == b"CODE" and r.id >= 0]
|
||||||
resources.sort(key=lambda r: r.id)
|
resources.sort(key=lambda r: r.id)
|
||||||
|
|
||||||
if not resources or resources[0].id != 0:
|
if not resources or resources[0].id != 0:
|
||||||
sys.exit('CODE 0 not found in %s' % args.src)
|
sys.exit("CODE 0 not found in %s" % args.src)
|
||||||
|
|
||||||
jt_resource, *other_resources = resources
|
jt_resource, *other_resources = resources
|
||||||
|
|
||||||
bigboy = bytearray()
|
bigboy = bytearray()
|
||||||
for i, r in enumerate(resources):
|
for i, r in enumerate(resources):
|
||||||
while len(bigboy) < i * 0x10000: bigboy.append(0)
|
while len(bigboy) < i * 0x10000:
|
||||||
|
bigboy.append(0)
|
||||||
bigboy.extend(r)
|
bigboy.extend(r)
|
||||||
|
|
||||||
with open(args.dest, 'wb') as f:
|
with open(args.dest, "wb") as f:
|
||||||
f.write(bigboy)
|
f.write(bigboy)
|
||||||
|
|
||||||
with open(args.dest + '.py', 'w') as idascript:
|
with open(args.dest + ".py", "w") as idascript:
|
||||||
# Find MacsBug symbols
|
# Find MacsBug symbols
|
||||||
namedict = {}
|
namedict = {}
|
||||||
for b in range(0, len(bigboy), 2):
|
for b in range(0, len(bigboy), 2):
|
||||||
if bigboy[b:b+2] == b'NV': # link a6, starting a compiled function
|
if bigboy[b : b + 2] == b"NV": # link a6, starting a compiled function
|
||||||
for c in range(b+2, len(bigboy), 2):
|
for c in range(b + 2, len(bigboy), 2):
|
||||||
if bigboy[c:c+2] == b'NV': break
|
if bigboy[c : c + 2] == b"NV":
|
||||||
if 0x81 <= bigboy[c] < 0xb0:
|
break
|
||||||
|
if 0x81 <= bigboy[c] < 0xB0:
|
||||||
strlen = bigboy[c] & 0x0F
|
strlen = bigboy[c] & 0x0F
|
||||||
if strlen < 2: break
|
if strlen < 2:
|
||||||
namestr = bigboy[c+1:c+1+strlen]
|
break
|
||||||
if len(namestr) < strlen: break
|
namestr = bigboy[c + 1 : c + 1 + strlen]
|
||||||
namestr = namestr.decode('latin-1')
|
if len(namestr) < strlen:
|
||||||
if not all(c in (string.ascii_letters + string.digits + '_') for c in namestr): break
|
break
|
||||||
if strlen % 2 == 0 and bigboy[c+1+strlen:c+1+strlen+1] not in b'\0': break
|
namestr = namestr.decode("latin-1")
|
||||||
|
if not all(c in (string.ascii_letters + string.digits + "_") for c in namestr):
|
||||||
|
break
|
||||||
|
if strlen % 2 == 0 and bigboy[c + 1 + strlen : c + 1 + strlen + 1] not in b"\0":
|
||||||
|
break
|
||||||
|
|
||||||
namedict[b] = namestr
|
namedict[b] = namestr
|
||||||
break
|
break
|
||||||
|
@ -58,40 +64,44 @@ with open(args.dest + '.py', 'w') as idascript:
|
||||||
segnames = {}
|
segnames = {}
|
||||||
for r in other_resources:
|
for r in other_resources:
|
||||||
if r.name:
|
if r.name:
|
||||||
segnames[r.id] = ''.join(c for c in r.name if c in (string.ascii_letters + string.digits))
|
segnames[r.id] = "".join(c for c in r.name if c in (string.ascii_letters + string.digits))
|
||||||
else:
|
else:
|
||||||
segnames[r.id] = f'seg_{r.id:X}'
|
segnames[r.id] = f"seg_{r.id:X}"
|
||||||
|
|
||||||
jt_size, a5_offset_of_jt = struct.unpack_from('>LL', jt_resource, 8)
|
jt_size, a5_offset_of_jt = struct.unpack_from(">LL", jt_resource, 8)
|
||||||
|
|
||||||
for jt_ofs in range(16, 16 + jt_size, 8):
|
for jt_ofs in range(16, 16 + jt_size, 8):
|
||||||
ofs, be_3f3c, segnum, be_a9f0 = struct.unpack_from('>HHHH', jt_resource, jt_ofs)
|
ofs, be_3f3c, segnum, be_a9f0 = struct.unpack_from(">HHHH", jt_resource, jt_ofs)
|
||||||
if be_3f3c != 0x3f3c or be_a9f0 != 0xa9f0: break
|
if be_3f3c != 0x3F3C or be_a9f0 != 0xA9F0:
|
||||||
ofs += 4 # not sure what the leading stuff is?
|
break
|
||||||
|
ofs += 4 # not sure what the leading stuff is?
|
||||||
|
|
||||||
bigboy_ofs = ((segnum) * 0x10000) + ofs
|
bigboy_ofs = ((segnum) * 0x10000) + ofs
|
||||||
a5_ofs = jt_ofs - 16 + a5_offset_of_jt + 2
|
a5_ofs = jt_ofs - 16 + a5_offset_of_jt + 2
|
||||||
|
|
||||||
cool_name = f'{segnames[segnum]}_'
|
cool_name = f"{segnames[segnum]}_"
|
||||||
if bigboy_ofs in namedict:
|
if bigboy_ofs in namedict:
|
||||||
cool_name += namedict[bigboy_ofs]
|
cool_name += namedict[bigboy_ofs]
|
||||||
del namedict[bigboy_ofs]
|
del namedict[bigboy_ofs]
|
||||||
else:
|
else:
|
||||||
cool_name += f'{bigboy_ofs:X}'
|
cool_name += f"{bigboy_ofs:X}"
|
||||||
|
|
||||||
print(f'MakeFunction(0x{bigboy_ofs:X}); MakeName(0x{bigboy_ofs:X}, "{cool_name}")', file=idascript)
|
print(f'MakeFunction(0x{bigboy_ofs:X}); MakeName(0x{bigboy_ofs:X}, "{cool_name}")', file=idascript)
|
||||||
|
|
||||||
call_to_me = struct.pack('>H', a5_ofs)
|
call_to_me = struct.pack(">H", a5_ofs)
|
||||||
bb_i = -1
|
bb_i = -1
|
||||||
while 1:
|
while 1:
|
||||||
bb_i = bigboy.find(call_to_me, bb_i+1)
|
bb_i = bigboy.find(call_to_me, bb_i + 1)
|
||||||
if bb_i == -1: break
|
if bb_i == -1:
|
||||||
if bb_i % 2: continue
|
break
|
||||||
if bigboy[bb_i-2:bb_i] not in (b'\x4e\xad', b'\x48\x6d'): continue # jsr/pea
|
if bb_i % 2:
|
||||||
|
continue
|
||||||
|
if bigboy[bb_i - 2 : bb_i] not in (b"\x4e\xad", b"\x48\x6d"):
|
||||||
|
continue # jsr/pea
|
||||||
|
|
||||||
# Okay, found one
|
# Okay, found one
|
||||||
print(f'MakeCode(0x{bb_i-2:X}); op_man(0x{bb_i-2:X}, 0, "{cool_name}")', file=idascript)
|
print(f'MakeCode(0x{bb_i-2:X}); op_man(0x{bb_i-2:X}, 0, "{cool_name}")', file=idascript)
|
||||||
|
|
||||||
for bigboy_ofs, name in sorted(namedict.items()):
|
for bigboy_ofs, name in sorted(namedict.items()):
|
||||||
cool_name = f'{segnames[bigboy_ofs >> 16]}_{name}'
|
cool_name = f"{segnames[bigboy_ofs >> 16]}_{name}"
|
||||||
print(f'MakeFunction(0x{bigboy_ofs:X}); MakeName(0x{bigboy_ofs:X}, "{cool_name}")', file=idascript)
|
print(f'MakeFunction(0x{bigboy_ofs:X}); MakeName(0x{bigboy_ofs:X}, "{cool_name}")', file=idascript)
|
||||||
|
|
Loading…
Reference in New Issue