splat64 0.37.1__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.
Files changed (158) hide show
  1. {splat64-0.37.1 → splat64-0.37.2}/.github/workflows/unit_tests.yml +1 -0
  2. {splat64-0.37.1 → splat64-0.37.2}/CHANGELOG.md +4 -0
  3. {splat64-0.37.1 → splat64-0.37.2}/PKG-INFO +2 -2
  4. {splat64-0.37.1 → splat64-0.37.2}/README.md +1 -1
  5. {splat64-0.37.1 → splat64-0.37.2}/docs/Configuration.md +4 -0
  6. {splat64-0.37.1 → splat64-0.37.2}/pyproject.toml +1 -1
  7. {splat64-0.37.1 → splat64-0.37.2}/src/splat/__init__.py +1 -1
  8. {splat64-0.37.1 → splat64-0.37.2}/src/splat/scripts/split.py +46 -0
  9. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/c.py +3 -3
  10. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/n64/rominfo.py +1 -2
  11. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/options.py +5 -0
  12. splat64-0.37.2/test_n64_entrypoints.py +1193 -0
  13. {splat64-0.37.1 → splat64-0.37.2}/.gitattributes +0 -0
  14. {splat64-0.37.1 → splat64-0.37.2}/.github/workflows/format.yml +0 -0
  15. {splat64-0.37.1 → splat64-0.37.2}/.github/workflows/lint.yml +0 -0
  16. {splat64-0.37.1 → splat64-0.37.2}/.github/workflows/publish_docs_to_wiki.yml +0 -0
  17. {splat64-0.37.1 → splat64-0.37.2}/.github/workflows/pypi.yml +0 -0
  18. {splat64-0.37.1 → splat64-0.37.2}/.github/workflows/test_lib.yml +0 -0
  19. {splat64-0.37.1 → splat64-0.37.2}/.gitignore +0 -0
  20. {splat64-0.37.1 → splat64-0.37.2}/LICENSE +0 -0
  21. {splat64-0.37.1 → splat64-0.37.2}/create_config.py +0 -0
  22. {splat64-0.37.1 → splat64-0.37.2}/docs/Adding-Symbols.md +0 -0
  23. {splat64-0.37.1 → splat64-0.37.2}/docs/Advanced-Reloc.md +0 -0
  24. {splat64-0.37.1 → splat64-0.37.2}/docs/Advanced.md +0 -0
  25. {splat64-0.37.1 → splat64-0.37.2}/docs/Examples.md +0 -0
  26. {splat64-0.37.1 → splat64-0.37.2}/docs/General-Workflow.md +0 -0
  27. {splat64-0.37.1 → splat64-0.37.2}/docs/Home.md +0 -0
  28. {splat64-0.37.1 → splat64-0.37.2}/docs/Quickstart-Elf.md +0 -0
  29. {splat64-0.37.1 → splat64-0.37.2}/docs/Quickstart.md +0 -0
  30. {splat64-0.37.1 → splat64-0.37.2}/docs/Segments.md +0 -0
  31. {splat64-0.37.1 → splat64-0.37.2}/docs/VramClasses.md +0 -0
  32. {splat64-0.37.1 → splat64-0.37.2}/mypy.ini +0 -0
  33. {splat64-0.37.1 → splat64-0.37.2}/requirements.txt +0 -0
  34. {splat64-0.37.1 → splat64-0.37.2}/split.py +0 -0
  35. {splat64-0.37.1 → splat64-0.37.2}/src/splat/__main__.py +0 -0
  36. {splat64-0.37.1 → splat64-0.37.2}/src/splat/disassembler/__init__.py +0 -0
  37. {splat64-0.37.1 → splat64-0.37.2}/src/splat/disassembler/disassembler.py +0 -0
  38. {splat64-0.37.1 → splat64-0.37.2}/src/splat/disassembler/disassembler_instance.py +0 -0
  39. {splat64-0.37.1 → splat64-0.37.2}/src/splat/disassembler/disassembler_section.py +0 -0
  40. {splat64-0.37.1 → splat64-0.37.2}/src/splat/disassembler/null_disassembler.py +0 -0
  41. {splat64-0.37.1 → splat64-0.37.2}/src/splat/disassembler/spimdisasm_disassembler.py +0 -0
  42. {splat64-0.37.1 → splat64-0.37.2}/src/splat/platforms/__init__.py +0 -0
  43. {splat64-0.37.1 → splat64-0.37.2}/src/splat/platforms/n64.py +0 -0
  44. {splat64-0.37.1 → splat64-0.37.2}/src/splat/platforms/ps2.py +0 -0
  45. {splat64-0.37.1 → splat64-0.37.2}/src/splat/platforms/psp.py +0 -0
  46. {splat64-0.37.1 → splat64-0.37.2}/src/splat/platforms/psx.py +0 -0
  47. {splat64-0.37.1 → splat64-0.37.2}/src/splat/py.typed +0 -0
  48. {splat64-0.37.1 → splat64-0.37.2}/src/splat/scripts/__init__.py +0 -0
  49. {splat64-0.37.1 → splat64-0.37.2}/src/splat/scripts/capy.py +0 -0
  50. {splat64-0.37.1 → splat64-0.37.2}/src/splat/scripts/create_config.py +0 -0
  51. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/__init__.py +0 -0
  52. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/__init__.py +0 -0
  53. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/asm.py +0 -0
  54. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/asmtu.py +0 -0
  55. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/bin.py +0 -0
  56. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/bss.py +0 -0
  57. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/code.py +0 -0
  58. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/codesubsegment.py +0 -0
  59. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/cpp.py +0 -0
  60. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/data.py +0 -0
  61. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/databin.py +0 -0
  62. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/eh_frame.py +0 -0
  63. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/gcc_except_table.py +0 -0
  64. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/group.py +0 -0
  65. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/hasm.py +0 -0
  66. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/header.py +0 -0
  67. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/lib.py +0 -0
  68. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/linker_offset.py +0 -0
  69. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/pad.py +0 -0
  70. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/rdata.py +0 -0
  71. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/rodata.py +0 -0
  72. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/rodatabin.py +0 -0
  73. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/sbss.py +0 -0
  74. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/sdata.py +0 -0
  75. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/segment.py +0 -0
  76. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/common/textbin.py +0 -0
  77. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/linker_entry.py +0 -0
  78. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/__init__.py +0 -0
  79. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/ci.py +0 -0
  80. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/ci4.py +0 -0
  81. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/ci8.py +0 -0
  82. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/decompressor.py +0 -0
  83. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/gfx.py +0 -0
  84. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/header.py +0 -0
  85. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/i1.py +0 -0
  86. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/i4.py +0 -0
  87. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/i8.py +0 -0
  88. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/ia16.py +0 -0
  89. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/ia4.py +0 -0
  90. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/ia8.py +0 -0
  91. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/img.py +0 -0
  92. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/ipl3.py +0 -0
  93. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/mio0.py +0 -0
  94. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/palette.py +0 -0
  95. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/rgba16.py +0 -0
  96. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/rgba32.py +0 -0
  97. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/rsp.py +0 -0
  98. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/vtx.py +0 -0
  99. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/n64/yay0.py +0 -0
  100. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/ps2/__init__.py +0 -0
  101. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/ps2/ctor.py +0 -0
  102. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/ps2/lit4.py +0 -0
  103. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/ps2/lit8.py +0 -0
  104. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/ps2/vtables.py +0 -0
  105. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/psp/__init__.py +0 -0
  106. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/psx/__init__.py +0 -0
  107. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/psx/header.py +0 -0
  108. {splat64-0.37.1 → splat64-0.37.2}/src/splat/segtypes/segment.py +0 -0
  109. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/__init__.py +0 -0
  110. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/cache_handler.py +0 -0
  111. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/color.py +0 -0
  112. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/compiler.py +0 -0
  113. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/conf.py +0 -0
  114. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/file_presets.py +0 -0
  115. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/log.py +0 -0
  116. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/n64/__init__.py +0 -0
  117. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/n64/find_code_length.py +0 -0
  118. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/palettes.py +0 -0
  119. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/progress_bar.py +0 -0
  120. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/ps2/__init__.py +0 -0
  121. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/ps2/ps2elfinfo.py +0 -0
  122. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/psx/__init__.py +0 -0
  123. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/psx/psxexeinfo.py +0 -0
  124. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/relocs.py +0 -0
  125. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/statistics.py +0 -0
  126. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/symbols.py +0 -0
  127. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/utils.py +0 -0
  128. {splat64-0.37.1 → splat64-0.37.2}/src/splat/util/vram_classes.py +0 -0
  129. {splat64-0.37.1 → splat64-0.37.2}/test/Dockerfile +0 -0
  130. {splat64-0.37.1 → splat64-0.37.2}/test/README.md +0 -0
  131. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/.gitignore +0 -0
  132. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/Makefile +0 -0
  133. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/build/basic_app.bin +0 -0
  134. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/dummy_ipl3.s +0 -0
  135. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/.splache +0 -0
  136. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/data/main.bss.s +0 -0
  137. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/data/main.data.s +0 -0
  138. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/data/main.rodata.s +0 -0
  139. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/handwritten.s +0 -0
  140. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/header.s +0 -0
  141. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/main.s +0 -0
  142. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/nonmatchings/main/D_80000510.s +0 -0
  143. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/nonmatchings/main/func_80000400.s +0 -0
  144. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/asm/nonmatchings/main/func_800004A0.s +0 -0
  145. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/assets/dummy_ipl3.bin +0 -0
  146. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/basic_app.d +0 -0
  147. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/build/test/basic_app/split/src/main.asmproc.d +0 -0
  148. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/include/include_asm.h +0 -0
  149. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/include/labels.inc +0 -0
  150. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/include/macro.inc +0 -0
  151. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/src/main.c +0 -0
  152. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/undefined_funcs_auto.txt +0 -0
  153. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/expected/undefined_syms_auto.txt +0 -0
  154. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/handwritten.s +0 -0
  155. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/header.s +0 -0
  156. {splat64-0.37.1 → splat64-0.37.2}/test/basic_app/main.c +0 -0
  157. {splat64-0.37.1 → splat64-0.37.2}/test/test_gen_expected.sh +0 -0
  158. {splat64-0.37.1 → splat64-0.37.2}/test.py +0 -0
@@ -80,3 +80,4 @@ jobs:
80
80
  run: |
81
81
  ${{ matrix.os.python_venv_activate }}
82
82
  python3 test.py
83
+ python3 test_n64_entrypoints.py
@@ -1,5 +1,9 @@
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
+
3
7
  ### 0.37.1
4
8
 
5
9
  * Fix `make_full_disasm_for_code` not extracting data-only TUs.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: splat64
3
- Version: 0.37.1
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.1,<1.0.0
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.1,<1.0.0
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.
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "splat64"
3
3
  # Should be synced with src/splat/__init__.py
4
- version = "0.37.1"
4
+ version = "0.37.2"
5
5
  description = "A binary splitting tool to assist with decompilation and modding projects"
6
6
  readme = "README.md"
7
7
  license = {file = "LICENSE"}
@@ -1,7 +1,7 @@
1
1
  __package_name__ = __name__
2
2
 
3
3
  # Should be synced with pyproject.toml
4
- __version__ = "0.37.1"
4
+ __version__ = "0.37.2"
5
5
  __author__ = "ethteck"
6
6
 
7
7
  from . import util as util
@@ -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))
@@ -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
- if not insn.isUnsigned():
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
  ),