splat64 0.37.0__tar.gz → 0.37.2__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.37.0 → splat64-0.37.2}/.github/workflows/unit_tests.yml +1 -0
- {splat64-0.37.0 → splat64-0.37.2}/CHANGELOG.md +10 -0
- {splat64-0.37.0 → splat64-0.37.2}/PKG-INFO +2 -2
- {splat64-0.37.0 → splat64-0.37.2}/README.md +1 -1
- {splat64-0.37.0 → splat64-0.37.2}/docs/Configuration.md +14 -0
- {splat64-0.37.0 → splat64-0.37.2}/pyproject.toml +1 -1
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/__init__.py +1 -1
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/scripts/split.py +46 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/c.py +5 -3
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/codesubsegment.py +20 -15
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/file_presets.py +0 -3
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/n64/rominfo.py +1 -2
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/options.py +5 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/main.s +48 -0
- splat64-0.37.2/test_n64_entrypoints.py +1193 -0
- {splat64-0.37.0 → splat64-0.37.2}/.gitattributes +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/.github/workflows/format.yml +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/.github/workflows/lint.yml +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/.github/workflows/publish_docs_to_wiki.yml +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/.github/workflows/pypi.yml +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/.github/workflows/test_lib.yml +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/.gitignore +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/LICENSE +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/create_config.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Adding-Symbols.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Advanced-Reloc.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Advanced.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Examples.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/General-Workflow.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Home.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Quickstart-Elf.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Quickstart.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/Segments.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/docs/VramClasses.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/mypy.ini +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/requirements.txt +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/split.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/__main__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/disassembler/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/disassembler/disassembler.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/disassembler/disassembler_instance.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/disassembler/disassembler_section.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/disassembler/null_disassembler.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/disassembler/spimdisasm_disassembler.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/platforms/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/platforms/n64.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/platforms/ps2.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/platforms/psp.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/platforms/psx.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/py.typed +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/scripts/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/scripts/capy.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/scripts/create_config.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/asm.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/asmtu.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/bin.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/bss.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/code.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/cpp.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/data.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/databin.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/eh_frame.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/gcc_except_table.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/group.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/hasm.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/header.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/lib.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/linker_offset.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/pad.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/rdata.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/rodata.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/rodatabin.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/sbss.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/sdata.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/segment.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/common/textbin.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/linker_entry.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/ci.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/ci4.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/ci8.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/decompressor.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/gfx.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/header.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/i1.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/i4.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/i8.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/ia16.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/ia4.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/ia8.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/img.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/ipl3.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/mio0.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/palette.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/rgba16.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/rgba32.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/rsp.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/vtx.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/n64/yay0.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/ps2/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/ps2/ctor.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/ps2/lit4.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/ps2/lit8.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/ps2/vtables.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/psp/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/psx/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/psx/header.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/segtypes/segment.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/cache_handler.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/color.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/compiler.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/conf.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/log.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/n64/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/n64/find_code_length.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/palettes.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/progress_bar.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/ps2/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/ps2/ps2elfinfo.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/psx/__init__.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/psx/psxexeinfo.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/relocs.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/statistics.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/symbols.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/utils.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/src/splat/util/vram_classes.py +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/Dockerfile +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/README.md +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/.gitignore +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/Makefile +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/build/basic_app.bin +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/dummy_ipl3.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/.splache +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/data/main.bss.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/data/main.data.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/data/main.rodata.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/handwritten.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/header.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/nonmatchings/main/D_80000510.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/nonmatchings/main/func_80000400.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/asm/nonmatchings/main/func_800004A0.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/assets/dummy_ipl3.bin +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/basic_app.d +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/build/test/basic_app/split/src/main.asmproc.d +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/include/include_asm.h +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/include/labels.inc +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/include/macro.inc +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/src/main.c +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/undefined_funcs_auto.txt +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/expected/undefined_syms_auto.txt +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/handwritten.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/header.s +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/basic_app/main.c +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test/test_gen_expected.sh +0 -0
- {splat64-0.37.0 → splat64-0.37.2}/test.py +0 -0
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# splat Release Notes
|
|
2
2
|
|
|
3
|
+
### 0.37.2
|
|
4
|
+
* Add new option `sort_segments_by_vram_dependency` to help with non-matching builds for binaries with complicated memory layouts. See the wiki for details.
|
|
5
|
+
* Fix create_config missing bss segments due to unsigned LO instructions.
|
|
6
|
+
|
|
7
|
+
### 0.37.1
|
|
8
|
+
|
|
9
|
+
* Fix `make_full_disasm_for_code` not extracting data-only TUs.
|
|
10
|
+
* Fix `make_full_disasm_for_code` and `disassemble_all` combo
|
|
11
|
+
* Fixes not writing other sections to asm file when both options are enabled.
|
|
12
|
+
|
|
3
13
|
### 0.37.0
|
|
4
14
|
|
|
5
15
|
* Add define check to allow using `macro.inc` instead of `labels.inc` in `include_asm.h`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: splat64
|
|
3
|
-
Version: 0.37.
|
|
3
|
+
Version: 0.37.2
|
|
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
|
|
@@ -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.37.
|
|
79
|
+
splat64[mips]>=0.37.2,<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.37.
|
|
24
|
+
splat64[mips]>=0.37.2,<1.0.0
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### Optional dependencies
|
|
@@ -526,6 +526,10 @@ Generates a discard section like this:
|
|
|
526
526
|
|
|
527
527
|
Determines whether to add wildcards for section linking in the linker script (.rodata* for example)
|
|
528
528
|
|
|
529
|
+
### ld_sort_segments_by_vram_class_dependency
|
|
530
|
+
|
|
531
|
+
Ensures segments of vram classes with dependencies (`vram_symbol` / `follows_classes`) are written to the linker script AFTER the segments they depend on. This is intended to preserve vram class ordering for shifted builds (e.g., mods) and is not expected to produce a matching build. Disable this when a matching build is desired.
|
|
532
|
+
|
|
529
533
|
### ld_use_symbolic_vram_addresses
|
|
530
534
|
|
|
531
535
|
Determines whether to use `follows_vram` (segment option) and `vram_symbol` / `follows_classes` (vram_class options) to calculate vram addresses in the linker script.
|
|
@@ -848,6 +852,16 @@ Emit a full `.s` file for each `c`/`cpp` segment containing disassembly of .text
|
|
|
848
852
|
|
|
849
853
|
Can be used to generate "target" or "expected" objects for asm diffing.
|
|
850
854
|
|
|
855
|
+
To generate `.s` files for data-only TUs (or rodata/bss only, or any other combination that doesn't have a text section) a dummy `c` or `cpp` section with the same name as the data section must be defined in the yaml with an start value of `auto` instead of a number. For example:
|
|
856
|
+
|
|
857
|
+
```yaml
|
|
858
|
+
- [auto, c, boot/rom_offsets]
|
|
859
|
+
|
|
860
|
+
# -- Other c or data subsegments --
|
|
861
|
+
|
|
862
|
+
- [0x00F340, .data, boot/rom_offsets]
|
|
863
|
+
```
|
|
864
|
+
|
|
851
865
|
### global_vram_start and global_vram_end
|
|
852
866
|
|
|
853
867
|
Allow specifying that the global memory range may be larger than what was automatically detected.
|
|
@@ -6,6 +6,8 @@ import importlib
|
|
|
6
6
|
from typing import Any, Dict, List, Optional, Set, Tuple, Union
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
+
from collections import defaultdict, deque
|
|
10
|
+
|
|
9
11
|
from .. import __package_name__, __version__
|
|
10
12
|
from ..disassembler import disassembler_instance
|
|
11
13
|
from ..util import cache_handler, progress_bar, vram_classes, statistics, file_presets
|
|
@@ -222,6 +224,47 @@ def calc_segment_dependences(
|
|
|
222
224
|
return vram_class_to_follows_segments
|
|
223
225
|
|
|
224
226
|
|
|
227
|
+
def sort_segments_by_vram_class_dependency(
|
|
228
|
+
all_segments: List[Segment],
|
|
229
|
+
) -> List[Segment]:
|
|
230
|
+
# map all "_VRAM_END" strings to segments
|
|
231
|
+
end_sym_to_seg: Dict[str, Segment] = {}
|
|
232
|
+
for seg in all_segments:
|
|
233
|
+
end_sym_to_seg[get_segment_vram_end_symbol_name(seg)] = seg
|
|
234
|
+
|
|
235
|
+
# build dependency graph: A -> B means "A must come before B"
|
|
236
|
+
graph: Dict[Segment, List[Segment]] = defaultdict(list)
|
|
237
|
+
indeg: Dict[Segment, int] = {seg: 0 for seg in all_segments}
|
|
238
|
+
|
|
239
|
+
for seg in all_segments:
|
|
240
|
+
sym = seg.vram_symbol
|
|
241
|
+
if sym is None:
|
|
242
|
+
continue
|
|
243
|
+
dep = end_sym_to_seg.get(sym)
|
|
244
|
+
if dep is None or dep is seg:
|
|
245
|
+
continue
|
|
246
|
+
graph[dep].append(seg)
|
|
247
|
+
indeg[seg] += 1
|
|
248
|
+
|
|
249
|
+
# stable topo sort with queue seeded in original order
|
|
250
|
+
q = deque([seg for seg in all_segments if indeg[seg] == 0])
|
|
251
|
+
out: List[Segment] = []
|
|
252
|
+
|
|
253
|
+
while q:
|
|
254
|
+
n = q.popleft()
|
|
255
|
+
out.append(n)
|
|
256
|
+
for m in graph.get(n, []):
|
|
257
|
+
indeg[m] -= 1
|
|
258
|
+
if indeg[m] == 0:
|
|
259
|
+
q.append(m)
|
|
260
|
+
|
|
261
|
+
assert len(out) == len(all_segments), (
|
|
262
|
+
"Encountered cyclic dependency when reordering segments by vram class."
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
return out
|
|
266
|
+
|
|
267
|
+
|
|
225
268
|
def read_target_binary() -> bytes:
|
|
226
269
|
rom_bytes = options.opts.target_path.read_bytes()
|
|
227
270
|
|
|
@@ -317,6 +360,9 @@ def do_split(
|
|
|
317
360
|
|
|
318
361
|
|
|
319
362
|
def write_linker_script(all_segments: List[Segment]) -> LinkerWriter:
|
|
363
|
+
if options.opts.ld_sort_segments_by_vram_class_dependency:
|
|
364
|
+
all_segments = sort_segments_by_vram_class_dependency(all_segments)
|
|
365
|
+
|
|
320
366
|
vram_class_dependencies = calc_segment_dependences(all_segments)
|
|
321
367
|
vram_classes_to_search = set(vram_class_dependencies.keys())
|
|
322
368
|
|
|
@@ -51,7 +51,7 @@ class CommonSegC(CommonSegCodeSubsegment):
|
|
|
51
51
|
|
|
52
52
|
@staticmethod
|
|
53
53
|
def get_funcs_defined_in_c(c_file: Path) -> Set[str]:
|
|
54
|
-
with open(c_file, "r") as f:
|
|
54
|
+
with open(c_file, "r", encoding="utf-8") as f:
|
|
55
55
|
text = CommonSegC.strip_c_comments(f.read())
|
|
56
56
|
|
|
57
57
|
return set(m.group(1) for m in C_FUNC_RE.finditer(text))
|
|
@@ -105,7 +105,7 @@ class CommonSegC(CommonSegCodeSubsegment):
|
|
|
105
105
|
|
|
106
106
|
@staticmethod
|
|
107
107
|
def get_global_asm_funcs(c_file: Path) -> Set[str]:
|
|
108
|
-
with c_file.open() as f:
|
|
108
|
+
with c_file.open(encoding="utf-8") as f:
|
|
109
109
|
text = CommonSegC.strip_c_comments(f.read())
|
|
110
110
|
if options.opts.compiler == IDO:
|
|
111
111
|
return set(m.group(2) for m in C_GLOBAL_ASM_IDO_RE.finditer(text))
|
|
@@ -114,7 +114,7 @@ class CommonSegC(CommonSegCodeSubsegment):
|
|
|
114
114
|
|
|
115
115
|
@staticmethod
|
|
116
116
|
def get_global_asm_rodata_syms(c_file: Path) -> Set[str]:
|
|
117
|
-
with c_file.open() as f:
|
|
117
|
+
with c_file.open(encoding="utf-8") as f:
|
|
118
118
|
text = CommonSegC.strip_c_comments(f.read())
|
|
119
119
|
if options.opts.compiler == IDO:
|
|
120
120
|
return set(m.group(2) for m in C_GLOBAL_ASM_IDO_RE.finditer(text))
|
|
@@ -152,6 +152,8 @@ class CommonSegC(CommonSegCodeSubsegment):
|
|
|
152
152
|
|
|
153
153
|
def split(self, rom_bytes: bytes):
|
|
154
154
|
if self.is_auto_segment:
|
|
155
|
+
if options.opts.make_full_disasm_for_code:
|
|
156
|
+
self.split_as_asmtu_file(self.asm_out_path())
|
|
155
157
|
return
|
|
156
158
|
|
|
157
159
|
if self.rom_start != self.rom_end:
|
|
@@ -252,22 +252,21 @@ class CommonSegCodeSubsegment(Segment):
|
|
|
252
252
|
f.write(self.spim_section.disassemble())
|
|
253
253
|
|
|
254
254
|
# Same as above but write all sections from siblings
|
|
255
|
-
def split_as_asmtu_file(self, out_path:
|
|
256
|
-
if self.spim_section is None:
|
|
257
|
-
return
|
|
258
|
-
|
|
259
|
-
if not out_path:
|
|
260
|
-
return
|
|
261
|
-
|
|
255
|
+
def split_as_asmtu_file(self, out_path: Path):
|
|
262
256
|
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
263
257
|
|
|
264
258
|
self.print_file_boundaries()
|
|
265
259
|
|
|
266
260
|
with open(out_path, "w", newline="\n") as f:
|
|
267
|
-
#
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
261
|
+
# self.spim_section would be None if the current section was
|
|
262
|
+
# declared `auto` in the yaml.
|
|
263
|
+
# This can be useful when there are TUs with only data/rodata/bss/etc
|
|
264
|
+
# sections but not text section.
|
|
265
|
+
if self.spim_section is not None:
|
|
266
|
+
# Write `.text` contents
|
|
267
|
+
for line in self.get_asm_file_header():
|
|
268
|
+
f.write(line + "\n")
|
|
269
|
+
f.write(self.spim_section.disassemble())
|
|
271
270
|
|
|
272
271
|
# Disassemble the siblings to this file by respecting the `section_order`
|
|
273
272
|
for sect in self.section_order:
|
|
@@ -281,25 +280,31 @@ class CommonSegCodeSubsegment(Segment):
|
|
|
281
280
|
if (
|
|
282
281
|
isinstance(sibling, CommonSegCodeSubsegment)
|
|
283
282
|
and sibling.spim_section is not None
|
|
284
|
-
and
|
|
283
|
+
and (
|
|
284
|
+
not sibling.should_self_split()
|
|
285
|
+
or options.opts.make_full_disasm_for_code
|
|
286
|
+
)
|
|
285
287
|
):
|
|
286
288
|
f.write("\n")
|
|
287
289
|
f.write(f"{sibling.get_section_asm_line()}\n\n")
|
|
288
290
|
f.write(sibling.spim_section.disassemble())
|
|
289
291
|
|
|
290
|
-
# Another loop to check anything that somehow may not be present
|
|
292
|
+
# Another loop to check anything that somehow may not be present in the `section_order`
|
|
291
293
|
for sect, sibling in self.siblings.items():
|
|
292
294
|
if sect == self.get_linker_section_linksection():
|
|
293
295
|
continue
|
|
294
296
|
|
|
295
297
|
if sect in self.section_order:
|
|
296
|
-
# Already handled
|
|
298
|
+
# Already handled in the above loop
|
|
297
299
|
continue
|
|
298
300
|
|
|
299
301
|
if (
|
|
300
302
|
isinstance(sibling, CommonSegCodeSubsegment)
|
|
301
303
|
and sibling.spim_section is not None
|
|
302
|
-
and
|
|
304
|
+
and (
|
|
305
|
+
not sibling.should_self_split()
|
|
306
|
+
or options.opts.make_full_disasm_for_code
|
|
307
|
+
)
|
|
303
308
|
):
|
|
304
309
|
f.write("\n")
|
|
305
310
|
f.write(f"{sibling.get_section_asm_line()}\n\n")
|
|
@@ -162,8 +162,7 @@ class N64EntrypointInfo:
|
|
|
162
162
|
register_values[insn.rs.value] + insn.getProcessedImmediate()
|
|
163
163
|
)
|
|
164
164
|
completed_pair[insn.rt.value] = True
|
|
165
|
-
|
|
166
|
-
lo_assignments[insn.rt.value] = current_rom
|
|
165
|
+
lo_assignments[insn.rt.value] = current_rom
|
|
167
166
|
elif insn.doesStore():
|
|
168
167
|
if insn.rt == rabbitizer.RegGprO32.zero:
|
|
169
168
|
# Try to detect the zero-ing bss algorithm
|
|
@@ -127,6 +127,8 @@ class SplatOpts:
|
|
|
127
127
|
# `vram_symbol` / `follows_classes` (vram_class options) to calculate vram addresses in the linker script.
|
|
128
128
|
# If disabled, this uses the plain integer values for vram addresses defined in the yaml.
|
|
129
129
|
ld_use_symbolic_vram_addresses: bool
|
|
130
|
+
# Ensures segments of vram classes with dependencies (`vram_symbol` / `follows_classes`) are written to the linker script AFTER the segments they depend on.
|
|
131
|
+
ld_sort_segments_by_vram_class_dependency: bool
|
|
130
132
|
# Change linker script generation to allow partially linking segments. Requires both `ld_partial_scripts_path` and `ld_partial_build_segments_path` to be set.
|
|
131
133
|
ld_partial_linking: bool
|
|
132
134
|
# Folder were each intermediary linker script will be written to.
|
|
@@ -512,6 +514,9 @@ def _parse_yaml(
|
|
|
512
514
|
ld_sections_allowlist=p.parse_opt("ld_sections_allowlist", list, []),
|
|
513
515
|
ld_sections_denylist=p.parse_opt("ld_sections_denylist", list, []),
|
|
514
516
|
ld_wildcard_sections=p.parse_opt("ld_wildcard_sections", bool, False),
|
|
517
|
+
ld_sort_segments_by_vram_class_dependency=p.parse_opt(
|
|
518
|
+
"ld_sort_segments_by_vram_class_dependency", bool, False
|
|
519
|
+
),
|
|
515
520
|
ld_use_symbolic_vram_addresses=p.parse_opt(
|
|
516
521
|
"ld_use_symbolic_vram_addresses", bool, True
|
|
517
522
|
),
|
|
@@ -86,3 +86,51 @@ glabel func_800004A0
|
|
|
86
86
|
/* 10E8 800004E8 27BD0018 */ addiu $sp, $sp, 0x18
|
|
87
87
|
endlabel func_800004A0
|
|
88
88
|
/* 10EC 800004EC 00000000 */ nop
|
|
89
|
+
|
|
90
|
+
.section .data, "wa"
|
|
91
|
+
|
|
92
|
+
nonmatching D_80000500
|
|
93
|
+
|
|
94
|
+
dlabel D_80000500
|
|
95
|
+
/* 1100 80000500 00000001 */ .word 0x00000001
|
|
96
|
+
enddlabel D_80000500
|
|
97
|
+
|
|
98
|
+
nonmatching D_80000504
|
|
99
|
+
|
|
100
|
+
dlabel D_80000504
|
|
101
|
+
/* 1104 80000504 00000000 */ .word 0x00000000
|
|
102
|
+
/* 1108 80000508 00000000 */ .word 0x00000000
|
|
103
|
+
/* 110C 8000050C 00000000 */ .word 0x00000000
|
|
104
|
+
enddlabel D_80000504
|
|
105
|
+
|
|
106
|
+
.section .rodata, "a"
|
|
107
|
+
|
|
108
|
+
nonmatching D_80000510
|
|
109
|
+
|
|
110
|
+
dlabel D_80000510
|
|
111
|
+
/* 1110 80000510 00010203 */ .word 0x00010203
|
|
112
|
+
/* 1114 80000514 04050607 */ .word 0x04050607
|
|
113
|
+
enddlabel D_80000510
|
|
114
|
+
|
|
115
|
+
.align 3
|
|
116
|
+
nonmatching jtbl_80000518
|
|
117
|
+
|
|
118
|
+
dlabel jtbl_80000518
|
|
119
|
+
/* 1118 80000518 80000448 */ .word .L80000448
|
|
120
|
+
/* 111C 8000051C 80000450 */ .word .L80000450
|
|
121
|
+
/* 1120 80000520 80000458 */ .word .L80000458
|
|
122
|
+
/* 1124 80000524 80000460 */ .word .L80000460
|
|
123
|
+
/* 1128 80000528 80000468 */ .word .L80000468
|
|
124
|
+
/* 112C 8000052C 80000470 */ .word .L80000470
|
|
125
|
+
/* 1130 80000530 80000478 */ .word .L80000478
|
|
126
|
+
/* 1134 80000534 80000480 */ .word .L80000480
|
|
127
|
+
/* 1138 80000538 00000000 */ .word 0x00000000
|
|
128
|
+
/* 113C 8000053C 00000000 */ .word 0x00000000
|
|
129
|
+
enddlabel jtbl_80000518
|
|
130
|
+
|
|
131
|
+
.section .bss, "wa"
|
|
132
|
+
|
|
133
|
+
nonmatching D_80000540, 0x80
|
|
134
|
+
|
|
135
|
+
dlabel D_80000540
|
|
136
|
+
/* 80000540 */ .space 0x80
|