#!/usr/bin/env python3 """Lift original MapDeserialiser initialization and its actual C1 target dependency.""" import argparse import hashlib import json import struct import subprocess from pathlib import Path from a64_program import ProgramCompiler from lift_rng import arm64_image, file_range from build_target_deserialiser import RANGES as TARGET_RANGES, HOSTS as TARGET_HOSTS ROOT=Path(__file__).resolve().parents[1] ENTRY=0x1014DEF40 RANGES=[(ENTRY,1272,'afef8906673fbfdab8f47b5663112ce9c4666a757bd1c80ab7e670e121f383ea'), (0x1012C1044,116,'c607983877925865ddb27bca5841f45a88f90896250f36864deac97462687d08'), *TARGET_RANGES[1:]] HOSTS={**TARGET_HOSTS,0x10035E264:'read_or_throw',0x1027D3918:'zero_memory', 0x1000EA874:'version_error',0x101D5C248:'unsupported',0x1000EABE4:'unsupported', 0x102226250:'unsupported',0x102226290:'unsupported',0x101B89938:'unsupported'} STATIC_PAGES={0x102FC2000:65536,0x102D55000:69632,0x1014DF000:73728} def run(*args): subprocess.run(list(map(str,args)),cwd=ROOT,check=True) def main(): parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('binary',type=Path) args=parser.parse_args();image,_=arm64_image(args.binary.read_bytes()) source_hash=hashlib.sha256(image).hexdigest() if source_hash!='2cb4de127b50d54c6c5666acfef2263fae16d11a3361ad39353ecf8a66a4d9c7': raise ValueError('Unrecognized ARM64 image') bodies={} for address,size,expected in RANGES: offset=file_range(image,address,size);data=image[offset:offset+size] if hashlib.sha256(data).hexdigest()!=expected: raise ValueError('Unrecognized constructor input') bodies[address]=data functions={address:bodies[address] for address,_,_ in RANGES[:-1]} compiler=ProgramCompiler(HOSTS,returning_hosts={0x1027D36E4},memory_pages=16,static_pages=STATIC_PAGES) wat=compiler.compile(functions,ENTRY).replace('(import "env"','(import "deser_host"') out=ROOT/'build/deserialiser';out.mkdir(parents=True,exist_ok=True) (out/'factorio_deser.wat').write_text(wat) run(ROOT/'build/wabt/wat2wasm',out/'factorio_deser.wat','-o',out/'factorio_deser.wasm') run(ROOT/'build/wabt/wasm2c',out/'factorio_deser.wasm','-o',out/'factorio_deser.c','--module-name=factorio_deser') assembly=['.text','.p2align 2','.globl _factorio_deser_original'] for address,data in functions.items(): if address==ENTRY: assembly.append('_factorio_deser_original:') for i,(word,) in enumerate(struct.iter_unpack('