diff --git a/.gitignore b/.gitignore index 7262526de..f73a1084b 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,6 @@ tools.zip .~lock.* doxygen + +# diff.py expected +expected diff --git a/build.py b/build.py index c09beaece..2733f08c6 100644 --- a/build.py +++ b/build.py @@ -46,6 +46,9 @@ parser.add_argument( "--match", type=str, default=None, help="Only compile sources matching pattern" ) +parser.add_argument( + "--diff_py", type=str, default=None, help="Recompile a .o file for diff.py" +) parser.add_argument("--link_only", action="store_true", help="Link only, don't build") args = parser.parse_args() # Start by running gen_asm. @@ -333,12 +336,17 @@ def compile_sources(): for src in chain(SOURCES_DOL, SOURCES_REL): queue_compile_source(Path(src.src), src.cc, src.opts) - if args.match: + if args.match or args.diff_py: + if args.match: + match = args.match + else: + # (Will still match a .cpp with the same name) + match = args.diff_py[len("out/"):-len(".o")] + ".c" print( - colored('[NOTE] Only compiling sources matching "%s".' % args.match, "red") + colored('[NOTE] Only compiling sources matching "%s".' % match, "red") ) global gSourceQueue - gSourceQueue = list(filter(lambda x: args.match in str(x[0]), gSourceQueue)) + gSourceQueue = list(filter(lambda x: match in str(x[0]), gSourceQueue)) if args.link_only: gSourceQueue = [] @@ -417,6 +425,9 @@ def build(): compile_sources() + if args.diff_py: + return + orig_dol_path = Path("artifacts", "orig", "pal", "main.dol") orig_rel_path = Path("artifacts", "orig", "pal", "StaticR.rel") target_dol_path = link_dol(dol_objects) diff --git a/diff.py b/diff.py index 682946705..8e5c00ae7 100644 --- a/diff.py +++ b/diff.py @@ -3,12 +3,10 @@ """ Imported from https://github.com/simonlindholm/asm-differ/ -on commit 291173ed30e8a6dc91c28334aa1275a555d725b1 +on commit e7d0aaf06ce7f73acc2870bbc0f6ef66c76cb46a Edits: - Symbol map regex changed to allow alignments longer than 1 digit Dol & rel ram-rom conversion added using mkwutil - -mpowerpc and -Mgekko added to PPC_SETTINGS arch_flags """ import argparse @@ -212,11 +210,11 @@ def complete_symbol( ) parser.add_argument( "-s", - "--stop-jr-ra", - dest="stop_jrra", + "--stop-at-ret", + dest="stop_at_ret", action="store_true", - help="""Stop disassembling at the first 'jr ra'. Some functions have - multiple return points, so use with care!""", + help="""Stop disassembling at the first return instruction. + Some functions have multiple return points, so use with care!""", ) parser.add_argument( "-i", @@ -426,7 +424,7 @@ class Config: show_branches: bool show_line_numbers: bool show_source: bool - stop_jrra: bool + stop_at_ret: bool ignore_large_imms: bool ignore_addr_diffs: bool algorithm: str @@ -513,7 +511,7 @@ def create_config(args: argparse.Namespace, project: ProjectSettings) -> Config: show_branches=args.show_branches, show_line_numbers=show_line_numbers, show_source=args.show_source or args.source_old_binutils, - stop_jrra=args.stop_jrra, + stop_at_ret=args.stop_at_ret, ignore_large_imms=args.ignore_large_imms, ignore_addr_diffs=args.ignore_addr_diffs, algorithm=args.algorithm, @@ -1122,7 +1120,7 @@ def search_map_file( elif project.map_format == "mw": find = re.findall( re.compile( - # ram elf rom + # ram elf rom alignment r" \S+ \S+ (\S+) (\S+) +\S+ " + re.escape(fn_name) + r"(?: \(entry of " @@ -1839,7 +1837,7 @@ class ArchSettings: r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(r1)|[^ \t,]+@(l|ha|h|sda21)" ), re_reloc=re.compile(r"R_PPC_"), - arch_flags=["-m", "powerpc", "-M", "gekko"], + arch_flags=["-m", "powerpc", "-M", "broadway"], branch_instructions=PPC_BRANCH_INSTRUCTIONS, instructions_with_address_immediates=PPC_BRANCH_INSTRUCTIONS.union({"bl"}), proc=AsmProcessorPPC, @@ -1979,9 +1977,9 @@ def process(dump: str, config: Config) -> List[Line]: if not re.match(r"^\s+[0-9a-f]+:\s+", row): # This regex is conservative, and assumes the file path does not contain "weird" - # characters like colons, tabs, or angle brackets. + # characters like tabs or angle brackets. if re.match( - r"^[^ \t<>:][^\t<>:]*:[0-9]+( \(discriminator [0-9]+\))?$", row + r"^[^ \t<>][^\t<>]*:[0-9]+( \(discriminator [0-9]+\))?$", row ): source_filename, _, tail = row.rpartition(":") source_line_num = int(tail.partition(" ")[0]) @@ -2108,10 +2106,15 @@ def process(dump: str, config: Config) -> List[Line]: num_instr += 1 source_lines = [] - if config.stop_jrra and mnemonic == "jr" and args == "ra": - stop_after_delay_slot = True - elif stop_after_delay_slot: - break + if config.stop_at_ret: + if config.arch.name == "mips": + if mnemonic == "jr" and args == "ra": + stop_after_delay_slot = True + elif stop_after_delay_slot: + break + if config.arch.name == "ppc": + if mnemonic == "blr": + break processor.post_process(output) return output diff --git a/diff_settings.py b/diff_settings.py index 978d1f9b1..c16be12ee 100644 --- a/diff_settings.py +++ b/diff_settings.py @@ -1,6 +1,7 @@ from argparse import ArgumentParser import os from pathlib import Path +from sys import executable DEVKITPPC = Path(os.environ.get("DEVKITPPC", "./tools/devkitppc")) @@ -14,6 +15,7 @@ def apply(config: dict, args): config["mapfile"] = "artifacts/target/pal/main.map" config["myimg"] = "artifacts/target/pal/main.dol" config["baseimg"] = "artifacts/orig/pal/main.dol" + config["make_command"] = [executable, "build.py", "--diff_py"] config["makeflags"] = [] config["source_directories"] = ["source"] config["arch"] = "ppc" @@ -21,6 +23,7 @@ def apply(config: dict, args): config["mw_build_dir"] = "out" # only needed for mw map format config["makeflags"] = [] config["objdump_executable"] = DEVKITPPC / "bin" / "powerpc-eabi-objdump.exe" + config["show_line_numbers_default"] = True def add_custom_arguments(parser: ArgumentParser): parser.add_argument("-r", "--rel", action="store_true", help="(MKW) Diff a function in staticR.rel") diff --git a/expected.py b/expected.py new file mode 100644 index 000000000..79ee30139 --- /dev/null +++ b/expected.py @@ -0,0 +1,14 @@ +""" +Creates the expected folder for diff.py +""" + +from shutil import copytree, rmtree + +# Remove it if already existing +try: + rmtree("expected") +except FileNotFoundError: + pass + +# Copy in out and artifacts directories +copytree("out", "expected/out")