diff --git a/CHANGELOG.md b/CHANGELOG.md index 71877fef..149aee8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,17 @@ # splat Release Notes +### 0.25.2 + +* Two new yaml options: `use_gp_rel_macro_nonmatching` and `use_gp_rel_macro` + * Allows to toggle the use of `%gp_rel`s. + * Not using `%gp_rel`s may be desirable for projects that use old assemblers that do not support said relocation parameter. + * The assembler is free to choose the kind of relocation to use if no explicit relocation parameter is used for a given instruction, it may even expand the instruction into multiple instructions. To avoid this, it is the user's responsability to provide the symbol's information (like the symbol's size) to the assembler so it can pick the correct relocation. + ### 0.25.1 * Added two new segment types: `gcc_except_table` and `eh_frame`. * Used by GCC to handle C++ exceptions. -* New yaml option: `asm_jtbl_label_macro` +* New yaml option: `asm_ehtable_label_macro` * Allows to specify the macro used by ehlabels, the ones generated by `gcc_except_table` references. ### 0.25.0 diff --git a/README.md b/README.md index 6567b1bd..f22f9469 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The brackets corresponds to the optional dependencies to install while installin If you use a `requirements.txt` file in your repository, then you can add this library with the following line: ```txt -splat64[mips]>=0.25.1,<1.0.0 +splat64[mips]>=0.25.2,<1.0.0 ``` ### Optional dependencies diff --git a/docs/Configuration.md b/docs/Configuration.md index 8d13b44c..7d4c8ee8 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -635,6 +635,26 @@ Allow specifying that the global memory range may be larger than what was automa Useful for projects where splat is used in multiple individual files, meaning the expected global segment may not be properly detected because each instance of splat can't see the info from other files, like in PSX and PSP projects. +### use_gp_rel_macro_nonmatching + +If True then use the `%gp_rel` explicit relocation parameter on instructions that use the $gp register, otherwise strip the `%gp_rel` parameter entirely +and convert those instructions into macro instructions that may not assemble to the original bytes. + +In the latter case, it is the user's responsability to provide the symbol's information to the assembler so it can assemble the instruction with the +proper relocation, for example by declaring the required symbol on the corresponding `.c` or `.cpp` file. + +Turning off this setting may be useful for projects with old assemblers that do not support `%gp_rel`, like PS2 and PSP projects. + +This setting is applied exclusively to `c` segments (functions under the nonmatchings folder). + +Defaults to `True` + +### use_gp_rel_macro + +Does the same as `use_gp_rel_macro_nonmatching`, except it is only applied to `asm` and `hasm` segments. + +Defaults to `True` + ## N64-specific options ### header_encoding diff --git a/pyproject.toml b/pyproject.toml index 932d9c63..055dea28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "splat64" # Should be synced with src/splat/__init__.py -version = "0.25.1" +version = "0.25.2" description = "A binary splitting tool to assist with decompilation and modding projects" readme = "README.md" license = {file = "LICENSE"} @@ -20,7 +20,7 @@ dependencies = [ [project.optional-dependencies] mips = [ - "spimdisasm>=1.27.0,<2.0.0", # This value should be keep in sync with the version listed on disassembler/spimdisasm_disassembler.py + "spimdisasm>=1.28.0,<2.0.0", # This value should be keep in sync with the version listed on disassembler/spimdisasm_disassembler.py "rabbitizer>=1.10.0,<2.0.0", "pygfxd", "n64img>=0.1.4", diff --git a/requirements.txt b/requirements.txt index 6da9aabf..bbb30287 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ tqdm intervaltree colorama # This value should be keep in sync with the version listed on disassembler/spimdisasm_disassembler.py and pyproject.toml -spimdisasm>=1.26.0 +spimdisasm>=1.28.0 rabbitizer>=1.10.0 pygfxd n64img>=0.1.4 diff --git a/src/splat/__init__.py b/src/splat/__init__.py index 644d0932..4ac87435 100644 --- a/src/splat/__init__.py +++ b/src/splat/__init__.py @@ -3,7 +3,7 @@ __package_name__ = __name__ # Should be synced with pyproject.toml -__version__ = "0.25.0" +__version__ = "0.25.2" __author__ = "ethteck" from . import util as util diff --git a/src/splat/disassembler/spimdisasm_disassembler.py b/src/splat/disassembler/spimdisasm_disassembler.py index 67bb9b0d..787ba64e 100644 --- a/src/splat/disassembler/spimdisasm_disassembler.py +++ b/src/splat/disassembler/spimdisasm_disassembler.py @@ -7,7 +7,7 @@ class SpimdisasmDisassembler(disassembler.Disassembler): # This value should be kept in sync with the version listed on requirements.txt and pyproject.toml - SPIMDISASM_MIN = (1, 27, 0) + SPIMDISASM_MIN = (1, 28, 0) def configure(self): # Configure spimdisasm diff --git a/src/splat/segtypes/common/c.py b/src/splat/segtypes/common/c.py index c0f4721b..5072609c 100644 --- a/src/splat/segtypes/common/c.py +++ b/src/splat/segtypes/common/c.py @@ -36,6 +36,8 @@ def __init__(self, *args, **kwargs): self.file_extension = "c" + self.use_gp_rel_macro = options.opts.use_gp_rel_macro_nonmatching + @staticmethod def strip_c_comments(text): def replacer(match): diff --git a/src/splat/segtypes/common/codesubsegment.py b/src/splat/segtypes/common/codesubsegment.py index e903879b..f917279a 100644 --- a/src/splat/segtypes/common/codesubsegment.py +++ b/src/splat/segtypes/common/codesubsegment.py @@ -41,6 +41,7 @@ def __init__(self, *args, **kwargs): ) self.is_hasm = False + self.use_gp_rel_macro = options.opts.use_gp_rel_macro @property def needs_symbols(self) -> bool: @@ -59,6 +60,7 @@ def configure_disassembler_section( section.isHandwritten = self.is_hasm section.instrCat = self.instr_category section.detectRedundantFunctionEnd = self.detect_redundant_function_end + section.gpRelHack = not self.use_gp_rel_macro def scan_code(self, rom_bytes, is_hasm=False): self.is_hasm = is_hasm diff --git a/src/splat/util/options.py b/src/splat/util/options.py index f45d7cca..cf358636 100644 --- a/src/splat/util/options.py +++ b/src/splat/util/options.py @@ -183,7 +183,7 @@ class SplatOpts: asm_data_macro: str # Determines the macro used at the end of a function, such as endlabel or .end asm_end_label: str - # Determines the macro used to declare data symbols in asm files + # Determines the macro used to declare ehtable labels in asm files asm_ehtable_label_macro: str # Toggles the .size directive emitted by the disassembler asm_emit_size_directive: Optional[bool] @@ -226,6 +226,14 @@ class SplatOpts: # Useful for projects where splat is used in multiple individual files, meaning the expected global segment may not be properly detected because each instance of splat can't see the info from other files. global_vram_start: Optional[int] global_vram_end: Optional[int] + # For `c` segments (functions under the nonmatchings folder). + # If True then use the `%gp_rel` explicit relocation parameter on instructions that use the $gp register, + # otherwise strip the `%gp_rel` parameter entirely and convert those instructions into macro instructions that may not assemble to the original + # bytes. In the latter case, it is the user's responsability to provide the symbol's information to the assembler so it can assemble the + # instruction with the proper relocation. + use_gp_rel_macro_nonmatching: bool + # Does the same as `use_gp_rel_macro_nonmatching`, except it is only applied to `asm` and `hasm` segments. + use_gp_rel_macro: bool ################################################################################ # N64-specific options @@ -550,6 +558,10 @@ def parse_endianness() -> Literal["big", "little"]: ), global_vram_start=p.parse_optional_opt("global_vram_start", int), global_vram_end=p.parse_optional_opt("global_vram_end", int), + use_gp_rel_macro_nonmatching=p.parse_opt( + "use_gp_rel_macro_nonmatching", bool, True + ), + use_gp_rel_macro=p.parse_opt("use_gp_rel_macro", bool, True), ) p.check_no_unread_opts() return ret