diff --git a/tools/disasm_script.py b/tools/disasm_script.py index e6c4c55e68..2372f18274 100755 --- a/tools/disasm_script.py +++ b/tools/disasm_script.py @@ -1,6 +1,6 @@ #! /usr/bin/python3 -import sys +import sym_info from pathlib import Path _script_lib = None @@ -1230,7 +1230,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("file", type=str, help="File to dissassemble from") - parser.add_argument("offset", type=lambda x: int(x, 16), default=0, help="Offset to start dissassembling from") + parser.add_argument("offset", help="Offset to start dissassembling from") parser.add_argument("-end", "-e", "--e", type=lambda x: int(x, 16), default=0, dest="end", required=False, help="End offset to stop dissassembling from.\nOnly used as a way to find valid scripts.") parser.add_argument("-vram", "-v", "--v", type=lambda x: int(x, 16), default=0, dest="vram", required=False, help="VRAM start will be tracked and used for the script output name") parser.add_argument("-si", "--si", action="store_true", default=False, dest="si", required=False, help="Force si script output") @@ -1248,14 +1248,23 @@ if __name__ == "__main__": INCLUDES_NEEDED["npcs"] = {} INCLUDES_NEEDED["sprites"] = set() - if args.end > args.offset: + try: + offset = int(args.offset, 0) + except ValueError: + info = sym_info.search_symbol(args.offset) + if info is None: + print(f"{args.offset} is not a valid symbol name") + exit(1) + offset = info[0] + + if args.end > offset: # Search the given memory range and report scripts with open(args.file, "rb") as f: gap = False first_print = False - while args.offset < args.end: - f.seek(args.offset) + while offset < args.end: + f.seek(offset) script = ScriptDSLDisassembler(f, "", {}, 0x978DE0, INCLUDES_NEEDED, INCLUDED) try: @@ -1264,7 +1273,7 @@ if __name__ == "__main__": if script.instructions > 1 and "_EVT_CMD" not in script_text: if gap and first_print: potential_struct_sizes = { "StaticNpc": 0x1F0, "NpcAISettings":0x30, "NpcSettings":0x2C, "NpcGroupList":0xC } - gap_size = args.offset - gap_start + gap_size = offset - gap_start potential_struct = "Unknown data" potential_count = 1 for k,v in potential_struct_sizes.items(): @@ -1272,36 +1281,36 @@ if __name__ == "__main__": potential_struct = k potential_count = gap_size // v - print(f"========== 0x{gap_size:X} byte gap ({potential_count} {potential_struct}?) 0x{gap_start:X} - 0x{args.offset:X} ==========") + print(f"========== 0x{gap_size:X} byte gap ({potential_count} {potential_struct}?) 0x{gap_start:X} - 0x{offset:X} ==========") print() gap = False #print(f"EvtSource read from 0x{script.start_pos:X} to 0x{script.end_pos:X} " # f"(0x{script.end_pos - script.start_pos:X} bytes, {script.instructions} instructions)") #print() vram = f"{args.vram:X}_" if vram_base > 0 else f"" - script_text = script_text.replace("EvtSource script = SCRIPT({", f"EvtSource N(D_{vram}{args.offset:X}) = " + "SCRIPT({") + script_text = script_text.replace("EvtSource script = SCRIPT({", f"EvtSource N(D_{vram}{offset:X}) = " + "SCRIPT({") print(script_text, end="") print() - #print(f"Valid script found at 0x{args.offset:X}") - args.vram += script.end_pos - args.offset - args.offset = script.end_pos + #print(f"Valid script found at 0x{offset:X}") + args.vram += script.end_pos - offset + offset = script.end_pos first_print = True else: if not gap: - gap_start = args.offset + gap_start = offset gap = True - args.offset += 4 + offset += 4 args.vram += 4 except Exception: if not gap: - gap_start = args.offset + gap_start = offset gap = True - args.offset += 4 + offset += 4 args.vram += 4 else: with open(args.file, "rb") as f: - f.seek(args.offset) + f.seek(offset) script = ScriptDSLDisassembler(f, "", {}, 0x978DE0, INCLUDES_NEEDED, INCLUDED) @@ -1317,5 +1326,5 @@ if __name__ == "__main__": print(script_text, end="") except UnsupportedScript: - f.seek(args.offset) + f.seek(offset) print(ScriptDisassembler(f).disassemble(), end="") diff --git a/tools/sym_info.py b/tools/sym_info.py index bb37563e4f..74c4f5359f 100755 --- a/tools/sym_info.py +++ b/tools/sym_info.py @@ -22,18 +22,14 @@ parser.add_argument( action="store_true", help="use the map file in expected/build/ instead of build/" ) -args = parser.parse_args() -mymap = os.path.join(root_dir, "ver", "current", "build", "papermario.map") -if args.use_expected: - mymap = os.path.join(root_dir, "ver", "current", "expected", "build", "papermario.map") +def get_map(expected: bool = False): + mymap = os.path.join(root_dir, "ver", "current", "build", "papermario.map") + if expected: + mymap = os.path.join(root_dir, "ver", "current", "expected", "build", "papermario.map") + return mymap -if not os.path.isfile(mymap): - print(f"{mymap} must exist.") - exit(1) - - -def search_address(target_addr): +def search_address(target_addr, map=get_map()): is_ram = target_addr & 0x80000000 ram_offset = None prev_ram = 0 @@ -42,7 +38,7 @@ def search_address(target_addr): cur_file = "" prev_file = cur_file prev_line = "" - with open(mymap) as f: + with open(map) as f: for line in f: if "load address" in line: # Ignore .bss sections if we're looking for a ROM address @@ -88,12 +84,11 @@ def search_address(target_addr): return "at end of rom?" - -def search_symbol(target_sym): +def search_symbol(target_sym, map=get_map()): ram_offset = None cur_file = "" prev_line = "" - with open(mymap) as f: + with open(map) as f: for line in f: if "load address" in line: ram = int(line[16 : 16 + 18], 0) @@ -127,16 +122,24 @@ def search_symbol(target_sym): return None +if __name__ == "__main__": + args = parser.parse_args() -try: - target_addr = int(args.name, 0) - print(args.name, "is", search_address(target_addr)) -except ValueError: - sym_info = search_symbol(args.name) - if sym_info is not None: - sym_rom = sym_info[0] - sym_file = sym_info[1] - sym_ram = sym_info[2] - print(f"Symbol {args.name} (RAM: 0x{sym_ram:08X}, ROM: 0x{sym_rom:06X}, {sym_file})") - else: - print(f"Symbol {args.name} not found in map file {mymap}") + map = get_map(args.use_expected) + + if not os.path.isfile(map): + print(f"{map} must exist.") + exit(1) + + try: + target_addr = int(args.name, 0) + print(args.name, "is", search_address(target_addr)) + except ValueError: + sym_info = search_symbol(args.name) + if sym_info is not None: + sym_rom = sym_info[0] + sym_file = sym_info[1] + sym_ram = sym_info[2] + print(f"Symbol {args.name} (RAM: 0x{sym_ram:08X}, ROM: 0x{sym_rom:06X}, {sym_file})") + else: + print(f"Symbol {args.name} not found in map file {map}")