splat64 0.35.2__tar.gz → 0.36.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {splat64-0.35.2 → splat64-0.36.1}/CHANGELOG.md +22 -0
- {splat64-0.35.2 → splat64-0.36.1}/PKG-INFO +4 -4
- {splat64-0.35.2 → splat64-0.36.1}/README.md +1 -1
- {splat64-0.35.2 → splat64-0.36.1}/docs/Adding-Symbols.md +26 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/Configuration.md +52 -1
- {splat64-0.35.2 → splat64-0.36.1}/docs/Segments.md +3 -1
- {splat64-0.35.2 → splat64-0.36.1}/pyproject.toml +2 -2
- {splat64-0.35.2 → splat64-0.36.1}/requirements.txt +1 -1
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/__init__.py +1 -1
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/disassembler/spimdisasm_disassembler.py +1 -1
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/scripts/create_config.py +5 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/textbin.py +55 -30
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/linker_entry.py +4 -2
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/i1.py +9 -9
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/file_presets.py +127 -88
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/options.py +26 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/symbols.py +28 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/data/main.bss.s +2 -1
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/data/main.data.s +4 -2
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/data/main.rodata.s +4 -2
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/handwritten.s +2 -1
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/main.s +4 -2
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/nonmatchings/main/D_80000510.s +2 -1
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/nonmatchings/main/func_80000400.s +4 -2
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/nonmatchings/main/func_800004A0.s +2 -1
- {splat64-0.35.2 → splat64-0.36.1}/.gitattributes +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/.github/workflows/black.yml +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/.github/workflows/mypy.yml +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/.github/workflows/publish_docs_to_wiki.yml +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/.github/workflows/pypi.yml +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/.github/workflows/test_lib.yml +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/.github/workflows/unit_tests.yml +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/.gitignore +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/LICENSE +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/create_config.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/Advanced-Reloc.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/Advanced.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/Examples.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/General-Workflow.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/Home.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/Quickstart.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/docs/VramClasses.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/mypy.ini +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/split.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/__main__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/disassembler/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/disassembler/disassembler.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/disassembler/disassembler_instance.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/disassembler/disassembler_section.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/disassembler/null_disassembler.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/platforms/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/platforms/n64.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/platforms/ps2.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/platforms/psp.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/platforms/psx.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/py.typed +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/scripts/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/scripts/capy.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/scripts/split.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/asm.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/asmtu.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/bin.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/bss.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/c.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/code.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/codesubsegment.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/cpp.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/data.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/databin.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/eh_frame.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/gcc_except_table.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/group.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/hasm.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/header.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/lib.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/linker_offset.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/pad.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/rdata.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/rodata.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/rodatabin.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/sbss.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/sdata.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/common/segment.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/ci.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/ci4.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/ci8.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/decompressor.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/gfx.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/header.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/i4.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/i8.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/ia16.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/ia4.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/ia8.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/img.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/ipl3.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/mio0.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/palette.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/rgba16.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/rgba32.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/rsp.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/vtx.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/n64/yay0.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/ps2/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/ps2/ctor.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/ps2/lit4.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/ps2/lit8.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/ps2/vtables.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/psp/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/psx/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/psx/header.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/segtypes/segment.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/cache_handler.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/color.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/compiler.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/conf.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/log.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/n64/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/n64/find_code_length.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/n64/rominfo.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/palettes.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/progress_bar.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/psx/__init__.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/psx/psxexeinfo.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/relocs.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/statistics.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/utils.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/src/splat/util/vram_classes.py +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/Dockerfile +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/README.md +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/.gitignore +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/Makefile +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/build/basic_app.bin +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/dummy_ipl3.s +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/.splache +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/asm/header.s +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/assets/dummy_ipl3.bin +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/basic_app.d +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/build/test/basic_app/split/src/main.asmproc.d +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/include/include_asm.h +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/include/labels.inc +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/include/macro.inc +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/src/main.c +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/undefined_funcs_auto.txt +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/expected/undefined_syms_auto.txt +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/handwritten.s +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/header.s +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/basic_app/main.c +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test/test_gen_expected.sh +0 -0
- {splat64-0.35.2 → splat64-0.36.1}/test.py +0 -0
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# splat Release Notes
|
|
2
2
|
|
|
3
|
+
### 0.36.1
|
|
4
|
+
* Files generated with `generate_asm_macros_files` will not be overwritten if they already exist on disk unchanged.
|
|
5
|
+
* Updated GTE macros to better document opcode encodings
|
|
6
|
+
|
|
7
|
+
### 0.36.0
|
|
8
|
+
|
|
9
|
+
* New symbol attribute: `align`.
|
|
10
|
+
* Emit an alignment directive for the given symbol during disassembly.
|
|
11
|
+
* The given alignment must be positive, be a power of two and The symbol's address must already be aligned to the given custom alignment, otherwise splat will emit an error and halt.
|
|
12
|
+
* New yaml option: `ld_gp_expression`:
|
|
13
|
+
* Allows setting a custom expression for the `_gp` symbol in the generated linker script, making this symbol to properly shift around instead of hardcoding it to the given `gp_value`.
|
|
14
|
+
* New yaml option: `include_asm_macro_style`:
|
|
15
|
+
* Allows configuring the style used by the generated `INCLUDE_ASM` macro. It currently allows two possible values:
|
|
16
|
+
* `default`: Uses the default definition for the macro. This is the default.
|
|
17
|
+
* `maspsx_hack`: Changes the definition of the generated `INCLUDE_ASM` to be compatible with the one expected by `maspsx` when using the [reordering workaround hack](https://github.com/mkst/maspsx?tab=readme-ov-file#include_asm-reordering-workaround-hack). This value is only relevant for psx projects.
|
|
18
|
+
* `incbin` segments now provide a default symbol if the user hasn't defined a symbol at that given address.
|
|
19
|
+
* This name is automatically escaped to be a valid symbol name.
|
|
20
|
+
* The name of this symbol is based on the segment's name, with a `__` prefix and a suffix depending on the type of incbin used.
|
|
21
|
+
* This naming scheme may change at any time.
|
|
22
|
+
* `incbin` segments now emit a nonmatching marker.
|
|
23
|
+
* `spimdisasm` 1.36.1 or above is now required.
|
|
24
|
+
|
|
3
25
|
### 0.35.2
|
|
4
26
|
|
|
5
27
|
* Miscellaneous updates to generated macro labels.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: splat64
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.36.1
|
|
4
4
|
Summary: A binary splitting tool to assist with decompilation and modding projects
|
|
5
5
|
Project-URL: Repository, https://github.com/ethteck/splat
|
|
6
6
|
Project-URL: Issues, https://github.com/ethteck/splat/issues
|
|
@@ -42,7 +42,7 @@ Requires-Dist: mypy; extra == 'dev'
|
|
|
42
42
|
Requires-Dist: n64img>=0.3.3; extra == 'dev'
|
|
43
43
|
Requires-Dist: pygfxd; extra == 'dev'
|
|
44
44
|
Requires-Dist: rabbitizer<2.0.0,>=1.12.0; extra == 'dev'
|
|
45
|
-
Requires-Dist: spimdisasm<2.0.0,>=1.36.
|
|
45
|
+
Requires-Dist: spimdisasm<2.0.0,>=1.36.1; extra == 'dev'
|
|
46
46
|
Requires-Dist: types-colorama; extra == 'dev'
|
|
47
47
|
Requires-Dist: types-pyyaml; extra == 'dev'
|
|
48
48
|
Provides-Extra: mips
|
|
@@ -50,7 +50,7 @@ Requires-Dist: crunch64<1.0.0,>=0.5.1; extra == 'mips'
|
|
|
50
50
|
Requires-Dist: n64img>=0.3.3; extra == 'mips'
|
|
51
51
|
Requires-Dist: pygfxd; extra == 'mips'
|
|
52
52
|
Requires-Dist: rabbitizer<2.0.0,>=1.12.0; extra == 'mips'
|
|
53
|
-
Requires-Dist: spimdisasm<2.0.0,>=1.36.
|
|
53
|
+
Requires-Dist: spimdisasm<2.0.0,>=1.36.1; extra == 'mips'
|
|
54
54
|
Description-Content-Type: text/markdown
|
|
55
55
|
|
|
56
56
|
# splat
|
|
@@ -76,7 +76,7 @@ The brackets corresponds to the optional dependencies to install while installin
|
|
|
76
76
|
If you use a `requirements.txt` file in your repository, then you can add this library with the following line:
|
|
77
77
|
|
|
78
78
|
```txt
|
|
79
|
-
splat64[mips]>=0.
|
|
79
|
+
splat64[mips]>=0.36.1,<1.0.0
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
### Optional dependencies
|
|
@@ -21,7 +21,7 @@ The brackets corresponds to the optional dependencies to install while installin
|
|
|
21
21
|
If you use a `requirements.txt` file in your repository, then you can add this library with the following line:
|
|
22
22
|
|
|
23
23
|
```txt
|
|
24
|
-
splat64[mips]>=0.
|
|
24
|
+
splat64[mips]>=0.36.1,<1.0.0
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### Optional dependencies
|
|
@@ -209,3 +209,29 @@ __opPCc__Q23std34_RefCountedPtr<c,Q23std9_Array<c>>CFv = 0x00202850; // filename
|
|
|
209
209
|
```
|
|
210
210
|
|
|
211
211
|
Gets written to `func_00202850.s`
|
|
212
|
+
|
|
213
|
+
### `align`
|
|
214
|
+
|
|
215
|
+
Emit an alignment directive for the given symbol during disassembly.
|
|
216
|
+
|
|
217
|
+
Even though an explicit alignment directive is not necessary in most situations, it may be desirable to have one on shiftable builds of partially matched projects. This allows ensuring the symbol's required alignment even when it is still being disassembled.
|
|
218
|
+
|
|
219
|
+
Some situations that may require an explicit alignment directive include textures in N64 (0x8 alignment) or symbols sent to the IOP on PS2 (0x40 alignment).
|
|
220
|
+
|
|
221
|
+
The symbol's address must already be aligned to the given custom alignment, or the value will be discarded.
|
|
222
|
+
|
|
223
|
+
This value must be a power of two, otherwise it will be discarded.
|
|
224
|
+
|
|
225
|
+
**Example**
|
|
226
|
+
|
|
227
|
+
```ini
|
|
228
|
+
rgb_texture = 0x82013118; // align:0x8
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Produces a disassembly similar to the following:
|
|
232
|
+
|
|
233
|
+
```mips
|
|
234
|
+
.align 3
|
|
235
|
+
dlabel rgb_texture
|
|
236
|
+
# ...
|
|
237
|
+
```
|
|
@@ -138,6 +138,15 @@ Some files may not be generated depending on the selected platform and compiler,
|
|
|
138
138
|
|
|
139
139
|
Defaults to `True`.
|
|
140
140
|
|
|
141
|
+
### include_asm_macro_style
|
|
142
|
+
|
|
143
|
+
Allows configuring the style used by the generated `INCLUDE_ASM` macro. It currently allows two possible values:
|
|
144
|
+
|
|
145
|
+
- `default`: Uses the default definition for the macro. This is the default.
|
|
146
|
+
- `maspsx_hack`: Changes the definition of the generated `INCLUDE_ASM` to be compatible with the one expected by `maspsx` when using the [reordering workaround hack](https://github.com/mkst/maspsx?tab=readme-ov-file#include_asm-reordering-workaround-hack).
|
|
147
|
+
|
|
148
|
+
Defaults to `default`.
|
|
149
|
+
|
|
141
150
|
### o_as_suffix
|
|
142
151
|
|
|
143
152
|
Used to determine the file extension of the built files that will be listed on the linker script.
|
|
@@ -155,6 +164,8 @@ Defaults to `False`.
|
|
|
155
164
|
|
|
156
165
|
The value of the `$gp` register to correctly calculate offset to `%gp_rel` relocs.
|
|
157
166
|
|
|
167
|
+
It is strongly encouraged to provide a [`ld_gp_expression`](#ld_gp_expression) once the sections of the binary are properly understood.
|
|
168
|
+
Not setting this expression makes splat always emit a hardcoded value for `_gp` in the linker script, preventing proper shiftability.
|
|
158
169
|
|
|
159
170
|
### check_consecutive_segment_types
|
|
160
171
|
|
|
@@ -579,7 +590,7 @@ Defaults to `True`, meaning `bss` sections will be put on `NOLOAD` segments.
|
|
|
579
590
|
|
|
580
591
|
Specify that segments should be aligned before starting them.
|
|
581
592
|
|
|
582
|
-
This option specifies the desired alignment value, or `null` if no
|
|
593
|
+
This option specifies the desired alignment value, or `null` if no alignment should be imposed on the segment start.
|
|
583
594
|
|
|
584
595
|
This behavior can be customized per segment too. See [ld_align_segment_start](Segments.md#ld_align_segment_start) on the Segments section.
|
|
585
596
|
|
|
@@ -615,6 +626,46 @@ Sets the default option for the `bss_contains_common` attribute of all segments.
|
|
|
615
626
|
|
|
616
627
|
Defaults to `False`.
|
|
617
628
|
|
|
629
|
+
### ld_gp_expression
|
|
630
|
+
|
|
631
|
+
Provides an expression for the `_gp` symbol to be emitted in the generated linker script.
|
|
632
|
+
|
|
633
|
+
Most projects start by only setting a [`gp_value`](#gp_value) on their yamls. This is fine while matching the project, but it is bad for shiftable builds, becuase it prevents the `_gp` symbol to shift around as needed.
|
|
634
|
+
|
|
635
|
+
This expression is used as-is in the generated linker script, so care must be taken to provide an expression that makes sense for shiftable builds and also matches the original gp value on matching builds.
|
|
636
|
+
|
|
637
|
+
Usually this expression is relative to the start of an "small section" (`.sdata`, `.srodata`, `.sbss`, etc.) plus an optional offset (usually `0x7FF0` or `0x8000`).
|
|
638
|
+
|
|
639
|
+
The recommended approach to know what to set here is to try to understand where the first small section is, take the difference between the [`gp_value`](#gp_value) and the address of the small section to know what the offset is and then use the linker symbol for the start of that small section.
|
|
640
|
+
|
|
641
|
+
For example, say your gp value is `0x00397FF0` and you found the first small section on the rom is a `.sdata` section at vram address `0x00390000` (note *vram* address, not rom address) which is part of the top-level segment `main`. The difference between those two addresses is `0x7FF0`, so that's your offset. Given this information the expression you want for gp is `main_SDATA_START + 0x7FF0`; where `main` is the top-level segment, `SDATA` comes from the `.sdata` section and the `+ 0x7FF0` is your calculated offset. If you did this process right, then the matching build should still match after setting the gp expression.
|
|
642
|
+
|
|
643
|
+
Note you should **not** remove the `gp_value` from your yaml when you set `ld_gp_expression`. `gp_value` is still used for the disassembly; without it you wouldn't get symbolized gp-accesses.
|
|
644
|
+
|
|
645
|
+
#### Usage
|
|
646
|
+
|
|
647
|
+
Not using `ld_gp_expression` makes splat hardcode the value:
|
|
648
|
+
|
|
649
|
+
```yaml
|
|
650
|
+
gp_value: 0x0039DD70
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
```txt
|
|
654
|
+
_gp = 0x0039DD70;
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
When a `ld_gp_expression` is given then splat is able to emit a non-hardcoded expression for `_gp` without interfering with the disassembly process:
|
|
658
|
+
|
|
659
|
+
```yaml
|
|
660
|
+
gp_value: 0x0039DD70
|
|
661
|
+
ld_gp_expression: main_SDATA_START + 0x7FF0
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
```txt
|
|
665
|
+
_gp = main_SDATA_START + 0x7FF0;
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
|
|
618
669
|
## C file options
|
|
619
670
|
|
|
620
671
|
### create_c_files
|
|
@@ -318,6 +318,8 @@ Generating assembly files enables better customization of these binaries, like a
|
|
|
318
318
|
|
|
319
319
|
If a known symbol (via a symbol_addrs file) matches the vram of a incbin segment then it will be emitted accordingly at the top. If the symbol contains a [`name_end`](Adding-Symbols.md#name_end) property then it will be emitted after the `.incbin` (useful for Nintendo64's RSP ucodes).
|
|
320
320
|
|
|
321
|
+
If no symbol is provided then splat will emit a symbol based on the segment's name with a `__` prefix and a suffix depending on the type of incbin used. This autogenerated naming scheme may change at any time.
|
|
322
|
+
|
|
321
323
|
Curretly there are 3 types of incbins, `textbin`, `databin` and `rodatabin`, which are intended for binary blobs of `.text`, `.data` and `.rodata` sections.
|
|
322
324
|
|
|
323
325
|
If a `textbin` section has a corresponding `databin` and/or `rodatabin` section with the same name then those will be included in the same generated assembly file.
|
|
@@ -542,7 +544,7 @@ Defaults to the value of the global option.
|
|
|
542
544
|
|
|
543
545
|
Specify the current segment should be aligned before starting it.
|
|
544
546
|
|
|
545
|
-
This option specifies the desired alignment value, or `null` if no
|
|
547
|
+
This option specifies the desired alignment value, or `null` if no alignment should be imposed on the segment start.
|
|
546
548
|
|
|
547
549
|
If not set, then the global configuration is used. See [ld_align_segment_start](Configuration.md#ld_align_segment_start) on the Configuration section.
|
|
548
550
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "splat64"
|
|
3
3
|
# Should be synced with src/splat/__init__.py
|
|
4
|
-
version = "0.
|
|
4
|
+
version = "0.36.1"
|
|
5
5
|
description = "A binary splitting tool to assist with decompilation and modding projects"
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
license = {file = "LICENSE"}
|
|
@@ -20,7 +20,7 @@ dependencies = [
|
|
|
20
20
|
|
|
21
21
|
[project.optional-dependencies]
|
|
22
22
|
mips = [
|
|
23
|
-
"spimdisasm>=1.36.
|
|
23
|
+
"spimdisasm>=1.36.1,<2.0.0", # This value should be keep in sync with the version listed on disassembler/spimdisasm_disassembler.py
|
|
24
24
|
"rabbitizer>=1.12.0,<2.0.0",
|
|
25
25
|
"pygfxd",
|
|
26
26
|
"n64img>=0.3.3",
|
|
@@ -7,7 +7,7 @@ from typing import Set
|
|
|
7
7
|
|
|
8
8
|
class SpimdisasmDisassembler(disassembler.Disassembler):
|
|
9
9
|
# This value should be kept in sync with the version listed on requirements.txt and pyproject.toml
|
|
10
|
-
SPIMDISASM_MIN = (1, 36,
|
|
10
|
+
SPIMDISASM_MIN = (1, 36, 1)
|
|
11
11
|
|
|
12
12
|
def configure(self):
|
|
13
13
|
# Configure spimdisasm
|
|
@@ -286,6 +286,7 @@ options:
|
|
|
286
286
|
|
|
287
287
|
find_file_boundaries: False
|
|
288
288
|
gp_value: 0x{exe.initial_gp:08X}
|
|
289
|
+
# ld_gp_expression: main_SCOMMON_START + 0x7FF0
|
|
289
290
|
|
|
290
291
|
o_as_suffix: True
|
|
291
292
|
use_legacy_include_asm: False
|
|
@@ -309,6 +310,10 @@ options:
|
|
|
309
310
|
data_string_encoding: ASCII
|
|
310
311
|
rodata_string_guesser_level: 2
|
|
311
312
|
data_string_guesser_level: 2
|
|
313
|
+
|
|
314
|
+
# Uncomment this line if you need to use the maspsx reorder workaround hack
|
|
315
|
+
# https://github.com/mkst/maspsx?tab=readme-ov-file#include_asm-reordering-workaround-hack
|
|
316
|
+
# include_asm_macro_style: maspsx_hack
|
|
312
317
|
"""
|
|
313
318
|
|
|
314
319
|
segments = f"""\
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
+
import re
|
|
2
3
|
from typing import Optional, TextIO
|
|
3
4
|
|
|
4
5
|
from ...util import log, options
|
|
@@ -75,45 +76,66 @@ class CommonSegTextbin(CommonSegment):
|
|
|
75
76
|
|
|
76
77
|
f.write(f"{self.get_section_asm_line()}\n\n")
|
|
77
78
|
|
|
79
|
+
sym_name = None
|
|
80
|
+
sym_name_end = None
|
|
81
|
+
sym_size_matches = None
|
|
82
|
+
|
|
78
83
|
# Check if there's a symbol at this address
|
|
79
|
-
sym = None
|
|
80
84
|
vram = self.rom_to_ram(self.rom_start)
|
|
81
85
|
if vram is not None:
|
|
82
86
|
sym = self.get_symbol(vram, in_segment=True)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
if sym is not None:
|
|
88
|
+
sym.defined = True
|
|
89
|
+
sym_name = sym.name
|
|
90
|
+
sym_name_end = sym.given_name_end
|
|
91
|
+
if (
|
|
92
|
+
sym.given_size is None
|
|
93
|
+
or sym.given_size == self.rom_end - self.rom_start
|
|
94
|
+
):
|
|
95
|
+
sym_size_matches = self.rom_end - self.rom_start
|
|
96
|
+
|
|
97
|
+
if sym_name is None:
|
|
98
|
+
# Normalize stuff like slashes and such.
|
|
99
|
+
n = regex_sym_name_normalizer.sub("_", self.name)
|
|
100
|
+
if self.is_text():
|
|
101
|
+
suffix = "textbin"
|
|
102
|
+
elif self.is_data():
|
|
103
|
+
suffix = "databin"
|
|
104
|
+
elif self.is_rodata():
|
|
105
|
+
suffix = "rodatabin"
|
|
106
|
+
else:
|
|
107
|
+
suffix = "incbin"
|
|
108
|
+
sym_name = f"__{n}_{suffix}"
|
|
109
|
+
|
|
110
|
+
if options.opts.asm_nonmatching_label_macro != "":
|
|
111
|
+
siz = f", 0x{sym_size_matches:X}" if sym_size_matches is not None else ""
|
|
112
|
+
f.write(f"{options.opts.asm_nonmatching_label_macro} {sym_name}{siz}\n\n")
|
|
113
|
+
|
|
114
|
+
f.write(f"{asm_label} {sym_name}\n")
|
|
115
|
+
if asm_label == ".globl":
|
|
116
|
+
if self.is_text():
|
|
117
|
+
f.write(f".ent {sym_name}\n")
|
|
118
|
+
f.write(f"{sym_name}:\n")
|
|
91
119
|
|
|
92
120
|
f.write(f'.incbin "{binpath.as_posix()}"\n')
|
|
93
121
|
|
|
94
|
-
if
|
|
95
|
-
|
|
96
|
-
f.write(f".size {sym.name}, . - {sym.name}\n")
|
|
122
|
+
if options.opts.asm_emit_size_directive:
|
|
123
|
+
f.write(f".size {sym_name}, . - {sym_name}\n")
|
|
97
124
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
125
|
+
if self.is_text() and options.opts.asm_end_label != "":
|
|
126
|
+
f.write(f"{options.opts.asm_end_label} {sym_name}\n")
|
|
127
|
+
elif options.opts.asm_data_end_label != "":
|
|
128
|
+
f.write(f"{options.opts.asm_data_end_label} {sym_name}\n")
|
|
102
129
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
f.write(f"{options.opts.asm_end_label} {sym.given_name_end}\n")
|
|
113
|
-
elif self.is_data() and options.opts.asm_data_end_label != "":
|
|
114
|
-
f.write(
|
|
115
|
-
f"{options.opts.asm_data_end_label} {sym.given_name_end}\n"
|
|
116
|
-
)
|
|
130
|
+
if sym_name_end is not None and sym_size_matches is not None:
|
|
131
|
+
f.write(f"{asm_label} {sym_name_end}\n")
|
|
132
|
+
if asm_label == ".globl":
|
|
133
|
+
f.write(f"{sym_name_end}:\n")
|
|
134
|
+
|
|
135
|
+
if self.is_text() and options.opts.asm_end_label != "":
|
|
136
|
+
f.write(f"{options.opts.asm_end_label} {sym_name_end}\n")
|
|
137
|
+
elif options.opts.asm_data_end_label != "":
|
|
138
|
+
f.write(f"{options.opts.asm_data_end_label} {sym_name_end}\n")
|
|
117
139
|
|
|
118
140
|
def split(self, rom_bytes):
|
|
119
141
|
if self.rom_end is None:
|
|
@@ -159,3 +181,6 @@ class CommonSegTextbin(CommonSegment):
|
|
|
159
181
|
return (
|
|
160
182
|
self.extract and self.should_scan()
|
|
161
183
|
) # only split if the segment was scanned first
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
regex_sym_name_normalizer = re.compile(r"[^0-9a-zA-Z_]")
|
|
@@ -204,8 +204,10 @@ class LinkerWriter:
|
|
|
204
204
|
if not self.is_partial:
|
|
205
205
|
self._writeln(f"__romPos = {options.opts.ld_rom_start};")
|
|
206
206
|
|
|
207
|
-
if options.opts.
|
|
208
|
-
self._writeln("_gp =
|
|
207
|
+
if options.opts.ld_gp_expression is not None:
|
|
208
|
+
self._writeln(f"_gp = {options.opts.ld_gp_expression};")
|
|
209
|
+
elif options.opts.gp is not None:
|
|
210
|
+
self._writeln(f"_gp = 0x{options.opts.gp:X};")
|
|
209
211
|
|
|
210
212
|
# Write a series of statements which compute a symbol that represents the highest address among a list of segments' end addresses
|
|
211
213
|
def write_max_vram_end_sym(self, symbol: str, overlays: List[Segment]):
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import n64img.image
|
|
2
|
-
|
|
3
|
-
from .img import N64SegImg
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class N64SegI1(N64SegImg):
|
|
7
|
-
def __init__(self, *args, **kwargs):
|
|
8
|
-
kwargs["img_cls"] = n64img.image.I1
|
|
9
|
-
super().__init__(*args, **kwargs)
|
|
1
|
+
import n64img.image
|
|
2
|
+
|
|
3
|
+
from .img import N64SegImg
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class N64SegI1(N64SegImg):
|
|
7
|
+
def __init__(self, *args, **kwargs):
|
|
8
|
+
kwargs["img_cls"] = n64img.image.I1
|
|
9
|
+
super().__init__(*args, **kwargs)
|