diff --git a/tools/isledecomp/isledecomp/compare/core.py b/tools/isledecomp/isledecomp/compare/core.py index ec49f70b..ce992f41 100644 --- a/tools/isledecomp/isledecomp/compare/core.py +++ b/tools/isledecomp/isledecomp/compare/core.py @@ -174,6 +174,21 @@ def _load_markers(self): codefiles = list(walk_source_dir(self.code_dir)) codebase = DecompCodebase(codefiles, module.upper()) + def orig_bin_checker(addr: int) -> bool: + return self.orig_bin.is_valid_vaddr(addr) + + # If the address of any annotation would cause an exception, + # remove it and report an error. + bad_annotations = codebase.prune_invalid_addrs(orig_bin_checker) + + for sym in bad_annotations: + logger.error( + "Invalid address 0x%x on %s annotation in file: %s", + sym.offset, + sym.type.name, + sym.filename, + ) + # Match lineref functions first because this is a guaranteed match. # If we have two functions that share the same name, and one is # a lineref, we can match the nameref correctly because the lineref diff --git a/tools/isledecomp/isledecomp/parser/codebase.py b/tools/isledecomp/isledecomp/parser/codebase.py index 184b1256..bae0d122 100644 --- a/tools/isledecomp/isledecomp/parser/codebase.py +++ b/tools/isledecomp/isledecomp/parser/codebase.py @@ -1,5 +1,5 @@ """For aggregating decomp markers read from an entire directory and for a single module.""" -from typing import Iterable, Iterator, List +from typing import Callable, Iterable, Iterator, List from .parser import DecompParser from .node import ( ParserSymbol, @@ -24,6 +24,15 @@ def __init__(self, filenames: Iterable[str], module: str) -> None: sym.filename = filename self._symbols.append(sym) + def prune_invalid_addrs(self, is_valid: Callable[int, bool]) -> List[ParserSymbol]: + """Some decomp annotations might have an invalid address. + Return the list of addresses where we fail the is_valid check, + and remove those from our list of symbols.""" + invalid_symbols = [sym for sym in self._symbols if not is_valid(sym.offset)] + self._symbols = [sym for sym in self._symbols if is_valid(sym.offset)] + + return invalid_symbols + def iter_line_functions(self) -> Iterator[ParserFunction]: """Return lineref functions separately from nameref. Assuming the PDB matches the state of the source code, a line reference is a guaranteed match, even if