splat64 0.34.3__tar.gz → 0.35.0__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 (154) hide show
  1. {splat64-0.34.3 → splat64-0.35.0}/CHANGELOG.md +23 -0
  2. {splat64-0.34.3 → splat64-0.35.0}/PKG-INFO +2 -2
  3. {splat64-0.34.3 → splat64-0.35.0}/README.md +1 -1
  4. splat64-0.35.0/docs/Advanced-Reloc.md +200 -0
  5. {splat64-0.34.3 → splat64-0.35.0}/docs/Configuration.md +48 -5
  6. {splat64-0.34.3 → splat64-0.35.0}/docs/General-Workflow.md +54 -6
  7. {splat64-0.34.3 → splat64-0.35.0}/docs/Segments.md +33 -0
  8. {splat64-0.34.3 → splat64-0.35.0}/pyproject.toml +1 -1
  9. {splat64-0.34.3 → splat64-0.35.0}/requirements.txt +1 -1
  10. {splat64-0.34.3 → splat64-0.35.0}/src/splat/__init__.py +1 -1
  11. {splat64-0.34.3 → splat64-0.35.0}/src/splat/disassembler/spimdisasm_disassembler.py +7 -1
  12. {splat64-0.34.3 → splat64-0.35.0}/src/splat/scripts/create_config.py +99 -19
  13. {splat64-0.34.3 → splat64-0.35.0}/src/splat/scripts/split.py +55 -2
  14. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/group.py +23 -0
  15. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/textbin.py +8 -0
  16. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/linker_entry.py +1 -1
  17. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/segment.py +9 -0
  18. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/__init__.py +1 -0
  19. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/compiler.py +11 -6
  20. splat64-0.35.0/src/splat/util/file_presets.py +702 -0
  21. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/n64/rominfo.py +83 -30
  22. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/options.py +17 -0
  23. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/relocs.py +1 -3
  24. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/data/main.bss.s +2 -1
  25. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/data/main.data.s +6 -4
  26. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/data/main.rodata.s +6 -4
  27. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/handwritten.s +2 -1
  28. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/main.s +12 -10
  29. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/nonmatchings/main/D_80000510.s +3 -2
  30. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/nonmatchings/main/func_80000400.s +5 -3
  31. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/nonmatchings/main/func_800004A0.s +2 -1
  32. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/basic_app.d +1 -1
  33. splat64-0.35.0/test/basic_app/expected/include/include_asm.h +38 -0
  34. splat64-0.35.0/test/basic_app/expected/include/labels.inc +58 -0
  35. splat64-0.35.0/test/basic_app/expected/include/macro.inc +130 -0
  36. {splat64-0.34.3 → splat64-0.35.0}/.gitattributes +0 -0
  37. {splat64-0.34.3 → splat64-0.35.0}/.github/workflows/black.yml +0 -0
  38. {splat64-0.34.3 → splat64-0.35.0}/.github/workflows/mypy.yml +0 -0
  39. {splat64-0.34.3 → splat64-0.35.0}/.github/workflows/publish_docs_to_wiki.yml +0 -0
  40. {splat64-0.34.3 → splat64-0.35.0}/.github/workflows/pypi.yml +0 -0
  41. {splat64-0.34.3 → splat64-0.35.0}/.github/workflows/test_lib.yml +0 -0
  42. {splat64-0.34.3 → splat64-0.35.0}/.github/workflows/unit_tests.yml +0 -0
  43. {splat64-0.34.3 → splat64-0.35.0}/.gitignore +0 -0
  44. {splat64-0.34.3 → splat64-0.35.0}/LICENSE +0 -0
  45. {splat64-0.34.3 → splat64-0.35.0}/create_config.py +0 -0
  46. {splat64-0.34.3 → splat64-0.35.0}/docs/Adding-Symbols.md +0 -0
  47. {splat64-0.34.3 → splat64-0.35.0}/docs/Advanced.md +0 -0
  48. {splat64-0.34.3 → splat64-0.35.0}/docs/Examples.md +0 -0
  49. {splat64-0.34.3 → splat64-0.35.0}/docs/Home.md +0 -0
  50. {splat64-0.34.3 → splat64-0.35.0}/docs/Quickstart.md +0 -0
  51. {splat64-0.34.3 → splat64-0.35.0}/docs/VramClasses.md +0 -0
  52. {splat64-0.34.3 → splat64-0.35.0}/mypy.ini +0 -0
  53. {splat64-0.34.3 → splat64-0.35.0}/split.py +0 -0
  54. {splat64-0.34.3 → splat64-0.35.0}/src/splat/__main__.py +0 -0
  55. {splat64-0.34.3 → splat64-0.35.0}/src/splat/disassembler/__init__.py +0 -0
  56. {splat64-0.34.3 → splat64-0.35.0}/src/splat/disassembler/disassembler.py +0 -0
  57. {splat64-0.34.3 → splat64-0.35.0}/src/splat/disassembler/disassembler_instance.py +0 -0
  58. {splat64-0.34.3 → splat64-0.35.0}/src/splat/disassembler/disassembler_section.py +0 -0
  59. {splat64-0.34.3 → splat64-0.35.0}/src/splat/disassembler/null_disassembler.py +0 -0
  60. {splat64-0.34.3 → splat64-0.35.0}/src/splat/platforms/__init__.py +0 -0
  61. {splat64-0.34.3 → splat64-0.35.0}/src/splat/platforms/n64.py +0 -0
  62. {splat64-0.34.3 → splat64-0.35.0}/src/splat/platforms/ps2.py +0 -0
  63. {splat64-0.34.3 → splat64-0.35.0}/src/splat/platforms/psp.py +0 -0
  64. {splat64-0.34.3 → splat64-0.35.0}/src/splat/platforms/psx.py +0 -0
  65. {splat64-0.34.3 → splat64-0.35.0}/src/splat/py.typed +0 -0
  66. {splat64-0.34.3 → splat64-0.35.0}/src/splat/scripts/__init__.py +0 -0
  67. {splat64-0.34.3 → splat64-0.35.0}/src/splat/scripts/capy.py +0 -0
  68. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/__init__.py +0 -0
  69. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/__init__.py +0 -0
  70. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/asm.py +0 -0
  71. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/asmtu.py +0 -0
  72. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/bin.py +0 -0
  73. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/bss.py +0 -0
  74. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/c.py +0 -0
  75. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/code.py +0 -0
  76. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/codesubsegment.py +0 -0
  77. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/cpp.py +0 -0
  78. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/data.py +0 -0
  79. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/databin.py +0 -0
  80. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/eh_frame.py +0 -0
  81. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/gcc_except_table.py +0 -0
  82. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/hasm.py +0 -0
  83. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/header.py +0 -0
  84. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/lib.py +0 -0
  85. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/linker_offset.py +0 -0
  86. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/pad.py +0 -0
  87. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/rdata.py +0 -0
  88. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/rodata.py +0 -0
  89. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/rodatabin.py +0 -0
  90. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/sbss.py +0 -0
  91. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/sdata.py +0 -0
  92. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/common/segment.py +0 -0
  93. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/__init__.py +0 -0
  94. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/ci.py +0 -0
  95. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/ci4.py +0 -0
  96. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/ci8.py +0 -0
  97. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/decompressor.py +0 -0
  98. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/gfx.py +0 -0
  99. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/header.py +0 -0
  100. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/i1.py +0 -0
  101. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/i4.py +0 -0
  102. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/i8.py +0 -0
  103. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/ia16.py +0 -0
  104. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/ia4.py +0 -0
  105. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/ia8.py +0 -0
  106. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/img.py +0 -0
  107. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/ipl3.py +0 -0
  108. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/mio0.py +0 -0
  109. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/palette.py +0 -0
  110. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/rgba16.py +0 -0
  111. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/rgba32.py +0 -0
  112. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/rsp.py +0 -0
  113. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/vtx.py +0 -0
  114. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/n64/yay0.py +0 -0
  115. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/ps2/__init__.py +0 -0
  116. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/ps2/ctor.py +0 -0
  117. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/ps2/lit4.py +0 -0
  118. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/ps2/lit8.py +0 -0
  119. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/ps2/vtables.py +0 -0
  120. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/psp/__init__.py +0 -0
  121. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/psx/__init__.py +0 -0
  122. {splat64-0.34.3 → splat64-0.35.0}/src/splat/segtypes/psx/header.py +0 -0
  123. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/cache_handler.py +0 -0
  124. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/color.py +0 -0
  125. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/conf.py +0 -0
  126. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/log.py +0 -0
  127. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/n64/__init__.py +0 -0
  128. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/n64/find_code_length.py +0 -0
  129. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/palettes.py +0 -0
  130. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/progress_bar.py +0 -0
  131. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/psx/__init__.py +0 -0
  132. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/psx/psxexeinfo.py +0 -0
  133. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/statistics.py +0 -0
  134. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/symbols.py +0 -0
  135. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/utils.py +0 -0
  136. {splat64-0.34.3 → splat64-0.35.0}/src/splat/util/vram_classes.py +0 -0
  137. {splat64-0.34.3 → splat64-0.35.0}/test/Dockerfile +0 -0
  138. {splat64-0.34.3 → splat64-0.35.0}/test/README.md +0 -0
  139. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/.gitignore +0 -0
  140. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/Makefile +0 -0
  141. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/build/basic_app.bin +0 -0
  142. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/dummy_ipl3.s +0 -0
  143. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/.splache +0 -0
  144. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/asm/header.s +0 -0
  145. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/assets/dummy_ipl3.bin +0 -0
  146. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/build/test/basic_app/split/src/main.asmproc.d +0 -0
  147. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/src/main.c +0 -0
  148. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/undefined_funcs_auto.txt +0 -0
  149. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/expected/undefined_syms_auto.txt +0 -0
  150. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/handwritten.s +0 -0
  151. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/header.s +0 -0
  152. {splat64-0.34.3 → splat64-0.35.0}/test/basic_app/main.c +0 -0
  153. {splat64-0.34.3 → splat64-0.35.0}/test/test_gen_expected.sh +0 -0
  154. {splat64-0.34.3 → splat64-0.35.0}/test.py +0 -0
@@ -1,6 +1,29 @@
1
1
  # splat Release Notes
2
2
 
3
+ ### 0.35.0
4
+
5
+ * Add `pair_segment` option to segments.
6
+ * Allows pairing the sections of two different segments together, making cross-segment rodata migration possible.
7
+ * Now `create_config` for N64 games can create basic `symbol_addrs.txt` and `reloc_addrs.txt` files from the information inferred from its analysis.
8
+ * splat will now start generating and regenerating files related to assembly macros, allowing less painful updates to newer splat versions.
9
+ * This includes generating files like `include/include_asm.h`, `include/macro.inc`, `include/labels.inc` and `include/gte_macros.inc`.
10
+ * This makes easier for splat to introduce new kinds of labels or update the current definitions with minimal pain for the end-user.
11
+ * This behaviour can be slightly customized with `generated_macro_inc_content` or completely turned off with `generate_asm_macros_files`.
12
+ * Both `splat` and `create_config` have this behaviour.
13
+ * New yaml options:
14
+ * `asm_nonmatching_label_macro`: Set the label to be used to signal an assembly symbol haven't been matched yet. Defaults to `nonmatching`.
15
+ * `asm_data_end_label`: Set the label used at the end of a data symbol. Defaults to `enddlabel`.
16
+ * `generated_macro_inc_content`: A string defining custom contents to be emitted at the generated `include/macro.inc` file.
17
+ * `generate_asm_macros_files`: Controls if the assembly macros files should be regenerated by splat or not.
18
+ * Change the default value for multiple assembly macro labels.
19
+ * `asm_function_alt_macro`: Changed from `glabel` to `alabel`.
20
+ * `asm_jtbl_label_macro`: Changed from `glabel` to `jlabel`.
21
+ * `asm_data_macro`: Changed from `glabel` to `dlabel`.
22
+ * `asm_end_label`: Changed from empty to `endlabel`.
23
+ * `spimdisasm` 1.36.0 or above is now required.
24
+
3
25
  ### 0.34.3
26
+
4
27
  * `asm_emit_size_directive` now also affects generated assembly from `textbin`, `databin`, and `rodatabin` segments.
5
28
 
6
29
  ### 0.34.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: splat64
3
- Version: 0.34.3
3
+ Version: 0.35.0
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.34.3,<1.0.0
79
+ splat64[mips]>=0.35.0,<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.34.3,<1.0.0
24
+ splat64[mips]>=0.35.0,<1.0.0
25
25
  ```
26
26
 
27
27
  ### Optional dependencies
@@ -0,0 +1,200 @@
1
+ # Advanced: Manual relocation handling
2
+
3
+ Sometimes the disassembler is unable to determine the correct symbol to be referenced by a given function or data symbol. For cases like this you can manually tell the disassembler what symbol should be used on each specific instance and how it should be referenced in a `reloc_addrs.txt` file.
4
+
5
+ Assembly function or data symbol references other symbol by using relocations (relocs for short). This section will explain how to override the automatic relocations generated by the disassembler.
6
+
7
+ By default splat will read the `reloc_addrs.txt` file from the root of the project, if any, but it is possible to rename the file, move it to a different folder or even provide multiple files for organizational purposes. Please refer to the [`reloc_addrs_path`](Configuration.md#reloc_addrs_path) for more information.
8
+
9
+ ## Syntax
10
+
11
+ To override relocs you need to have at least one `reloc_addrs.txt` file. Each line of this file corresponds to a reloc override entry. Empty lines are allowed and comments are used with `//`.
12
+
13
+ The format for defining an entry is:
14
+
15
+ ```ini
16
+ rom:0x04B440 reloc:MIPS_HI16 symbol:BonusWait addend:-0x3
17
+ ```
18
+
19
+ Each attribute is defined as follows:
20
+
21
+ - `rom`: The rom address of the instruction or data reference you want to affect is located.
22
+ - `symbol`: The symbol that you want to reference at this given place.
23
+ - `addend`: Optional. A displacement into the symbol. It can be either positive or negative.
24
+ - `reloc`: The relocation kind to be used. It mirrors the standard MIPS relocations. The following values are valid for this attribute:
25
+ - Function relocs:
26
+ - `MIPS_HI16`: Corresponds to the `%hi` reloc operator.
27
+ - `MIPS_LO16`: Corresponds to the `%lo` reloc operator.
28
+ - `MIPS_GPREL16`: Corresponds to the `%gp_rel` reloc operator.
29
+ - `MIPS_GOT16`: Corresponds to the `%got` reloc operator.
30
+ - `MIPS_CALL16`: Corresponds to the `%call16` reloc operator.
31
+ - `MIPS_GOT_HI16`: Corresponds to the `%got_hi` reloc operator.
32
+ - `MIPS_GOT_LO16`: Corresponds to the `%got_lo` reloc operator.
33
+ - `MIPS_CALL_HI16`: Corresponds to the `%call_hi` reloc operator.
34
+ - `MIPS_CALL_LO16`: Corresponds to the `%call_lo` reloc operator.
35
+ - `MIPS_26`: No direct operator. Used in `jal` (jump and link) and `j` (jump) instructions.
36
+ - `MIPS_PC16`: No direct operator. Used in branch instructions.
37
+ - Data relocs:
38
+ - `MIPS_32`: Corresponds to `.word`.
39
+ - `MIPS_GPREL32`: Corresponds to `.gpword`.
40
+ - No reloc:
41
+ - `MIPS_NONE`: Makes no reloc to be used at all, making the disassembler to use the raw value instead. Useful for fake positives on the symbol detector.
42
+
43
+ ## Examples
44
+
45
+ Next are a common patterns where providing manual relocs is useful.
46
+
47
+ ### Negative offsets
48
+
49
+ A common that can be seen on many C functions is to access a global array with an index substraction, making the compiler to emit an assembly access that ends up pointing to a different index than the one would expect.
50
+
51
+ Take for example the following C code.
52
+
53
+ ```c
54
+ int some_sym = 0;
55
+ int some_array[3] = {0};
56
+
57
+ int get_value(int index) {
58
+ return some_array[index - 1];
59
+ }
60
+ ```
61
+
62
+ Some compilers with some optimization flags enabled may optimize the generated assembly into something that doesn't need to actually perform the `- 1` subtraction, as seen in the following example assembly:
63
+
64
+ ```mips
65
+ sll $t6, $a0, 0x2
66
+ lui $v0, %hi(some_array - 0x4)
67
+ addu $v0, $v0, $t6
68
+ jr $ra
69
+ lw $v0, %lo(some_array - 0x4)($v0)
70
+ ```
71
+
72
+ This then gets build and linked into a final binary. That binary won't have those explicit relocations, it will just have raw addresses, meaning that code will techincally reference the symbol "behind" the array we want to actually use, in this case we end up refering to `some_sym` instead.
73
+
74
+ A direct disassembly of this assembly would look like similar to the following assembly. Note there's no mention of `some_array` anywhere.
75
+
76
+ ```mips
77
+ /* 0000 80000000 00047080 */ sll $t6, $a0, 0x2
78
+ /* 0004 80000004 3C028000 */ lui $v0, %hi(some_sym)
79
+ /* 0008 80000008 004E1021 */ addu $v0, $v0, $t6
80
+ /* 000C 8000000C 03E00008 */ jr $ra
81
+ /* 0010 80000010 8C420020 */ lw $v0, %lo(some_sym)($v0)
82
+ ```
83
+
84
+ While this assembly is very likely to build to a matching binary again, it may cause some issues under a few circunstances, like when a poject aims to achieve proper shiftability while it haven't been completely matched.
85
+
86
+ To fix this disassembly it is needed to provide reloc entries in a `reloc_addrs.txt` file like the following:
87
+
88
+ ```ini
89
+ rom:0x0004 reloc:MIPS_HI16 symbol:some_array addend:-0x4
90
+ rom:0x0010 reloc:MIPS_LO16 symbol:some_array addend:-0x4
91
+ ```
92
+
93
+ This tells the disassembler to reference `some_array - 0x4` at the instruction at rom address `0x0004` (the `lui` instruction), and that it should use the `%hi` reloc operator to do so. A similar logic is used for the instruction at rom address `0x0010` (the `lw`), but instead we told it to use the `%lw` reloc operator instead. This generates an assembly like the following:
94
+
95
+ ```mips
96
+ /* 0000 80000000 00047080 */ sll $t6, $a0, 0x2
97
+ /* 0004 80000004 3C028000 */ lui $v0, %hi(some_array - 0x4)
98
+ /* 0008 80000008 004E1021 */ addu $v0, $v0, $t6
99
+ /* 000C 8000000C 03E00008 */ jr $ra
100
+ /* 0010 80000010 8C420020 */ lw $v0, %lo(some_array - 0x4)($v0)
101
+ ```
102
+
103
+ ### Segment symbols in code
104
+
105
+ A common pattern seen on N64 projects is when the code references special symbols known as "segment symbols" to load some fragments or segments of the ROM into VRAM. N64 games do this because it isn't possible to load the whole ROM into VRAM, and also the N64 games lack a proper filesystem.
106
+
107
+ Segment symbols exist to describe addresses or sizes of specific regions of the ROM, like the start and end of the ROM addresses of a given segment, the expected start and end of the VRAM addresses of that segment, the size of the segment, etc.
108
+
109
+ Sadly the disassembler is unable to properly disambiguate these segment addresses from other symbols or even plain numbers, so disassembly of code referencing segment symbols tend to be far from optimal.
110
+
111
+ Take for example the following C code:
112
+
113
+ ```c
114
+ /* segment symbols */
115
+ u32 segment_menu_ROM_START[];
116
+ u32 segment_menu_ROM_END[];
117
+
118
+ void load_menu_segment(void *dst) {
119
+ load_segment(segment_menu_ROM_START, (u32)segment_menu_ROM_END - (u32)segment_menu_ROM_START, dst);
120
+ }
121
+ ```
122
+
123
+ After compiling this code, the generated assembly would look like the following:
124
+
125
+ ```mips
126
+ addiu $sp, $sp, -0x18
127
+ sw $ra, 0x10($sp)
128
+ addu $a2, $a0, $zero
129
+ lui $a0, %hi(segment_menu_ROM_START)
130
+ addiu $a0, $a0, %lo(segment_menu_ROM_START)
131
+ lui $a1, %hi(segment_menu_ROM_END)
132
+ addiu $a1, $a1, %lo(segment_menu_ROM_END)
133
+ jal load_segment
134
+ subu $a1, $a1, $a0
135
+ lw $ra, 0x10($sp)
136
+ addiu $sp, $sp, 0x18
137
+ jr $ra
138
+ nop
139
+ ```
140
+
141
+ But when this gets linked into a ROM those symbols get replaced with their raw numeric values, and since they point to rom addresses or vram addresses that are at the boundaries of each segment, the disassembler strugles symbolizing them, so it ends up symbolizing them into generic symbols, like the following:
142
+
143
+ ```mips
144
+ /* 0000 80000000 27BDFFE8 */ addiu $sp, $sp, -0x18
145
+ /* 0004 80000004 AFBF0010 */ sw $ra, 0x10($sp)
146
+ /* 0008 80000008 00803021 */ addu $a2, $a0, $zero
147
+ /* 000C 8000000C 3C040000 */ lui $a0, %hi(D_000FB480)
148
+ /* 0010 80000010 24840000 */ addiu $a0, $a0, %lo(D_000FB480)
149
+ /* 0014 80000014 3C050000 */ lui $a1, %hi(D_00101A80)
150
+ /* 0018 80000018 24A50000 */ addiu $a1, $a1, %lo(D_00101A80)
151
+ /* 001C 8000001C 0C000000 */ jal load_segment
152
+ /* 0020 80000020 00A42823 */ subu $a1, $a1, $a0
153
+ /* 0024 80000024 8FBF0010 */ lw $ra, 0x10($sp)
154
+ /* 0028 80000028 27BD0018 */ addiu $sp, $sp, 0x18
155
+ /* 002C 8000002C 03E00008 */ jr $ra
156
+ /* 0030 80000030 00000000 */ nop
157
+ ```
158
+
159
+ To fix the disassembly and make it use the proper segment symbols, we add more entries to the reloc_addrs.txt file. Note here we don't need to specify an `addend`, since we just want to refer to the symbol without any other calculation.
160
+
161
+ ```ini
162
+ rom:0x000C reloc:MIPS_HI16 symbol:segment_menu_ROM_START
163
+ rom:0x0010 reloc:MIPS_LO16 symbol:segment_menu_ROM_START
164
+ rom:0x0014 reloc:MIPS_HI16 symbol:segment_menu_ROM_END
165
+ rom:0x0018 reloc:MIPS_LO16 symbol:segment_menu_ROM_END
166
+ ```
167
+
168
+ ### Segment symbols in data
169
+
170
+ On the other side, segment symbols may be referenced in data structures like arrays or structs. [Here you can read a bit more about what segment symbols are](#segment-symbols-in-code).
171
+
172
+ Take for example the following C code and its corresponding compiled assembly:
173
+
174
+ ```c
175
+ u32 segment_menu_ROM_START[];
176
+ u32 segment_menu_ROM_END[];
177
+
178
+ u32 *menu_addresses[] = {
179
+ segment_menu_ROM_START, segment_menu_ROM_END,
180
+ }
181
+ ```
182
+
183
+ ```mips
184
+ .word segment_menu_ROM_START
185
+ .word segment_menu_ROM_END
186
+ ```
187
+
188
+ But when we try disassembling a rom with this data, the disassembler won't be able to recognize these as segment symbols:
189
+
190
+ ```mips
191
+ /* 0100 80000100 000FB480 */ .word D_000FB480 # It may use a D_ symbol
192
+ /* 0104 80000104 000FB480 */ .word 0x000FB480 # Or it may even fail completely to symbolize it
193
+ ```
194
+
195
+ In this case we can use the `MIPS_32` reloc in our `reloc_addrs` file to fix this kind of issue.
196
+
197
+ ```ini
198
+ rom:0x0100 reloc:MIPS_32 symbol:segment_menu_ROM_START
199
+ rom:0x0104 reloc:MIPS_32 symbol:segment_menu_ROM_END
200
+ ```
@@ -122,6 +122,21 @@ String that is placed before the contents of newly-generated assembly (`.s`) fil
122
122
  generated_s_preamble: .set fp=64
123
123
  ```
124
124
 
125
+ ### generated_macro_inc_content
126
+
127
+ String that is placed after the contents of the splat-generated `macro.inc` file.
128
+
129
+ ### generate_asm_macros_files
130
+
131
+ Tells splat to regenerate files containing assembly macros and C macros each time splat is run.
132
+
133
+ Specifically splat generates `include/include_asm.h`, `include/macro.inc`, `include/labels.inc` and `include/gte_macros.inc`, which contain the proper C and assembly macro definitions expected for building the generated assembly correctly. This allows splat to update the macro definitions with minimal user intervention and headaches.
134
+
135
+ Turning this off can be useful in case the user wants to control exactly the contents of those files, but it is not recommended, since the user definitions may get outdated. Before turning this option off consider using the [`generated_macro_inc_content`](#generated_macro_inc_content) option to customize the contents of the generated `macro.inc` file.
136
+
137
+ Some files may not be generated depending on the selected platform and compiler, because those setups don't require them. For example `include_asm.h` won't be generated if the compiler is set to `IDO` or `MWCCPS2`. `include/gte_macros.inc` is only generated on psx projects.
138
+
139
+ Defaults to `True`.
125
140
 
126
141
  ### o_as_suffix
127
142
 
@@ -203,9 +218,15 @@ symbol_addrs_path: path/to/symbol_addrs
203
218
 
204
219
 
205
220
 
206
- ### reloc_addrs_paths
221
+ ### reloc_addrs_path
222
+
223
+ Determines the path to the reloc addresses file(s). A `reloc_addrs` file contains metadata to override relocations within the generated assembly. For more information about the syntax and how to use it refer to the corresponding [reloc_addrs chapter](Advanced-Reloc.md).
207
224
 
225
+ It's possible to use more than one file by supplying a list instead of a string.
226
+
227
+ #### Default
208
228
 
229
+ `reloc_addrs.txt`
209
230
 
210
231
  ### build_path
211
232
  Path that built files will be found. Used for generation of the linker script.
@@ -647,19 +668,33 @@ Determines the macro used to declare functions in asm files
647
668
 
648
669
  ### asm_function_alt_macro
649
670
 
650
- Determines the macro used to declare symbols in the middle of functions in asm files (which may be alternative entries)
671
+ Determines the macro used to declare symbols in the middle of functions in asm files (which may be alternative entries).
672
+
673
+ Defaults to `alabel`.
651
674
 
652
675
  ### asm_jtbl_label_macro
653
676
 
654
- Determines the macro used to declare jumptable labels in asm files
677
+ Determines the macro used to declare jumptable labels in asm files.
678
+
679
+ Defaults to `jlabel`.
655
680
 
656
681
  ### asm_data_macro
657
682
 
658
- Determines the macro used to declare data symbols in asm files
683
+ Determines the macro used to declare data symbols in asm files.
684
+
685
+ Defaults to `dlabel`.
659
686
 
660
687
  ### asm_end_label
661
688
 
662
- Determines the macro used at the end of a function, such as endlabel or .end
689
+ Determines the macro used at the end of a function, such as `endlabel` or `.end`.
690
+
691
+ Defaults to `endlabel`.
692
+
693
+ ### asm_data_end_label
694
+
695
+ Determines the macro used at the end of a data symbol.
696
+
697
+ Defaults to `enddlabel`.
663
698
 
664
699
  ### asm_ehtable_label_macro
665
700
 
@@ -667,6 +702,14 @@ Determines the macro used to declare ehtable labels in asm files.
667
702
 
668
703
  Defaults to `ehlabel`
669
704
 
705
+ ### asm_nonmatching_label_macro
706
+
707
+ Determines the macro used to declare the given symbol is a non matching one.
708
+
709
+ Explicitly specifying that a symbol haven't been matched yet in the generated assembly is useful for other tools that consume the build artifacts of the project. This information can be used by those tools for stuff like progress reporting.
710
+
711
+ Defaults to `nonmatching`
712
+
670
713
  ### asm_emit_size_directive
671
714
 
672
715
  Toggles the .size directive emitted by the disassembler
@@ -118,7 +118,7 @@ The macros to include text/rodata assembly are different for GCC vs IDO compiler
118
118
  **GCC**: `INCLUDE_ASM` & `INCLUDE_RODATA` (text/rodata respectively)
119
119
  **IDO**: `GLOBAL_ASM`
120
120
 
121
- These macros must be defined in an included header, which splat currently does not produce.
121
+ These macros must be defined in an included header, which splat generates and updates by default for GCC-based projects.
122
122
 
123
123
  For a GCC example, see the [include.h](https://github.com/AngheloAlf/drmario64/blob/master/include/include_asm.h) from the Dr. Mario project.
124
124
 
@@ -130,27 +130,75 @@ For MWCC, you will need [mwccgap](https://github.com/mkst/mwccgap) to include as
130
130
 
131
131
  splat relies on some assembly macros for the asm generation. They usually live on the `include/macro.inc` file. Without these macros then an assembler would not be able to build our disassemblies.
132
132
 
133
+ By default splat will generate files with the required assembly macros.
134
+
133
135
  Those macros usually look like this:
134
136
 
135
137
  ```mips
136
- .macro glabel label
137
- .global \label
138
+ # A function symbol.
139
+ .macro glabel label, visibility=global
140
+ .\visibility \label
138
141
  .type \label, @function
139
142
  \label:
143
+ .ent \label
140
144
  .endm
141
145
 
142
- .macro dlabel label
143
- .global \label
146
+ # The end of a function symbol.
147
+ .macro endlabel label
148
+ .size \label, . - \label
149
+ .end \label
150
+ .endm
151
+
152
+ # An alternative entry to a function.
153
+ .macro alabel label, visibility=global
154
+ .\visibility \label
155
+ .type \label, @function
144
156
  \label:
157
+ .aent \label
145
158
  .endm
146
159
 
160
+ # A label referenced by an error handler table.
161
+ .macro ehlabel label, visibility=global
162
+ .\visibility \label
163
+ \label:
164
+ .endm
165
+
166
+
167
+ # A label referenced by a jumptable.
147
168
  .macro jlabel label
148
169
  .global \label
149
170
  \label:
150
171
  .endm
172
+
173
+
174
+ # A data symbol.
175
+ .macro dlabel label, visibility=global
176
+ .\visibility \label
177
+ .type \label, @object
178
+ \label:
179
+ .endm
180
+
181
+ # End of a data symbol.
182
+ .macro enddlabel label
183
+ .size \label, . - \label
184
+ .endm
185
+
186
+
187
+ # Label to signal the symbol haven't been matched yet.
188
+ .macro nonmatching label, size=1
189
+ .global \label\().NON_MATCHING
190
+ .type \label\().NON_MATCHING, @object
191
+ .size \label\().NON_MATCHING, \size
192
+ \label\().NON_MATCHING:
193
+ .endm
151
194
  ```
152
195
 
153
- Where `glabel` is used for functions, `dlabel` is used for data, rodata and bss variables and `jlabel` is used for branch labels used by jumptables.
196
+ The most commonly used labels are:
197
+
198
+ - `glabel` and `endlabel` which are used to define function symbols.
199
+ - `dlabel` and `enddlabel` which are used to defined data, rodata and bss symbols.
200
+ - `jlabel` is used for defining branch labels used by jumptables.
201
+ - `nonmatching` is used to define the symbol haven't been matched yet.
154
202
 
155
203
  Asm differ tools can sometimes struggle to show diffs with `jlabel`s when combined with certain compilers. A workaround for this issue is to mark the `jlabel` as a function, like this:
156
204
 
@@ -583,3 +583,36 @@ Defaults to the global option.
583
583
  vram: 0x80000460
584
584
  suggestion_rodata_section_start: False
585
585
  ```
586
+
587
+ ### `pair_segment`
588
+
589
+ Allows pairing sections of two different segments together.
590
+
591
+ The main purpose of this is to make the automatic rodata-to-function migration possible, since the default behavior only allows pairing different sections of the same name under the same segment only. This kind of ROM layout can be seen on some TLB games from N64 projects.
592
+
593
+ This value expects the name of the other segment that should be paired to the current one. Only one of the two to-be-paired segments should have this attribute.
594
+
595
+ **Example:**
596
+
597
+ ```yaml
598
+ - name: init
599
+ type: code
600
+ start: 0x00001000
601
+ vram: 0x10001000
602
+ pair_segment: init_data # This is the name of the following segment.
603
+ subsegments:
604
+ # -- snip --
605
+ - [0x15550, c, libultra/audio/init_15550]
606
+ # -- snip --
607
+
608
+ - name: init_data
609
+ type: code
610
+ start: 0x000290D0
611
+ vram: 0x800290D0
612
+ bss_size: 0x16690
613
+ # Note there's no `pair_segment: init` on this segment.
614
+ subsegments:
615
+ # -- snip --
616
+ - [0x2C6B0, .rodata, libultra/audio/init_15550]
617
+ # -- snip --
618
+ ```
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "splat64"
3
3
  # Should be synced with src/splat/__init__.py
4
- version = "0.34.3"
4
+ version = "0.35.0"
5
5
  description = "A binary splitting tool to assist with decompilation and modding projects"
6
6
  readme = "README.md"
7
7
  license = {file = "LICENSE"}
@@ -4,7 +4,7 @@ tqdm
4
4
  intervaltree
5
5
  colorama
6
6
  # This value should be keep in sync with the version listed on disassembler/spimdisasm_disassembler.py and pyproject.toml
7
- spimdisasm>=1.33.0
7
+ spimdisasm>=1.36.0
8
8
  rabbitizer>=1.10.0
9
9
  pygfxd
10
10
  n64img>=0.1.4
@@ -1,7 +1,7 @@
1
1
  __package_name__ = __name__
2
2
 
3
3
  # Should be synced with pyproject.toml
4
- __version__ = "0.34.3"
4
+ __version__ = "0.35.0"
5
5
  __author__ = "ethteck"
6
6
 
7
7
  from . import util as util
@@ -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, 33, 0)
10
+ SPIMDISASM_MIN = (1, 36, 0)
11
11
 
12
12
  def configure(self):
13
13
  # Configure spimdisasm
@@ -93,9 +93,15 @@ class SpimdisasmDisassembler(disassembler.Disassembler):
93
93
  )
94
94
  spimdisasm.common.GlobalConfig.ASM_DATA_LABEL = options.opts.asm_data_macro
95
95
  spimdisasm.common.GlobalConfig.ASM_TEXT_END_LABEL = options.opts.asm_end_label
96
+ spimdisasm.common.GlobalConfig.ASM_DATA_END_LABEL = (
97
+ options.opts.asm_data_end_label
98
+ )
96
99
  spimdisasm.common.GlobalConfig.ASM_EHTBL_LABEL = (
97
100
  options.opts.asm_ehtable_label_macro
98
101
  )
102
+ spimdisasm.common.GlobalConfig.ASM_NM_LABEL = (
103
+ options.opts.asm_nonmatching_label_macro
104
+ )
99
105
 
100
106
  if options.opts.asm_emit_size_directive is not None:
101
107
  spimdisasm.common.GlobalConfig.ASM_EMIT_SIZE_DIRECTIVE = (