diff --git a/setup.cfg b/setup.cfg index 467800a5..5624b617 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,7 @@ [metadata] name = spimdisasm -version = 1.5.0 +version = 1.5.1 author = Decompollaborate license = MIT description = N64 MIPS disassembler diff --git a/spimdisasm/__init__.py b/spimdisasm/__init__.py index a2e6503b..0ee5284d 100644 --- a/spimdisasm/__init__.py +++ b/spimdisasm/__init__.py @@ -5,7 +5,7 @@ from __future__ import annotations -__version_info__ = (1, 5, 0) +__version_info__ = (1, 5, 1) __version__ = ".".join(map(str, __version_info__)) __author__ = "Decompollaborate" diff --git a/spimdisasm/common/ContextSymbols.py b/spimdisasm/common/ContextSymbols.py index a2c94041..b460c83d 100644 --- a/spimdisasm/common/ContextSymbols.py +++ b/spimdisasm/common/ContextSymbols.py @@ -264,8 +264,27 @@ def getSymbolLabel(self) -> str: return label + @staticmethod + def getCsvHeader() -> str: + output = "address,name,getName,getType," + output += "size," + output += "getSize,getVrom,sectionType," + output += "isDefined,isUserDeclared,isAutogenerated,isMaybeString," + output += "referenceCounter,overlayCategory,unknownSegment," + output += "isGot,isGotGlobal" + return output + def toCsv(self) -> str: - return f"0x{self.address:06X},{self.name},{self.getName()},{self.getType()},0x{self.getSize():X},{self.getVrom():X},{self.sectionType.toStr()},{self.isDefined},{self.isUserDeclared},{self.isAutogenerated},{self.isMaybeString},{self.referenceCounter},{self.overlayCategory},{self.unknownSegment},{self.isGot},{self.isGotGlobal}" + output = f"0x{self.address:06X},{self.name},{self.getName()},{self.getType()}," + if self.size is None: + output += "None," + else: + output += f"0x{self.size:X}," + output += f"0x{self.getSize():X},0x{self.getVrom():X},{self.sectionType.toStr()}," + output += f"{self.isDefined},{self.isUserDeclared},{self.isAutogenerated},{self.isMaybeString}," + output += f"{self.referenceCounter},{self.overlayCategory},{self.unknownSegment}," + output += f"{self.isGot},{self.isGotGlobal}" + return output class ContextOffsetSymbol(ContextSymbol): diff --git a/spimdisasm/common/ElementBase.py b/spimdisasm/common/ElementBase.py index eaaee2f4..68f6deb2 100644 --- a/spimdisasm/common/ElementBase.py +++ b/spimdisasm/common/ElementBase.py @@ -79,6 +79,13 @@ def getVromOffset(self, localOffset: int) -> int: def getVramOffset(self, localOffset: int) -> int: return self.vram + localOffset + def containsVram(self, vram: int) -> bool: + if vram < self.vram: + return False + if vram >= self.vramEnd: + return False + return True + def getLabelFromSymbol(self, sym: ContextSymbol|None) -> str: "Generates a glabel for the passed symbol, including an optional index value if it was set and it is enabled in the GlobalConfig" diff --git a/spimdisasm/common/SymbolsSegment.py b/spimdisasm/common/SymbolsSegment.py index d65dbc65..bde54875 100644 --- a/spimdisasm/common/SymbolsSegment.py +++ b/spimdisasm/common/SymbolsSegment.py @@ -182,6 +182,8 @@ def getLoPatch(self, loInstrVram: int|None) -> int|None: def saveContextToFile(self, f: TextIO): + f.write(f"category,{ContextSymbol.getCsvHeader()}\n") + for address in self.symbols: f.write(f"symbol,{self.symbols[address].toCsv()}\n") diff --git a/spimdisasm/mips/sections/MipsSectionData.py b/spimdisasm/mips/sections/MipsSectionData.py index 43922679..ff57f72d 100644 --- a/spimdisasm/mips/sections/MipsSectionData.py +++ b/spimdisasm/mips/sections/MipsSectionData.py @@ -23,19 +23,44 @@ def analyze(self): symbolList: list[tuple[int, common.ContextSymbol]] = [] localOffset = 0 + needsFurtherAnalyzis = False + for w in self.words: currentVram = self.getVramOffset(localOffset) contextSym = self.getSymbol(currentVram, tryPlusOffset=False) if contextSym is not None: symbolList.append((localOffset, contextSym)) + elif self.popPointerInDataReference(currentVram) is not None: + if common.GlobalConfig.ADD_NEW_SYMBOLS: + contextSym = self.addSymbol(currentVram, self.sectionType, isAutogenerated=True) + symbolList.append((localOffset, contextSym)) if w >= self.vram and w > 0x80000000 and w < 0x84000000: if self.getSymbol(w, tryPlusOffset=False) is None: self.addPointerInDataReference(w) + if w < currentVram and self.containsVram(w): + # References a data symbol from this section and it is behind this current symbol + needsFurtherAnalyzis = True + localOffset += 4 + if needsFurtherAnalyzis: + localOffset = 0 + for w in self.words: + currentVram = self.getVramOffset(localOffset) + + contextSym = self.getSymbol(currentVram, tryPlusOffset=False) + if contextSym is None and self.popPointerInDataReference(currentVram) is not None: + if common.GlobalConfig.ADD_NEW_SYMBOLS: + contextSym = self.addSymbol(currentVram, self.sectionType, isAutogenerated=True) + symbolList.append((localOffset, contextSym)) + + localOffset += 4 + + symbolList.sort() + for i, (offset, contextSym) in enumerate(symbolList): if i + 1 == len(symbolList): words = self.words[offset//4:] diff --git a/spimdisasm/mips/symbols/MipsSymbolFunction.py b/spimdisasm/mips/symbols/MipsSymbolFunction.py index ef48b3ab..ac228c7b 100644 --- a/spimdisasm/mips/symbols/MipsSymbolFunction.py +++ b/spimdisasm/mips/symbols/MipsSymbolFunction.py @@ -194,8 +194,11 @@ def analyze(self): if contextSym.address % 4 != 0 or symVram % 4 != 0: if contextSym.getType() in {"u16", "s16", "u8", "u8"} or symType in {"u16", "s16", "u8", "u8"}: if not (contextSym.getSize() > 4): - if common.GlobalConfig.ADD_NEW_SYMBOLS: - contextSym = self.addSymbol(symVram, isAutogenerated=True) + if contextSym.size is None or symVram >= contextSym.address + contextSym.size: + if common.GlobalConfig.ADD_NEW_SYMBOLS: + if symType is not None: + contextSym.setTypeIfUnset(symType) + contextSym = self.addSymbol(symVram, isAutogenerated=True) contextSym.referenceCounter += 1 if symType is not None: