mirror of
https://github.com/zeldaret/tww.git
synced 2026-08-04 17:09:45 -04:00
debug_map_diff.py: Several improvements
Auto-detect if the TU is in main.dol or a REL. Detect this separately for the target and the base, in order to support TUs like d_a_npc_tt which are in main.dol for the debug build, but a REL for release builds. And disable linkage comparison when comparing a REL TU to a main.dol TU as the official main.dol maps do not include linkage information, but the REL maps do.
This commit is contained in:
@@ -4,6 +4,10 @@
|
||||
# Checks for missing inline usages, fake inline usages, and inlines being the wrong size.
|
||||
# NOTE: You must mark the TU as "Matching" in configure.py, even if it doesn't match! Otherwise this script won't work properly.
|
||||
|
||||
# To use this script, pass the name of the TU as the only argument. Examples:
|
||||
# ./tools/utilities/debug_map_diff.py d_a_andsw0
|
||||
# ./tools/utilities/debug_map_diff.py d_a_npc_fa1
|
||||
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
@@ -11,28 +15,46 @@ import argparse
|
||||
from collections import defaultdict
|
||||
|
||||
arg_parse = argparse.ArgumentParser()
|
||||
arg_parse.add_argument("object_name", help="Name of the object to compare, e.g. d_a_bridge for a REL, or main/d_a_npc_fa1 for a main.dol object")
|
||||
arg_parse.add_argument("object_name", help="Name of the object to compare, e.g. d_a_bridge or d_a_npc_fa1")
|
||||
args = arg_parse.parse_args()
|
||||
object_name: str = args.object_name
|
||||
assert "/" not in object_name and "." not in object_name, "The object name should not contain slashes or dots"
|
||||
|
||||
debug_maps_root_path = Path("orig/D44J01/files/maps")
|
||||
decomp_root_path = Path(".")
|
||||
|
||||
is_rel: bool
|
||||
if object_name.startswith("main/"):
|
||||
is_rel = False
|
||||
object_name = object_name.split("/", 1)[1]
|
||||
object_name = object_name.split(".", 1)[0]
|
||||
target_map_path = debug_maps_root_path / "frameworkD.map"
|
||||
base_map_path = decomp_root_path / "build/D44J01/framework.elf.MAP"
|
||||
else:
|
||||
is_rel = True
|
||||
target_map_path = debug_maps_root_path / f"{object_name}D.map"
|
||||
base_map_path = decomp_root_path / f"build/D44J01/{object_name}/{object_name}.plf.MAP"
|
||||
assert "/" not in object_name and "." not in object_name
|
||||
|
||||
retcode = subprocess.call(["python", "configure.py", "--version", "D44J01", "--debug", "--map", "--non-matching"], cwd=decomp_root_path)
|
||||
assert retcode == 0, "Failed to configure"
|
||||
|
||||
all_ninja_outputs = []
|
||||
for ninja_target in subprocess.check_output(["ninja", "-t", "targets", "all"]).decode("utf-8").splitlines():
|
||||
ninja_output, ninja_rule = ninja_target.split(":", 1)
|
||||
all_ninja_outputs.append(ninja_output)
|
||||
|
||||
target_map_path_dol = debug_maps_root_path / "frameworkD.map"
|
||||
target_map_path_rel = debug_maps_root_path / f"{object_name}D.map"
|
||||
if target_map_path_rel.exists():
|
||||
target_is_rel = True
|
||||
target_map_path = target_map_path_rel
|
||||
else:
|
||||
assert target_map_path_dol.exists()
|
||||
target_is_rel = False
|
||||
target_map_path = target_map_path_dol
|
||||
del target_map_path_dol
|
||||
del target_map_path_rel
|
||||
|
||||
base_map_path_dol = decomp_root_path / "build/D44J01/framework.elf.MAP"
|
||||
base_map_path_rel = decomp_root_path / f"build/D44J01/{object_name}/{object_name}.plf.MAP"
|
||||
if str(base_map_path_rel) in all_ninja_outputs:
|
||||
base_is_rel = True
|
||||
base_map_path = base_map_path_rel
|
||||
else:
|
||||
assert str(base_map_path_dol) in all_ninja_outputs
|
||||
base_is_rel = False
|
||||
base_map_path = base_map_path_dol
|
||||
del base_map_path_dol
|
||||
del base_map_path_rel
|
||||
|
||||
retcode = subprocess.call(["ninja", base_map_path.relative_to(decomp_root_path)], cwd=decomp_root_path)
|
||||
assert retcode == 0, "Ninja build call failed"
|
||||
|
||||
@@ -61,7 +83,7 @@ def get_main_symbols(framework_map_contents: str, valid_obj_names = None):
|
||||
|
||||
symbols[name] = Symbol(name, size)
|
||||
if len(symbols) == 0:
|
||||
raise Exception("Failed to find object matching the given name")
|
||||
raise Exception("Failed to find object matching the given name (check for typos)")
|
||||
return symbols
|
||||
|
||||
def get_rel_symbols(rel_map_data: str):
|
||||
@@ -157,13 +179,15 @@ def is_debug_only_symbol(symbol_name: str):
|
||||
return True
|
||||
return False
|
||||
|
||||
if is_rel:
|
||||
if target_is_rel:
|
||||
target_symbols = get_rel_symbols(target_map_path.read_text())
|
||||
else:
|
||||
target_symbols = get_main_symbols(target_map_path.read_text(), valid_obj_names=[object_name])
|
||||
|
||||
if base_is_rel:
|
||||
base_symbols = get_rel_symbols(base_map_path.read_text())
|
||||
else:
|
||||
obj_names = [object_name]
|
||||
target_symbols = get_main_symbols(target_map_path.read_text(), valid_obj_names=obj_names)
|
||||
base_symbols = get_main_symbols(base_map_path.read_text(), valid_obj_names=obj_names)
|
||||
base_symbols = get_main_symbols(base_map_path.read_text(), valid_obj_names=[object_name])
|
||||
|
||||
print(len(target_symbols), len(base_symbols))
|
||||
|
||||
@@ -219,15 +243,16 @@ for symbol_name, target_size, base_size, ratio in symbol_size_diffs:
|
||||
total_missing += 1
|
||||
print(prefix + symbol_name, "0x%X" % target_size)
|
||||
|
||||
for symbol_name, target_symbol in target_symbols.items():
|
||||
if target_symbol.size == 0:
|
||||
continue
|
||||
if symbol_name not in base_symbols:
|
||||
continue
|
||||
base_symbol = base_symbols[symbol_name]
|
||||
if target_symbol.linkage != base_symbol.linkage:
|
||||
total_wrong_linkage += 1
|
||||
print(f"LINKAGE: {symbol_name} (should be {target_symbol.linkage}, is {base_symbol.linkage})")
|
||||
if target_is_rel:
|
||||
for symbol_name, target_symbol in target_symbols.items():
|
||||
if target_symbol.size == 0:
|
||||
continue
|
||||
if symbol_name not in base_symbols:
|
||||
continue
|
||||
base_symbol = base_symbols[symbol_name]
|
||||
if target_symbol.linkage != base_symbol.linkage:
|
||||
total_wrong_linkage += 1
|
||||
print(f"LINKAGE: {symbol_name} (should be {target_symbol.linkage}, is {base_symbol.linkage})")
|
||||
|
||||
print("==================================================")
|
||||
print(f"Total right size: {total_right_size}")
|
||||
|
||||
Reference in New Issue
Block a user