diff --git a/tools/isledecomp/isledecomp/bin.py b/tools/isledecomp/isledecomp/bin.py index 514f4a8e..9ca3195b 100644 --- a/tools/isledecomp/isledecomp/bin.py +++ b/tools/isledecomp/isledecomp/bin.py @@ -113,6 +113,7 @@ def __init__(self, filename: str, find_str: bool = False) -> None: self.imports = [] self.thunks = [] self.exports: List[Tuple[int, str]] = [] + self.is_debug: bool = False def __enter__(self): logger.debug("Bin %s Enter", self.filename) @@ -143,6 +144,13 @@ def __enter__(self): *struct.iter_unpack("<2I", optional_hdr[0x60 : 0x60 + number_of_rva * 8]) ] + # Check for presence of .debug subsection in .rdata + try: + if data_dictionaries[6][0] != 0: + self.is_debug = True + except IndexError: + pass + headers_view = optional_hdr[ pe_hdr.SizeOfOptionalHeader : pe_hdr.SizeOfOptionalHeader + 0x28 * pe_hdr.NumberOfSections @@ -337,9 +345,27 @@ def _populate_thunks(self): Search .text to find these functions.""" text_sect = self.get_section_by_name(".text") + text_start = text_sect.virtual_address + + # If this is a debug build, read the thunks at the start of .text + # Terminated by a big block of 0xcc padding bytes before the first + # real function in the section. + if self.is_debug: + ofs = 0 + while True: + (opcode, operand) = struct.unpack(" str: def _compare_match(self, match: MatchInfo) -> Optional[DiffReport]: """Router for comparison type""" - if match.size == 0: + if match.size is None or match.size == 0: return None options = self._db.get_match_options(match.orig_addr) diff --git a/tools/isledecomp/isledecomp/compare/db.py b/tools/isledecomp/isledecomp/compare/db.py index 71f10373..de67dfc8 100644 --- a/tools/isledecomp/isledecomp/compare/db.py +++ b/tools/isledecomp/isledecomp/compare/db.py @@ -221,6 +221,29 @@ def set_function_pair(self, orig: int, recomp: int) -> bool: """For lineref match or _entry""" return self.set_pair(orig, recomp, SymbolType.FUNCTION) + def register_thunk(self, orig: int, recomp: int, name: str) -> bool: + """orig/recomp are an address pair of a thunk to some other function. + We may or may not already have this function tracked in the db. + If not, we need to create it, and we will use the name + (of the function being thunked, presumably) to mock up a name for + this symbol.""" + + # Start by assuming the row exists + if self.set_function_pair(orig, recomp): + return True + + thunk_name = f"Thunk of '{name}'" + + # Assuming relative jump instruction for thunks (5 bytes) + cur = self._db.execute( + """INSERT INTO `symbols` + (orig_addr, recomp_addr, compare_type, name, size) + VALUES (?,?,?,?,?)""", + (orig, recomp, SymbolType.FUNCTION.value, thunk_name, 5), + ) + + return cur.rowcount > 0 + def _set_opt_bool(self, addr: int, option: str, enabled: bool = True): if enabled: self._db.execute(