Fuse symbol_info with disasm_script so you can give it symbols (#552)

This commit is contained in:
Ethan Roseman 2021-12-15 19:27:26 -05:00 committed by GitHub
parent 967427ba97
commit 731d270014
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 43 deletions

View File

@ -1,6 +1,6 @@
#! /usr/bin/python3 #! /usr/bin/python3
import sys import sym_info
from pathlib import Path from pathlib import Path
_script_lib = None _script_lib = None
@ -1230,7 +1230,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("file", type=str, help="File to dissassemble from") 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("-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("-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") 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["npcs"] = {}
INCLUDES_NEEDED["sprites"] = set() 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 # Search the given memory range and report scripts
with open(args.file, "rb") as f: with open(args.file, "rb") as f:
gap = False gap = False
first_print = False first_print = False
while args.offset < args.end: while offset < args.end:
f.seek(args.offset) f.seek(offset)
script = ScriptDSLDisassembler(f, "", {}, 0x978DE0, INCLUDES_NEEDED, INCLUDED) script = ScriptDSLDisassembler(f, "", {}, 0x978DE0, INCLUDES_NEEDED, INCLUDED)
try: try:
@ -1264,7 +1273,7 @@ if __name__ == "__main__":
if script.instructions > 1 and "_EVT_CMD" not in script_text: if script.instructions > 1 and "_EVT_CMD" not in script_text:
if gap and first_print: if gap and first_print:
potential_struct_sizes = { "StaticNpc": 0x1F0, "NpcAISettings":0x30, "NpcSettings":0x2C, "NpcGroupList":0xC } 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_struct = "Unknown data"
potential_count = 1 potential_count = 1
for k,v in potential_struct_sizes.items(): for k,v in potential_struct_sizes.items():
@ -1272,36 +1281,36 @@ if __name__ == "__main__":
potential_struct = k potential_struct = k
potential_count = gap_size // v 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() print()
gap = False gap = False
#print(f"EvtSource read from 0x{script.start_pos:X} to 0x{script.end_pos:X} " #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)") # f"(0x{script.end_pos - script.start_pos:X} bytes, {script.instructions} instructions)")
#print() #print()
vram = f"{args.vram:X}_" if vram_base > 0 else f"" 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(script_text, end="")
print() print()
#print(f"Valid script found at 0x{args.offset:X}") #print(f"Valid script found at 0x{offset:X}")
args.vram += script.end_pos - args.offset args.vram += script.end_pos - offset
args.offset = script.end_pos offset = script.end_pos
first_print = True first_print = True
else: else:
if not gap: if not gap:
gap_start = args.offset gap_start = offset
gap = True gap = True
args.offset += 4 offset += 4
args.vram += 4 args.vram += 4
except Exception: except Exception:
if not gap: if not gap:
gap_start = args.offset gap_start = offset
gap = True gap = True
args.offset += 4 offset += 4
args.vram += 4 args.vram += 4
else: else:
with open(args.file, "rb") as f: with open(args.file, "rb") as f:
f.seek(args.offset) f.seek(offset)
script = ScriptDSLDisassembler(f, "", {}, 0x978DE0, INCLUDES_NEEDED, INCLUDED) script = ScriptDSLDisassembler(f, "", {}, 0x978DE0, INCLUDES_NEEDED, INCLUDED)
@ -1317,5 +1326,5 @@ if __name__ == "__main__":
print(script_text, end="") print(script_text, end="")
except UnsupportedScript: except UnsupportedScript:
f.seek(args.offset) f.seek(offset)
print(ScriptDisassembler(f).disassemble(), end="") print(ScriptDisassembler(f).disassemble(), end="")

View File

@ -22,18 +22,14 @@ parser.add_argument(
action="store_true", action="store_true",
help="use the map file in expected/build/ instead of build/" 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") def get_map(expected: bool = False):
if args.use_expected: mymap = os.path.join(root_dir, "ver", "current", "build", "papermario.map")
mymap = os.path.join(root_dir, "ver", "current", "expected", "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): def search_address(target_addr, map=get_map()):
print(f"{mymap} must exist.")
exit(1)
def search_address(target_addr):
is_ram = target_addr & 0x80000000 is_ram = target_addr & 0x80000000
ram_offset = None ram_offset = None
prev_ram = 0 prev_ram = 0
@ -42,7 +38,7 @@ def search_address(target_addr):
cur_file = "<no file>" cur_file = "<no file>"
prev_file = cur_file prev_file = cur_file
prev_line = "" prev_line = ""
with open(mymap) as f: with open(map) as f:
for line in f: for line in f:
if "load address" in line: if "load address" in line:
# Ignore .bss sections if we're looking for a ROM address # 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?" return "at end of rom?"
def search_symbol(target_sym, map=get_map()):
def search_symbol(target_sym):
ram_offset = None ram_offset = None
cur_file = "<no file>" cur_file = "<no file>"
prev_line = "" prev_line = ""
with open(mymap) as f: with open(map) as f:
for line in f: for line in f:
if "load address" in line: if "load address" in line:
ram = int(line[16 : 16 + 18], 0) ram = int(line[16 : 16 + 18], 0)
@ -127,16 +122,24 @@ def search_symbol(target_sym):
return None return None
if __name__ == "__main__":
args = parser.parse_args()
try: map = get_map(args.use_expected)
target_addr = int(args.name, 0)
print(args.name, "is", search_address(target_addr)) if not os.path.isfile(map):
except ValueError: print(f"{map} must exist.")
sym_info = search_symbol(args.name) exit(1)
if sym_info is not None:
sym_rom = sym_info[0] try:
sym_file = sym_info[1] target_addr = int(args.name, 0)
sym_ram = sym_info[2] print(args.name, "is", search_address(target_addr))
print(f"Symbol {args.name} (RAM: 0x{sym_ram:08X}, ROM: 0x{sym_rom:06X}, {sym_file})") except ValueError:
else: sym_info = search_symbol(args.name)
print(f"Symbol {args.name} not found in map file {mymap}") 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}")