summaryrefslogtreecommitdiff
path: root/tools/splat/disassembler
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2023-07-14 14:44:11 -0400
committerGitHub <noreply@github.com>2023-07-14 14:44:11 -0400
commitce93cd026259b5724a8de4a2d3bb2e87297ce5e4 (patch)
tree33797b411d2451d9aeddd3b43d7fe2d7b244fa56 /tools/splat/disassembler
parent39a2e453bb882b2498c7c4aa9073a9f85d048f0c (diff)
Update subrepos (#19)
* git subrepo pull --force tools/asm-processor subrepo: subdir: "tools/asm-processor" merged: "6dd4d3a" upstream: origin: "git@github.com:simonlindholm/asm-processor.git" branch: "main" commit: "6dd4d3a" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull lib/ultralib --force subrepo: subdir: "lib/ultralib" merged: "0417857" upstream: origin: "git@github.com:decompals/ultralib.git" branch: "main" commit: "0417857" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/asm-differ --force subrepo: subdir: "tools/asm-differ" merged: "6d3e4c4" upstream: origin: "git@github.com:simonlindholm/asm-differ.git" branch: "main" commit: "6d3e4c4" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/splat --force subrepo: subdir: "tools/splat" merged: "406b646" upstream: origin: "git@github.com:ethteck/splat.git" branch: "master" commit: "406b646" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Revert "git subrepo pull lib/ultralib --force" This reverts commit da9fca47be7d8f957b786c02d7bf4b4a48830f4a. * git subrepo pull tools/splat subrepo: subdir: "tools/splat" merged: "7869ef2" upstream: origin: "git@github.com:ethteck/splat.git" branch: "master" commit: "7869ef2" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Disable asm size directive
Diffstat (limited to 'tools/splat/disassembler')
-rw-r--r--tools/splat/disassembler/__init__.py2
-rw-r--r--tools/splat/disassembler/disassembler.py17
-rw-r--r--tools/splat/disassembler/disassembler_instance.py26
-rw-r--r--tools/splat/disassembler/null_disassembler.py14
-rw-r--r--tools/splat/disassembler/spimdisasm_disassembler.py118
5 files changed, 177 insertions, 0 deletions
diff --git a/tools/splat/disassembler/__init__.py b/tools/splat/disassembler/__init__.py
new file mode 100644
index 0000000..09c2ca5
--- /dev/null
+++ b/tools/splat/disassembler/__init__.py
@@ -0,0 +1,2 @@
+from .disassembler import Disassembler
+from .spimdisasm_disassembler import SpimdisasmDisassembler
diff --git a/tools/splat/disassembler/disassembler.py b/tools/splat/disassembler/disassembler.py
new file mode 100644
index 0000000..e64aa26
--- /dev/null
+++ b/tools/splat/disassembler/disassembler.py
@@ -0,0 +1,17 @@
+from abc import ABC, abstractmethod
+from util.options import SplatOpts
+from typing import Set
+
+
+class Disassembler(ABC):
+ @abstractmethod
+ def configure(self, options: SplatOpts):
+ raise NotImplementedError("configure")
+
+ @abstractmethod
+ def check_version(self, skip_version_check: bool, splat_version: str):
+ raise NotImplementedError("check_version")
+
+ @abstractmethod
+ def known_types(self) -> Set[str]:
+ raise NotImplementedError("known_types")
diff --git a/tools/splat/disassembler/disassembler_instance.py b/tools/splat/disassembler/disassembler_instance.py
new file mode 100644
index 0000000..988fe3c
--- /dev/null
+++ b/tools/splat/disassembler/disassembler_instance.py
@@ -0,0 +1,26 @@
+from .disassembler import Disassembler
+from .spimdisasm_disassembler import SpimdisasmDisassembler
+from .null_disassembler import NullDisassembler
+
+__instance: Disassembler = NullDisassembler()
+__initialized = False
+
+
+def create_disassembler_instance(platform: str):
+ global __instance
+ global __initialized
+ if platform in ["n64", "psx", "ps2"]:
+ __instance = SpimdisasmDisassembler()
+ __initialized = True
+ return
+
+ raise NotImplementedError("No disassembler for requested platform")
+
+
+def get_instance() -> Disassembler:
+ global __instance
+ global __initialized
+ if not __initialized:
+ raise Exception("Disassembler instance not initialized")
+ return None
+ return __instance
diff --git a/tools/splat/disassembler/null_disassembler.py b/tools/splat/disassembler/null_disassembler.py
new file mode 100644
index 0000000..046725e
--- /dev/null
+++ b/tools/splat/disassembler/null_disassembler.py
@@ -0,0 +1,14 @@
+from disassembler import disassembler
+from util.options import SplatOpts
+from typing import Set
+
+
+class NullDisassembler(disassembler.Disassembler):
+ def configure(self, opts: SplatOpts):
+ pass
+
+ def check_version(self, skip_version_check: bool, splat_version: str):
+ pass
+
+ def known_types(self) -> Set[str]:
+ return set()
diff --git a/tools/splat/disassembler/spimdisasm_disassembler.py b/tools/splat/disassembler/spimdisasm_disassembler.py
new file mode 100644
index 0000000..399b4e3
--- /dev/null
+++ b/tools/splat/disassembler/spimdisasm_disassembler.py
@@ -0,0 +1,118 @@
+from disassembler import disassembler
+import spimdisasm
+import rabbitizer
+from util import log, compiler
+from util.options import SplatOpts
+from typing import Set
+
+
+class SpimdisasmDisassembler(disassembler.Disassembler):
+ # This value should be kept in sync with the version listed on requirements.txt
+ SPIMDISASM_MIN = (1, 15, 0)
+
+ def configure(self, opts: SplatOpts):
+ # Configure spimdisasm
+ spimdisasm.common.GlobalConfig.PRODUCE_SYMBOLS_PLUS_OFFSET = True
+ spimdisasm.common.GlobalConfig.TRUST_USER_FUNCTIONS = True
+ spimdisasm.common.GlobalConfig.TRUST_JAL_FUNCTIONS = True
+ spimdisasm.common.GlobalConfig.GLABEL_ASM_COUNT = False
+
+ if opts.rom_address_padding:
+ spimdisasm.common.GlobalConfig.ASM_COMMENT_OFFSET_WIDTH = 6
+ else:
+ spimdisasm.common.GlobalConfig.ASM_COMMENT_OFFSET_WIDTH = 0
+
+ # spimdisasm is not performing any analyzis on non-text sections so enabling this options is pointless
+ spimdisasm.common.GlobalConfig.AUTOGENERATED_NAMES_BASED_ON_SECTION_TYPE = False
+ spimdisasm.common.GlobalConfig.AUTOGENERATED_NAMES_BASED_ON_DATA_TYPE = False
+
+ spimdisasm.common.GlobalConfig.SYMBOL_FINDER_FILTERED_ADDRESSES_AS_HILO = False
+
+ if opts.rodata_string_guesser_level is not None:
+ spimdisasm.common.GlobalConfig.RODATA_STRING_GUESSER_LEVEL = (
+ opts.rodata_string_guesser_level
+ )
+
+ if opts.data_string_guesser_level is not None:
+ spimdisasm.common.GlobalConfig.DATA_STRING_GUESSER_LEVEL = (
+ opts.data_string_guesser_level
+ )
+
+ rabbitizer.config.regNames_userFpcCsr = False
+ rabbitizer.config.regNames_vr4300Cop0NamedRegisters = False
+
+ rabbitizer.config.misc_opcodeLJust = opts.mnemonic_ljust - 1
+
+ rabbitizer.config.regNames_gprAbiNames = rabbitizer.Abi.fromStr(
+ opts.mips_abi_gpr
+ )
+ rabbitizer.config.regNames_fprAbiNames = rabbitizer.Abi.fromStr(
+ opts.mips_abi_float_regs
+ )
+
+ if opts.endianness == "big":
+ spimdisasm.common.GlobalConfig.ENDIAN = spimdisasm.common.InputEndian.BIG
+ else:
+ spimdisasm.common.GlobalConfig.ENDIAN = spimdisasm.common.InputEndian.LITTLE
+
+ rabbitizer.config.pseudos_pseudoMove = False
+
+ selected_compiler = opts.compiler
+ if selected_compiler == compiler.SN64:
+ rabbitizer.config.regNames_namedRegisters = False
+ rabbitizer.config.toolchainTweaks_sn64DivFix = True
+ rabbitizer.config.toolchainTweaks_treatJAsUnconditionalBranch = True
+ spimdisasm.common.GlobalConfig.ASM_COMMENT = False
+ spimdisasm.common.GlobalConfig.SYMBOL_FINDER_FILTERED_ADDRESSES_AS_HILO = (
+ False
+ )
+ spimdisasm.common.GlobalConfig.COMPILER = spimdisasm.common.Compiler.SN64
+ elif selected_compiler == compiler.GCC:
+ rabbitizer.config.toolchainTweaks_treatJAsUnconditionalBranch = True
+ spimdisasm.common.GlobalConfig.COMPILER = spimdisasm.common.Compiler.GCC
+ elif selected_compiler == compiler.IDO:
+ spimdisasm.common.GlobalConfig.COMPILER = spimdisasm.common.Compiler.IDO
+
+ spimdisasm.common.GlobalConfig.GP_VALUE = opts.gp
+
+ spimdisasm.common.GlobalConfig.ASM_TEXT_LABEL = opts.asm_function_macro
+ spimdisasm.common.GlobalConfig.ASM_JTBL_LABEL = opts.asm_jtbl_label_macro
+ spimdisasm.common.GlobalConfig.ASM_DATA_LABEL = opts.asm_data_macro
+ spimdisasm.common.GlobalConfig.ASM_TEXT_END_LABEL = opts.asm_end_label
+
+ if opts.asm_emit_size_directive is not None:
+ spimdisasm.common.GlobalConfig.ASM_EMIT_SIZE_DIRECTIVE = (
+ opts.asm_emit_size_directive
+ )
+
+ if spimdisasm.common.GlobalConfig.ASM_TEXT_LABEL == ".globl":
+ spimdisasm.common.GlobalConfig.ASM_TEXT_ENT_LABEL = ".ent"
+ spimdisasm.common.GlobalConfig.ASM_TEXT_FUNC_AS_LABEL = True
+
+ if spimdisasm.common.GlobalConfig.ASM_DATA_LABEL == ".globl":
+ spimdisasm.common.GlobalConfig.ASM_DATA_SYM_AS_LABEL = True
+
+ spimdisasm.common.GlobalConfig.LINE_ENDS = opts.c_newline
+
+ spimdisasm.common.GlobalConfig.ALLOW_ALL_ADDENDS_ON_DATA = (
+ opts.allow_data_addends
+ )
+
+ spimdisasm.common.GlobalConfig.ASM_GENERATED_BY = opts.asm_generated_by
+
+ spimdisasm.common.GlobalConfig.DISASSEMBLE_UNKNOWN_INSTRUCTIONS = (
+ opts.disasm_unknown
+ )
+
+ def check_version(self, skip_version_check: bool, splat_version: str):
+ if not skip_version_check and spimdisasm.__version_info__ < self.SPIMDISASM_MIN:
+ log.error(
+ f"splat {splat_version} requires as minimum spimdisasm {self.SPIMDISASM_MIN}, but the installed version is {spimdisasm.__version_info__}"
+ )
+
+ log.write(
+ f"splat {splat_version} (powered by spimdisasm {spimdisasm.__version__})"
+ )
+
+ def known_types(self) -> Set[str]:
+ return spimdisasm.common.gKnownTypes